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