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