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