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 : \returns \ref status_codes
251 : */
252 : int16_t init();
253 :
254 : /*!
255 : \brief Terminate low-level module control.
256 : \returns \ref status_codes
257 : */
258 : int16_t term();
259 :
260 : // SPI methods
261 :
262 : /*!
263 : \brief SPI read method that automatically masks unused bits. This method is the preferred SPI read mechanism.
264 : \param reg Address of SPI register to read.
265 : \param msb Most significant bit of the register variable. Bits above this one will be masked out.
266 : \param lsb Least significant bit of the register variable. Bits below this one will be masked out.
267 : \returns Masked register value or status code.
268 : */
269 : int16_t SPIgetRegValue(uint32_t reg, uint8_t msb = 7, uint8_t lsb = 0);
270 :
271 : /*!
272 : \brief Overwrite-safe SPI write method with verification. This method is the preferred SPI write mechanism.
273 : \param reg Address of SPI register to write.
274 : \param value Single byte value that will be written to the SPI register.
275 : \param msb Most significant bit of the register variable. Bits above this one will not be affected by the write operation.
276 : \param lsb Least significant bit of the register variable. Bits below this one will not be affected by the write operation.
277 : \param checkInterval Number of milliseconds between register writing and verification reading. Some registers need up to 10ms to process the change.
278 : \param checkMask Mask of bits to check, only bits set to 1 will be verified.
279 : \param force Write new value even if the old value is the same.
280 : \returns \ref status_codes
281 : */
282 : 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);
283 :
284 : /*!
285 : \brief SPI burst read method.
286 : \param reg Address of SPI register to read.
287 : \param numBytes Number of bytes that will be read.
288 : \param inBytes Pointer to array that will hold the read data.
289 : */
290 : void SPIreadRegisterBurst(uint32_t reg, size_t numBytes, uint8_t* inBytes);
291 :
292 : /*!
293 : \brief SPI basic read method. Use of this method is reserved for special cases, SPIgetRegValue should be used instead.
294 : \param reg Address of SPI register to read.
295 : \returns Value that was read from register.
296 : */
297 : uint8_t SPIreadRegister(uint32_t reg);
298 :
299 : /*!
300 : \brief SPI burst write method.
301 : \param reg Address of SPI register to write.
302 : \param data Pointer to array that holds the data that will be written.
303 : \param numBytes Number of bytes that will be written.
304 : */
305 : void SPIwriteRegisterBurst(uint32_t reg, const uint8_t* data, size_t numBytes);
306 :
307 : /*!
308 : \brief SPI basic write method. Use of this method is reserved for special cases, SPIsetRegValue should be used instead.
309 : \param reg Address of SPI register to write.
310 : \param data Value that will be written to the register.
311 : */
312 : void SPIwriteRegister(uint32_t reg, uint8_t data);
313 :
314 : /*!
315 : \brief SPI single transfer method.
316 : \param cmd SPI access command (read/write/burst/...).
317 : \param reg Address of SPI register to transfer to/from.
318 : \param dataOut Data that will be transferred from master to slave.
319 : \param dataIn Data that was transferred from slave to master.
320 : \param numBytes Number of bytes to transfer.
321 : */
322 : void SPItransfer(uint16_t cmd, uint32_t reg, const uint8_t* dataOut, uint8_t* dataIn, size_t numBytes);
323 :
324 : /*!
325 : \brief Method to check the result of last SPI stream transfer.
326 : \returns \ref status_codes
327 : */
328 : int16_t SPIcheckStream();
329 :
330 : /*!
331 : \brief Method to perform a read transaction with SPI stream.
332 : \param cmd SPI operation command.
333 : \param data Data that will be transferred from slave to master.
334 : \param numBytes Number of bytes to transfer.
335 : \param waitForGpio Whether to wait for some GPIO at the end of transfer (e.g. BUSY line on SX126x/SX128x).
336 : \param verify Whether to verify the result of the transaction after it is finished.
337 : \returns \ref status_codes
338 : */
339 : int16_t SPIreadStream(uint16_t cmd, uint8_t* data, size_t numBytes, bool waitForGpio = true, bool verify = true);
340 :
341 : /*!
342 : \brief Method to perform a read transaction with SPI stream.
343 : \param cmd SPI operation command.
344 : \param cmdLen SPI command length in bytes.
345 : \param data Data that will be transferred from slave to master.
346 : \param numBytes Number of bytes to transfer.
347 : \param waitForGpio Whether to wait for some GPIO at the end of transfer (e.g. BUSY line on SX126x/SX128x).
348 : \param verify Whether to verify the result of the transaction after it is finished.
349 : \returns \ref status_codes
350 : */
351 : int16_t SPIreadStream(const uint8_t* cmd, uint8_t cmdLen, uint8_t* data, size_t numBytes, bool waitForGpio = true, bool verify = true);
352 :
353 : /*!
354 : \brief Method to perform a write transaction with SPI stream.
355 : \param cmd SPI operation command.
356 : \param data Data that will be transferred from master to slave.
357 : \param numBytes Number of bytes to transfer.
358 : \param waitForGpio Whether to wait for some GPIO at the end of transfer (e.g. BUSY line on SX126x/SX128x).
359 : \param verify Whether to verify the result of the transaction after it is finished.
360 : \returns \ref status_codes
361 : */
362 : int16_t SPIwriteStream(uint16_t cmd, const uint8_t* data, size_t numBytes, bool waitForGpio = true, bool verify = true);
363 :
364 : /*!
365 : \brief Method to perform a write transaction with SPI stream.
366 : \param cmd SPI operation command.
367 : \param cmdLen SPI command length in bytes.
368 : \param data Data that will be transferred from master to slave.
369 : \param numBytes Number of bytes to transfer.
370 : \param waitForGpio Whether to wait for some GPIO at the end of transfer (e.g. BUSY line on SX126x/SX128x).
371 : \param verify Whether to verify the result of the transaction after it is finished.
372 : \returns \ref status_codes
373 : */
374 : int16_t SPIwriteStream(const uint8_t* cmd, uint8_t cmdLen, const uint8_t* data, size_t numBytes, bool waitForGpio = true, bool verify = true);
375 :
376 : /*!
377 : \brief SPI single transfer method for modules with stream-type SPI interface (SX126x, SX128x etc.).
378 : \param cmd SPI operation command.
379 : \param cmdLen SPI command length in bytes.
380 : \param write Set to true for write commands, false for read commands.
381 : \param dataOut Data that will be transferred from master to slave.
382 : \param dataIn Data that was transferred from slave to master.
383 : \param numBytes Number of bytes to transfer.
384 : \param waitForGpio Whether to wait for some GPIO at the end of transfer (e.g. BUSY line on SX126x/SX128x).
385 : \returns \ref status_codes
386 : */
387 : int16_t SPItransferStream(const uint8_t* cmd, uint8_t cmdLen, bool write, const uint8_t* dataOut, uint8_t* dataIn, size_t numBytes, bool waitForGpio);
388 :
389 : // pin number access methods
390 : // getCs is omitted on purpose, as it can interfere when accessing the SPI in a concurrent environment
391 : // so it is considered to be part of the SPI pins and hence not accessible from outside
392 : // see https://github.com/jgromes/RadioLib/discussions/1364
393 :
394 : /*!
395 : \brief Access method to get the pin number of interrupt/GPIO.
396 : \returns Pin number of interrupt/GPIO configured in the constructor.
397 : */
398 0 : uint32_t getIrq() const { return(irqPin); }
399 :
400 : /*!
401 : \brief Access method to get the pin number of hardware reset pin.
402 : \returns Pin number of hardware reset pin configured in the constructor.
403 : */
404 0 : uint32_t getRst() const { return(rstPin); }
405 :
406 : /*!
407 : \brief Access method to get the pin number of second interrupt/GPIO.
408 : \returns Pin number of second interrupt/GPIO configured in the constructor.
409 : */
410 0 : uint32_t getGpio() const { return(gpioPin); }
411 :
412 : /*!
413 : \brief Some modules contain external RF switch controlled by pins.
414 : This function gives RadioLib control over those pins to
415 : automatically switch between various modes: When idle both pins
416 : will be LOW, during TX the `txEn` pin will be HIGH, during RX the
417 : `rxPin` will be HIGH.
418 :
419 : Radiolib will automatically set the pin mode and value of these
420 : pins, so do not control them from the sketch.
421 :
422 : When more than two pins or more control over the output values are
423 : needed, use the setRfSwitchTable() function.
424 :
425 : \param rxEn RX enable pin.
426 : \param txEn TX enable pin.
427 : */
428 : void setRfSwitchPins(uint32_t rxEn, uint32_t txEn);
429 :
430 : /*!
431 : \brief Some modules contain external RF switch controlled by pins.
432 : This function gives RadioLib control over those pins to
433 : automatically switch between various modes.
434 :
435 : Radiolib will automatically set the pin mode and value of these
436 : pins, so do not control them from the sketch.
437 :
438 :
439 : \param pins A reference to an array of pins to control. This
440 : should always be an array of 5 elements. If you need less pins,
441 : use RADIOLIB_NC for the unused elements.
442 :
443 : \param table A reference to an array of pin values to use for each
444 : supported mode. Each element is an RfSwitchMode_T struct that
445 : lists the mode for which it applies and the values for each of the
446 : pins passed in the pins argument respectively.
447 :
448 : The `pins` array will be copied into the Module object, so the
449 : original array can be deallocated after this call. However,
450 : a reference to the `table` array will be stored, so that array
451 : must remain valid as long RadioLib is being used.
452 :
453 : The `mode` field in each table row should normally use any of the
454 : `MODE_*` constants from the Module::OpMode_t enum. However, some
455 : radios support additional modes and will define their own OpMode_t
456 : enum.
457 :
458 : The length of the table is variable (to support radios that add
459 : additional modes), so the table must always be terminated with the
460 : special END_OF_MODE_TABLE value.
461 :
462 : Normally all modes should be listed in the table, but for some
463 : radios, modes can be omitted to indicate they are not supported
464 : (e.g. when a radio has a high power and low power TX mode but
465 : external circuitry only supports low power). If applicable, this
466 : is documented in the radio class itself.
467 :
468 : #### Example
469 : For example, on a board that has an RF switch with an enable pin
470 : connected to PA0 and a TX/RX select pin connected to PA1:
471 :
472 : \code
473 : // In global scope, define the pin array and mode table
474 : static const uint32_t rfswitch_pins[] =
475 : {PA0, PA1, RADIOLIB_NC, RADIOLIB_NC, RADIOLIB_NC};
476 : static const Module::RfSwitchMode_t rfswitch_table[] = {
477 : {Module::MODE_IDLE, {LOW, LOW}},
478 : {Module::MODE_RX, {HIGH, LOW}},
479 : {Module::MODE_TX, {HIGH, HIGH}},
480 : Module::END_OF_MODE_TABLE,
481 : };
482 :
483 : void setup() {
484 : ...
485 : // Then somewhere in setup, pass them to radiolib
486 : radio.setRfSwitchTable(rfswitch_pins, rfswitch_table);
487 : ...
488 : }
489 : \endcode
490 : */
491 : void setRfSwitchTable(const uint32_t (&pins)[RFSWITCH_MAX_PINS], const RfSwitchMode_t table[]);
492 :
493 : /*!
494 : \brief Retrieve previously configured RF switch table.
495 : \param pins Pointer to array where pin numbers will be saved.
496 : NOTE: It is up to the caller to ensure the array is large enough to save all the pins!
497 : \param table Pointer to variable which will end up pointing to the RF switch table.
498 : */
499 : void getRfSwitchTable(uint32_t* pins, const RfSwitchMode_t** table);
500 :
501 : /*!
502 : \brief Find a mode in the RfSwitchTable.
503 : \param mode The mode to find.
504 : \returns A pointer to the RfSwitchMode_t struct in the table that
505 : matches the passed mode. Returns nullptr if no rfswitch pins are
506 : configured, or the passed mode is not listed in the table.
507 : */
508 : const RfSwitchMode_t *findRfSwitchMode(uint8_t mode) const;
509 :
510 : /*!
511 : \brief Set RF switch state.
512 : \param mode The mode to set. This must be one of the MODE_ constants, or a radio-specific constant.
513 : */
514 : void setRfSwitchState(uint8_t mode);
515 :
516 : /*!
517 : \brief Wait for time to elapse, either using the microsecond timer, or the TimerFlag.
518 : Note that in interrupt timing mode, it is up to the user to set up the timing interrupt!
519 :
520 : \param start Waiting start timestamp, in microseconds.
521 : \param len Waiting duration, in microseconds;
522 : */
523 : void waitForMicroseconds(RadioLibTime_t start, RadioLibTime_t len);
524 :
525 : #if RADIOLIB_DEBUG
526 : /*!
527 : \brief Function to dump device registers as hex into the debug port.
528 : \param level RadioLib debug level, set to NULL to not print.
529 : \param start First address to dump.
530 : \param len Number of bytes to dump.
531 : */
532 : void regdump(const char* level, uint16_t start, size_t len);
533 : #endif
534 :
535 : #if !RADIOLIB_GODMODE
536 : private:
537 : #endif
538 : uint32_t csPin = RADIOLIB_NC;
539 : uint32_t irqPin = RADIOLIB_NC;
540 : uint32_t rstPin = RADIOLIB_NC;
541 : uint32_t gpioPin = RADIOLIB_NC;
542 :
543 : // RF switch pins and table
544 : uint32_t rfSwitchPins[RFSWITCH_MAX_PINS] = { RADIOLIB_NC, RADIOLIB_NC, RADIOLIB_NC, RADIOLIB_NC, RADIOLIB_NC };
545 : const RfSwitchMode_t *rfSwitchTable = nullptr;
546 :
547 : #if RADIOLIB_INTERRUPT_TIMING
548 : uint32_t prevTimingLen = 0;
549 : #endif
550 : };
551 :
552 : #endif
|