1 /*!
2  * \file      sx126x.h
3  *
4  * \brief     SX126x driver implementation
5  *
6  * \copyright Revised BSD License, see section \ref LICENSE.
7  *
8  * \code
9  *                ______                              _
10  *               / _____)             _              | |
11  *              ( (____  _____ ____ _| |_ _____  ____| |__
12  *               \____ \| ___ |    (_   _) ___ |/ ___)  _ \
13  *               _____) ) ____| | | || |_| ____( (___| | | |
14  *              (______/|_____)_|_|_| \__)_____)\____)_| |_|
15  *              (C)2013-2017 Semtech
16  *
17  * \endcode
18  *
19  * \author    Miguel Luis ( Semtech )
20  *
21  * \author    Gregory Cristian ( Semtech )
22  */
23 #ifndef __SX126x_H__
24 #define __SX126x_H__
25 
26 #ifdef __cplusplus
27 extern "C"
28 {
29 #endif
30 
31 #include <stdint.h>
32 #include <stdbool.h>
33 #include <math.h>
34 #include "gpio.h"
35 #include "spi.h"
36 #include "radio.h"
37 
38 #define SX1261                                      1
39 #define SX1262                                      2
40 
41 /*!
42  * Radio complete Wake-up Time with margin for temperature compensation
43  */
44 #define RADIO_WAKEUP_TIME                           3 // [ms]
45 
46 /*!
47  * \brief Compensation delay for SetAutoTx/Rx functions in 15.625 microseconds
48  */
49 #define AUTO_RX_TX_OFFSET                           2
50 
51 /*!
52  * \brief LFSR initial value to compute IBM type CRC
53  */
54 #define CRC_IBM_SEED                                0xFFFF
55 
56 /*!
57  * \brief LFSR initial value to compute CCIT type CRC
58  */
59 #define CRC_CCITT_SEED                              0x1D0F
60 
61 /*!
62  * \brief Polynomial used to compute IBM CRC
63  */
64 #define CRC_POLYNOMIAL_IBM                          0x8005
65 
66 /*!
67  * \brief Polynomial used to compute CCIT CRC
68  */
69 #define CRC_POLYNOMIAL_CCITT                        0x1021
70 
71 /*!
72  * \brief The address of the register holding the first byte defining the CRC seed
73  *
74  */
75 #define REG_LR_CRCSEEDBASEADDR                      0x06BC
76 
77 /*!
78  * \brief The address of the register holding the first byte defining the CRC polynomial
79  */
80 #define REG_LR_CRCPOLYBASEADDR                      0x06BE
81 
82 /*!
83  * \brief The address of the register holding the first byte defining the whitening seed
84  */
85 #define REG_LR_WHITSEEDBASEADDR_MSB                 0x06B8
86 #define REG_LR_WHITSEEDBASEADDR_LSB                 0x06B9
87 
88 /*!
89  * \brief The address of the register holding the packet configuration
90  */
91 #define REG_LR_PACKETPARAMS                         0x0704
92 
93 /*!
94  * \brief The address of the register holding the payload size
95  */
96 #define REG_LR_PAYLOADLENGTH                        0x0702
97 
98 /*!
99  * \brief The address of the register holding the re-calculated number of symbols
100  */
101 #define REG_LR_SYNCH_TIMEOUT                        0x0706
102 
103 /*!
104  * \brief The addresses of the registers holding SyncWords values
105  */
106 #define REG_LR_SYNCWORDBASEADDRESS                  0x06C0
107 
108 /*!
109  * \brief The addresses of the register holding LoRa Modem SyncWord value
110  */
111 #define REG_LR_SYNCWORD                             0x0740
112 
113 /*!
114  * Syncword for Private LoRa networks
115  */
116 #define LORA_MAC_PRIVATE_SYNCWORD                   0x1424
117 
118 /*!
119  * Syncword for Public LoRa networks
120  */
121 #define LORA_MAC_PUBLIC_SYNCWORD                    0x3444
122 
123 
124 /*!
125  * The address of the register giving a 32-bit random number
126  */
127 #define RANDOM_NUMBER_GENERATORBASEADDR             0x0819
128 
129 /*!
130  * The address of the register used to disable the LNA
131  */
132 #define REG_ANA_LNA                                 0x08E2
133 
134 /*!
135  * The address of the register used to disable the mixer
136  */
137 #define REG_ANA_MIXER                               0x08E5
138 
139 /*!
140  * The address of the register holding RX Gain value (0x94: power saving, 0x96: rx boosted)
141  */
142 #define REG_RX_GAIN                                 0x08AC
143 
144 /*!
145  * Change the value on the device internal trimming capacitor
146  */
147 #define REG_XTA_TRIM                                0x0911
148 
149 /*!
150  * Set the current max value in the over current protection
151  */
152 #define REG_OCP                                     0x08E7
153 
154 /*!
155  * \brief Maximum number of register that can be added to the retention list
156  */
157 #define MAX_NB_REG_IN_RETENTION                     4
158 
159 /*!
160  * \brief Base address of the register retention list
161  */
162 #define REG_RETENTION_LIST_BASE_ADDRESS             0x029F
163 
164 /*!
165  * \brief WORKAROUND - Optimizing the Inverted IQ Operation, see DS_SX1261-2_V1.2 datasheet chapter 15.4
166  */
167 #define REG_IQ_POLARITY                             0x0736
168 
169 /*!
170  * \brief WORKAROUND - Modulation Quality with 500 kHz LoRa Bandwidth, see DS_SX1261-2_V1.2 datasheet chapter 15.1
171  */
172 #define REG_TX_MODULATION                           0x0889
173 
174 /*!
175  * \brief WORKAROUND - Better resistance to antenna mismatch, see DS_SX1261-2_V1.2 datasheet chapter 15.2
176  */
177 #define REG_TX_CLAMP_CFG                            0x08D8
178 
179 /*!
180  * \brief RTC control
181  */
182 #define REG_RTC_CTRL                                0x0902
183 
184 /*!
185  * \brief Event clear
186  */
187 #define REG_EVT_CLR                                 0x0944
188 
189 /*!
190  * \brief Structure describing the radio status
191  */
192 typedef union RadioStatus_u
193 {
194     uint8_t Value;
195     struct
196     {   //bit order is lsb -> msb
197         uint8_t           : 1;  //!< Reserved
198         uint8_t CmdStatus : 3;  //!< Command status
199         uint8_t ChipMode  : 3;  //!< Chip mode
200         uint8_t           : 1;  //!< Reserved
201     }Fields;
202 }RadioStatus_t;
203 
204 /*!
205  * \brief Structure describing the error codes for callback functions
206  */
207 typedef enum
208 {
209     IRQ_HEADER_ERROR_CODE                   = 0x01,
210     IRQ_SYNCWORD_ERROR_CODE                 = 0x02,
211     IRQ_CRC_ERROR_CODE                      = 0x04,
212 }IrqErrorCode_t;
213 
214 enum IrqPblSyncHeaderCode_t
215 {
216     IRQ_PBL_DETECT_CODE                     = 0x01,
217     IRQ_SYNCWORD_VALID_CODE                 = 0x02,
218     IRQ_HEADER_VALID_CODE                   = 0x04,
219 };
220 
221 /*!
222  * \brief Represents the operating mode the radio is actually running
223  */
224 typedef enum
225 {
226     MODE_SLEEP                              = 0x00,         //! The radio is in sleep mode
227     MODE_STDBY_RC,                                          //! The radio is in standby mode with RC oscillator
228     MODE_STDBY_XOSC,                                        //! The radio is in standby mode with XOSC oscillator
229     MODE_FS,                                                //! The radio is in frequency synthesis mode
230     MODE_TX,                                                //! The radio is in transmit mode
231     MODE_RX,                                                //! The radio is in receive mode
232     MODE_RX_DC,                                             //! The radio is in receive duty cycle mode
233     MODE_CAD                                                //! The radio is in channel activity detection mode
234 }RadioOperatingModes_t;
235 
236 /*!
237  * \brief Declares the oscillator in use while in standby mode
238  *
239  * Using the STDBY_RC standby mode allow to reduce the energy consumption
240  * STDBY_XOSC should be used for time critical applications
241  */
242 typedef enum
243 {
244     STDBY_RC                                = 0x00,
245     STDBY_XOSC                              = 0x01,
246 }RadioStandbyModes_t;
247 
248 /*!
249  * \brief Declares the power regulation used to power the device
250  *
251  * This command allows the user to specify if DC-DC or LDO is used for power regulation.
252  * Using only LDO implies that the Rx or Tx current is doubled
253  */
254 typedef enum
255 {
256     USE_LDO                                 = 0x00, // default
257     USE_DCDC                                = 0x01,
258 }RadioRegulatorMode_t;
259 
260 /*!
261  * \brief Represents the possible packet type (i.e. modem) used
262  */
263 typedef enum
264 {
265     PACKET_TYPE_GFSK                        = 0x00,
266     PACKET_TYPE_LORA                        = 0x01,
267     PACKET_TYPE_NONE                        = 0x0F,
268 }RadioPacketTypes_t;
269 
270 /*!
271  * \brief Represents the ramping time for power amplifier
272  */
273 typedef enum
274 {
275     RADIO_RAMP_10_US                        = 0x00,
276     RADIO_RAMP_20_US                        = 0x01,
277     RADIO_RAMP_40_US                        = 0x02,
278     RADIO_RAMP_80_US                        = 0x03,
279     RADIO_RAMP_200_US                       = 0x04,
280     RADIO_RAMP_800_US                       = 0x05,
281     RADIO_RAMP_1700_US                      = 0x06,
282     RADIO_RAMP_3400_US                      = 0x07,
283 }RadioRampTimes_t;
284 
285 /*!
286  * \brief Represents the number of symbols to be used for channel activity detection operation
287  */
288 typedef enum
289 {
290     LORA_CAD_01_SYMBOL                      = 0x00,
291     LORA_CAD_02_SYMBOL                      = 0x01,
292     LORA_CAD_04_SYMBOL                      = 0x02,
293     LORA_CAD_08_SYMBOL                      = 0x03,
294     LORA_CAD_16_SYMBOL                      = 0x04,
295 }RadioLoRaCadSymbols_t;
296 
297 /*!
298  * \brief Represents the Channel Activity Detection actions after the CAD operation is finished
299  */
300 typedef enum
301 {
302     LORA_CAD_ONLY                           = 0x00,
303     LORA_CAD_RX                             = 0x01,
304     LORA_CAD_LBT                            = 0x10,
305 }RadioCadExitModes_t;
306 
307 /*!
308  * \brief Represents the modulation shaping parameter
309  */
310 typedef enum
311 {
312     MOD_SHAPING_OFF                         = 0x00,
313     MOD_SHAPING_G_BT_03                     = 0x08,
314     MOD_SHAPING_G_BT_05                     = 0x09,
315     MOD_SHAPING_G_BT_07                     = 0x0A,
316     MOD_SHAPING_G_BT_1                      = 0x0B,
317 }RadioModShapings_t;
318 
319 /*!
320  * \brief Represents the modulation shaping parameter
321  */
322 typedef enum
323 {
324     RX_BW_4800                              = 0x1F,
325     RX_BW_5800                              = 0x17,
326     RX_BW_7300                              = 0x0F,
327     RX_BW_9700                              = 0x1E,
328     RX_BW_11700                             = 0x16,
329     RX_BW_14600                             = 0x0E,
330     RX_BW_19500                             = 0x1D,
331     RX_BW_23400                             = 0x15,
332     RX_BW_29300                             = 0x0D,
333     RX_BW_39000                             = 0x1C,
334     RX_BW_46900                             = 0x14,
335     RX_BW_58600                             = 0x0C,
336     RX_BW_78200                             = 0x1B,
337     RX_BW_93800                             = 0x13,
338     RX_BW_117300                            = 0x0B,
339     RX_BW_156200                            = 0x1A,
340     RX_BW_187200                            = 0x12,
341     RX_BW_234300                            = 0x0A,
342     RX_BW_312000                            = 0x19,
343     RX_BW_373600                            = 0x11,
344     RX_BW_467000                            = 0x09,
345 }RadioRxBandwidth_t;
346 
347 /*!
348  * \brief Represents the possible spreading factor values in LoRa packet types
349  */
350 typedef enum
351 {
352     LORA_SF5                                = 0x05,
353     LORA_SF6                                = 0x06,
354     LORA_SF7                                = 0x07,
355     LORA_SF8                                = 0x08,
356     LORA_SF9                                = 0x09,
357     LORA_SF10                               = 0x0A,
358     LORA_SF11                               = 0x0B,
359     LORA_SF12                               = 0x0C,
360 }RadioLoRaSpreadingFactors_t;
361 
362 /*!
363  * \brief Represents the bandwidth values for LoRa packet type
364  */
365 typedef enum
366 {
367     LORA_BW_500                             = 6,
368     LORA_BW_250                             = 5,
369     LORA_BW_125                             = 4,
370     LORA_BW_062                             = 3,
371     LORA_BW_041                             = 10,
372     LORA_BW_031                             = 2,
373     LORA_BW_020                             = 9,
374     LORA_BW_015                             = 1,
375     LORA_BW_010                             = 8,
376     LORA_BW_007                             = 0,
377 }RadioLoRaBandwidths_t;
378 
379 /*!
380  * \brief Represents the coding rate values for LoRa packet type
381  */
382 typedef enum
383 {
384     LORA_CR_4_5                             = 0x01,
385     LORA_CR_4_6                             = 0x02,
386     LORA_CR_4_7                             = 0x03,
387     LORA_CR_4_8                             = 0x04,
388 }RadioLoRaCodingRates_t;
389 
390 /*!
391  * \brief Represents the preamble length used to detect the packet on Rx side
392  */
393 typedef enum
394 {
395     RADIO_PREAMBLE_DETECTOR_OFF             = 0x00,         //!< Preamble detection length off
396     RADIO_PREAMBLE_DETECTOR_08_BITS         = 0x04,         //!< Preamble detection length 8 bits
397     RADIO_PREAMBLE_DETECTOR_16_BITS         = 0x05,         //!< Preamble detection length 16 bits
398     RADIO_PREAMBLE_DETECTOR_24_BITS         = 0x06,         //!< Preamble detection length 24 bits
399     RADIO_PREAMBLE_DETECTOR_32_BITS         = 0x07,         //!< Preamble detection length 32 bit
400 }RadioPreambleDetection_t;
401 
402 /*!
403  * \brief Represents the possible combinations of SyncWord correlators activated
404  */
405 typedef enum
406 {
407     RADIO_ADDRESSCOMP_FILT_OFF              = 0x00,         //!< No correlator turned on, i.e. do not search for SyncWord
408     RADIO_ADDRESSCOMP_FILT_NODE             = 0x01,
409     RADIO_ADDRESSCOMP_FILT_NODE_BROAD       = 0x02,
410 }RadioAddressComp_t;
411 
412 /*!
413  *  \brief Radio GFSK packet length mode
414  */
415 typedef enum
416 {
417     RADIO_PACKET_FIXED_LENGTH               = 0x00,         //!< The packet is known on both sides, no header included in the packet
418     RADIO_PACKET_VARIABLE_LENGTH            = 0x01,         //!< The packet is on variable size, header included
419 }RadioPacketLengthModes_t;
420 
421 /*!
422  * \brief Represents the CRC length
423  */
424 typedef enum
425 {
426     RADIO_CRC_OFF                           = 0x01,         //!< No CRC in use
427     RADIO_CRC_1_BYTES                       = 0x00,
428     RADIO_CRC_2_BYTES                       = 0x02,
429     RADIO_CRC_1_BYTES_INV                   = 0x04,
430     RADIO_CRC_2_BYTES_INV                   = 0x06,
431     RADIO_CRC_2_BYTES_IBM                   = 0xF1,
432     RADIO_CRC_2_BYTES_CCIT                  = 0xF2,
433 }RadioCrcTypes_t;
434 
435 /*!
436  * \brief Radio whitening mode activated or deactivated
437  */
438 typedef enum
439 {
440     RADIO_DC_FREE_OFF                       = 0x00,
441     RADIO_DC_FREEWHITENING                  = 0x01,
442 }RadioDcFree_t;
443 
444 /*!
445  * \brief Holds the Radio lengths mode for the LoRa packet type
446  */
447 typedef enum
448 {
449     LORA_PACKET_VARIABLE_LENGTH             = 0x00,         //!< The packet is on variable size, header included
450     LORA_PACKET_FIXED_LENGTH                = 0x01,         //!< The packet is known on both sides, no header included in the packet
451     LORA_PACKET_EXPLICIT                    = LORA_PACKET_VARIABLE_LENGTH,
452     LORA_PACKET_IMPLICIT                    = LORA_PACKET_FIXED_LENGTH,
453 }RadioLoRaPacketLengthsMode_t;
454 
455 /*!
456  * \brief Represents the CRC mode for LoRa packet type
457  */
458 typedef enum
459 {
460     LORA_CRC_ON                             = 0x01,         //!< CRC activated
461     LORA_CRC_OFF                            = 0x00,         //!< CRC not used
462 }RadioLoRaCrcModes_t;
463 
464 /*!
465  * \brief Represents the IQ mode for LoRa packet type
466  */
467 typedef enum
468 {
469     LORA_IQ_NORMAL                          = 0x00,
470     LORA_IQ_INVERTED                        = 0x01,
471 }RadioLoRaIQModes_t;
472 
473 /*!
474  * \brief Represents the voltage used to control the TCXO on/off from DIO3
475  */
476 typedef enum
477 {
478     TCXO_CTRL_1_6V                          = 0x00,
479     TCXO_CTRL_1_7V                          = 0x01,
480     TCXO_CTRL_1_8V                          = 0x02,
481     TCXO_CTRL_2_2V                          = 0x03,
482     TCXO_CTRL_2_4V                          = 0x04,
483     TCXO_CTRL_2_7V                          = 0x05,
484     TCXO_CTRL_3_0V                          = 0x06,
485     TCXO_CTRL_3_3V                          = 0x07,
486 }RadioTcxoCtrlVoltage_t;
487 
488 /*!
489  * \brief Represents the interruption masks available for the radio
490  *
491  * \remark Note that not all these interruptions are available for all packet types
492  */
493 typedef enum
494 {
495     IRQ_RADIO_NONE                          = 0x0000,
496     IRQ_TX_DONE                             = 0x0001,
497     IRQ_RX_DONE                             = 0x0002,
498     IRQ_PREAMBLE_DETECTED                   = 0x0004,
499     IRQ_SYNCWORD_VALID                      = 0x0008,
500     IRQ_HEADER_VALID                        = 0x0010,
501     IRQ_HEADER_ERROR                        = 0x0020,
502     IRQ_CRC_ERROR                           = 0x0040,
503     IRQ_CAD_DONE                            = 0x0080,
504     IRQ_CAD_ACTIVITY_DETECTED               = 0x0100,
505     IRQ_RX_TX_TIMEOUT                       = 0x0200,
506     IRQ_RADIO_ALL                           = 0xFFFF,
507 }RadioIrqMasks_t;
508 
509 /*!
510  * \brief Represents all possible opcode understood by the radio
511  */
512 typedef enum RadioCommands_e
513 {
514     RADIO_GET_STATUS                        = 0xC0,
515     RADIO_WRITE_REGISTER                    = 0x0D,
516     RADIO_READ_REGISTER                     = 0x1D,
517     RADIO_WRITE_BUFFER                      = 0x0E,
518     RADIO_READ_BUFFER                       = 0x1E,
519     RADIO_SET_SLEEP                         = 0x84,
520     RADIO_SET_STANDBY                       = 0x80,
521     RADIO_SET_FS                            = 0xC1,
522     RADIO_SET_TX                            = 0x83,
523     RADIO_SET_RX                            = 0x82,
524     RADIO_SET_RXDUTYCYCLE                   = 0x94,
525     RADIO_SET_CAD                           = 0xC5,
526     RADIO_SET_TXCONTINUOUSWAVE              = 0xD1,
527     RADIO_SET_TXCONTINUOUSPREAMBLE          = 0xD2,
528     RADIO_SET_PACKETTYPE                    = 0x8A,
529     RADIO_GET_PACKETTYPE                    = 0x11,
530     RADIO_SET_RFFREQUENCY                   = 0x86,
531     RADIO_SET_TXPARAMS                      = 0x8E,
532     RADIO_SET_PACONFIG                      = 0x95,
533     RADIO_SET_CADPARAMS                     = 0x88,
534     RADIO_SET_BUFFERBASEADDRESS             = 0x8F,
535     RADIO_SET_MODULATIONPARAMS              = 0x8B,
536     RADIO_SET_PACKETPARAMS                  = 0x8C,
537     RADIO_GET_RXBUFFERSTATUS                = 0x13,
538     RADIO_GET_PACKETSTATUS                  = 0x14,
539     RADIO_GET_RSSIINST                      = 0x15,
540     RADIO_GET_STATS                         = 0x10,
541     RADIO_RESET_STATS                       = 0x00,
542     RADIO_CFG_DIOIRQ                        = 0x08,
543     RADIO_GET_IRQSTATUS                     = 0x12,
544     RADIO_CLR_IRQSTATUS                     = 0x02,
545     RADIO_CALIBRATE                         = 0x89,
546     RADIO_CALIBRATEIMAGE                    = 0x98,
547     RADIO_SET_REGULATORMODE                 = 0x96,
548     RADIO_GET_ERROR                         = 0x17,
549     RADIO_CLR_ERROR                         = 0x07,
550     RADIO_SET_TCXOMODE                      = 0x97,
551     RADIO_SET_TXFALLBACKMODE                = 0x93,
552     RADIO_SET_RFSWITCHMODE                  = 0x9D,
553     RADIO_SET_STOPRXTIMERONPREAMBLE         = 0x9F,
554     RADIO_SET_LORASYMBTIMEOUT               = 0xA0,
555 }RadioCommands_t;
556 
557 /*!
558  * \brief The type describing the modulation parameters for every packet types
559  */
560 typedef struct
561 {
562     RadioPacketTypes_t                   PacketType;        //!< Packet to which the modulation parameters are referring to.
563     struct
564     {
565         struct
566         {
567             uint32_t                     BitRate;
568             uint32_t                     Fdev;
569             RadioModShapings_t           ModulationShaping;
570             uint8_t                      Bandwidth;
571         }Gfsk;
572         struct
573         {
574             RadioLoRaSpreadingFactors_t  SpreadingFactor;   //!< Spreading Factor for the LoRa modulation
575             RadioLoRaBandwidths_t        Bandwidth;         //!< Bandwidth for the LoRa modulation
576             RadioLoRaCodingRates_t       CodingRate;        //!< Coding rate for the LoRa modulation
577             uint8_t                      LowDatarateOptimize; //!< Indicates if the modem uses the low datarate optimization
578         }LoRa;
579     }Params;                                                //!< Holds the modulation parameters structure
580 }ModulationParams_t;
581 
582 /*!
583  * \brief The type describing the packet parameters for every packet types
584  */
585 typedef struct
586 {
587     RadioPacketTypes_t                    PacketType;        //!< Packet to which the packet parameters are referring to.
588     struct
589     {
590         /*!
591          * \brief Holds the GFSK packet parameters
592          */
593         struct
594         {
595             uint16_t                     PreambleLength;    //!< The preamble Tx length for GFSK packet type in bit
596             RadioPreambleDetection_t     PreambleMinDetect; //!< The preamble Rx length minimal for GFSK packet type
597             uint8_t                      SyncWordLength;    //!< The synchronization word length for GFSK packet type
598             RadioAddressComp_t           AddrComp;          //!< Activated SyncWord correlators
599             RadioPacketLengthModes_t     HeaderType;        //!< If the header is explicit, it will be transmitted in the GFSK packet. If the header is implicit, it will not be transmitted
600             uint8_t                      PayloadLength;     //!< Size of the payload in the GFSK packet
601             RadioCrcTypes_t              CrcLength;         //!< Size of the CRC block in the GFSK packet
602             RadioDcFree_t                DcFree;
603         }Gfsk;
604         /*!
605          * \brief Holds the LoRa packet parameters
606          */
607         struct
608         {
609             uint16_t                     PreambleLength;    //!< The preamble length is the number of LoRa symbols in the preamble
610             RadioLoRaPacketLengthsMode_t HeaderType;        //!< If the header is explicit, it will be transmitted in the LoRa packet. If the header is implicit, it will not be transmitted
611             uint8_t                      PayloadLength;     //!< Size of the payload in the LoRa packet
612             RadioLoRaCrcModes_t          CrcMode;           //!< Size of CRC block in LoRa packet
613             RadioLoRaIQModes_t           InvertIQ;          //!< Allows to swap IQ for LoRa packet
614         }LoRa;
615     }Params;                                                //!< Holds the packet parameters structure
616 }PacketParams_t;
617 
618 /*!
619  * \brief Represents the packet status for every packet type
620  */
621 typedef struct
622 {
623     RadioPacketTypes_t                    packetType;      //!< Packet to which the packet status are referring to.
624     struct
625     {
626         struct
627         {
628             uint8_t RxStatus;
629             int8_t RssiAvg;                                //!< The averaged RSSI
630             int8_t RssiSync;                               //!< The RSSI measured on last packet
631             uint32_t FreqError;
632         }Gfsk;
633         struct
634         {
635             int8_t RssiPkt;                                //!< The RSSI of the last packet
636             int8_t SnrPkt;                                 //!< The SNR of the last packet
637             int8_t SignalRssiPkt;
638             uint32_t FreqError;
639         }LoRa;
640     }Params;
641 }PacketStatus_t;
642 
643 /*!
644  * \brief Represents the Rx internal counters values when GFSK or LoRa packet type is used
645  */
646 typedef struct
647 {
648     RadioPacketTypes_t                    packetType;       //!< Packet to which the packet status are referring to.
649     uint16_t PacketReceived;
650     uint16_t CrcOk;
651     uint16_t LengthError;
652 }RxCounter_t;
653 
654 /*!
655  * \brief Represents a calibration configuration
656  */
657 typedef union
658 {
659     struct
660     {
661         uint8_t RC64KEnable    : 1;                             //!< Calibrate RC64K clock
662         uint8_t RC13MEnable    : 1;                             //!< Calibrate RC13M clock
663         uint8_t PLLEnable      : 1;                             //!< Calibrate PLL
664         uint8_t ADCPulseEnable : 1;                             //!< Calibrate ADC Pulse
665         uint8_t ADCBulkNEnable : 1;                             //!< Calibrate ADC bulkN
666         uint8_t ADCBulkPEnable : 1;                             //!< Calibrate ADC bulkP
667         uint8_t ImgEnable      : 1;
668         uint8_t                : 1;
669     }Fields;
670     uint8_t Value;
671 }CalibrationParams_t;
672 
673 /*!
674  * \brief Represents a sleep mode configuration
675  */
676 typedef union
677 {
678     struct
679     {
680         uint8_t WakeUpRTC               : 1;                    //!< Get out of sleep mode if wakeup signal received from RTC
681         uint8_t Reset                   : 1;
682         uint8_t WarmStart               : 1;
683         uint8_t Reserved                : 5;
684     }Fields;
685     uint8_t Value;
686 }SleepParams_t;
687 
688 /*!
689  * \brief Represents the possible radio system error states
690  */
691 typedef union
692 {
693     struct
694     {
695         uint8_t Rc64kCalib              : 1;                    //!< RC 64kHz oscillator calibration failed
696         uint8_t Rc13mCalib              : 1;                    //!< RC 13MHz oscillator calibration failed
697         uint8_t PllCalib                : 1;                    //!< PLL calibration failed
698         uint8_t AdcCalib                : 1;                    //!< ADC calibration failed
699         uint8_t ImgCalib                : 1;                    //!< Image calibration failed
700         uint8_t XoscStart               : 1;                    //!< XOSC oscillator failed to start
701         uint8_t PllLock                 : 1;                    //!< PLL lock failed
702         uint8_t                         : 1;                    //!< Buck converter failed to start
703         uint8_t PaRamp                  : 1;                    //!< PA ramp failed
704         uint8_t                         : 7;                    //!< Reserved
705     }Fields;
706     uint16_t Value;
707 }RadioError_t;
708 
709 /*!
710  * Radio hardware and global parameters
711  */
712 typedef struct SX126x_s
713 {
714     Gpio_t        Reset;
715     Gpio_t        BUSY;
716     Gpio_t        DIO1;
717     Gpio_t        DIO2;
718     Gpio_t        DIO3;
719     Spi_t         Spi;
720     PacketParams_t PacketParams;
721     PacketStatus_t PacketStatus;
722     ModulationParams_t ModulationParams;
723 }SX126x_t;
724 
725 /*!
726  * Hardware IO IRQ callback function definition
727  */
728 typedef void ( DioIrqHandler )( void* context );
729 
730 /*
731  * SX126x definitions
732  */
733 
734 /*!
735  * \brief The radio callbacks structure
736  * Holds function pointers to be called on radio interrupts
737  */
738 typedef struct
739 {
740     void ( *txDone )( void );                       //!< Pointer to a function run on successful transmission
741     void ( *rxDone )( void );                       //!< Pointer to a function run on successful reception
742     void ( *rxPreambleDetect )( void );             //!< Pointer to a function run on successful Preamble detection
743     void ( *rxSyncWordDone )( void );               //!< Pointer to a function run on successful SyncWord reception
744     void ( *rxHeaderDone )( bool isOk );            //!< Pointer to a function run on successful Header reception
745     void ( *txTimeout )( void );                    //!< Pointer to a function run on transmission timeout
746     void ( *rxTimeout )( void );                    //!< Pointer to a function run on reception timeout
747     void ( *rxError )( IrqErrorCode_t errCode );    //!< Pointer to a function run on reception error
748     void ( *cadDone )( bool cadFlag );              //!< Pointer to a function run on channel activity detected
749 }SX126xCallbacks_t;
750 
751 /*!
752  * ============================================================================
753  * Public functions prototypes
754  * ============================================================================
755  */
756 
757 /*!
758  * \brief Initializes the radio driver
759  */
760 void SX126xInit( DioIrqHandler dioIrq );
761 
762 /*!
763  * \brief Wakeup the radio if it is in Sleep mode and check that Busy is low
764  */
765 void SX126xCheckDeviceReady( void );
766 
767 /*!
768  * \brief Saves the payload to be send in the radio buffer
769  *
770  * \param [in]  payload       A pointer to the payload
771  * \param [in]  size          The size of the payload
772  */
773 void SX126xSetPayload( uint8_t *payload, uint8_t size );
774 
775 /*!
776  * \brief Reads the payload received. If the received payload is longer
777  * than maxSize, then the method returns 1 and do not set size and payload.
778  *
779  * \param [out] payload       A pointer to a buffer into which the payload will be copied
780  * \param [out] size          A pointer to the size of the payload received
781  * \param [in]  maxSize       The maximal size allowed to copy into the buffer
782  */
783 uint8_t SX126xGetPayload( uint8_t *payload, uint8_t *size, uint8_t maxSize );
784 
785 /*!
786  * \brief Sends a payload
787  *
788  * \param [in]  payload       A pointer to the payload to send
789  * \param [in]  size          The size of the payload to send
790  * \param [in]  timeout       The timeout for Tx operation
791  */
792 void SX126xSendPayload( uint8_t *payload, uint8_t size, uint32_t timeout );
793 
794 /*!
795  * \brief Sets the Sync Word given by index used in GFSK
796  *
797  * \param [in]  syncWord      SyncWord bytes ( 8 bytes )
798  *
799  * \retval      status        [0: OK, 1: NOK]
800  */
801 uint8_t SX126xSetSyncWord( uint8_t *syncWord );
802 
803 /*!
804  * \brief Sets the Initial value for the LFSR used for the CRC calculation
805  *
806  * \param [in]  seed          Initial LFSR value ( 2 bytes )
807  *
808  */
809 void SX126xSetCrcSeed( uint16_t seed );
810 
811 /*!
812  * \brief Sets the seed used for the CRC calculation
813  *
814  * \param [in]  seed          The seed value
815  *
816  */
817 void SX126xSetCrcPolynomial( uint16_t polynomial );
818 
819 /*!
820  * \brief Sets the Initial value of the LFSR used for the whitening in GFSK protocols
821  *
822  * \param [in]  seed          Initial LFSR value
823  */
824 void SX126xSetWhiteningSeed( uint16_t seed );
825 
826 /*!
827  * \brief Gets a 32-bit random value generated by the radio
828  *
829  * \remark A valid packet type must have been configured with \ref SX126xSetPacketType
830  *         before using this command.
831  *
832  * \remark The radio must be in reception mode before executing this function
833  *         This code can potentially result in interrupt generation. It is the responsibility of
834  *         the calling code to disable radio interrupts before calling this function,
835  *         and re-enable them afterwards if necessary, or be certain that any interrupts
836  *         generated during this process will not cause undesired side-effects in the software.
837  *
838  *         Please note that the random numbers produced by the generator do not have a uniform or Gaussian distribution. If
839  *         uniformity is needed, perform appropriate software post-processing.
840  *
841  * \retval randomValue    32 bits random value
842  */
843 uint32_t SX126xGetRandom( void );
844 
845 /*!
846  * \brief Sets the radio in sleep mode
847  *
848  * \param [in]  sleepConfig   The sleep configuration describing data
849  *                            retention and RTC wake-up
850  */
851 void SX126xSetSleep( SleepParams_t sleepConfig );
852 
853 /*!
854  * \brief Sets the radio in configuration mode
855  *
856  * \param [in]  mode          The standby mode to put the radio into
857  */
858 void SX126xSetStandby( RadioStandbyModes_t mode );
859 
860 /*!
861  * \brief Sets the radio in FS mode
862  */
863 void SX126xSetFs( void );
864 
865 /*!
866  * \brief Sets the radio in transmission mode
867  *
868  * \param [in]  timeout       Structure describing the transmission timeout value
869  */
870 void SX126xSetTx( uint32_t timeout );
871 
872 /*!
873  * \brief Sets the radio in reception mode
874  *
875  * \param [in]  timeout       Structure describing the reception timeout value
876  */
877 void SX126xSetRx( uint32_t timeout );
878 
879 /*!
880  * \brief Sets the radio in reception mode with Boosted LNA gain
881  *
882  * \param [in]  timeout       Structure describing the reception timeout value
883  */
884 void SX126xSetRxBoosted( uint32_t timeout );
885 
886 /*!
887  * \brief Sets the Rx duty cycle management parameters
888  *
889  * \param [in]  rxTime        Structure describing reception timeout value
890  * \param [in]  sleepTime     Structure describing sleep timeout value
891  */
892 void SX126xSetRxDutyCycle( uint32_t rxTime, uint32_t sleepTime );
893 
894 /*!
895  * \brief Sets the radio in CAD mode
896  */
897 void SX126xSetCad( void );
898 
899 /*!
900  * \brief Sets the radio in continuous wave transmission mode
901  */
902 void SX126xSetTxContinuousWave( void );
903 
904 /*!
905  * \brief Sets the radio in continuous preamble transmission mode
906  */
907 void SX126xSetTxInfinitePreamble( void );
908 
909 /*!
910  * \brief Decide which interrupt will stop the internal radio rx timer.
911  *
912  * \param [in]  enable          [0: Timer stop after header/syncword detection
913  *                               1: Timer stop after preamble detection]
914  */
915 void SX126xSetStopRxTimerOnPreambleDetect( bool enable );
916 
917 /*!
918  * \brief Set the number of symbol the radio will wait to validate a reception
919  *
920  * \param [in]  SymbNum          number of LoRa symbols
921  */
922 void SX126xSetLoRaSymbNumTimeout( uint8_t SymbNum );
923 
924 /*!
925  * \brief Sets the power regulators operating mode
926  *
927  * \param [in]  mode          [0: LDO, 1:DC_DC]
928  */
929 void SX126xSetRegulatorMode( RadioRegulatorMode_t mode );
930 
931 /*!
932  * \brief Calibrates the given radio block
933  *
934  * \param [in]  calibParam    The description of blocks to be calibrated
935  */
936 void SX126xCalibrate( CalibrationParams_t calibParam );
937 
938 /*!
939  * \brief Calibrates the Image rejection depending of the frequency
940  *
941  * \param [in]  freq    The operating frequency
942  */
943 void SX126xCalibrateImage( uint32_t freq );
944 
945 /*!
946  * \brief Activate the extention of the timeout when long preamble is used
947  *
948  * \param [in]  enable      The radio will extend the timeout to cope with long preamble
949  */
950 void SX126xSetLongPreamble( uint8_t enable );
951 
952 /*!
953  * \brief Sets the transmission parameters
954  *
955  * \param [in]  paDutyCycle     Duty Cycle for the PA
956  * \param [in]  hpMax          0 for sx1261, 7 for sx1262
957  * \param [in]  deviceSel       1 for sx1261, 0 for sx1262
958  * \param [in]  paLut           0 for 14dBm LUT, 1 for 22dBm LUT
959  */
960 void SX126xSetPaConfig( uint8_t paDutyCycle, uint8_t hpMax, uint8_t deviceSel, uint8_t paLut );
961 
962 /*!
963  * \brief Defines into which mode the chip goes after a TX / RX done
964  *
965  * \param [in]  fallbackMode    The mode in which the radio goes
966  */
967 void SX126xSetRxTxFallbackMode( uint8_t fallbackMode );
968 
969 /*!
970  * \brief Write data to the radio memory
971  *
972  * \param [in]  address       The address of the first byte to write in the radio
973  * \param [in]  buffer        The data to be written in radio's memory
974  * \param [in]  size          The number of bytes to write in radio's memory
975  */
976 void SX126xWriteRegisters( uint16_t address, uint8_t *buffer, uint16_t size );
977 
978 /*!
979  * \brief Read data from the radio memory
980  *
981  * \param [in]  address       The address of the first byte to read from the radio
982  * \param [out] buffer        The buffer that holds data read from radio
983  * \param [in]  size          The number of bytes to read from radio's memory
984  */
985 void SX126xReadRegisters( uint16_t address, uint8_t *buffer, uint16_t size );
986 
987 /*!
988  * \brief Write data to the buffer holding the payload in the radio
989  *
990  * \param [in]  offset        The offset to start writing the payload
991  * \param [in]  buffer        The data to be written (the payload)
992  * \param [in]  size          The number of byte to be written
993  */
994 void SX126xWriteBuffer( uint8_t offset, uint8_t *buffer, uint8_t size );
995 
996 /*!
997  * \brief Read data from the buffer holding the payload in the radio
998  *
999  * \param [in]  offset        The offset to start reading the payload
1000  * \param [out] buffer        A pointer to a buffer holding the data from the radio
1001  * \param [in]  size          The number of byte to be read
1002  */
1003 void SX126xReadBuffer( uint8_t offset, uint8_t *buffer, uint8_t size );
1004 
1005 /*!
1006  * \brief   Sets the IRQ mask and DIO masks
1007  *
1008  * \param [in]  irqMask       General IRQ mask
1009  * \param [in]  dio1Mask      DIO1 mask
1010  * \param [in]  dio2Mask      DIO2 mask
1011  * \param [in]  dio3Mask      DIO3 mask
1012  */
1013 void SX126xSetDioIrqParams( uint16_t irqMask, uint16_t dio1Mask, uint16_t dio2Mask, uint16_t dio3Mask );
1014 
1015 /*!
1016  * \brief Returns the current IRQ status
1017  *
1018  * \retval      irqStatus     IRQ status
1019  */
1020 uint16_t SX126xGetIrqStatus( void );
1021 
1022 /*!
1023  * \brief Indicates if DIO2 is used to control an RF Switch
1024  *
1025  * \param [in] enable     true of false
1026  */
1027 void SX126xSetDio2AsRfSwitchCtrl( uint8_t enable );
1028 
1029 /*!
1030  * \brief Indicates if the Radio main clock is supplied from a tcxo
1031  *
1032  * \param [in] tcxoVoltage     voltage used to control the TCXO
1033  * \param [in] timeout         time given to the TCXO to go to 32MHz
1034  */
1035 void SX126xSetDio3AsTcxoCtrl( RadioTcxoCtrlVoltage_t tcxoVoltage, uint32_t timeout );
1036 
1037 /*!
1038  * \brief Sets the RF frequency
1039  *
1040  * \param [in]  frequency     RF frequency [Hz]
1041  */
1042 void SX126xSetRfFrequency( uint32_t frequency );
1043 
1044 /*!
1045  * \brief Sets the radio for the given protocol
1046  *
1047  * \param [in]  packetType    [PACKET_TYPE_GFSK, PACKET_TYPE_LORA]
1048  *
1049  * \remark This method has to be called before SetRfFrequency,
1050  *         SetModulationParams and SetPacketParams
1051  */
1052 void SX126xSetPacketType( RadioPacketTypes_t packetType );
1053 
1054 /*!
1055  * \brief Gets the current radio protocol
1056  *
1057  * \retval      packetType    [PACKET_TYPE_GFSK, PACKET_TYPE_LORA]
1058  */
1059 RadioPacketTypes_t SX126xGetPacketType( void );
1060 
1061 /*!
1062  * \brief Sets the transmission parameters
1063  *
1064  * \param [in]  power         RF output power [-18..13] dBm
1065  * \param [in]  rampTime      Transmission ramp up time
1066  */
1067 void SX126xSetTxParams( int8_t power, RadioRampTimes_t rampTime );
1068 
1069 /*!
1070  * \brief Set the modulation parameters
1071  *
1072  * \param [in]  modParams     A structure describing the modulation parameters
1073  */
1074 void SX126xSetModulationParams( ModulationParams_t *modParams );
1075 
1076 /*!
1077  * \brief Sets the packet parameters
1078  *
1079  * \param [in]  packetParams  A structure describing the packet parameters
1080  */
1081 void SX126xSetPacketParams( PacketParams_t *packetParams );
1082 
1083 /*!
1084  * \brief Sets the Channel Activity Detection (CAD) parameters
1085  *
1086  * \param [in]  cadSymbolNum   The number of symbol to use for CAD operations
1087  *                             [LORA_CAD_01_SYMBOL, LORA_CAD_02_SYMBOL,
1088  *                              LORA_CAD_04_SYMBOL, LORA_CAD_08_SYMBOL,
1089  *                              LORA_CAD_16_SYMBOL]
1090  * \param [in]  cadDetPeak     Limit for detection of SNR peak used in the CAD
1091  * \param [in]  cadDetMin      Set the minimum symbol recognition for CAD
1092  * \param [in]  cadExitMode    Operation to be done at the end of CAD action
1093  *                             [LORA_CAD_ONLY, LORA_CAD_RX, LORA_CAD_LBT]
1094  * \param [in]  cadTimeout     Defines the timeout value to abort the CAD activity
1095  */
1096 void SX126xSetCadParams( RadioLoRaCadSymbols_t cadSymbolNum, uint8_t cadDetPeak, uint8_t cadDetMin, RadioCadExitModes_t cadExitMode, uint32_t cadTimeout );
1097 
1098 /*!
1099  * \brief Sets the data buffer base address for transmission and reception
1100  *
1101  * \param [in]  txBaseAddress Transmission base address
1102  * \param [in]  rxBaseAddress Reception base address
1103  */
1104 void SX126xSetBufferBaseAddress( uint8_t txBaseAddress, uint8_t rxBaseAddress );
1105 
1106 /*!
1107  * \brief Gets the current radio status
1108  *
1109  * \retval      status        Radio status
1110  */
1111 RadioStatus_t SX126xGetStatus( void );
1112 
1113 /*!
1114  * \brief Returns the instantaneous RSSI value for the last packet received
1115  *
1116  * \retval      rssiInst      Instantaneous RSSI
1117  */
1118 int8_t SX126xGetRssiInst( void );
1119 
1120 /*!
1121  * \brief Gets the last received packet buffer status
1122  *
1123  * \param [out] payloadLength Last received packet payload length
1124  * \param [out] rxStartBuffer Last received packet buffer address pointer
1125  */
1126 void SX126xGetRxBufferStatus( uint8_t *payloadLength, uint8_t *rxStartBuffer );
1127 
1128 /*!
1129  * \brief Gets the last received packet payload length
1130  *
1131  * \param [out] pktStatus     A structure of packet status
1132  */
1133 void SX126xGetPacketStatus( PacketStatus_t *pktStatus );
1134 
1135 /*!
1136  * \brief Returns the possible system errors
1137  *
1138  * \retval sysErrors Value representing the possible sys failures
1139  */
1140 RadioError_t SX126xGetDeviceErrors( void );
1141 
1142 /*!
1143  * \brief Clear all the errors in the device
1144  */
1145 void SX126xClearDeviceErrors( void );
1146 
1147 /*!
1148  * \brief Clears the IRQs
1149  *
1150  * \param [in]  irq           IRQ(s) to be cleared
1151  */
1152 void SX126xClearIrqStatus( uint16_t irq );
1153 
1154 #ifdef __cplusplus
1155 }
1156 #endif
1157 
1158 #endif // __SX126x_H__
1159