1 /*!
2  * \file      sx1272.c
3  *
4  * \brief     SX1272 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 #include <math.h>
24 #include <string.h>
25 #include "utilities.h"
26 #include "timer.h"
27 #include "radio.h"
28 #include "delay.h"
29 #include "sx1272.h"
30 #include "sx1272-board.h"
31 
32 /*!
33  * \brief Internal frequency of the radio
34  */
35 #define SX1272_XTAL_FREQ                            32000000UL
36 
37 /*!
38  * \brief Scaling factor used to perform fixed-point operations
39  */
40 #define SX1272_PLL_STEP_SHIFT_AMOUNT                ( 8 )
41 
42 /*!
43  * \brief PLL step - scaled with SX1276_PLL_STEP_SHIFT_AMOUNT
44  */
45 #define SX1272_PLL_STEP_SCALED                      ( SX1272_XTAL_FREQ >> ( 19 - SX1272_PLL_STEP_SHIFT_AMOUNT ) )
46 
47 /*!
48  * \brief Radio buffer size
49  */
50 #define RX_TX_BUFFER_SIZE                           256
51 
52 /*
53  * Local types definition
54  */
55 
56 /*!
57  * Radio registers definition
58  */
59 typedef struct
60 {
61     RadioModems_t Modem;
62     uint8_t       Addr;
63     uint8_t       Value;
64 }RadioRegisters_t;
65 
66 /*!
67  * FSK bandwidth definition
68  */
69 typedef struct
70 {
71     uint32_t bandwidth;
72     uint8_t  RegValue;
73 }FskBandwidth_t;
74 
75 
76 /*
77  * Private functions prototypes
78  */
79 
80 
81 /*!
82  * \brief Sets the SX1272 in transmission mode for the given time
83  * \param [IN] timeout Transmission timeout [ms] [0: continuous, others timeout]
84  */
85 static void SX1272SetTx( uint32_t timeout );
86 
87 /*!
88  * \brief Writes the buffer contents to the SX1272 FIFO
89  *
90  * \param [IN] buffer Buffer containing data to be put on the FIFO.
91  * \param [IN] size Number of bytes to be written to the FIFO
92  */
93 static void SX1272WriteFifo( uint8_t *buffer, uint8_t size );
94 
95 /*!
96  * \brief Reads the contents of the SX1272 FIFO
97  *
98  * \param [OUT] buffer Buffer where to copy the FIFO read data.
99  * \param [IN] size Number of bytes to be read from the FIFO
100  */
101 static void SX1272ReadFifo( uint8_t *buffer, uint8_t size );
102 
103 /*!
104  * \brief Sets the SX1272 operating mode
105  *
106  * \param [IN] opMode New operating mode
107  */
108 static void SX1272SetOpMode( uint8_t opMode );
109 
110 /*!
111  * \brief Get frequency in Hertz for a given number of PLL steps
112  *
113  * \param [in] pllSteps Number of PLL steps
114  *
115  * \returns Frequency in Hertz
116  */
117 static uint32_t SX1272ConvertPllStepToFreqInHz( uint32_t pllSteps );
118 
119 /*!
120  * \brief Get the number of PLL steps for a given frequency in Hertz
121  *
122  * \param [in] freqInHz Frequency in Hertz
123  *
124  * \returns Number of PLL steps
125  */
126 static uint32_t SX1272ConvertFreqInHzToPllStep( uint32_t freqInHz );
127 
128 /*!
129  * \brief Get the parameter corresponding to a FSK Rx bandwith immediately above the minimum requested one.
130  *
131  * \param [in] bw Minimum required bandwith in Hz
132  *
133  * \returns parameter
134  */
135 static uint8_t GetFskBandwidthRegValue( uint32_t bw );
136 
137 /*!
138  * \brief Get the actual value in Hertz of a given LoRa bandwidth
139  *
140  * \param [in] bw LoRa bandwidth parameter
141  *
142  * \returns Actual LoRa bandwidth in Hertz
143  */
144 static uint32_t SX1272GetLoRaBandwidthInHz( uint32_t bw );
145 
146 /*!
147  * Compute the numerator for GFSK time-on-air computation.
148  *
149  * \remark To get the actual time-on-air in second, this value has to be divided by the GFSK bitrate in bits per
150  * second.
151  *
152  * \param [in] preambleLen
153  * \param [in] fixLen
154  * \param [in] payloadLen
155  * \param [in] crcOn
156  *
157  * \returns GFSK time-on-air numerator
158  */
159 static uint32_t SX1272GetGfskTimeOnAirNumerator( uint16_t preambleLen, bool fixLen,
160                                                  uint8_t payloadLen, bool crcOn );
161 
162 /*!
163  * Compute the numerator for LoRa time-on-air computation.
164  *
165  * \remark To get the actual time-on-air in second, this value has to be divided by the LoRa bandwidth in Hertz.
166  *
167  * \param [in] bandwidth
168  * \param [in] datarate
169  * \param [in] coderate
170  * \param [in] preambleLen
171  * \param [in] fixLen
172  * \param [in] payloadLen
173  * \param [in] crcOn
174  *
175  * \returns LoRa time-on-air numerator
176  */
177 static uint32_t SX1272GetLoRaTimeOnAirNumerator( uint32_t bandwidth,
178                               uint32_t datarate, uint8_t coderate,
179                               uint16_t preambleLen, bool fixLen, uint8_t payloadLen,
180                               bool crcOn );
181 
182 /*
183  * SX1272 DIO IRQ callback functions prototype
184  */
185 
186 /*!
187  * \brief DIO 0 IRQ callback
188  */
189 static void SX1272OnDio0Irq( void* context );
190 
191 /*!
192  * \brief DIO 1 IRQ callback
193  */
194 static void SX1272OnDio1Irq( void* context );
195 
196 /*!
197  * \brief DIO 2 IRQ callback
198  */
199 static void SX1272OnDio2Irq( void* context );
200 
201 /*!
202  * \brief DIO 3 IRQ callback
203  */
204 static void SX1272OnDio3Irq( void* context );
205 
206 /*!
207  * \brief DIO 4 IRQ callback
208  */
209 static void SX1272OnDio4Irq( void* context );
210 
211 /*!
212  * \brief Tx & Rx timeout timer callback
213  */
214 static void SX1272OnTimeoutIrq( void* context );
215 
216 /*
217  * Private global constants
218  */
219 
220 /*!
221  * Radio hardware registers initialization
222  *
223  * \remark RADIO_INIT_REGISTERS_VALUE is defined in sx1272-board.h file
224  */
225 const RadioRegisters_t RadioRegsInit[] = RADIO_INIT_REGISTERS_VALUE;
226 
227 /*!
228  * Constant values need to compute the RSSI value
229  */
230 #define RSSI_OFFSET                                 -139
231 
232 /*!
233  * Precomputed FSK bandwidth registers values
234  */
235 const FskBandwidth_t FskBandwidths[] =
236 {
237     { 2600  , 0x17 },
238     { 3100  , 0x0F },
239     { 3900  , 0x07 },
240     { 5200  , 0x16 },
241     { 6300  , 0x0E },
242     { 7800  , 0x06 },
243     { 10400 , 0x15 },
244     { 12500 , 0x0D },
245     { 15600 , 0x05 },
246     { 20800 , 0x14 },
247     { 25000 , 0x0C },
248     { 31300 , 0x04 },
249     { 41700 , 0x13 },
250     { 50000 , 0x0B },
251     { 62500 , 0x03 },
252     { 83333 , 0x12 },
253     { 100000, 0x0A },
254     { 125000, 0x02 },
255     { 166700, 0x11 },
256     { 200000, 0x09 },
257     { 250000, 0x01 },
258     { 300000, 0x00 }, // Invalid Bandwidth
259 };
260 
261 /*
262  * Private global variables
263  */
264 
265 /*!
266  * Radio callbacks variable
267  */
268 static RadioEvents_t *RadioEvents;
269 
270 /*!
271  * Reception buffer
272  */
273 static uint8_t RxTxBuffer[RX_TX_BUFFER_SIZE];
274 
275 /*
276  * Public global variables
277  */
278 
279 /*!
280  * Radio hardware and global parameters
281  */
282 SX1272_t SX1272;
283 
284 /*!
285  * Hardware DIO IRQ callback initialization
286  */
287 DioIrqHandler *DioIrq[] = { SX1272OnDio0Irq, SX1272OnDio1Irq,
288                             SX1272OnDio2Irq, SX1272OnDio3Irq,
289                             SX1272OnDio4Irq, NULL };
290 
291 /*!
292  * Tx and Rx timers
293  */
294 TimerEvent_t TxTimeoutTimer;
295 TimerEvent_t RxTimeoutTimer;
296 TimerEvent_t RxTimeoutSyncWord;
297 
298 /*
299  * Radio driver functions implementation
300  */
301 
SX1272Init(RadioEvents_t * events)302 void SX1272Init( RadioEvents_t *events )
303 {
304     uint8_t i;
305 
306     RadioEvents = events;
307 
308     // Initialize driver timeout timers
309     TimerInit( &TxTimeoutTimer, SX1272OnTimeoutIrq );
310     TimerInit( &RxTimeoutTimer, SX1272OnTimeoutIrq );
311     TimerInit( &RxTimeoutSyncWord, SX1272OnTimeoutIrq );
312 
313     SX1272Reset( );
314 
315     SX1272SetOpMode( RF_OPMODE_SLEEP );
316 
317     SX1272IoIrqInit( DioIrq );
318 
319     for( i = 0; i < sizeof( RadioRegsInit ) / sizeof( RadioRegisters_t ); i++ )
320     {
321         SX1272SetModem( RadioRegsInit[i].Modem );
322         SX1272Write( RadioRegsInit[i].Addr, RadioRegsInit[i].Value );
323     }
324 
325     SX1272SetModem( MODEM_FSK );
326 
327     SX1272.Settings.State = RF_IDLE;
328 }
329 
SX1272GetStatus(void)330 RadioState_t SX1272GetStatus( void )
331 {
332     return SX1272.Settings.State;
333 }
334 
SX1272SetChannel(uint32_t freq)335 void SX1272SetChannel( uint32_t freq )
336 {
337     uint32_t freqInPllSteps = SX1272ConvertFreqInHzToPllStep( freq );
338 
339     SX1272.Settings.Channel = freq;
340 
341     SX1272Write( REG_FRFMSB, ( uint8_t )( ( freqInPllSteps >> 16 ) & 0xFF ) );
342     SX1272Write( REG_FRFMID, ( uint8_t )( ( freqInPllSteps >> 8 ) & 0xFF ) );
343     SX1272Write( REG_FRFLSB, ( uint8_t )( freqInPllSteps & 0xFF ) );
344 }
345 
SX1272IsChannelFree(uint32_t freq,uint32_t rxBandwidth,int16_t rssiThresh,uint32_t maxCarrierSenseTime)346 bool SX1272IsChannelFree( uint32_t freq, uint32_t rxBandwidth, int16_t rssiThresh, uint32_t maxCarrierSenseTime )
347 {
348     bool status = true;
349     int16_t rssi = 0;
350     uint32_t carrierSenseTime = 0;
351 
352     SX1272SetSleep( );
353 
354     SX1272SetModem( MODEM_FSK );
355 
356     SX1272SetChannel( freq );
357 
358     SX1272Write( REG_RXBW, GetFskBandwidthRegValue( rxBandwidth ) );
359     SX1272Write( REG_AFCBW, GetFskBandwidthRegValue( rxBandwidth ) );
360 
361     SX1272SetOpMode( RF_OPMODE_RECEIVER );
362 
363     DelayMs( 1 );
364 
365     carrierSenseTime = TimerGetCurrentTime( );
366 
367     // Perform carrier sense for maxCarrierSenseTime
368     while( TimerGetElapsedTime( carrierSenseTime ) < maxCarrierSenseTime )
369     {
370         rssi = SX1272ReadRssi( MODEM_FSK );
371 
372         if( rssi > rssiThresh )
373         {
374             status = false;
375             break;
376         }
377     }
378     SX1272SetSleep( );
379     return status;
380 }
381 
SX1272Random(void)382 uint32_t SX1272Random( void )
383 {
384     uint8_t i;
385     uint32_t rnd = 0;
386 
387     /*
388      * Radio setup for random number generation
389      */
390     // Set LoRa modem ON
391     SX1272SetModem( MODEM_LORA );
392 
393     // Disable LoRa modem interrupts
394     SX1272Write( REG_LR_IRQFLAGSMASK, RFLR_IRQFLAGS_RXTIMEOUT |
395                   RFLR_IRQFLAGS_RXDONE |
396                   RFLR_IRQFLAGS_PAYLOADCRCERROR |
397                   RFLR_IRQFLAGS_VALIDHEADER |
398                   RFLR_IRQFLAGS_TXDONE |
399                   RFLR_IRQFLAGS_CADDONE |
400                   RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL |
401                   RFLR_IRQFLAGS_CADDETECTED );
402 
403     // Set radio in continuous reception
404     SX1272SetOpMode( RF_OPMODE_RECEIVER );
405 
406     for( i = 0; i < 32; i++ )
407     {
408         DelayMs( 1 );
409         // Unfiltered RSSI value reading. Only takes the LSB value
410         rnd |= ( ( uint32_t )SX1272Read( REG_LR_RSSIWIDEBAND ) & 0x01 ) << i;
411     }
412 
413     SX1272SetSleep( );
414 
415     return rnd;
416 }
417 
SX1272SetRxConfig(RadioModems_t modem,uint32_t bandwidth,uint32_t datarate,uint8_t coderate,uint32_t bandwidthAfc,uint16_t preambleLen,uint16_t symbTimeout,bool fixLen,uint8_t payloadLen,bool crcOn,bool freqHopOn,uint8_t hopPeriod,bool iqInverted,bool rxContinuous)418 void SX1272SetRxConfig( RadioModems_t modem, uint32_t bandwidth,
419                          uint32_t datarate, uint8_t coderate,
420                          uint32_t bandwidthAfc, uint16_t preambleLen,
421                          uint16_t symbTimeout, bool fixLen,
422                          uint8_t payloadLen,
423                          bool crcOn, bool freqHopOn, uint8_t hopPeriod,
424                          bool iqInverted, bool rxContinuous )
425 {
426     SX1272SetModem( modem );
427 
428     SX1272SetStby( );
429 
430     switch( modem )
431     {
432     case MODEM_FSK:
433         {
434             SX1272.Settings.Fsk.Bandwidth = bandwidth;
435             SX1272.Settings.Fsk.Datarate = datarate;
436             SX1272.Settings.Fsk.BandwidthAfc = bandwidthAfc;
437             SX1272.Settings.Fsk.FixLen = fixLen;
438             SX1272.Settings.Fsk.PayloadLen = payloadLen;
439             SX1272.Settings.Fsk.CrcOn = crcOn;
440             SX1272.Settings.Fsk.IqInverted = iqInverted;
441             SX1272.Settings.Fsk.RxContinuous = rxContinuous;
442             SX1272.Settings.Fsk.PreambleLen = preambleLen;
443             SX1272.Settings.Fsk.RxSingleTimeout = ( uint32_t )symbTimeout * 8000UL / datarate;
444 
445             uint32_t bitRate = ( uint32_t )( SX1272_XTAL_FREQ / datarate );
446             SX1272Write( REG_BITRATEMSB, ( uint8_t )( bitRate >> 8 ) );
447             SX1272Write( REG_BITRATELSB, ( uint8_t )( bitRate & 0xFF ) );
448 
449             SX1272Write( REG_RXBW, GetFskBandwidthRegValue( bandwidth ) );
450             SX1272Write( REG_AFCBW, GetFskBandwidthRegValue( bandwidthAfc ) );
451 
452             SX1272Write( REG_PREAMBLEMSB, ( uint8_t )( ( preambleLen >> 8 ) & 0xFF ) );
453             SX1272Write( REG_PREAMBLELSB, ( uint8_t )( preambleLen & 0xFF ) );
454 
455             if( fixLen == 1 )
456             {
457                 SX1272Write( REG_PAYLOADLENGTH, payloadLen );
458             }
459             else
460             {
461                 SX1272Write( REG_PAYLOADLENGTH, 0xFF ); // Set payload length to the maximum
462             }
463 
464             SX1272Write( REG_PACKETCONFIG1,
465                          ( SX1272Read( REG_PACKETCONFIG1 ) &
466                            RF_PACKETCONFIG1_CRC_MASK &
467                            RF_PACKETCONFIG1_PACKETFORMAT_MASK ) |
468                            ( ( fixLen == 1 ) ? RF_PACKETCONFIG1_PACKETFORMAT_FIXED : RF_PACKETCONFIG1_PACKETFORMAT_VARIABLE ) |
469                            ( crcOn << 4 ) );
470             SX1272Write( REG_PACKETCONFIG2, ( SX1272Read( REG_PACKETCONFIG2 ) | RF_PACKETCONFIG2_DATAMODE_PACKET ) );
471         }
472         break;
473     case MODEM_LORA:
474         {
475             SX1272.Settings.LoRa.Bandwidth = bandwidth;
476             SX1272.Settings.LoRa.Datarate = datarate;
477             SX1272.Settings.LoRa.Coderate = coderate;
478             SX1272.Settings.LoRa.PreambleLen = preambleLen;
479             SX1272.Settings.LoRa.FixLen = fixLen;
480             SX1272.Settings.LoRa.PayloadLen = payloadLen;
481             SX1272.Settings.LoRa.CrcOn = crcOn;
482             SX1272.Settings.LoRa.FreqHopOn = freqHopOn;
483             SX1272.Settings.LoRa.HopPeriod = hopPeriod;
484             SX1272.Settings.LoRa.IqInverted = iqInverted;
485             SX1272.Settings.LoRa.RxContinuous = rxContinuous;
486 
487             if( datarate > 12 )
488             {
489                 datarate = 12;
490             }
491             else if( datarate < 6 )
492             {
493                 datarate = 6;
494             }
495 
496             if( ( ( bandwidth == 0 ) && ( ( datarate == 11 ) || ( datarate == 12 ) ) ) ||
497                 ( ( bandwidth == 1 ) && ( datarate == 12 ) ) )
498             {
499                 SX1272.Settings.LoRa.LowDatarateOptimize = 0x01;
500             }
501             else
502             {
503                 SX1272.Settings.LoRa.LowDatarateOptimize = 0x00;
504             }
505 
506             SX1272Write( REG_LR_MODEMCONFIG1,
507                          ( SX1272Read( REG_LR_MODEMCONFIG1 ) &
508                            RFLR_MODEMCONFIG1_BW_MASK &
509                            RFLR_MODEMCONFIG1_CODINGRATE_MASK &
510                            RFLR_MODEMCONFIG1_IMPLICITHEADER_MASK &
511                            RFLR_MODEMCONFIG1_RXPAYLOADCRC_MASK &
512                            RFLR_MODEMCONFIG1_LOWDATARATEOPTIMIZE_MASK ) |
513                            ( bandwidth << 6 ) | ( coderate << 3 ) |
514                            ( fixLen << 2 ) | ( crcOn << 1 ) |
515                            SX1272.Settings.LoRa.LowDatarateOptimize );
516 
517             SX1272Write( REG_LR_MODEMCONFIG2,
518                          ( SX1272Read( REG_LR_MODEMCONFIG2 ) &
519                            RFLR_MODEMCONFIG2_SF_MASK &
520                            RFLR_MODEMCONFIG2_SYMBTIMEOUTMSB_MASK ) |
521                            ( datarate << 4 ) |
522                            ( ( symbTimeout >> 8 ) & ~RFLR_MODEMCONFIG2_SYMBTIMEOUTMSB_MASK ) );
523 
524             SX1272Write( REG_LR_SYMBTIMEOUTLSB, ( uint8_t )( symbTimeout & 0xFF ) );
525 
526             SX1272Write( REG_LR_PREAMBLEMSB, ( uint8_t )( ( preambleLen >> 8 ) & 0xFF ) );
527             SX1272Write( REG_LR_PREAMBLELSB, ( uint8_t )( preambleLen & 0xFF ) );
528 
529             if( fixLen == 1 )
530             {
531                 SX1272Write( REG_LR_PAYLOADLENGTH, payloadLen );
532             }
533 
534             if( SX1272.Settings.LoRa.FreqHopOn == true )
535             {
536                 SX1272Write( REG_LR_PLLHOP, ( SX1272Read( REG_LR_PLLHOP ) & RFLR_PLLHOP_FASTHOP_MASK ) | RFLR_PLLHOP_FASTHOP_ON );
537                 SX1272Write( REG_LR_HOPPERIOD, SX1272.Settings.LoRa.HopPeriod );
538             }
539 
540             if( datarate == 6 )
541             {
542                 SX1272Write( REG_LR_DETECTOPTIMIZE,
543                              ( SX1272Read( REG_LR_DETECTOPTIMIZE ) &
544                                RFLR_DETECTIONOPTIMIZE_MASK ) |
545                                RFLR_DETECTIONOPTIMIZE_SF6 );
546                 SX1272Write( REG_LR_DETECTIONTHRESHOLD,
547                              RFLR_DETECTIONTHRESH_SF6 );
548             }
549             else
550             {
551                 SX1272Write( REG_LR_DETECTOPTIMIZE,
552                              ( SX1272Read( REG_LR_DETECTOPTIMIZE ) &
553                              RFLR_DETECTIONOPTIMIZE_MASK ) |
554                              RFLR_DETECTIONOPTIMIZE_SF7_TO_SF12 );
555                 SX1272Write( REG_LR_DETECTIONTHRESHOLD,
556                              RFLR_DETECTIONTHRESH_SF7_TO_SF12 );
557             }
558         }
559         break;
560     }
561 }
562 
SX1272SetTxConfig(RadioModems_t modem,int8_t power,uint32_t fdev,uint32_t bandwidth,uint32_t datarate,uint8_t coderate,uint16_t preambleLen,bool fixLen,bool crcOn,bool freqHopOn,uint8_t hopPeriod,bool iqInverted,uint32_t timeout)563 void SX1272SetTxConfig( RadioModems_t modem, int8_t power, uint32_t fdev,
564                         uint32_t bandwidth, uint32_t datarate,
565                         uint8_t coderate, uint16_t preambleLen,
566                         bool fixLen, bool crcOn, bool freqHopOn,
567                         uint8_t hopPeriod, bool iqInverted, uint32_t timeout )
568 {
569     SX1272SetModem( modem );
570 
571     SX1272SetStby( );
572 
573     SX1272SetRfTxPower( power );
574 
575     switch( modem )
576     {
577     case MODEM_FSK:
578         {
579             SX1272.Settings.Fsk.Power = power;
580             SX1272.Settings.Fsk.Fdev = fdev;
581             SX1272.Settings.Fsk.Bandwidth = bandwidth;
582             SX1272.Settings.Fsk.Datarate = datarate;
583             SX1272.Settings.Fsk.PreambleLen = preambleLen;
584             SX1272.Settings.Fsk.FixLen = fixLen;
585             SX1272.Settings.Fsk.CrcOn = crcOn;
586             SX1272.Settings.Fsk.IqInverted = iqInverted;
587             SX1272.Settings.Fsk.TxTimeout = timeout;
588 
589             uint32_t fdevInPllSteps = SX1272ConvertFreqInHzToPllStep( fdev );
590             SX1272Write( REG_FDEVMSB, ( uint8_t )( fdevInPllSteps >> 8 ) );
591             SX1272Write( REG_FDEVLSB, ( uint8_t )( fdevInPllSteps & 0xFF ) );
592 
593             uint32_t bitRate = ( uint32_t )( SX1272_XTAL_FREQ / datarate );
594             SX1272Write( REG_BITRATEMSB, ( uint8_t )( bitRate >> 8 ) );
595             SX1272Write( REG_BITRATELSB, ( uint8_t )( bitRate & 0xFF ) );
596 
597             SX1272Write( REG_PREAMBLEMSB, ( preambleLen >> 8 ) & 0x00FF );
598             SX1272Write( REG_PREAMBLELSB, preambleLen & 0xFF );
599 
600             SX1272Write( REG_PACKETCONFIG1,
601                          ( SX1272Read( REG_PACKETCONFIG1 ) &
602                            RF_PACKETCONFIG1_CRC_MASK &
603                            RF_PACKETCONFIG1_PACKETFORMAT_MASK ) |
604                            ( ( fixLen == 1 ) ? RF_PACKETCONFIG1_PACKETFORMAT_FIXED : RF_PACKETCONFIG1_PACKETFORMAT_VARIABLE ) |
605                            ( crcOn << 4 ) );
606             SX1272Write( REG_PACKETCONFIG2, ( SX1272Read( REG_PACKETCONFIG2 ) | RF_PACKETCONFIG2_DATAMODE_PACKET ) );
607         }
608         break;
609     case MODEM_LORA:
610         {
611             SX1272.Settings.LoRa.Power = power;
612             SX1272.Settings.LoRa.Bandwidth = bandwidth;
613             SX1272.Settings.LoRa.Datarate = datarate;
614             SX1272.Settings.LoRa.Coderate = coderate;
615             SX1272.Settings.LoRa.PreambleLen = preambleLen;
616             SX1272.Settings.LoRa.FixLen = fixLen;
617             SX1272.Settings.LoRa.FreqHopOn = freqHopOn;
618             SX1272.Settings.LoRa.HopPeriod = hopPeriod;
619             SX1272.Settings.LoRa.CrcOn = crcOn;
620             SX1272.Settings.LoRa.IqInverted = iqInverted;
621             SX1272.Settings.LoRa.TxTimeout = timeout;
622 
623             if( datarate > 12 )
624             {
625                 datarate = 12;
626             }
627             else if( datarate < 6 )
628             {
629                 datarate = 6;
630             }
631             if( ( ( bandwidth == 0 ) && ( ( datarate == 11 ) || ( datarate == 12 ) ) ) ||
632                 ( ( bandwidth == 1 ) && ( datarate == 12 ) ) )
633             {
634                 SX1272.Settings.LoRa.LowDatarateOptimize = 0x01;
635             }
636             else
637             {
638                 SX1272.Settings.LoRa.LowDatarateOptimize = 0x00;
639             }
640 
641             if( SX1272.Settings.LoRa.FreqHopOn == true )
642             {
643                 SX1272Write( REG_LR_PLLHOP, ( SX1272Read( REG_LR_PLLHOP ) & RFLR_PLLHOP_FASTHOP_MASK ) | RFLR_PLLHOP_FASTHOP_ON );
644                 SX1272Write( REG_LR_HOPPERIOD, SX1272.Settings.LoRa.HopPeriod );
645             }
646 
647             SX1272Write( REG_LR_MODEMCONFIG1,
648                          ( SX1272Read( REG_LR_MODEMCONFIG1 ) &
649                            RFLR_MODEMCONFIG1_BW_MASK &
650                            RFLR_MODEMCONFIG1_CODINGRATE_MASK &
651                            RFLR_MODEMCONFIG1_IMPLICITHEADER_MASK &
652                            RFLR_MODEMCONFIG1_RXPAYLOADCRC_MASK &
653                            RFLR_MODEMCONFIG1_LOWDATARATEOPTIMIZE_MASK ) |
654                            ( bandwidth << 6 ) | ( coderate << 3 ) |
655                            ( fixLen << 2 ) | ( crcOn << 1 ) |
656                            SX1272.Settings.LoRa.LowDatarateOptimize );
657 
658             SX1272Write( REG_LR_MODEMCONFIG2,
659                         ( SX1272Read( REG_LR_MODEMCONFIG2 ) &
660                           RFLR_MODEMCONFIG2_SF_MASK ) |
661                           ( datarate << 4 ) );
662 
663 
664             SX1272Write( REG_LR_PREAMBLEMSB, ( preambleLen >> 8 ) & 0x00FF );
665             SX1272Write( REG_LR_PREAMBLELSB, preambleLen & 0xFF );
666 
667             if( datarate == 6 )
668             {
669                 SX1272Write( REG_LR_DETECTOPTIMIZE,
670                              ( SX1272Read( REG_LR_DETECTOPTIMIZE ) &
671                                RFLR_DETECTIONOPTIMIZE_MASK ) |
672                                RFLR_DETECTIONOPTIMIZE_SF6 );
673                 SX1272Write( REG_LR_DETECTIONTHRESHOLD,
674                              RFLR_DETECTIONTHRESH_SF6 );
675             }
676             else
677             {
678                 SX1272Write( REG_LR_DETECTOPTIMIZE,
679                              ( SX1272Read( REG_LR_DETECTOPTIMIZE ) &
680                              RFLR_DETECTIONOPTIMIZE_MASK ) |
681                              RFLR_DETECTIONOPTIMIZE_SF7_TO_SF12 );
682                 SX1272Write( REG_LR_DETECTIONTHRESHOLD,
683                              RFLR_DETECTIONTHRESH_SF7_TO_SF12 );
684             }
685         }
686         break;
687     }
688 }
689 
SX1272GetTimeOnAir(RadioModems_t modem,uint32_t bandwidth,uint32_t datarate,uint8_t coderate,uint16_t preambleLen,bool fixLen,uint8_t payloadLen,bool crcOn)690 uint32_t SX1272GetTimeOnAir( RadioModems_t modem, uint32_t bandwidth,
691                               uint32_t datarate, uint8_t coderate,
692                               uint16_t preambleLen, bool fixLen, uint8_t payloadLen,
693                               bool crcOn )
694 {
695     uint32_t numerator = 0;
696     uint32_t denominator = 1;
697 
698     switch( modem )
699     {
700     case MODEM_FSK:
701         {
702             numerator   = 1000U * SX1272GetGfskTimeOnAirNumerator( preambleLen, fixLen, payloadLen, crcOn );
703             denominator = datarate;
704         }
705         break;
706     case MODEM_LORA:
707         {
708             numerator   = 1000U * SX1272GetLoRaTimeOnAirNumerator( bandwidth, datarate, coderate, preambleLen, fixLen,
709                                                                    payloadLen, crcOn );
710             denominator = SX1272GetLoRaBandwidthInHz( bandwidth );
711         }
712         break;
713     }
714     // Perform integral ceil()
715     return ( numerator + denominator - 1 ) / denominator;
716 }
717 
SX1272Send(uint8_t * buffer,uint8_t size)718 void SX1272Send( uint8_t *buffer, uint8_t size )
719 {
720     uint32_t txTimeout = 0;
721 
722     switch( SX1272.Settings.Modem )
723     {
724     case MODEM_FSK:
725         {
726             SX1272.Settings.FskPacketHandler.NbBytes = 0;
727             SX1272.Settings.FskPacketHandler.Size = size;
728 
729             if( SX1272.Settings.Fsk.FixLen == false )
730             {
731                 SX1272WriteFifo( ( uint8_t* )&size, 1 );
732             }
733             else
734             {
735                 SX1272Write( REG_PAYLOADLENGTH, size );
736             }
737 
738             if( ( size > 0 ) && ( size <= 64 ) )
739             {
740                 SX1272.Settings.FskPacketHandler.ChunkSize = size;
741             }
742             else
743             {
744                 memcpy1( RxTxBuffer, buffer, size );
745                 SX1272.Settings.FskPacketHandler.ChunkSize = 32;
746             }
747 
748             // Write payload buffer
749             SX1272WriteFifo( buffer, SX1272.Settings.FskPacketHandler.ChunkSize );
750             SX1272.Settings.FskPacketHandler.NbBytes += SX1272.Settings.FskPacketHandler.ChunkSize;
751             txTimeout = SX1272.Settings.Fsk.TxTimeout;
752         }
753         break;
754     case MODEM_LORA:
755         {
756             if( SX1272.Settings.LoRa.IqInverted == true )
757             {
758                 SX1272Write( REG_LR_INVERTIQ, ( ( SX1272Read( REG_LR_INVERTIQ ) & RFLR_INVERTIQ_TX_MASK & RFLR_INVERTIQ_RX_MASK ) | RFLR_INVERTIQ_RX_OFF | RFLR_INVERTIQ_TX_ON ) );
759                 SX1272Write( REG_LR_INVERTIQ2, RFLR_INVERTIQ2_ON );
760             }
761             else
762             {
763                 SX1272Write( REG_LR_INVERTIQ, ( ( SX1272Read( REG_LR_INVERTIQ ) & RFLR_INVERTIQ_TX_MASK & RFLR_INVERTIQ_RX_MASK ) | RFLR_INVERTIQ_RX_OFF | RFLR_INVERTIQ_TX_OFF ) );
764                 SX1272Write( REG_LR_INVERTIQ2, RFLR_INVERTIQ2_OFF );
765             }
766 
767             SX1272.Settings.LoRaPacketHandler.Size = size;
768 
769             // Initializes the payload size
770             SX1272Write( REG_LR_PAYLOADLENGTH, size );
771 
772             // Full buffer used for Tx
773             SX1272Write( REG_LR_FIFOTXBASEADDR, 0 );
774             SX1272Write( REG_LR_FIFOADDRPTR, 0 );
775 
776             // FIFO operations can not take place in Sleep mode
777             if( ( SX1272Read( REG_OPMODE ) & ~RF_OPMODE_MASK ) == RF_OPMODE_SLEEP )
778             {
779                 SX1272SetStby( );
780                 DelayMs( 1 );
781             }
782             // Write payload buffer
783             SX1272WriteFifo( buffer, size );
784             txTimeout = SX1272.Settings.LoRa.TxTimeout;
785         }
786         break;
787     }
788 
789     SX1272SetTx( txTimeout );
790 }
791 
SX1272SetSleep(void)792 void SX1272SetSleep( void )
793 {
794     TimerStop( &RxTimeoutTimer );
795     TimerStop( &TxTimeoutTimer );
796     TimerStop( &RxTimeoutSyncWord );
797 
798     SX1272SetOpMode( RF_OPMODE_SLEEP );
799 
800     // Disable TCXO radio is in SLEEP mode
801     SX1272SetBoardTcxo( false );
802 
803     SX1272.Settings.State = RF_IDLE;
804 }
805 
SX1272SetStby(void)806 void SX1272SetStby( void )
807 {
808     TimerStop( &RxTimeoutTimer );
809     TimerStop( &TxTimeoutTimer );
810     TimerStop( &RxTimeoutSyncWord );
811 
812     SX1272SetOpMode( RF_OPMODE_STANDBY );
813     SX1272.Settings.State = RF_IDLE;
814 }
815 
SX1272SetRx(uint32_t timeout)816 void SX1272SetRx( uint32_t timeout )
817 {
818     bool rxContinuous = false;
819     TimerStop( &TxTimeoutTimer );
820 
821     switch( SX1272.Settings.Modem )
822     {
823     case MODEM_FSK:
824         {
825             rxContinuous = SX1272.Settings.Fsk.RxContinuous;
826 
827             // DIO0=PayloadReady
828             // DIO1=FifoLevel
829             // DIO2=SyncAddr
830             // DIO3=FifoEmpty
831             // DIO4=Preamble
832             // DIO5=ModeReady
833             SX1272Write( REG_DIOMAPPING1, ( SX1272Read( REG_DIOMAPPING1 ) & RF_DIOMAPPING1_DIO0_MASK &
834                                                                             RF_DIOMAPPING1_DIO1_MASK &
835                                                                             RF_DIOMAPPING1_DIO2_MASK ) |
836                                                                             RF_DIOMAPPING1_DIO0_00 |
837                                                                             RF_DIOMAPPING1_DIO1_00 |
838                                                                             RF_DIOMAPPING1_DIO2_11 );
839 
840             SX1272Write( REG_DIOMAPPING2, ( SX1272Read( REG_DIOMAPPING2 ) & RF_DIOMAPPING2_DIO4_MASK &
841                                                                             RF_DIOMAPPING2_MAP_MASK ) |
842                                                                             RF_DIOMAPPING2_DIO4_11 |
843                                                                             RF_DIOMAPPING2_MAP_PREAMBLEDETECT );
844 
845             SX1272.Settings.FskPacketHandler.FifoThresh = SX1272Read( REG_FIFOTHRESH ) & 0x3F;
846 
847             SX1272Write( REG_RXCONFIG, RF_RXCONFIG_AFCAUTO_ON | RF_RXCONFIG_AGCAUTO_ON | RF_RXCONFIG_RXTRIGER_PREAMBLEDETECT );
848 
849             SX1272.Settings.FskPacketHandler.PreambleDetected = false;
850             SX1272.Settings.FskPacketHandler.SyncWordDetected = false;
851             SX1272.Settings.FskPacketHandler.NbBytes = 0;
852             SX1272.Settings.FskPacketHandler.Size = 0;
853         }
854         break;
855     case MODEM_LORA:
856         {
857             if( SX1272.Settings.LoRa.IqInverted == true )
858             {
859                 SX1272Write( REG_LR_INVERTIQ, ( ( SX1272Read( REG_LR_INVERTIQ ) & RFLR_INVERTIQ_TX_MASK & RFLR_INVERTIQ_RX_MASK ) | RFLR_INVERTIQ_RX_ON | RFLR_INVERTIQ_TX_OFF ) );
860                 SX1272Write( REG_LR_INVERTIQ2, RFLR_INVERTIQ2_ON );
861             }
862             else
863             {
864                 SX1272Write( REG_LR_INVERTIQ, ( ( SX1272Read( REG_LR_INVERTIQ ) & RFLR_INVERTIQ_TX_MASK & RFLR_INVERTIQ_RX_MASK ) | RFLR_INVERTIQ_RX_OFF | RFLR_INVERTIQ_TX_OFF ) );
865                 SX1272Write( REG_LR_INVERTIQ2, RFLR_INVERTIQ2_OFF );
866             }
867 
868             rxContinuous = SX1272.Settings.LoRa.RxContinuous;
869 
870             if( SX1272.Settings.LoRa.FreqHopOn == true )
871             {
872                 SX1272Write( REG_LR_IRQFLAGSMASK, //RFLR_IRQFLAGS_RXTIMEOUT |
873                                                   //RFLR_IRQFLAGS_RXDONE |
874                                                   //RFLR_IRQFLAGS_PAYLOADCRCERROR |
875                                                   RFLR_IRQFLAGS_VALIDHEADER |
876                                                   RFLR_IRQFLAGS_TXDONE |
877                                                   RFLR_IRQFLAGS_CADDONE |
878                                                   //RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL |
879                                                   RFLR_IRQFLAGS_CADDETECTED );
880 
881                 // DIO0=RxDone, DIO2=FhssChangeChannel
882                 SX1272Write( REG_DIOMAPPING1, ( SX1272Read( REG_DIOMAPPING1 ) & RFLR_DIOMAPPING1_DIO0_MASK & RFLR_DIOMAPPING1_DIO2_MASK  ) | RFLR_DIOMAPPING1_DIO0_00 | RFLR_DIOMAPPING1_DIO2_00 );
883             }
884             else
885             {
886                 SX1272Write( REG_LR_IRQFLAGSMASK, //RFLR_IRQFLAGS_RXTIMEOUT |
887                                                   //RFLR_IRQFLAGS_RXDONE |
888                                                   //RFLR_IRQFLAGS_PAYLOADCRCERROR |
889                                                   RFLR_IRQFLAGS_VALIDHEADER |
890                                                   RFLR_IRQFLAGS_TXDONE |
891                                                   RFLR_IRQFLAGS_CADDONE |
892                                                   RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL |
893                                                   RFLR_IRQFLAGS_CADDETECTED );
894 
895                 // DIO0=RxDone
896                 SX1272Write( REG_DIOMAPPING1, ( SX1272Read( REG_DIOMAPPING1 ) & RFLR_DIOMAPPING1_DIO0_MASK ) | RFLR_DIOMAPPING1_DIO0_00 );
897             }
898             SX1272Write( REG_LR_FIFORXBASEADDR, 0 );
899             SX1272Write( REG_LR_FIFOADDRPTR, 0 );
900         }
901         break;
902     }
903 
904     SX1272.Settings.State = RF_RX_RUNNING;
905     if( timeout != 0 )
906     {
907         TimerSetValue( &RxTimeoutTimer, timeout );
908         TimerStart( &RxTimeoutTimer );
909     }
910 
911     if( SX1272.Settings.Modem == MODEM_FSK )
912     {
913         SX1272SetOpMode( RF_OPMODE_RECEIVER );
914 
915         if( rxContinuous == false )
916         {
917             TimerSetValue( &RxTimeoutSyncWord, SX1272.Settings.Fsk.RxSingleTimeout );
918             TimerStart( &RxTimeoutSyncWord );
919         }
920     }
921     else
922     {
923         if( rxContinuous == true )
924         {
925             SX1272SetOpMode( RFLR_OPMODE_RECEIVER );
926         }
927         else
928         {
929             SX1272SetOpMode( RFLR_OPMODE_RECEIVER_SINGLE );
930         }
931     }
932 }
933 
SX1272SetTx(uint32_t timeout)934 static void SX1272SetTx( uint32_t timeout )
935 {
936     TimerStop( &RxTimeoutTimer );
937 
938     TimerSetValue( &TxTimeoutTimer, timeout );
939 
940     switch( SX1272.Settings.Modem )
941     {
942     case MODEM_FSK:
943         {
944             // DIO0=PacketSent
945             // DIO1=FifoLevel
946             // DIO2=FifoFull
947             // DIO3=FifoEmpty
948             // DIO4=LowBat
949             // DIO5=ModeReady
950             SX1272Write( REG_DIOMAPPING1, ( SX1272Read( REG_DIOMAPPING1 ) & RF_DIOMAPPING1_DIO0_MASK &
951                                                                             RF_DIOMAPPING1_DIO1_MASK &
952                                                                             RF_DIOMAPPING1_DIO2_MASK ) );
953 
954             SX1272Write( REG_DIOMAPPING2, ( SX1272Read( REG_DIOMAPPING2 ) & RF_DIOMAPPING2_DIO4_MASK &
955                                                                             RF_DIOMAPPING2_MAP_MASK ) );
956             SX1272.Settings.FskPacketHandler.FifoThresh = SX1272Read( REG_FIFOTHRESH ) & 0x3F;
957         }
958         break;
959     case MODEM_LORA:
960         {
961             if( SX1272.Settings.LoRa.FreqHopOn == true )
962             {
963                 SX1272Write( REG_LR_IRQFLAGSMASK, RFLR_IRQFLAGS_RXTIMEOUT |
964                                                   RFLR_IRQFLAGS_RXDONE |
965                                                   RFLR_IRQFLAGS_PAYLOADCRCERROR |
966                                                   RFLR_IRQFLAGS_VALIDHEADER |
967                                                   //RFLR_IRQFLAGS_TXDONE |
968                                                   RFLR_IRQFLAGS_CADDONE |
969                                                   //RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL |
970                                                   RFLR_IRQFLAGS_CADDETECTED );
971 
972                 // DIO0=TxDone, DIO2=FhssChangeChannel
973                 SX1272Write( REG_DIOMAPPING1, ( SX1272Read( REG_DIOMAPPING1 ) & RFLR_DIOMAPPING1_DIO0_MASK & RFLR_DIOMAPPING1_DIO2_MASK ) | RFLR_DIOMAPPING1_DIO0_01 | RFLR_DIOMAPPING1_DIO2_00 );
974             }
975             else
976             {
977                 SX1272Write( REG_LR_IRQFLAGSMASK, RFLR_IRQFLAGS_RXTIMEOUT |
978                                                   RFLR_IRQFLAGS_RXDONE |
979                                                   RFLR_IRQFLAGS_PAYLOADCRCERROR |
980                                                   RFLR_IRQFLAGS_VALIDHEADER |
981                                                   //RFLR_IRQFLAGS_TXDONE |
982                                                   RFLR_IRQFLAGS_CADDONE |
983                                                   RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL |
984                                                   RFLR_IRQFLAGS_CADDETECTED );
985 
986                 // DIO0=TxDone
987                 SX1272Write( REG_DIOMAPPING1, ( SX1272Read( REG_DIOMAPPING1 ) & RFLR_DIOMAPPING1_DIO0_MASK ) | RFLR_DIOMAPPING1_DIO0_01 );
988             }
989         }
990         break;
991     }
992 
993     SX1272.Settings.State = RF_TX_RUNNING;
994     TimerStart( &TxTimeoutTimer );
995     SX1272SetOpMode( RF_OPMODE_TRANSMITTER );
996 }
997 
SX1272StartCad(void)998 void SX1272StartCad( void )
999 {
1000     switch( SX1272.Settings.Modem )
1001     {
1002     case MODEM_FSK:
1003         {
1004 
1005         }
1006         break;
1007     case MODEM_LORA:
1008         {
1009             SX1272Write( REG_LR_IRQFLAGSMASK, RFLR_IRQFLAGS_RXTIMEOUT |
1010                                         RFLR_IRQFLAGS_RXDONE |
1011                                         RFLR_IRQFLAGS_PAYLOADCRCERROR |
1012                                         RFLR_IRQFLAGS_VALIDHEADER |
1013                                         RFLR_IRQFLAGS_TXDONE |
1014                                         //RFLR_IRQFLAGS_CADDONE |
1015                                         RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL // |
1016                                         //RFLR_IRQFLAGS_CADDETECTED
1017                                         );
1018 
1019             // DIO3=CADDone
1020             SX1272Write( REG_DIOMAPPING1, ( SX1272Read( REG_DIOMAPPING1 ) & RFLR_DIOMAPPING1_DIO3_MASK ) | RFLR_DIOMAPPING1_DIO3_00 );
1021 
1022             SX1272.Settings.State = RF_CAD;
1023             SX1272SetOpMode( RFLR_OPMODE_CAD );
1024         }
1025         break;
1026     default:
1027         break;
1028     }
1029 }
1030 
SX1272SetTxContinuousWave(uint32_t freq,int8_t power,uint16_t time)1031 void SX1272SetTxContinuousWave( uint32_t freq, int8_t power, uint16_t time )
1032 {
1033     uint32_t timeout = ( uint32_t )time * 1000;
1034 
1035     SX1272SetChannel( freq );
1036 
1037     SX1272SetTxConfig( MODEM_FSK, power, 0, 0, 4800, 0, 5, false, false, 0, 0, 0, timeout );
1038 
1039     SX1272Write( REG_PACKETCONFIG2, ( SX1272Read( REG_PACKETCONFIG2 ) & RF_PACKETCONFIG2_DATAMODE_MASK ) );
1040     // Disable radio interrupts
1041     SX1272Write( REG_DIOMAPPING1, RF_DIOMAPPING1_DIO0_11 | RF_DIOMAPPING1_DIO1_11 );
1042     SX1272Write( REG_DIOMAPPING2, RF_DIOMAPPING2_DIO4_10 | RF_DIOMAPPING2_DIO5_10 );
1043 
1044     TimerSetValue( &TxTimeoutTimer, timeout );
1045 
1046     SX1272.Settings.State = RF_TX_RUNNING;
1047     TimerStart( &TxTimeoutTimer );
1048     SX1272SetOpMode( RF_OPMODE_TRANSMITTER );
1049 }
1050 
SX1272ReadRssi(RadioModems_t modem)1051 int16_t SX1272ReadRssi( RadioModems_t modem )
1052 {
1053     int16_t rssi = 0;
1054 
1055     switch( modem )
1056     {
1057     case MODEM_FSK:
1058         rssi = -( SX1272Read( REG_RSSIVALUE ) >> 1 );
1059         break;
1060     case MODEM_LORA:
1061         rssi = RSSI_OFFSET + SX1272Read( REG_LR_RSSIVALUE );
1062         break;
1063     default:
1064         rssi = -1;
1065         break;
1066     }
1067     return rssi;
1068 }
1069 
SX1272SetOpMode(uint8_t opMode)1070 static void SX1272SetOpMode( uint8_t opMode )
1071 {
1072 #if defined( USE_RADIO_DEBUG )
1073     switch( opMode )
1074     {
1075         case RF_OPMODE_TRANSMITTER:
1076             SX1272DbgPinTxWrite( 1 );
1077             SX1272DbgPinRxWrite( 0 );
1078             break;
1079         case RF_OPMODE_RECEIVER:
1080         case RFLR_OPMODE_RECEIVER_SINGLE:
1081             SX1272DbgPinTxWrite( 0 );
1082             SX1272DbgPinRxWrite( 1 );
1083             break;
1084         default:
1085             SX1272DbgPinTxWrite( 0 );
1086             SX1272DbgPinRxWrite( 0 );
1087             break;
1088     }
1089 #endif
1090     if( opMode == RF_OPMODE_SLEEP )
1091     {
1092         SX1272SetAntSwLowPower( true );
1093     }
1094     else
1095     {
1096         // Enable TCXO if operating mode different from SLEEP.
1097         SX1272SetBoardTcxo( true );
1098         SX1272SetAntSwLowPower( false );
1099         SX1272SetAntSw( opMode );
1100     }
1101     SX1272Write( REG_OPMODE, ( SX1272Read( REG_OPMODE ) & RF_OPMODE_MASK ) | opMode );
1102 }
1103 
SX1272SetModem(RadioModems_t modem)1104 void SX1272SetModem( RadioModems_t modem )
1105 {
1106     if( ( SX1272Read( REG_OPMODE ) & RFLR_OPMODE_LONGRANGEMODE_ON ) != 0 )
1107     {
1108         SX1272.Settings.Modem = MODEM_LORA;
1109     }
1110     else
1111     {
1112         SX1272.Settings.Modem = MODEM_FSK;
1113     }
1114 
1115     if( SX1272.Settings.Modem == modem )
1116     {
1117         return;
1118     }
1119 
1120     SX1272.Settings.Modem = modem;
1121     switch( SX1272.Settings.Modem )
1122     {
1123     default:
1124     case MODEM_FSK:
1125         SX1272SetOpMode( RF_OPMODE_SLEEP );
1126         SX1272Write( REG_OPMODE, ( SX1272Read( REG_OPMODE ) & RFLR_OPMODE_LONGRANGEMODE_MASK ) | RFLR_OPMODE_LONGRANGEMODE_OFF );
1127 
1128         SX1272Write( REG_DIOMAPPING1, 0x00 );
1129         SX1272Write( REG_DIOMAPPING2, 0x30 ); // DIO5=ModeReady
1130         break;
1131     case MODEM_LORA:
1132         SX1272SetOpMode( RF_OPMODE_SLEEP );
1133         SX1272Write( REG_OPMODE, ( SX1272Read( REG_OPMODE ) & RFLR_OPMODE_LONGRANGEMODE_MASK ) | RFLR_OPMODE_LONGRANGEMODE_ON );
1134 
1135         SX1272Write( REG_DIOMAPPING1, 0x00 );
1136         SX1272Write( REG_DIOMAPPING2, 0x00 );
1137         break;
1138     }
1139 }
1140 
SX1272Write(uint32_t addr,uint8_t data)1141 void SX1272Write( uint32_t addr, uint8_t data )
1142 {
1143     SX1272WriteBuffer( addr, &data, 1 );
1144 }
1145 
SX1272Read(uint32_t addr)1146 uint8_t SX1272Read( uint32_t addr )
1147 {
1148     uint8_t data;
1149     SX1272ReadBuffer( addr, &data, 1 );
1150     return data;
1151 }
1152 
1153 #ifndef __ZEPHYR__
SX1272WriteBuffer(uint32_t addr,uint8_t * buffer,uint8_t size)1154 void SX1272WriteBuffer( uint32_t addr, uint8_t *buffer, uint8_t size )
1155 {
1156     uint8_t i;
1157 
1158     //NSS = 0;
1159     GpioWrite( &SX1272.Spi.Nss, 0 );
1160 
1161     SpiInOut( &SX1272.Spi, addr | 0x80 );
1162     for( i = 0; i < size; i++ )
1163     {
1164         SpiInOut( &SX1272.Spi, buffer[i] );
1165     }
1166 
1167     //NSS = 1;
1168     GpioWrite( &SX1272.Spi.Nss, 1 );
1169 }
1170 
SX1272ReadBuffer(uint32_t addr,uint8_t * buffer,uint8_t size)1171 void SX1272ReadBuffer( uint32_t addr, uint8_t *buffer, uint8_t size )
1172 {
1173     uint8_t i;
1174 
1175     //NSS = 0;
1176     GpioWrite( &SX1272.Spi.Nss, 0 );
1177 
1178     SpiInOut( &SX1272.Spi, addr & 0x7F );
1179 
1180     for( i = 0; i < size; i++ )
1181     {
1182         buffer[i] = SpiInOut( &SX1272.Spi, 0 );
1183     }
1184 
1185     //NSS = 1;
1186     GpioWrite( &SX1272.Spi.Nss, 1 );
1187 }
1188 #endif
1189 
SX1272WriteFifo(uint8_t * buffer,uint8_t size)1190 static void SX1272WriteFifo( uint8_t *buffer, uint8_t size )
1191 {
1192     SX1272WriteBuffer( 0, buffer, size );
1193 }
1194 
SX1272ReadFifo(uint8_t * buffer,uint8_t size)1195 static void SX1272ReadFifo( uint8_t *buffer, uint8_t size )
1196 {
1197     SX1272ReadBuffer( 0, buffer, size );
1198 }
1199 
SX1272SetMaxPayloadLength(RadioModems_t modem,uint8_t max)1200 void SX1272SetMaxPayloadLength( RadioModems_t modem, uint8_t max )
1201 {
1202     SX1272SetModem( modem );
1203 
1204     switch( modem )
1205     {
1206     case MODEM_FSK:
1207         if( SX1272.Settings.Fsk.FixLen == false )
1208         {
1209             SX1272Write( REG_PAYLOADLENGTH, max );
1210         }
1211         break;
1212     case MODEM_LORA:
1213         SX1272Write( REG_LR_PAYLOADMAXLENGTH, max );
1214         break;
1215     }
1216 }
1217 
SX1272SetPublicNetwork(bool enable)1218 void SX1272SetPublicNetwork( bool enable )
1219 {
1220     SX1272SetModem( MODEM_LORA );
1221     SX1272.Settings.LoRa.PublicNetwork = enable;
1222     if( enable == true )
1223     {
1224         // Change LoRa modem SyncWord
1225         SX1272Write( REG_LR_SYNCWORD, LORA_MAC_PUBLIC_SYNCWORD );
1226     }
1227     else
1228     {
1229         // Change LoRa modem SyncWord
1230         SX1272Write( REG_LR_SYNCWORD, LORA_MAC_PRIVATE_SYNCWORD );
1231     }
1232 }
1233 
SX1272GetWakeupTime(void)1234 uint32_t SX1272GetWakeupTime( void )
1235 {
1236     return SX1272GetBoardTcxoWakeupTime( ) + RADIO_WAKEUP_TIME;
1237 }
1238 
SX1272ConvertPllStepToFreqInHz(uint32_t pllSteps)1239 static uint32_t SX1272ConvertPllStepToFreqInHz( uint32_t pllSteps )
1240 {
1241     uint32_t freqInHzInt;
1242     uint32_t freqInHzFrac;
1243 
1244     // freqInHz = pllSteps * ( SX1272_XTAL_FREQ / 2^19 )
1245     // Get integer and fractional parts of the frequency computed with a PLL step scaled value
1246     freqInHzInt = pllSteps >> SX1272_PLL_STEP_SHIFT_AMOUNT;
1247     freqInHzFrac = pllSteps - ( freqInHzInt << SX1272_PLL_STEP_SHIFT_AMOUNT );
1248 
1249     // Apply the scaling factor to retrieve a frequency in Hz (+ ceiling)
1250     return freqInHzInt * SX1272_PLL_STEP_SCALED +
1251            ( ( freqInHzFrac * SX1272_PLL_STEP_SCALED + ( 128 ) ) >> SX1272_PLL_STEP_SHIFT_AMOUNT );
1252 }
1253 
SX1272ConvertFreqInHzToPllStep(uint32_t freqInHz)1254 static uint32_t SX1272ConvertFreqInHzToPllStep( uint32_t freqInHz )
1255 {
1256     uint32_t stepsInt;
1257     uint32_t stepsFrac;
1258 
1259     // pllSteps = freqInHz / (SX1272_XTAL_FREQ / 2^19 )
1260     // Get integer and fractional parts of the frequency computed with a PLL step scaled value
1261     stepsInt = freqInHz / SX1272_PLL_STEP_SCALED;
1262     stepsFrac = freqInHz - ( stepsInt * SX1272_PLL_STEP_SCALED );
1263 
1264     // Apply the scaling factor to retrieve a frequency in Hz (+ ceiling)
1265     return ( stepsInt << SX1272_PLL_STEP_SHIFT_AMOUNT ) +
1266            ( ( ( stepsFrac << SX1272_PLL_STEP_SHIFT_AMOUNT ) + ( SX1272_PLL_STEP_SCALED >> 1 ) ) /
1267              SX1272_PLL_STEP_SCALED );
1268 }
1269 
GetFskBandwidthRegValue(uint32_t bw)1270 static uint8_t GetFskBandwidthRegValue( uint32_t bw )
1271 {
1272     uint8_t i;
1273 
1274     for( i = 0; i < ( sizeof( FskBandwidths ) / sizeof( FskBandwidth_t ) ) - 1; i++ )
1275     {
1276         if( ( bw >= FskBandwidths[i].bandwidth ) && ( bw < FskBandwidths[i + 1].bandwidth ) )
1277         {
1278             return FskBandwidths[i].RegValue;
1279         }
1280     }
1281     // ERROR: Value not found
1282     while( 1 );
1283 }
1284 
SX1272GetLoRaBandwidthInHz(uint32_t bw)1285 static uint32_t SX1272GetLoRaBandwidthInHz( uint32_t bw )
1286 {
1287     uint32_t bandwidthInHz = 0;
1288 
1289     switch( bw )
1290     {
1291     case 0: // 125 kHz
1292         bandwidthInHz = 125000UL;
1293         break;
1294     case 1: // 250 kHz
1295         bandwidthInHz = 250000UL;
1296         break;
1297     case 2: // 500 kHz
1298         bandwidthInHz = 500000UL;
1299         break;
1300     }
1301 
1302     return bandwidthInHz;
1303 }
1304 
SX1272GetGfskTimeOnAirNumerator(uint16_t preambleLen,bool fixLen,uint8_t payloadLen,bool crcOn)1305 static uint32_t SX1272GetGfskTimeOnAirNumerator( uint16_t preambleLen, bool fixLen,
1306                                                  uint8_t payloadLen, bool crcOn )
1307 {
1308     const uint8_t syncWordLength = 3;
1309 
1310     return ( preambleLen << 3 ) +
1311            ( ( fixLen == false ) ? 8 : 0 ) +
1312              ( syncWordLength << 3 ) +
1313              ( ( payloadLen +
1314                ( 0 ) + // Address filter size
1315                ( ( crcOn == true ) ? 2 : 0 )
1316                ) << 3
1317              );
1318 }
1319 
SX1272GetLoRaTimeOnAirNumerator(uint32_t bandwidth,uint32_t datarate,uint8_t coderate,uint16_t preambleLen,bool fixLen,uint8_t payloadLen,bool crcOn)1320 static uint32_t SX1272GetLoRaTimeOnAirNumerator( uint32_t bandwidth,
1321                               uint32_t datarate, uint8_t coderate,
1322                               uint16_t preambleLen, bool fixLen, uint8_t payloadLen,
1323                               bool crcOn )
1324 {
1325     int32_t crDenom           = coderate + 4;
1326     bool    lowDatareOptimize = false;
1327 
1328     // Ensure that the preamble length is at least 12 symbols when using SF5 or
1329     // SF6
1330     if( ( datarate == 5 ) || ( datarate == 6 ) )
1331     {
1332         if( preambleLen < 12 )
1333         {
1334             preambleLen = 12;
1335         }
1336     }
1337 
1338     if( ( ( bandwidth == 0 ) && ( ( datarate == 11 ) || ( datarate == 12 ) ) ) ||
1339         ( ( bandwidth == 1 ) && ( datarate == 12 ) ) )
1340     {
1341         lowDatareOptimize = true;
1342     }
1343 
1344     int32_t ceilDenominator;
1345     int32_t ceilNumerator = ( payloadLen << 3 ) +
1346                             ( crcOn ? 16 : 0 ) -
1347                             ( 4 * datarate ) +
1348                             ( fixLen ? 0 : 20 );
1349 
1350     if( datarate <= 6 )
1351     {
1352         ceilDenominator = 4 * datarate;
1353     }
1354     else
1355     {
1356         ceilNumerator += 8;
1357 
1358         if( lowDatareOptimize == true )
1359         {
1360             ceilDenominator = 4 * ( datarate - 2 );
1361         }
1362         else
1363         {
1364             ceilDenominator = 4 * datarate;
1365         }
1366     }
1367 
1368     if( ceilNumerator < 0 )
1369     {
1370         ceilNumerator = 0;
1371     }
1372 
1373     // Perform integral ceil()
1374     int32_t intermediate =
1375         ( ( ceilNumerator + ceilDenominator - 1 ) / ceilDenominator ) * crDenom + preambleLen + 12;
1376 
1377     if( datarate <= 6 )
1378     {
1379         intermediate += 2;
1380     }
1381 
1382     return ( uint32_t )( ( 4 * intermediate + 1 ) * ( 1 << ( datarate - 2 ) ) );
1383 }
1384 
SX1272OnTimeoutIrq(void * context)1385 static void SX1272OnTimeoutIrq( void* context )
1386 {
1387     switch( SX1272.Settings.State )
1388     {
1389     case RF_RX_RUNNING:
1390         if( SX1272.Settings.Modem == MODEM_FSK )
1391         {
1392             SX1272.Settings.FskPacketHandler.PreambleDetected = false;
1393             SX1272.Settings.FskPacketHandler.SyncWordDetected = false;
1394             SX1272.Settings.FskPacketHandler.NbBytes = 0;
1395             SX1272.Settings.FskPacketHandler.Size = 0;
1396 
1397             // Clear Irqs
1398             SX1272Write( REG_IRQFLAGS1, RF_IRQFLAGS1_RSSI |
1399                                         RF_IRQFLAGS1_PREAMBLEDETECT |
1400                                         RF_IRQFLAGS1_SYNCADDRESSMATCH );
1401             SX1272Write( REG_IRQFLAGS2, RF_IRQFLAGS2_FIFOOVERRUN );
1402 
1403             if( SX1272.Settings.Fsk.RxContinuous == true )
1404             {
1405                 // Continuous mode restart Rx chain
1406                 SX1272Write( REG_RXCONFIG, SX1272Read( REG_RXCONFIG ) | RF_RXCONFIG_RESTARTRXWITHOUTPLLLOCK );
1407             }
1408             else
1409             {
1410                 SX1272.Settings.State = RF_IDLE;
1411                 TimerStop( &RxTimeoutSyncWord );
1412             }
1413         }
1414         if( ( RadioEvents != NULL ) && ( RadioEvents->RxTimeout != NULL ) )
1415         {
1416             RadioEvents->RxTimeout( );
1417         }
1418         break;
1419     case RF_TX_RUNNING:
1420         // Tx timeout shouldn't happen.
1421         // Reported issue of SPI data corruption resulting in TX TIMEOUT
1422         // is NOT related to a bug in radio transceiver.
1423         // It is mainly caused by improper PCB routing of SPI lines and/or
1424         // violation of SPI specifications.
1425         // To mitigate redesign, Semtech offers a workaround which resets
1426         // the radio transceiver and putting it into a known state.
1427 
1428         // BEGIN WORKAROUND
1429 
1430         // Reset the radio
1431         SX1272Reset( );
1432 
1433         // Initialize radio default values
1434         SX1272SetOpMode( RF_OPMODE_SLEEP );
1435 
1436         for( uint8_t i = 0; i < sizeof( RadioRegsInit ) / sizeof( RadioRegisters_t ); i++ )
1437         {
1438             SX1272SetModem( RadioRegsInit[i].Modem );
1439             SX1272Write( RadioRegsInit[i].Addr, RadioRegsInit[i].Value );
1440         }
1441         SX1272SetModem( MODEM_FSK );
1442 
1443         // Restore previous network type setting.
1444         SX1272SetPublicNetwork( SX1272.Settings.LoRa.PublicNetwork );
1445         // END WORKAROUND
1446 
1447         SX1272.Settings.State = RF_IDLE;
1448         if( ( RadioEvents != NULL ) && ( RadioEvents->TxTimeout != NULL ) )
1449         {
1450             RadioEvents->TxTimeout( );
1451         }
1452         break;
1453     default:
1454         break;
1455     }
1456 }
1457 
SX1272OnDio0Irq(void * context)1458 static void SX1272OnDio0Irq( void* context )
1459 {
1460     volatile uint8_t irqFlags = 0;
1461 
1462     switch( SX1272.Settings.State )
1463     {
1464         case RF_RX_RUNNING:
1465             //TimerStop( &RxTimeoutTimer );
1466             // RxDone interrupt
1467             switch( SX1272.Settings.Modem )
1468             {
1469             case MODEM_FSK:
1470                 if( SX1272.Settings.Fsk.CrcOn == true )
1471                 {
1472                     irqFlags = SX1272Read( REG_IRQFLAGS2 );
1473                     if( ( irqFlags & RF_IRQFLAGS2_CRCOK ) != RF_IRQFLAGS2_CRCOK )
1474                     {
1475                         // Clear Irqs
1476                         SX1272Write( REG_IRQFLAGS1, RF_IRQFLAGS1_RSSI |
1477                                                     RF_IRQFLAGS1_PREAMBLEDETECT |
1478                                                     RF_IRQFLAGS1_SYNCADDRESSMATCH );
1479                         SX1272Write( REG_IRQFLAGS2, RF_IRQFLAGS2_FIFOOVERRUN );
1480 
1481                         TimerStop( &RxTimeoutTimer );
1482 
1483                         if( SX1272.Settings.Fsk.RxContinuous == false )
1484                         {
1485                             TimerStop( &RxTimeoutSyncWord );
1486                             SX1272.Settings.State = RF_IDLE;
1487                         }
1488                         else
1489                         {
1490                             // Continuous mode restart Rx chain
1491                             SX1272Write( REG_RXCONFIG, SX1272Read( REG_RXCONFIG ) | RF_RXCONFIG_RESTARTRXWITHOUTPLLLOCK );
1492                         }
1493 
1494                         if( ( RadioEvents != NULL ) && ( RadioEvents->RxError != NULL ) )
1495                         {
1496                             RadioEvents->RxError( );
1497                         }
1498                         SX1272.Settings.FskPacketHandler.PreambleDetected = false;
1499                         SX1272.Settings.FskPacketHandler.SyncWordDetected = false;
1500                         SX1272.Settings.FskPacketHandler.NbBytes = 0;
1501                         SX1272.Settings.FskPacketHandler.Size = 0;
1502                         break;
1503                     }
1504                 }
1505 
1506                 // Read received packet size
1507                 if( ( SX1272.Settings.FskPacketHandler.Size == 0 ) && ( SX1272.Settings.FskPacketHandler.NbBytes == 0 ) )
1508                 {
1509                     if( SX1272.Settings.Fsk.FixLen == false )
1510                     {
1511                         SX1272ReadFifo( ( uint8_t* )&SX1272.Settings.FskPacketHandler.Size, 1 );
1512                     }
1513                     else
1514                     {
1515                         SX1272.Settings.FskPacketHandler.Size = SX1272Read( REG_PAYLOADLENGTH );
1516                     }
1517                     SX1272ReadFifo( RxTxBuffer + SX1272.Settings.FskPacketHandler.NbBytes, SX1272.Settings.FskPacketHandler.Size - SX1272.Settings.FskPacketHandler.NbBytes );
1518                     SX1272.Settings.FskPacketHandler.NbBytes += ( SX1272.Settings.FskPacketHandler.Size - SX1272.Settings.FskPacketHandler.NbBytes );
1519                 }
1520                 else
1521                 {
1522                     SX1272ReadFifo( RxTxBuffer + SX1272.Settings.FskPacketHandler.NbBytes, SX1272.Settings.FskPacketHandler.Size - SX1272.Settings.FskPacketHandler.NbBytes );
1523                     SX1272.Settings.FskPacketHandler.NbBytes += ( SX1272.Settings.FskPacketHandler.Size - SX1272.Settings.FskPacketHandler.NbBytes );
1524                 }
1525 
1526                 TimerStop( &RxTimeoutTimer );
1527 
1528                 if( SX1272.Settings.Fsk.RxContinuous == false )
1529                 {
1530                     SX1272.Settings.State = RF_IDLE;
1531                     TimerStop( &RxTimeoutSyncWord );
1532                 }
1533                 else
1534                 {
1535                     // Continuous mode restart Rx chain
1536                     SX1272Write( REG_RXCONFIG, SX1272Read( REG_RXCONFIG ) | RF_RXCONFIG_RESTARTRXWITHOUTPLLLOCK );
1537                 }
1538 
1539                 if( ( RadioEvents != NULL ) && ( RadioEvents->RxDone != NULL ) )
1540                 {
1541                     RadioEvents->RxDone( RxTxBuffer, SX1272.Settings.FskPacketHandler.Size, SX1272.Settings.FskPacketHandler.RssiValue, 0 );
1542                 }
1543                 SX1272.Settings.FskPacketHandler.PreambleDetected = false;
1544                 SX1272.Settings.FskPacketHandler.SyncWordDetected = false;
1545                 SX1272.Settings.FskPacketHandler.NbBytes = 0;
1546                 SX1272.Settings.FskPacketHandler.Size = 0;
1547                 break;
1548             case MODEM_LORA:
1549                 {
1550                     // Clear Irq
1551                     SX1272Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_RXDONE );
1552 
1553                     irqFlags = SX1272Read( REG_LR_IRQFLAGS );
1554                     if( ( irqFlags & RFLR_IRQFLAGS_PAYLOADCRCERROR_MASK ) == RFLR_IRQFLAGS_PAYLOADCRCERROR )
1555                     {
1556                         // Clear Irq
1557                         SX1272Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_PAYLOADCRCERROR );
1558 
1559                         if( SX1272.Settings.LoRa.RxContinuous == false )
1560                         {
1561                             SX1272.Settings.State = RF_IDLE;
1562                         }
1563                         TimerStop( &RxTimeoutTimer );
1564 
1565                         if( ( RadioEvents != NULL ) && ( RadioEvents->RxError != NULL ) )
1566                         {
1567                             RadioEvents->RxError( );
1568                         }
1569                         break;
1570                     }
1571 
1572                     // Returns SNR value [dB] rounded to the nearest integer value
1573                     SX1272.Settings.LoRaPacketHandler.SnrValue = ( ( ( int8_t )SX1272Read( REG_LR_PKTSNRVALUE ) ) + 2 ) >> 2;
1574 
1575                     int16_t rssi = SX1272Read( REG_LR_PKTRSSIVALUE );
1576                     if( SX1272.Settings.LoRaPacketHandler.SnrValue < 0 )
1577                     {
1578                         SX1272.Settings.LoRaPacketHandler.RssiValue = RSSI_OFFSET + rssi + ( rssi >> 4 ) +
1579                                                                       SX1272.Settings.LoRaPacketHandler.SnrValue;
1580                     }
1581                     else
1582                     {
1583                         SX1272.Settings.LoRaPacketHandler.RssiValue = RSSI_OFFSET + rssi + ( rssi >> 4 );
1584                     }
1585 
1586                     SX1272.Settings.LoRaPacketHandler.Size = SX1272Read( REG_LR_RXNBBYTES );
1587                     SX1272Write( REG_LR_FIFOADDRPTR, SX1272Read( REG_LR_FIFORXCURRENTADDR ) );
1588                     SX1272ReadFifo( RxTxBuffer, SX1272.Settings.LoRaPacketHandler.Size );
1589 
1590                     if( SX1272.Settings.LoRa.RxContinuous == false )
1591                     {
1592                         SX1272.Settings.State = RF_IDLE;
1593                     }
1594                     TimerStop( &RxTimeoutTimer );
1595 
1596                     if( ( RadioEvents != NULL ) && ( RadioEvents->RxDone != NULL ) )
1597                     {
1598                         RadioEvents->RxDone( RxTxBuffer, SX1272.Settings.LoRaPacketHandler.Size, SX1272.Settings.LoRaPacketHandler.RssiValue, SX1272.Settings.LoRaPacketHandler.SnrValue );
1599                     }
1600                 }
1601                 break;
1602             default:
1603                 break;
1604             }
1605             break;
1606         case RF_TX_RUNNING:
1607             TimerStop( &TxTimeoutTimer );
1608             // TxDone interrupt
1609             switch( SX1272.Settings.Modem )
1610             {
1611             case MODEM_LORA:
1612                 // Clear Irq
1613                 SX1272Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_TXDONE );
1614                 // Intentional fall through
1615             case MODEM_FSK:
1616             default:
1617                 SX1272.Settings.State = RF_IDLE;
1618                 if( ( RadioEvents != NULL ) && ( RadioEvents->TxDone != NULL ) )
1619                 {
1620                     RadioEvents->TxDone( );
1621                 }
1622                 break;
1623             }
1624             break;
1625         default:
1626             break;
1627     }
1628 }
1629 
SX1272OnDio1Irq(void * context)1630 static void SX1272OnDio1Irq( void* context )
1631 {
1632     switch( SX1272.Settings.State )
1633     {
1634         case RF_RX_RUNNING:
1635             switch( SX1272.Settings.Modem )
1636             {
1637             case MODEM_FSK:
1638                 // Check FIFO level DIO1 pin state
1639                 //
1640                 // As DIO1 interrupt is triggered when a rising or a falling edge is detected the IRQ handler must
1641                 // verify DIO1 pin state in order to decide if something has to be done.
1642                 // When radio is operating in FSK reception mode a rising edge must be detected in order to handle the
1643                 // IRQ.
1644                 if( SX1272GetDio1PinState( ) == 0 )
1645                 {
1646                     break;
1647                 }
1648                 // Stop timer
1649                 TimerStop( &RxTimeoutSyncWord );
1650 
1651                 // FifoLevel interrupt
1652                 // Read received packet size
1653                 if( ( SX1272.Settings.FskPacketHandler.Size == 0 ) && ( SX1272.Settings.FskPacketHandler.NbBytes == 0 ) )
1654                 {
1655                     if( SX1272.Settings.Fsk.FixLen == false )
1656                     {
1657                         SX1272ReadFifo( ( uint8_t* )&SX1272.Settings.FskPacketHandler.Size, 1 );
1658                     }
1659                     else
1660                     {
1661                         SX1272.Settings.FskPacketHandler.Size = SX1272Read( REG_PAYLOADLENGTH );
1662                     }
1663                 }
1664                 // ERRATA 3.1 - PayloadReady Set for 31.25ns if FIFO is Empty
1665                 //
1666                 //              When FifoLevel interrupt is used to offload the
1667                 //              FIFO, the microcontroller should  monitor  both
1668                 //              PayloadReady  and FifoLevel interrupts, and
1669                 //              read only (FifoThreshold-1) bytes off the FIFO
1670                 //              when FifoLevel fires
1671                 if( ( SX1272.Settings.FskPacketHandler.Size - SX1272.Settings.FskPacketHandler.NbBytes ) >= SX1272.Settings.FskPacketHandler.FifoThresh )
1672                 {
1673                     SX1272ReadFifo( ( RxTxBuffer + SX1272.Settings.FskPacketHandler.NbBytes ), SX1272.Settings.FskPacketHandler.FifoThresh - 1 );
1674                     SX1272.Settings.FskPacketHandler.NbBytes += SX1272.Settings.FskPacketHandler.FifoThresh - 1;
1675                 }
1676                 else
1677                 {
1678                     SX1272ReadFifo( ( RxTxBuffer + SX1272.Settings.FskPacketHandler.NbBytes ), SX1272.Settings.FskPacketHandler.Size - SX1272.Settings.FskPacketHandler.NbBytes );
1679                     SX1272.Settings.FskPacketHandler.NbBytes += ( SX1272.Settings.FskPacketHandler.Size - SX1272.Settings.FskPacketHandler.NbBytes );
1680                 }
1681                 break;
1682             case MODEM_LORA:
1683                 // Check RxTimeout DIO1 pin state
1684                 //
1685                 // DIO1 irq is setup to be triggered on rsing and falling edges
1686                 // As DIO1 interrupt is triggered when a rising or a falling edge is detected the IRQ handler must
1687                 // verify DIO1 pin state in order to decide if something has to be done.
1688                 // When radio is operating in LoRa reception mode a rising edge must be detected in order to handle the
1689                 // IRQ.
1690                 if( SX1272GetDio1PinState( ) == 0 )
1691                 {
1692                     break;
1693                 }
1694                 // Sync time out
1695                 TimerStop( &RxTimeoutTimer );
1696                 // Clear Irq
1697                 SX1272Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_RXTIMEOUT );
1698 
1699                 SX1272.Settings.State = RF_IDLE;
1700                 if( ( RadioEvents != NULL ) && ( RadioEvents->RxTimeout != NULL ) )
1701                 {
1702                     RadioEvents->RxTimeout( );
1703                 }
1704                 break;
1705             default:
1706                 break;
1707             }
1708             break;
1709         case RF_TX_RUNNING:
1710             switch( SX1272.Settings.Modem )
1711             {
1712             case MODEM_FSK:
1713                 // Check FIFO level DIO1 pin state
1714                 //
1715                 // As DIO1 interrupt is triggered when a rising or a falling edge is detected the IRQ handler must
1716                 // verify DIO1 pin state in order to decide if something has to be done.
1717                 // When radio is operating in FSK transmission mode a falling edge must be detected in order to handle
1718                 // the IRQ.
1719                 if( SX1272GetDio1PinState( ) == 1 )
1720                 {
1721                     break;
1722                 }
1723 
1724                 // FifoLevel interrupt
1725                 if( ( SX1272.Settings.FskPacketHandler.Size - SX1272.Settings.FskPacketHandler.NbBytes ) > SX1272.Settings.FskPacketHandler.ChunkSize )
1726                 {
1727                     SX1272WriteFifo( ( RxTxBuffer + SX1272.Settings.FskPacketHandler.NbBytes ), SX1272.Settings.FskPacketHandler.ChunkSize );
1728                     SX1272.Settings.FskPacketHandler.NbBytes += SX1272.Settings.FskPacketHandler.ChunkSize;
1729                 }
1730                 else
1731                 {
1732                     // Write the last chunk of data
1733                     SX1272WriteFifo( RxTxBuffer + SX1272.Settings.FskPacketHandler.NbBytes, SX1272.Settings.FskPacketHandler.Size - SX1272.Settings.FskPacketHandler.NbBytes );
1734                     SX1272.Settings.FskPacketHandler.NbBytes += SX1272.Settings.FskPacketHandler.Size - SX1272.Settings.FskPacketHandler.NbBytes;
1735                 }
1736                 break;
1737             case MODEM_LORA:
1738                 break;
1739             default:
1740                 break;
1741             }
1742             break;
1743         default:
1744             break;
1745     }
1746 }
1747 
SX1272OnDio2Irq(void * context)1748 static void SX1272OnDio2Irq( void* context )
1749 {
1750     switch( SX1272.Settings.State )
1751     {
1752         case RF_RX_RUNNING:
1753             switch( SX1272.Settings.Modem )
1754             {
1755             case MODEM_FSK:
1756                 // Checks if DIO4 is connected. If it is not PreambleDetected is set to true.
1757                 if( SX1272.DIO4.port == NULL )
1758                 {
1759                     SX1272.Settings.FskPacketHandler.PreambleDetected = true;
1760                 }
1761 
1762                 if( ( SX1272.Settings.FskPacketHandler.PreambleDetected != 0 ) && ( SX1272.Settings.FskPacketHandler.SyncWordDetected == 0 ) )
1763                 {
1764                     TimerStop( &RxTimeoutSyncWord );
1765 
1766                     SX1272.Settings.FskPacketHandler.SyncWordDetected = true;
1767 
1768                     SX1272.Settings.FskPacketHandler.RssiValue = -( SX1272Read( REG_RSSIVALUE ) >> 1 );
1769 
1770                     SX1272.Settings.FskPacketHandler.AfcValue = ( int32_t )SX1272ConvertPllStepToFreqInHz( ( ( uint16_t )SX1272Read( REG_AFCMSB ) << 8 ) |
1771                                                                                                            ( uint16_t )SX1272Read( REG_AFCLSB ) );
1772                     SX1272.Settings.FskPacketHandler.RxGain = ( SX1272Read( REG_LNA ) >> 5 ) & 0x07;
1773                 }
1774                 break;
1775             case MODEM_LORA:
1776                 if( SX1272.Settings.LoRa.FreqHopOn == true )
1777                 {
1778                     // Clear Irq
1779                     SX1272Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL );
1780 
1781                     if( ( RadioEvents != NULL ) && ( RadioEvents->FhssChangeChannel != NULL ) )
1782                     {
1783                         RadioEvents->FhssChangeChannel( ( SX1272Read( REG_LR_HOPCHANNEL ) & RFLR_HOPCHANNEL_CHANNEL_MASK ) );
1784                     }
1785                 }
1786                 break;
1787             default:
1788                 break;
1789             }
1790             break;
1791         case RF_TX_RUNNING:
1792             switch( SX1272.Settings.Modem )
1793             {
1794             case MODEM_FSK:
1795                 break;
1796             case MODEM_LORA:
1797                 if( SX1272.Settings.LoRa.FreqHopOn == true )
1798                 {
1799                     // Clear Irq
1800                     SX1272Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL );
1801 
1802                     if( ( RadioEvents != NULL ) && ( RadioEvents->FhssChangeChannel != NULL ) )
1803                     {
1804                         RadioEvents->FhssChangeChannel( ( SX1272Read( REG_LR_HOPCHANNEL ) & RFLR_HOPCHANNEL_CHANNEL_MASK ) );
1805                     }
1806                 }
1807                 break;
1808             default:
1809                 break;
1810             }
1811             break;
1812         default:
1813             break;
1814     }
1815 }
1816 
SX1272OnDio3Irq(void * context)1817 static void SX1272OnDio3Irq( void* context )
1818 {
1819     switch( SX1272.Settings.Modem )
1820     {
1821     case MODEM_FSK:
1822         break;
1823     case MODEM_LORA:
1824         if( ( SX1272Read( REG_LR_IRQFLAGS ) & RFLR_IRQFLAGS_CADDETECTED ) == RFLR_IRQFLAGS_CADDETECTED )
1825         {
1826             // Clear Irq
1827             SX1272Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_CADDETECTED | RFLR_IRQFLAGS_CADDONE );
1828             if( ( RadioEvents != NULL ) && ( RadioEvents->CadDone != NULL ) )
1829             {
1830                 RadioEvents->CadDone( true );
1831             }
1832         }
1833         else
1834         {
1835             // Clear Irq
1836             SX1272Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_CADDONE );
1837             if( ( RadioEvents != NULL ) && ( RadioEvents->CadDone != NULL ) )
1838             {
1839                 RadioEvents->CadDone( false );
1840             }
1841         }
1842         break;
1843     default:
1844         break;
1845     }
1846 }
1847 
SX1272OnDio4Irq(void * context)1848 static void SX1272OnDio4Irq( void* context )
1849 {
1850     switch( SX1272.Settings.Modem )
1851     {
1852     case MODEM_FSK:
1853         {
1854             if( SX1272.Settings.FskPacketHandler.PreambleDetected == false )
1855             {
1856                 SX1272.Settings.FskPacketHandler.PreambleDetected = true;
1857             }
1858         }
1859         break;
1860     case MODEM_LORA:
1861         break;
1862     default:
1863         break;
1864     }
1865 }
1866