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