Line data Source code
1 : #if !defined(_RADIOLIB_MODULE_H)
2 : #define _RADIOLIB_MODULE_H
3 :
4 : #include "TypeDef.h"
5 : #include "Hal.h"
6 : #include "utils/Utils.h"
7 :
8 : #if defined(RADIOLIB_BUILD_ARDUINO)
9 : #include <SPI.h>
10 : #endif
11 :
12 : // Keep this SubGhz include here to fix Platformio LDO (#718).
13 : #if defined(STM32WLxx)
14 : #include <SubGhz.h>
15 : #endif
16 :
17 : /*!
18 : \def END_OF_MODE_TABLE Value to use as the last element in a mode table to indicate the
19 : end of the table. See \ref setRfSwitchTable for details.
20 : */
21 : #define END_OF_MODE_TABLE { Module::MODE_END_OF_TABLE, {} }
22 :
23 : /*!
24 : \def RFSWITCH_PIN_FLAG Bit flag used to mark unused pins in RF switch pin map. This can be either
25 : unconnected pin marked with RADIOLIB_NC, or a pin controlled by the radio (e.g. DIOx pins on LR11x0),
26 : as opposed to an MCU-controlled GPIO pin.
27 : */
28 : #define RFSWITCH_PIN_FLAG (0x01UL << 31)
29 :
30 : /*!
31 : \defgroup module_spi_command_pos Position of commands in Module::spiConfig command array.
32 : \{
33 : */
34 :
35 : /*! \def RADIOLIB_MODULE_SPI_COMMAND_READ Position of the read command. */
36 : #define RADIOLIB_MODULE_SPI_COMMAND_READ (0)
37 :
38 : /*! \def RADIOLIB_MODULE_SPI_COMMAND_WRITE Position of the write command. */
39 : #define RADIOLIB_MODULE_SPI_COMMAND_WRITE (1)
40 :
41 : /*! \def RADIOLIB_MODULE_SPI_COMMAND_NOP Position of the no-operation command. */
42 : #define RADIOLIB_MODULE_SPI_COMMAND_NOP (2)
43 :
44 : /*! \def RADIOLIB_MODULE_SPI_COMMAND_STATUS Position of the status command. */
45 : #define RADIOLIB_MODULE_SPI_COMMAND_STATUS (3)
46 :
47 : /*!
48 : \}
49 : */
50 :
51 : /*!
52 : \defgroup module_spi_width_pos Position of bit field widths in Module::spiConfig width array.
53 : \{
54 : */
55 :
56 : /*! \def RADIOLIB_MODULE_SPI_WIDTH_ADDR Position of the address width. */
57 : #define RADIOLIB_MODULE_SPI_WIDTH_ADDR (0)
58 :
59 : /*! \def RADIOLIB_MODULE_SPI_WIDTH_CMD Position of the command width. */
60 : #define RADIOLIB_MODULE_SPI_WIDTH_CMD (1)
61 :
62 : /*! \def RADIOLIB_MODULE_SPI_WIDTH_STATUS Position of the status width. */
63 : #define RADIOLIB_MODULE_SPI_WIDTH_STATUS (2)
64 :
65 : /*!
66 : \}
67 : */
68 :
69 : /*!
70 : \class Module
71 : \brief Implements all common low-level methods to control the wireless module.
72 : Every module class contains one private instance of this class.
73 : */
74 : class Module {
75 : public:
76 : /*!
77 : \brief The maximum number of pins supported by the RF switch code.
78 : Note: It is not recommended to use this constant in your sketch
79 : when defining a rfswitch pins array, to prevent issues when this
80 : value is ever increased and such an array gets extra zero
81 : elements (that will be interpreted as pin 0).
82 : */
83 : static const size_t RFSWITCH_MAX_PINS = 5;
84 :
85 : /*!
86 : \struct RfSwitchMode_t
87 : \brief Description of RF switch pin states for a single mode.
88 : See \ref setRfSwitchTable for details.
89 : */
90 : struct RfSwitchMode_t {
91 : /*! \brief RF switching mode, one of \ref OpMode_t or a custom radio-defined value. */
92 : uint8_t mode;
93 :
94 : /*! \brief Output pin values */
95 : uint32_t values[RFSWITCH_MAX_PINS];
96 : };
97 :
98 : /*!
99 : \enum OpMode_t
100 : \brief Constants to use in a mode table set be setRfSwitchTable. These
101 : constants work for most radios, but some radios define their own
102 : constants to be used instead.
103 :
104 : See \ref setRfSwitchTable for details.
105 : */
106 : enum OpMode_t {
107 : /*!
108 : \brief End of table marker, use \ref END_OF_MODE_TABLE constant instead.
109 : Value is zero to ensure zero-initialized mode ends the table.
110 : */
111 : MODE_END_OF_TABLE = 0,
112 :
113 : /*! \brief Idle mode */
114 : MODE_IDLE,
115 :
116 : /*! \brief Receive mode */
117 : MODE_RX,
118 :
119 : /*! \brief Transmission mode */
120 : MODE_TX,
121 : };
122 :
123 : #if defined(RADIOLIB_BUILD_ARDUINO)
124 : /*!
125 : \brief Arduino Module constructor. Will use the default SPI interface and automatically initialize it.
126 : \param cs Arduino pin to be used as chip select.
127 : \param irq Arduino pin to be used as interrupt/GPIO.
128 : \param rst Arduino pin to be used as hardware reset for the module.
129 : \param gpio Arduino pin to be used as additional interrupt/GPIO.
130 : */
131 : Module(uint32_t cs, uint32_t irq, uint32_t rst, uint32_t gpio = RADIOLIB_NC);
132 :
133 : /*!
134 : \brief Arduino Module constructor. Will not attempt SPI interface initialization.
135 : \param cs Arduino pin to be used as chip select.
136 : \param irq Arduino pin to be used as interrupt/GPIO.
137 : \param rst Arduino pin to be used as hardware reset for the module.
138 : \param gpio Arduino pin to be used as additional interrupt/GPIO.
139 : \param spi SPI interface to be used, can also use software SPI implementations.
140 : \param spiSettings SPI interface settings.
141 : */
142 : Module(uint32_t cs, uint32_t irq, uint32_t rst, uint32_t gpio, SPIClass& spi, SPISettings spiSettings = RADIOLIB_DEFAULT_SPI_SETTINGS);
143 : #endif
144 :
145 : /*!
146 : \brief Module constructor.
147 : \param hal A Hardware abstraction layer instance. An ArduinoHal instance for example.
148 : \param cs Pin to be used as chip select.
149 : \param irq Pin to be used as interrupt/GPIO.
150 : \param rst Pin to be used as hardware reset for the module.
151 : \param gpio Pin to be used as additional interrupt/GPIO.
152 : */
153 : Module(RadioLibHal *hal, uint32_t cs, uint32_t irq, uint32_t rst, uint32_t gpio = RADIOLIB_NC);
154 :
155 : /*!
156 : \brief Copy constructor.
157 : \param mod Module instance to copy.
158 : */
159 : Module(const Module& mod);
160 :
161 : /*!
162 : \brief Overload for assignment operator.
163 : \param mod rvalue Module.
164 : */
165 : Module& operator=(const Module& mod);
166 :
167 : // public member variables
168 : /*! \brief Hardware abstraction layer to be used. */
169 : RadioLibHal* hal = NULL;
170 :
171 : /*! \brief Callback for parsing SPI status. */
172 : typedef int16_t (*SPIparseStatusCb_t)(uint8_t in);
173 :
174 : /*! \brief Callback for validation SPI status. */
175 : typedef int16_t (*SPIcheckStatusCb_t)(Module* mod);
176 :
177 : enum BitWidth_t {
178 : BITS_0 = 0,
179 : BITS_8 = 8,
180 : BITS_16 = 16,
181 : BITS_24 = 24,
182 : BITS_32 = 32,
183 : };
184 :
185 : /*!
186 : \struct SPIConfig_t
187 : \brief SPI configuration structure.
188 : */
189 : struct SPIConfig_t {
190 : /*! \brief Whether the SPI module is stream-type (SX126x/8x) or registrer access type (SX127x, CC1101 etc). */
191 : bool stream;
192 :
193 : /*! \brief Last recorded SPI error - only updated for modules that return status during SPI transfers. */
194 : int16_t err;
195 :
196 : /*! \brief SPI commands */
197 : uint16_t cmds[4];
198 :
199 : /*! \brief Bit widths of SPI addresses, commands and status bytes */
200 : BitWidth_t widths[3];
201 :
202 : /*! \brief Byte position of status command in SPI stream */
203 : uint8_t statusPos;
204 :
205 : /*! \brief Callback for parsing SPI status. */
206 : SPIparseStatusCb_t parseStatusCb;
207 :
208 : /*! \brief Callback for validation SPI status. */
209 : SPIcheckStatusCb_t checkStatusCb;
210 :
211 : /*! \brief Timeout in ms when waiting for GPIO signals. */
212 : RadioLibTime_t timeout;
213 : };
214 :
215 : /*! \brief SPI configuration structure. The default configuration corresponds to register-access modules, such as SX127x. */
216 : SPIConfig_t spiConfig = {
217 : .stream = false,
218 : .err = RADIOLIB_ERR_UNKNOWN,
219 : .cmds = { 0x00, 0x80, 0x00, 0x00 },
220 : .widths = { Module::BITS_8, Module::BITS_0, Module::BITS_8 },
221 : .statusPos = 0,
222 : .parseStatusCb = nullptr,
223 : .checkStatusCb = nullptr,
224 : .timeout = 1000,
225 : };
226 :
227 : #if RADIOLIB_INTERRUPT_TIMING
228 :
229 : /*!
230 : \brief Timer interrupt setup callback typedef.
231 : */
232 : typedef void (*TimerSetupCb_t)(uint32_t len);
233 :
234 : /*!
235 : \brief Callback to timer interrupt setup function when running in interrupt timing control mode.
236 : */
237 : TimerSetupCb_t TimerSetupCb = nullptr;
238 :
239 : /*!
240 : \brief Timer flag variable to be controlled by a platform-dependent interrupt.
241 : */
242 : volatile bool TimerFlag = false;
243 :
244 : #endif
245 :
246 : // basic methods
247 :
248 : /*!
249 : \brief Initialize low-level module control.
250 : */
251 : void init();
252 :
253 : /*!
254 : \brief Terminate low-level module control.
255 : */
256 : void term();
257 :
258 : // SPI methods
259 :
260 : /*!
261 : \brief SPI read method that automatically masks unused bits. This method is the preferred SPI read mechanism.
262 : \param reg Address of SPI register to read.
263 : \param msb Most significant bit of the register variable. Bits above this one will be masked out.
264 : \param lsb Least significant bit of the register variable. Bits below this one will be masked out.
265 : \returns Masked register value or status code.
266 : */
267 : int16_t SPIgetRegValue(uint32_t reg, uint8_t msb = 7, uint8_t lsb = 0);
268 :
269 : /*!
270 : \brief Overwrite-safe SPI write method with verification. This method is the preferred SPI write mechanism.
271 : \param reg Address of SPI register to write.
272 : \param value Single byte value that will be written to the SPI register.
273 : \param msb Most significant bit of the register variable. Bits above this one will not be affected by the write operation.
274 : \param lsb Least significant bit of the register variable. Bits below this one will not be affected by the write operation.
275 : \param checkInterval Number of milliseconds between register writing and verification reading. Some registers need up to 10ms to process the change.
276 : \param checkMask Mask of bits to check, only bits set to 1 will be verified.
277 : \param force Write new value even if the old value is the same.
278 : \returns \ref status_codes
279 : */
280 : int16_t SPIsetRegValue(uint32_t reg, uint8_t value, uint8_t msb = 7, uint8_t lsb = 0, uint8_t checkInterval = 2, uint8_t checkMask = 0xFF, bool force = false);
281 :
282 : /*!
283 : \brief SPI burst read method.
284 : \param reg Address of SPI register to read.
285 : \param numBytes Number of bytes that will be read.
286 : \param inBytes Pointer to array that will hold the read data.
287 : */
288 : void SPIreadRegisterBurst(uint32_t reg, size_t numBytes, uint8_t* inBytes);
289 :
290 : /*!
291 : \brief SPI basic read method. Use of this method is reserved for special cases, SPIgetRegValue should be used instead.
292 : \param reg Address of SPI register to read.
293 : \returns Value that was read from register.
294 : */
295 : uint8_t SPIreadRegister(uint32_t reg);
296 :
297 : /*!
298 : \brief SPI burst write method.
299 : \param reg Address of SPI register to write.
300 : \param data Pointer to array that holds the data that will be written.
301 : \param numBytes Number of bytes that will be written.
302 : */
303 : void SPIwriteRegisterBurst(uint32_t reg, const uint8_t* data, size_t numBytes);
304 :
305 : /*!
306 : \brief SPI basic write method. Use of this method is reserved for special cases, SPIsetRegValue should be used instead.
307 : \param reg Address of SPI register to write.
308 : \param data Value that will be written to the register.
309 : */
310 : void SPIwriteRegister(uint32_t reg, uint8_t data);
311 :
312 : /*!
313 : \brief SPI single transfer method.
314 : \param cmd SPI access command (read/write/burst/...).
315 : \param reg Address of SPI register to transfer to/from.
316 : \param dataOut Data that will be transferred from master to slave.
317 : \param dataIn Data that was transferred from slave to master.
318 : \param numBytes Number of bytes to transfer.
319 : */
320 : void SPItransfer(uint16_t cmd, uint32_t reg, const uint8_t* dataOut, uint8_t* dataIn, size_t numBytes);
321 :
322 : /*!
323 : \brief Method to check the result of last SPI stream transfer.
324 : \returns \ref status_codes
325 : */
326 : int16_t SPIcheckStream();
327 :
328 : /*!
329 : \brief Method to perform a read transaction with SPI stream.
330 : \param cmd SPI operation command.
331 : \param data Data that will be transferred from slave to master.
332 : \param numBytes Number of bytes to transfer.
333 : \param waitForGpio Whether to wait for some GPIO at the end of transfer (e.g. BUSY line on SX126x/SX128x).
334 : \param verify Whether to verify the result of the transaction after it is finished.
335 : \returns \ref status_codes
336 : */
337 : int16_t SPIreadStream(uint16_t cmd, uint8_t* data, size_t numBytes, bool waitForGpio = true, bool verify = true);
338 :
339 : /*!
340 : \brief Method to perform a read transaction with SPI stream.
341 : \param cmd SPI operation command.
342 : \param cmdLen SPI command length in bytes.
343 : \param data Data that will be transferred from slave to master.
344 : \param numBytes Number of bytes to transfer.
345 : \param waitForGpio Whether to wait for some GPIO at the end of transfer (e.g. BUSY line on SX126x/SX128x).
346 : \param verify Whether to verify the result of the transaction after it is finished.
347 : \returns \ref status_codes
348 : */
349 : int16_t SPIreadStream(const uint8_t* cmd, uint8_t cmdLen, uint8_t* data, size_t numBytes, bool waitForGpio = true, bool verify = true);
350 :
351 : /*!
352 : \brief Method to perform a write transaction with SPI stream.
353 : \param cmd SPI operation command.
354 : \param data Data that will be transferred from master to slave.
355 : \param numBytes Number of bytes to transfer.
356 : \param waitForGpio Whether to wait for some GPIO at the end of transfer (e.g. BUSY line on SX126x/SX128x).
357 : \param verify Whether to verify the result of the transaction after it is finished.
358 : \returns \ref status_codes
359 : */
360 : int16_t SPIwriteStream(uint16_t cmd, const uint8_t* data, size_t numBytes, bool waitForGpio = true, bool verify = true);
361 :
362 : /*!
363 : \brief Method to perform a write transaction with SPI stream.
364 : \param cmd SPI operation command.
365 : \param cmdLen SPI command length in bytes.
366 : \param data Data that will be transferred from master to slave.
367 : \param numBytes Number of bytes to transfer.
368 : \param waitForGpio Whether to wait for some GPIO at the end of transfer (e.g. BUSY line on SX126x/SX128x).
369 : \param verify Whether to verify the result of the transaction after it is finished.
370 : \returns \ref status_codes
371 : */
372 : int16_t SPIwriteStream(const uint8_t* cmd, uint8_t cmdLen, const uint8_t* data, size_t numBytes, bool waitForGpio = true, bool verify = true);
373 :
374 : /*!
375 : \brief SPI single transfer method for modules with stream-type SPI interface (SX126x, SX128x etc.).
376 : \param cmd SPI operation command.
377 : \param cmdLen SPI command length in bytes.
378 : \param write Set to true for write commands, false for read commands.
379 : \param dataOut Data that will be transferred from master to slave.
380 : \param dataIn Data that was transferred from slave to master.
381 : \param numBytes Number of bytes to transfer.
382 : \param waitForGpio Whether to wait for some GPIO at the end of transfer (e.g. BUSY line on SX126x/SX128x).
383 : \returns \ref status_codes
384 : */
385 : int16_t SPItransferStream(const uint8_t* cmd, uint8_t cmdLen, bool write, const uint8_t* dataOut, uint8_t* dataIn, size_t numBytes, bool waitForGpio);
386 :
387 : // pin number access methods
388 : // getCs is omitted on purpose, as it can interfere when accessing the SPI in a concurrent environment
389 : // so it is considered to be part of the SPI pins and hence not accessible from outside
390 : // see https://github.com/jgromes/RadioLib/discussions/1364
391 :
392 : /*!
393 : \brief Access method to get the pin number of interrupt/GPIO.
394 : \returns Pin number of interrupt/GPIO configured in the constructor.
395 : */
396 0 : uint32_t getIrq() const { return(irqPin); }
397 :
398 : /*!
399 : \brief Access method to get the pin number of hardware reset pin.
400 : \returns Pin number of hardware reset pin configured in the constructor.
401 : */
402 0 : uint32_t getRst() const { return(rstPin); }
403 :
404 : /*!
405 : \brief Access method to get the pin number of second interrupt/GPIO.
406 : \returns Pin number of second interrupt/GPIO configured in the constructor.
407 : */
408 0 : uint32_t getGpio() const { return(gpioPin); }
409 :
410 : /*!
411 : \brief Some modules contain external RF switch controlled by pins.
412 : This function gives RadioLib control over those pins to
413 : automatically switch between various modes: When idle both pins
414 : will be LOW, during TX the `txEn` pin will be HIGH, during RX the
415 : `rxPin` will be HIGH.
416 :
417 : Radiolib will automatically set the pin mode and value of these
418 : pins, so do not control them from the sketch.
419 :
420 : When more than two pins or more control over the output values are
421 : needed, use the setRfSwitchTable() function.
422 :
423 : \param rxEn RX enable pin.
424 : \param txEn TX enable pin.
425 : */
426 : void setRfSwitchPins(uint32_t rxEn, uint32_t txEn);
427 :
428 : /*!
429 : \brief Some modules contain external RF switch controlled by pins.
430 : This function gives RadioLib control over those pins to
431 : automatically switch between various modes.
432 :
433 : Radiolib will automatically set the pin mode and value of these
434 : pins, so do not control them from the sketch.
435 :
436 :
437 : \param pins A reference to an array of pins to control. This
438 : should always be an array of 5 elements. If you need less pins,
439 : use RADIOLIB_NC for the unused elements.
440 :
441 : \param table A reference to an array of pin values to use for each
442 : supported mode. Each element is an RfSwitchMode_T struct that
443 : lists the mode for which it applies and the values for each of the
444 : pins passed in the pins argument respectively.
445 :
446 : The `pins` array will be copied into the Module object, so the
447 : original array can be deallocated after this call. However,
448 : a reference to the `table` array will be stored, so that array
449 : must remain valid as long RadioLib is being used.
450 :
451 : The `mode` field in each table row should normally use any of the
452 : `MODE_*` constants from the Module::OpMode_t enum. However, some
453 : radios support additional modes and will define their own OpMode_t
454 : enum.
455 :
456 : The length of the table is variable (to support radios that add
457 : additional modes), so the table must always be terminated with the
458 : special END_OF_MODE_TABLE value.
459 :
460 : Normally all modes should be listed in the table, but for some
461 : radios, modes can be omitted to indicate they are not supported
462 : (e.g. when a radio has a high power and low power TX mode but
463 : external circuitry only supports low power). If applicable, this
464 : is documented in the radio class itself.
465 :
466 : #### Example
467 : For example, on a board that has an RF switch with an enable pin
468 : connected to PA0 and a TX/RX select pin connected to PA1:
469 :
470 : \code
471 : // In global scope, define the pin array and mode table
472 : static const uint32_t rfswitch_pins[] =
473 : {PA0, PA1, RADIOLIB_NC, RADIOLIB_NC, RADIOLIB_NC};
474 : static const Module::RfSwitchMode_t rfswitch_table[] = {
475 : {Module::MODE_IDLE, {LOW, LOW}},
476 : {Module::MODE_RX, {HIGH, LOW}},
477 : {Module::MODE_TX, {HIGH, HIGH}},
478 : Module::END_OF_MODE_TABLE,
479 : };
480 :
481 : void setup() {
482 : ...
483 : // Then somewhere in setup, pass them to radiolib
484 : radio.setRfSwitchTable(rfswitch_pins, rfswitch_table);
485 : ...
486 : }
487 : \endcode
488 : */
489 :
490 : void setRfSwitchTable(const uint32_t (&pins)[RFSWITCH_MAX_PINS], const RfSwitchMode_t table[]);
491 :
492 : /*!
493 : \brief Find a mode in the RfSwitchTable.
494 : \param mode The mode to find.
495 : \returns A pointer to the RfSwitchMode_t struct in the table that
496 : matches the passed mode. Returns nullptr if no rfswitch pins are
497 : configured, or the passed mode is not listed in the table.
498 : */
499 : const RfSwitchMode_t *findRfSwitchMode(uint8_t mode) const;
500 :
501 : /*!
502 : \brief Set RF switch state.
503 : \param mode The mode to set. This must be one of the MODE_ constants, or a radio-specific constant.
504 : */
505 : void setRfSwitchState(uint8_t mode);
506 :
507 : /*!
508 : \brief Wait for time to elapse, either using the microsecond timer, or the TimerFlag.
509 : Note that in interrupt timing mode, it is up to the user to set up the timing interrupt!
510 :
511 : \param start Waiting start timestamp, in microseconds.
512 : \param len Waiting duration, in microseconds;
513 : */
514 : void waitForMicroseconds(RadioLibTime_t start, RadioLibTime_t len);
515 :
516 : #if RADIOLIB_DEBUG
517 : /*!
518 : \brief Function to dump device registers as hex into the debug port.
519 : \param level RadioLib debug level, set to NULL to not print.
520 : \param start First address to dump.
521 : \param len Number of bytes to dump.
522 : */
523 : void regdump(const char* level, uint16_t start, size_t len);
524 : #endif
525 :
526 : #if !RADIOLIB_GODMODE
527 : private:
528 : #endif
529 : uint32_t csPin = RADIOLIB_NC;
530 : uint32_t irqPin = RADIOLIB_NC;
531 : uint32_t rstPin = RADIOLIB_NC;
532 : uint32_t gpioPin = RADIOLIB_NC;
533 :
534 : // RF switch pins and table
535 : uint32_t rfSwitchPins[RFSWITCH_MAX_PINS] = { RADIOLIB_NC, RADIOLIB_NC, RADIOLIB_NC, RADIOLIB_NC, RADIOLIB_NC };
536 : const RfSwitchMode_t *rfSwitchTable = nullptr;
537 :
538 : #if RADIOLIB_INTERRUPT_TIMING
539 : uint32_t prevTimingLen = 0;
540 : #endif
541 : };
542 :
543 : #endif
|