1 /*
2 ______ _
3 / _____) _ | |
4 ( (____ _____ ____ _| |_ _____ ____| |__
5 \____ \| ___ | (_ _) ___ |/ ___) _ \
6 _____) ) ____| | | || |_| ____( (___| | | |
7 (______/|_____)_|_|_| \__)_____)\____)_| |_|
8 (C)2016 Semtech
9
10 Description: Driver for SX1280 devices
11
12 License: Revised BSD License, see LICENSE.TXT file include in the project
13
14 Maintainer: Miguel Luis, Matthieu Verdy and Benjamin Boulet
15 */
16 #include <string.h>
17 #include "sx1280.h"
18 #include "sx1280-hal.h"
19 #include "RangingCorrection.h"
20
21 // logging on
22 #include "SEGGER_RTT.h"
23 #define printf(format, ...) SEGGER_RTT_printf(0, format, ## __VA_ARGS__)
24
25
26 /*!
27 * \brief Radio registers definition
28 *
29 */
30 typedef struct
31 {
32 uint16_t Addr; //!< The address of the register
33 uint8_t Value; //!< The value of the register
34 }RadioRegisters_t;
35
36 /*!
37 * \brief Radio hardware registers initialization definition
38 */
39 // { Address, RegValue }
40 #define RADIO_INIT_REGISTERS_VALUE { 0 }
41
42 /*!
43 * \brief Radio hardware registers initialization
44 */
45 const RadioRegisters_t RadioRegsInit[] = RADIO_INIT_REGISTERS_VALUE;
46
47 /*!
48 * \brief Holds the internal operating mode of the radio
49 */
50 static RadioOperatingModes_t OperatingMode;
51
52 /*!
53 * \brief Stores the current packet type set in the radio
54 */
55 static RadioPacketTypes_t PacketType;
56
57 /*!
58 * \brief Stores the current LoRa bandwidth set in the radio
59 */
60 static RadioLoRaBandwidths_t LoRaBandwidth;
61
62 /*!
63 * \brief Holds the polling state of the driver
64 */
65 static bool PollingMode;
66
67 /*!
68 * Hardware DIO IRQ callback initialization
69 */
70 DioIrqHandler *DioIrq[] = { SX1280OnDioIrq };
71
72 void SX1280OnDioIrq( void );
73
74 /*!
75 * \brief Holds a flag raised on radio interrupt
76 */
77 static bool IrqState;
78
79 static RadioCallbacks_t* RadioCallbacks;
80
SX1280complement2(const uint32_t num,const uint8_t bitCnt)81 int32_t SX1280complement2( const uint32_t num, const uint8_t bitCnt )
82 {
83 int32_t retVal = ( int32_t )num;
84 if( num >= 2<<( bitCnt - 2 ) )
85 {
86 retVal -= 2<<( bitCnt - 1 );
87 }
88 return retVal;
89 }
90
SX1280Init(RadioCallbacks_t * callbacks)91 void SX1280Init( RadioCallbacks_t *callbacks )
92 {
93 RadioCallbacks = callbacks;
94
95 SX1280HalInit( DioIrq );
96 }
97
SX1280SetRegistersDefault(void)98 void SX1280SetRegistersDefault( void )
99 {
100 for( int16_t i = 0; i < sizeof( RadioRegsInit ) / sizeof( RadioRegisters_t ); i++ )
101 {
102 SX1280HalWriteRegister( RadioRegsInit[i].Addr, RadioRegsInit[i].Value );
103 }
104 }
105
SX1280GetFirmwareVersion(void)106 uint16_t SX1280GetFirmwareVersion( void )
107 {
108 return( ( ( SX1280HalReadRegister( REG_LR_FIRMWARE_VERSION_MSB ) ) << 8 ) | ( SX1280HalReadRegister( REG_LR_FIRMWARE_VERSION_MSB + 1 ) ) );
109 }
110
SX1280GetStatus(void)111 RadioStatus_t SX1280GetStatus( void )
112 {
113 uint8_t stat = 0;
114 RadioStatus_t status;
115
116 SX1280HalReadCommand( RADIO_GET_STATUS, ( uint8_t * )&stat, 1 );
117 status.Value = stat;
118 return status;
119 }
120
SX1280GetOpMode(void)121 RadioOperatingModes_t SX1280GetOpMode( void )
122 {
123 return OperatingMode;
124 }
125
SX1280SetSleep(SleepParams_t sleepConfig)126 void SX1280SetSleep( SleepParams_t sleepConfig )
127 {
128 uint8_t sleep = ( sleepConfig.WakeUpRTC << 3 ) |
129 ( sleepConfig.InstructionRamRetention << 2 ) |
130 ( sleepConfig.DataBufferRetention << 1 ) |
131 ( sleepConfig.DataRamRetention );
132
133 OperatingMode = MODE_SLEEP;
134 SX1280HalWriteCommand( RADIO_SET_SLEEP, &sleep, 1 );
135 }
136
SX1280SetStandby(RadioStandbyModes_t standbyConfig)137 void SX1280SetStandby( RadioStandbyModes_t standbyConfig )
138 {
139 SX1280HalWriteCommand( RADIO_SET_STANDBY, ( uint8_t* )&standbyConfig, 1 );
140 if( standbyConfig == STDBY_RC )
141 {
142 OperatingMode = MODE_STDBY_RC;
143 }
144 else
145 {
146 OperatingMode = MODE_STDBY_XOSC;
147 }
148 }
149
SX1280SetFs(void)150 void SX1280SetFs( void )
151 {
152 SX1280HalWriteCommand( RADIO_SET_FS, 0, 0 );
153 OperatingMode = MODE_FS;
154 }
155
SX1280SetTx(TickTime_t timeout)156 void SX1280SetTx( TickTime_t timeout )
157 {
158 uint8_t buf[3];
159 buf[0] = timeout.Step;
160 buf[1] = ( uint8_t )( ( timeout.NbSteps >> 8 ) & 0x00FF );
161 buf[2] = ( uint8_t )( timeout.NbSteps & 0x00FF );
162
163 // BK BEGIN - skip clear IRQ, it is cleared in process irq
164 // SX1280ClearIrqStatus( IRQ_RADIO_ALL );
165 // BK END
166
167 // If the radio is doing ranging operations, then apply the specific calls
168 // prior to SetTx
169 if( SX1280GetPacketType( ) == PACKET_TYPE_RANGING )
170 {
171 SX1280SetRangingRole( RADIO_RANGING_ROLE_MASTER );
172 }
173 SX1280HalWriteCommand( RADIO_SET_TX, buf, 3 );
174 OperatingMode = MODE_TX;
175 }
176
SX1280SetRx(TickTime_t timeout)177 void SX1280SetRx( TickTime_t timeout )
178 {
179 uint8_t buf[3];
180 buf[0] = timeout.Step;
181 buf[1] = ( uint8_t )( ( timeout.NbSteps >> 8 ) & 0x00FF );
182 buf[2] = ( uint8_t )( timeout.NbSteps & 0x00FF );
183
184
185 // BK BEGIN - skip clear IRQ, it is cleared in process irq
186 // SX1280ClearIrqStatus( IRQ_RADIO_ALL );
187 // BK END
188
189 // If the radio is doing ranging operations, then apply the specific calls
190 // prior to SetRx
191 if( SX1280GetPacketType( ) == PACKET_TYPE_RANGING )
192 {
193 SX1280SetRangingRole( RADIO_RANGING_ROLE_SLAVE );
194 }
195 SX1280HalWriteCommand( RADIO_SET_RX, buf, 3 );
196 OperatingMode = MODE_RX;
197 }
198
SX1280SetRxDutyCycle(RadioTickSizes_t Step,uint16_t NbStepRx,uint16_t RxNbStepSleep)199 void SX1280SetRxDutyCycle( RadioTickSizes_t Step, uint16_t NbStepRx, uint16_t RxNbStepSleep )
200 {
201 uint8_t buf[5];
202
203 buf[0] = Step;
204 buf[1] = ( uint8_t )( ( NbStepRx >> 8 ) & 0x00FF );
205 buf[2] = ( uint8_t )( NbStepRx & 0x00FF );
206 buf[3] = ( uint8_t )( ( RxNbStepSleep >> 8 ) & 0x00FF );
207 buf[4] = ( uint8_t )( RxNbStepSleep & 0x00FF );
208 SX1280HalWriteCommand( RADIO_SET_RXDUTYCYCLE, buf, 5 );
209 OperatingMode = MODE_RX;
210 }
211
SX1280SetCad(void)212 void SX1280SetCad( void )
213 {
214 SX1280HalWriteCommand( RADIO_SET_CAD, 0, 0 );
215 OperatingMode = MODE_CAD;
216 }
217
SX1280SetTxContinuousWave(void)218 void SX1280SetTxContinuousWave( void )
219 {
220 SX1280HalWriteCommand( RADIO_SET_TXCONTINUOUSWAVE, 0, 0 );
221 }
222
SX1280SetTxContinuousPreamble(void)223 void SX1280SetTxContinuousPreamble( void )
224 {
225 SX1280HalWriteCommand( RADIO_SET_TXCONTINUOUSPREAMBLE, 0, 0 );
226 }
227
SX1280SetPacketType(RadioPacketTypes_t packetType)228 void SX1280SetPacketType( RadioPacketTypes_t packetType )
229 {
230 // Save packet type internally to avoid questioning the radio
231 PacketType = packetType;
232
233 SX1280HalWriteCommand( RADIO_SET_PACKETTYPE, ( uint8_t* )&packetType, 1 );
234 }
235
SX1280GetPacketType(void)236 RadioPacketTypes_t SX1280GetPacketType( void )
237 {
238 return PacketType;
239 }
240
SX1280SetRfFrequency(uint32_t frequency)241 void SX1280SetRfFrequency( uint32_t frequency )
242 {
243 uint8_t buf[3];
244 uint32_t freq = 0;
245
246 freq = ( uint32_t )( ( double )frequency / ( double )FREQ_STEP );
247 buf[0] = ( uint8_t )( ( freq >> 16 ) & 0xFF );
248 buf[1] = ( uint8_t )( ( freq >> 8 ) & 0xFF );
249 buf[2] = ( uint8_t )( freq & 0xFF );
250 SX1280HalWriteCommand( RADIO_SET_RFFREQUENCY, buf, 3 );
251 }
252
SX1280SetTxParams(int8_t power,RadioRampTimes_t rampTime)253 void SX1280SetTxParams( int8_t power, RadioRampTimes_t rampTime )
254 {
255 uint8_t buf[2];
256
257 // The power value to send on SPI/UART is in the range [0..31] and the
258 // physical output power is in the range [-18..13]dBm
259 buf[0] = power + 18;
260 buf[1] = ( uint8_t )rampTime;
261 SX1280HalWriteCommand( RADIO_SET_TXPARAMS, buf, 2 );
262 }
263
SX1280SetCadParams(RadioLoRaCadSymbols_t cadSymbolNum)264 void SX1280SetCadParams( RadioLoRaCadSymbols_t cadSymbolNum )
265 {
266 SX1280HalWriteCommand( RADIO_SET_CADPARAMS, ( uint8_t* )&cadSymbolNum, 1 );
267 OperatingMode = MODE_CAD;
268 }
269
SX1280SetBufferBaseAddresses(uint8_t txBaseAddress,uint8_t rxBaseAddress)270 void SX1280SetBufferBaseAddresses( uint8_t txBaseAddress, uint8_t rxBaseAddress )
271 {
272 uint8_t buf[2];
273
274 buf[0] = txBaseAddress;
275 buf[1] = rxBaseAddress;
276 SX1280HalWriteCommand( RADIO_SET_BUFFERBASEADDRESS, buf, 2 );
277 }
278
SX1280SetModulationParams(ModulationParams_t * modulationParams)279 void SX1280SetModulationParams( ModulationParams_t *modulationParams )
280 {
281 uint8_t buf[3];
282
283 // Check if required configuration corresponds to the stored packet type
284 // If not, silently update radio packet type
285 if( PacketType != modulationParams->PacketType )
286 {
287 SX1280SetPacketType( modulationParams->PacketType );
288 }
289
290 switch( modulationParams->PacketType )
291 {
292 case PACKET_TYPE_GFSK:
293 buf[0] = modulationParams->Params.Gfsk.BitrateBandwidth;
294 buf[1] = modulationParams->Params.Gfsk.ModulationIndex;
295 buf[2] = modulationParams->Params.Gfsk.ModulationShaping;
296 break;
297
298 case PACKET_TYPE_LORA:
299 case PACKET_TYPE_RANGING:
300 buf[0] = modulationParams->Params.LoRa.SpreadingFactor;
301 buf[1] = modulationParams->Params.LoRa.Bandwidth;
302 buf[2] = modulationParams->Params.LoRa.CodingRate;
303 LoRaBandwidth = modulationParams->Params.LoRa.Bandwidth;
304 break;
305
306 case PACKET_TYPE_FLRC:
307 buf[0] = modulationParams->Params.Flrc.BitrateBandwidth;
308 buf[1] = modulationParams->Params.Flrc.CodingRate;
309 buf[2] = modulationParams->Params.Flrc.ModulationShaping;
310 break;
311
312 case PACKET_TYPE_BLE:
313 buf[0] = modulationParams->Params.Ble.BitrateBandwidth;
314 buf[1] = modulationParams->Params.Ble.ModulationIndex;
315 buf[2] = modulationParams->Params.Ble.ModulationShaping;
316 break;
317
318 case PACKET_TYPE_NONE:
319 buf[0] = 0;
320 buf[1] = 0;
321 buf[2] = 0;
322 break;
323 }
324 SX1280HalWriteCommand( RADIO_SET_MODULATIONPARAMS, buf, 3 );
325 }
326
SX1280SetPacketParams(PacketParams_t * packetParams)327 void SX1280SetPacketParams( PacketParams_t *packetParams )
328 {
329 uint8_t buf[7];
330
331 // Check if required configuration corresponds to the stored packet type
332 // If not, silently update radio packet type
333 if( PacketType != packetParams->PacketType )
334 {
335 SX1280SetPacketType( packetParams->PacketType );
336 }
337
338 switch( packetParams->PacketType )
339 {
340 case PACKET_TYPE_GFSK:
341 buf[0] = packetParams->Params.Gfsk.PreambleLength;
342 buf[1] = packetParams->Params.Gfsk.SyncWordLength;
343 buf[2] = packetParams->Params.Gfsk.SyncWordMatch;
344 buf[3] = packetParams->Params.Gfsk.HeaderType;
345 buf[4] = packetParams->Params.Gfsk.PayloadLength;
346 buf[5] = packetParams->Params.Gfsk.CrcLength;
347 buf[6] = packetParams->Params.Gfsk.Whitening;
348 break;
349
350 case PACKET_TYPE_LORA:
351 case PACKET_TYPE_RANGING:
352 buf[0] = packetParams->Params.LoRa.PreambleLength;
353 buf[1] = packetParams->Params.LoRa.HeaderType;
354 buf[2] = packetParams->Params.LoRa.PayloadLength;
355 buf[3] = packetParams->Params.LoRa.CrcMode;
356 buf[4] = packetParams->Params.LoRa.InvertIQ;
357 buf[5] = 0;
358 buf[6] = 0;
359 break;
360
361 case PACKET_TYPE_FLRC:
362 buf[0] = packetParams->Params.Flrc.PreambleLength;
363 buf[1] = packetParams->Params.Flrc.SyncWordLength;
364 buf[2] = packetParams->Params.Flrc.SyncWordMatch;
365 buf[3] = packetParams->Params.Flrc.HeaderType;
366 buf[4] = packetParams->Params.Flrc.PayloadLength;
367 buf[5] = packetParams->Params.Flrc.CrcLength;
368 buf[6] = packetParams->Params.Flrc.Whitening;
369 break;
370
371 case PACKET_TYPE_BLE:
372 buf[0] = packetParams->Params.Ble.ConnectionState;
373 buf[1] = packetParams->Params.Ble.CrcField;
374 buf[2] = packetParams->Params.Ble.BlePacketType;
375 buf[3] = packetParams->Params.Ble.Whitening;
376 buf[4] = 0;
377 buf[5] = 0;
378 buf[6] = 0;
379 break;
380
381 case PACKET_TYPE_NONE:
382 buf[0] = 0;
383 buf[1] = 0;
384 buf[2] = 0;
385 buf[3] = 0;
386 buf[4] = 0;
387 buf[5] = 0;
388 buf[6] = 0;
389 break;
390 }
391 SX1280HalWriteCommand( RADIO_SET_PACKETPARAMS, buf, 7 );
392 }
393
SX1280GetRxBufferStatus(uint8_t * payloadLength,uint8_t * rxStartBufferPointer)394 void SX1280GetRxBufferStatus( uint8_t *payloadLength, uint8_t *rxStartBufferPointer )
395 {
396 uint8_t status[2];
397
398 SX1280HalReadCommand( RADIO_GET_RXBUFFERSTATUS, status, 2 );
399
400 // In case of LORA fixed header, the payloadLength is obtained by reading
401 // the register REG_LR_PAYLOADLENGTH
402 if( ( SX1280GetPacketType( ) == PACKET_TYPE_LORA ) && ( SX1280HalReadRegister( REG_LR_PACKETPARAMS ) >> 7 == 1 ) )
403 {
404 *payloadLength = SX1280HalReadRegister( REG_LR_PAYLOADLENGTH );
405 }
406 else if( SX1280GetPacketType( ) == PACKET_TYPE_BLE )
407 {
408 // In the case of BLE, the size returned in status[0] do not include the 2-byte length PDU header
409 // so it is added there
410 *payloadLength = status[0] + 2;
411 }
412 else
413 {
414 *payloadLength = status[0];
415 }
416
417 *rxStartBufferPointer = status[1];
418 }
419
SX1280GetPacketStatus(PacketStatus_t * pktStatus)420 void SX1280GetPacketStatus( PacketStatus_t *pktStatus )
421 {
422 uint8_t status[5];
423
424 SX1280HalReadCommand( RADIO_GET_PACKETSTATUS, status, 5 );
425
426 pktStatus->packetType = SX1280GetPacketType( );
427 switch( pktStatus->packetType )
428 {
429 case PACKET_TYPE_GFSK:
430 pktStatus->Params.Gfsk.RssiAvg = -status[0] / 2;
431 pktStatus->Params.Gfsk.RssiSync = -status[1] / 2;
432
433 pktStatus->Params.Gfsk.ErrorStatus.SyncError = ( status[2] >> 6 ) & 0x01;
434 pktStatus->Params.Gfsk.ErrorStatus.LengthError = ( status[2] >> 5 ) & 0x01;
435 pktStatus->Params.Gfsk.ErrorStatus.CrcError = ( status[2] >> 4 ) & 0x01;
436 pktStatus->Params.Gfsk.ErrorStatus.AbortError = ( status[2] >> 3 ) & 0x01;
437 pktStatus->Params.Gfsk.ErrorStatus.HeaderReceived = ( status[2] >> 2 ) & 0x01;
438 pktStatus->Params.Gfsk.ErrorStatus.PacketReceived = ( status[2] >> 1 ) & 0x01;
439 pktStatus->Params.Gfsk.ErrorStatus.PacketControlerBusy = status[2] & 0x01;
440
441 pktStatus->Params.Gfsk.TxRxStatus.RxNoAck = ( status[3] >> 5 ) & 0x01;
442 pktStatus->Params.Gfsk.TxRxStatus.PacketSent = status[3] & 0x01;
443
444 pktStatus->Params.Gfsk.SyncAddrStatus = status[4] & 0x07;
445 break;
446
447 case PACKET_TYPE_LORA:
448 case PACKET_TYPE_RANGING:
449 pktStatus->Params.LoRa.RssiPkt = -status[0] / 2;
450 ( status[1] < 128 ) ? ( pktStatus->Params.LoRa.SnrPkt = status[1] / 4 ) : ( pktStatus->Params.LoRa.SnrPkt = ( ( status[1] - 256 ) /4 ) );
451
452 pktStatus->Params.LoRa.ErrorStatus.SyncError = ( status[2] >> 6 ) & 0x01;
453 pktStatus->Params.LoRa.ErrorStatus.LengthError = ( status[2] >> 5 ) & 0x01;
454 pktStatus->Params.LoRa.ErrorStatus.CrcError = ( status[2] >> 4 ) & 0x01;
455 pktStatus->Params.LoRa.ErrorStatus.AbortError = ( status[2] >> 3 ) & 0x01;
456 pktStatus->Params.LoRa.ErrorStatus.HeaderReceived = ( status[2] >> 2 ) & 0x01;
457 pktStatus->Params.LoRa.ErrorStatus.PacketReceived = ( status[2] >> 1 ) & 0x01;
458 pktStatus->Params.LoRa.ErrorStatus.PacketControlerBusy = status[2] & 0x01;
459
460 pktStatus->Params.LoRa.TxRxStatus.RxNoAck = ( status[3] >> 5 ) & 0x01;
461 pktStatus->Params.LoRa.TxRxStatus.PacketSent = status[3] & 0x01;
462
463 pktStatus->Params.LoRa.SyncAddrStatus = status[4] & 0x07;
464 break;
465
466 case PACKET_TYPE_FLRC:
467 pktStatus->Params.Flrc.RssiAvg = -status[0] / 2;
468 pktStatus->Params.Flrc.RssiSync = -status[1] / 2;
469
470 pktStatus->Params.Flrc.ErrorStatus.SyncError = ( status[2] >> 6 ) & 0x01;
471 pktStatus->Params.Flrc.ErrorStatus.LengthError = ( status[2] >> 5 ) & 0x01;
472 pktStatus->Params.Flrc.ErrorStatus.CrcError = ( status[2] >> 4 ) & 0x01;
473 pktStatus->Params.Flrc.ErrorStatus.AbortError = ( status[2] >> 3 ) & 0x01;
474 pktStatus->Params.Flrc.ErrorStatus.HeaderReceived = ( status[2] >> 2 ) & 0x01;
475 pktStatus->Params.Flrc.ErrorStatus.PacketReceived = ( status[2] >> 1 ) & 0x01;
476 pktStatus->Params.Flrc.ErrorStatus.PacketControlerBusy = status[2] & 0x01;
477
478 pktStatus->Params.Flrc.TxRxStatus.RxPid = ( status[3] >> 6 ) & 0x03;
479 pktStatus->Params.Flrc.TxRxStatus.RxNoAck = ( status[3] >> 5 ) & 0x01;
480 pktStatus->Params.Flrc.TxRxStatus.RxPidErr = ( status[3] >> 4 ) & 0x01;
481 pktStatus->Params.Flrc.TxRxStatus.PacketSent = status[3] & 0x01;
482
483 pktStatus->Params.Flrc.SyncAddrStatus = status[4] & 0x07;
484 break;
485
486 case PACKET_TYPE_BLE:
487 pktStatus->Params.Ble.RssiAvg = -status[0] / 2;
488 pktStatus->Params.Ble.RssiSync = -status[1] / 2;
489
490 pktStatus->Params.Ble.ErrorStatus.SyncError = ( status[2] >> 6 ) & 0x01;
491 pktStatus->Params.Ble.ErrorStatus.LengthError = ( status[2] >> 5 ) & 0x01;
492 pktStatus->Params.Ble.ErrorStatus.CrcError = ( status[2] >> 4 ) & 0x01;
493 pktStatus->Params.Ble.ErrorStatus.AbortError = ( status[2] >> 3 ) & 0x01;
494 pktStatus->Params.Ble.ErrorStatus.HeaderReceived = ( status[2] >> 2 ) & 0x01;
495 pktStatus->Params.Ble.ErrorStatus.PacketReceived = ( status[2] >> 1 ) & 0x01;
496 pktStatus->Params.Ble.ErrorStatus.PacketControlerBusy = status[2] & 0x01;
497
498 pktStatus->Params.Ble.TxRxStatus.PacketSent = status[3] & 0x01;
499
500 pktStatus->Params.Ble.SyncAddrStatus = status[4] & 0x07;
501 break;
502
503 case PACKET_TYPE_NONE:
504 // In that specific case, we set everything in the pktStatus to zeros
505 // and reset the packet type accordingly
506 memset( pktStatus, 0, sizeof( PacketStatus_t ) );
507 pktStatus->packetType = PACKET_TYPE_NONE;
508 break;
509 }
510 }
511
SX1280GetRssiInst(void)512 int8_t SX1280GetRssiInst( void )
513 {
514 uint8_t raw = 0;
515
516 SX1280HalReadCommand( RADIO_GET_RSSIINST, &raw, 1 );
517
518 return ( int8_t )( -raw / 2 );
519 }
520
SX1280SetDioIrqParams(uint16_t irqMask,uint16_t dio1Mask,uint16_t dio2Mask,uint16_t dio3Mask)521 void SX1280SetDioIrqParams( uint16_t irqMask, uint16_t dio1Mask, uint16_t dio2Mask, uint16_t dio3Mask )
522 {
523 uint8_t buf[8];
524
525 buf[0] = ( uint8_t )( ( irqMask >> 8 ) & 0x00FF );
526 buf[1] = ( uint8_t )( irqMask & 0x00FF );
527 buf[2] = ( uint8_t )( ( dio1Mask >> 8 ) & 0x00FF );
528 buf[3] = ( uint8_t )( dio1Mask & 0x00FF );
529 buf[4] = ( uint8_t )( ( dio2Mask >> 8 ) & 0x00FF );
530 buf[5] = ( uint8_t )( dio2Mask & 0x00FF );
531 buf[6] = ( uint8_t )( ( dio3Mask >> 8 ) & 0x00FF );
532 buf[7] = ( uint8_t )( dio3Mask & 0x00FF );
533 SX1280HalWriteCommand( RADIO_SET_DIOIRQPARAMS, buf, 8 );
534 }
535
SX1280GetIrqStatus(void)536 uint16_t SX1280GetIrqStatus( void )
537 {
538 uint8_t irqStatus[2];
539
540 SX1280HalReadCommand( RADIO_GET_IRQSTATUS, irqStatus, 2 );
541
542 return ( irqStatus[0] << 8 ) | irqStatus[1];
543 }
544
SX1280ClearIrqStatus(uint16_t irq)545 void SX1280ClearIrqStatus( uint16_t irq )
546 {
547 uint8_t buf[2];
548
549 buf[0] = ( uint8_t )( ( ( uint16_t )irq >> 8 ) & 0x00FF );
550 buf[1] = ( uint8_t )( ( uint16_t )irq & 0x00FF );
551 SX1280HalWriteCommand( RADIO_CLR_IRQSTATUS, buf, 2 );
552 }
553
SX1280Calibrate(CalibrationParams_t calibParam)554 void SX1280Calibrate( CalibrationParams_t calibParam )
555 {
556 uint8_t cal = ( calibParam.ADCBulkPEnable << 5 ) |
557 ( calibParam.ADCBulkNEnable << 4 ) |
558 ( calibParam.ADCPulseEnable << 3 ) |
559 ( calibParam.PLLEnable << 2 ) |
560 ( calibParam.RC13MEnable << 1 ) |
561 ( calibParam.RC64KEnable );
562
563 SX1280HalWriteCommand( RADIO_CALIBRATE, &cal, 1 );
564 }
565
SX1280SetRegulatorMode(RadioRegulatorModes_t mode)566 void SX1280SetRegulatorMode( RadioRegulatorModes_t mode )
567 {
568 SX1280HalWriteCommand( RADIO_SET_REGULATORMODE, ( uint8_t* )&mode, 1 );
569 }
570
SX1280SetSaveContext(void)571 void SX1280SetSaveContext( void )
572 {
573 SX1280HalWriteCommand( RADIO_SET_SAVECONTEXT, 0, 0 );
574 }
575
SX1280SetAutoTx(uint16_t time)576 void SX1280SetAutoTx( uint16_t time )
577 {
578 uint16_t compensatedTime = time - ( uint16_t )AUTO_RX_TX_OFFSET;
579 uint8_t buf[2];
580
581 buf[0] = ( uint8_t )( ( compensatedTime >> 8 ) & 0x00FF );
582 buf[1] = ( uint8_t )( compensatedTime & 0x00FF );
583 SX1280HalWriteCommand( RADIO_SET_AUTOTX, buf, 2 );
584 }
585
SX1280StopAutoTx(void)586 void SX1280StopAutoTx( void )
587 {
588 uint8_t buf[2] = {0x00, 0x00};
589 SX1280HalWriteCommand( RADIO_SET_AUTOTX, buf, 2 );
590 }
591
SX1280SetAutoFS(uint8_t enable)592 void SX1280SetAutoFS( uint8_t enable )
593 {
594 SX1280HalWriteCommand( RADIO_SET_AUTOFS, &enable, 1 );
595 }
596
SX1280SetLongPreamble(uint8_t enable)597 void SX1280SetLongPreamble( uint8_t enable )
598 {
599 SX1280HalWriteCommand( RADIO_SET_LONGPREAMBLE, &enable, 1 );
600 }
601
SX1280SetPayload(uint8_t * buffer,uint8_t size)602 void SX1280SetPayload( uint8_t *buffer, uint8_t size )
603 {
604 SX1280HalWriteBuffer( 0x00, buffer, size );
605 }
606
SX1280GetPayload(uint8_t * buffer,uint8_t * size,uint8_t maxSize)607 uint8_t SX1280GetPayload( uint8_t *buffer, uint8_t *size , uint8_t maxSize )
608 {
609 uint8_t offset;
610
611 SX1280GetRxBufferStatus( size, &offset );
612 if( *size > maxSize )
613 {
614 return 1;
615 }
616 SX1280HalReadBuffer( offset, buffer, *size );
617 return 0;
618 }
619
SX1280SendPayload(uint8_t * payload,uint8_t size,TickTime_t timeout)620 void SX1280SendPayload( uint8_t *payload, uint8_t size, TickTime_t timeout )
621 {
622 SX1280SetPayload( payload, size );
623 SX1280SetTx( timeout );
624 }
625
SX1280SetSyncWord(uint8_t syncWordIdx,uint8_t * syncWord)626 uint8_t SX1280SetSyncWord( uint8_t syncWordIdx, uint8_t *syncWord )
627 {
628 uint16_t addr;
629 uint8_t syncwordSize = 0;
630
631 switch( SX1280GetPacketType( ) )
632 {
633 case PACKET_TYPE_GFSK:
634 syncwordSize = 5;
635 switch( syncWordIdx )
636 {
637 case 1:
638 addr = REG_LR_SYNCWORDBASEADDRESS1;
639 break;
640
641 case 2:
642 addr = REG_LR_SYNCWORDBASEADDRESS2;
643 break;
644
645 case 3:
646 addr = REG_LR_SYNCWORDBASEADDRESS3;
647 break;
648
649 default:
650 return 1;
651 }
652 break;
653
654 case PACKET_TYPE_FLRC:
655 // For FLRC packet type, the SyncWord is one byte shorter and
656 // the base address is shifted by one byte
657 syncwordSize = 4;
658 switch( syncWordIdx )
659 {
660 case 1:
661 addr = REG_LR_SYNCWORDBASEADDRESS1 + 1;
662 break;
663
664 case 2:
665 addr = REG_LR_SYNCWORDBASEADDRESS2 + 1;
666 break;
667
668 case 3:
669 addr = REG_LR_SYNCWORDBASEADDRESS3 + 1;
670 break;
671
672 default:
673 return 1;
674 }
675 break;
676
677 case PACKET_TYPE_BLE:
678 // For Ble packet type, only the first SyncWord is used and its
679 // address is shifted by one byte
680 syncwordSize = 4;
681 switch( syncWordIdx )
682 {
683 case 1:
684 addr = REG_LR_SYNCWORDBASEADDRESS1 + 1;
685 break;
686
687 default:
688 return 1;
689 }
690 break;
691
692 default:
693 return 1;
694 }
695 SX1280HalWriteRegisters( addr, syncWord, syncwordSize );
696 return 0;
697 }
698
SX1280SetSyncWordErrorTolerance(uint8_t ErrorBits)699 void SX1280SetSyncWordErrorTolerance( uint8_t ErrorBits )
700 {
701 ErrorBits = ( SX1280HalReadRegister( REG_LR_SYNCWORDTOLERANCE ) & 0xF0 ) | ( ErrorBits & 0x0F );
702 SX1280HalWriteRegister( REG_LR_SYNCWORDTOLERANCE, ErrorBits );
703 }
704
SX1280SetCrcSeed(uint16_t seed)705 void SX1280SetCrcSeed( uint16_t seed )
706 {
707 uint8_t val[2];
708
709 val[0] = ( uint8_t )( seed >> 8 ) & 0xFF;
710 val[1] = ( uint8_t )( seed & 0xFF );
711
712 switch( SX1280GetPacketType( ) )
713 {
714 case PACKET_TYPE_GFSK:
715 case PACKET_TYPE_FLRC:
716 SX1280HalWriteRegisters( REG_LR_CRCSEEDBASEADDR, val, 2 );
717 break;
718
719 default:
720 break;
721 }
722 }
723
SX1280SetBleAccessAddress(uint32_t accessAddress)724 void SX1280SetBleAccessAddress( uint32_t accessAddress )
725 {
726 SX1280HalWriteRegister( REG_LR_BLE_ACCESS_ADDRESS, ( accessAddress >> 24 ) & 0x000000FF );
727 SX1280HalWriteRegister( REG_LR_BLE_ACCESS_ADDRESS + 1, ( accessAddress >> 16 ) & 0x000000FF );
728 SX1280HalWriteRegister( REG_LR_BLE_ACCESS_ADDRESS + 2, ( accessAddress >> 8 ) & 0x000000FF );
729 SX1280HalWriteRegister( REG_LR_BLE_ACCESS_ADDRESS + 3, accessAddress & 0x000000FF );
730 }
731
SX1280SetBleAdvertizerAccessAddress(void)732 void SX1280SetBleAdvertizerAccessAddress( void )
733 {
734 SX1280SetBleAccessAddress( BLE_ADVERTIZER_ACCESS_ADDRESS );
735 }
736
SX1280SetCrcPolynomial(uint16_t polynomial)737 void SX1280SetCrcPolynomial( uint16_t polynomial )
738 {
739 uint8_t val[2];
740
741 val[0] = ( uint8_t )( polynomial >> 8 ) & 0xFF;
742 val[1] = ( uint8_t )( polynomial & 0xFF );
743
744 switch( SX1280GetPacketType( ) )
745 {
746 case PACKET_TYPE_GFSK:
747 case PACKET_TYPE_FLRC:
748 SX1280HalWriteRegisters( REG_LR_CRCPOLYBASEADDR, val, 2 );
749 break;
750
751 default:
752 break;
753 }
754 }
755
SX1280SetWhiteningSeed(uint8_t seed)756 void SX1280SetWhiteningSeed( uint8_t seed )
757 {
758 switch( SX1280GetPacketType( ) )
759 {
760 case PACKET_TYPE_GFSK:
761 case PACKET_TYPE_FLRC:
762 case PACKET_TYPE_BLE:
763 SX1280HalWriteRegister( REG_LR_WHITSEEDBASEADDR, seed );
764 break;
765
766 default:
767 break;
768 }
769 }
770
SX1280EnableManualGain(void)771 void SX1280EnableManualGain( void )
772 {
773 SX1280HalWriteRegister( REG_ENABLE_MANUAL_GAIN_CONTROL, SX1280HalReadRegister( REG_ENABLE_MANUAL_GAIN_CONTROL ) | MASK_MANUAL_GAIN_CONTROL );
774 SX1280HalWriteRegister( REG_DEMOD_DETECTION, SX1280HalReadRegister( REG_DEMOD_DETECTION ) & MASK_DEMOD_DETECTION );
775 }
776
SX1280DisableManualGain(void)777 void SX1280DisableManualGain( void )
778 {
779 SX1280HalWriteRegister( REG_ENABLE_MANUAL_GAIN_CONTROL, SX1280HalReadRegister( REG_ENABLE_MANUAL_GAIN_CONTROL ) & ~MASK_MANUAL_GAIN_CONTROL );
780 SX1280HalWriteRegister( REG_DEMOD_DETECTION, SX1280HalReadRegister( REG_DEMOD_DETECTION ) | ~MASK_DEMOD_DETECTION );
781 }
782
SX1280SetManualGainValue(uint8_t gain)783 void SX1280SetManualGainValue( uint8_t gain )
784 {
785 SX1280HalWriteRegister( REG_MANUAL_GAIN_VALUE, ( SX1280HalReadRegister( REG_MANUAL_GAIN_VALUE ) & MASK_MANUAL_GAIN_VALUE ) | gain );
786 }
787
SX1280SetLNAGainSetting(const RadioLnaSettings_t lnaSetting)788 void SX1280SetLNAGainSetting( const RadioLnaSettings_t lnaSetting )
789 {
790 switch( lnaSetting )
791 {
792 case LNA_HIGH_SENSITIVITY_MODE:
793 {
794 SX1280HalWriteRegister( REG_LNA_REGIME, SX1280HalReadRegister( REG_LNA_REGIME ) | MASK_LNA_REGIME );
795 break;
796 }
797 case LNA_LOW_POWER_MODE:
798 {
799 SX1280HalWriteRegister( REG_LNA_REGIME, SX1280HalReadRegister( REG_LNA_REGIME ) & ~MASK_LNA_REGIME );
800 break;
801 }
802 }
803 }
804
SX1280SetRangingIdLength(RadioRangingIdCheckLengths_t length)805 void SX1280SetRangingIdLength( RadioRangingIdCheckLengths_t length )
806 {
807 switch( SX1280GetPacketType( ) )
808 {
809 case PACKET_TYPE_RANGING:
810 SX1280HalWriteRegister( REG_LR_RANGINGIDCHECKLENGTH, ( ( ( ( uint8_t )length ) & 0x03 ) << 6 ) | ( SX1280HalReadRegister( REG_LR_RANGINGIDCHECKLENGTH ) & 0x3F ) );
811 break;
812
813 default:
814 break;
815 }
816 }
817
SX1280SetDeviceRangingAddress(uint32_t address)818 void SX1280SetDeviceRangingAddress( uint32_t address )
819 {
820 uint8_t addrArray[] = { address >> 24, address >> 16, address >> 8, address };
821
822 switch( SX1280GetPacketType( ) )
823 {
824 case PACKET_TYPE_RANGING:
825 SX1280HalWriteRegisters( REG_LR_DEVICERANGINGADDR, addrArray, 4 );
826 break;
827
828 default:
829 break;
830 }
831 }
832
SX1280SetRangingRequestAddress(uint32_t address)833 void SX1280SetRangingRequestAddress( uint32_t address )
834 {
835 uint8_t addrArray[] = { address >> 24, address >> 16, address >> 8, address };
836
837 switch( SX1280GetPacketType( ) )
838 {
839 case PACKET_TYPE_RANGING:
840 SX1280HalWriteRegisters( REG_LR_REQUESTRANGINGADDR, addrArray, 4 );
841 break;
842
843 default:
844 break;
845 }
846 }
847
SX1280GetRangingResult(RadioRangingResultTypes_t resultType)848 double SX1280GetRangingResult( RadioRangingResultTypes_t resultType )
849 {
850 uint32_t valLsb = 0;
851 double val = 0.0;
852
853 switch( SX1280GetPacketType( ) )
854 {
855 case PACKET_TYPE_RANGING:
856 SX1280SetStandby( STDBY_XOSC );
857 SX1280HalWriteRegister( 0x97F, SX1280HalReadRegister( 0x97F ) | ( 1 << 1 ) ); // enable LORA modem clock
858 SX1280HalWriteRegister( REG_LR_RANGINGRESULTCONFIG, ( SX1280HalReadRegister( REG_LR_RANGINGRESULTCONFIG ) & MASK_RANGINGMUXSEL ) | ( ( ( ( uint8_t )resultType ) & 0x03 ) << 4 ) );
859 valLsb = ( ( SX1280HalReadRegister( REG_LR_RANGINGRESULTBASEADDR ) << 16 ) | ( SX1280HalReadRegister( REG_LR_RANGINGRESULTBASEADDR + 1 ) << 8 ) | ( SX1280HalReadRegister( REG_LR_RANGINGRESULTBASEADDR + 2 ) ) );
860 SX1280SetStandby( STDBY_RC );
861
862 // Convertion from LSB to distance. For explanation on the formula, refer to Datasheet of SX1280
863 switch( resultType )
864 {
865 case RANGING_RESULT_RAW:
866 // Convert the ranging LSB to distance in meter
867 val = ( double )SX1280complement2( valLsb, 24 ) / ( double )SX1280GetLoRaBandwidth( ) * 36621.09375;
868 break;
869
870 case RANGING_RESULT_AVERAGED:
871 case RANGING_RESULT_DEBIASED:
872 case RANGING_RESULT_FILTERED:
873 val = ( double )valLsb * 20.0 / 100.0;
874 break;
875
876 default:
877 val = 0.0;
878 }
879 break;
880
881 default:
882 break;
883 }
884 return val;
885 }
886
SX1280GetRangingPowerDeltaThresholdIndicator(void)887 uint8_t SX1280GetRangingPowerDeltaThresholdIndicator( void )
888 {
889 SX1280SetStandby( STDBY_XOSC );
890 SX1280HalWriteRegister( 0x97F, SX1280HalReadRegister( 0x97F ) | ( 1 << 1 ) ); // enable LoRa modem clock
891 SX1280HalWriteRegister( REG_LR_RANGINGRESULTCONFIG, ( SX1280HalReadRegister( REG_LR_RANGINGRESULTCONFIG ) & MASK_RANGINGMUXSEL ) | ( ( ( ( uint8_t )RANGING_RESULT_RAW ) & 0x03 ) << 4 ) ); // Select raw results
892 return SX1280HalReadRegister( REG_RANGING_RSSI );
893 }
894
SX1280SetRangingCalibration(uint16_t cal)895 void SX1280SetRangingCalibration( uint16_t cal )
896 {
897 switch( SX1280GetPacketType( ) )
898 {
899 case PACKET_TYPE_RANGING:
900 SX1280HalWriteRegister( REG_LR_RANGINGRERXTXDELAYCAL, ( uint8_t )( ( cal >> 8 ) & 0xFF ) );
901 SX1280HalWriteRegister( REG_LR_RANGINGRERXTXDELAYCAL + 1, ( uint8_t )( ( cal ) & 0xFF ) );
902 break;
903
904 default:
905 break;
906 }
907 }
908
SX1280RangingClearFilterResult(void)909 void SX1280RangingClearFilterResult( void )
910 {
911 uint8_t regVal = SX1280HalReadRegister( REG_LR_RANGINGRESULTCLEARREG );
912
913 // To clear result, set bit 5 to 1 then to 0
914 SX1280HalWriteRegister( REG_LR_RANGINGRESULTCLEARREG, regVal | ( 1 << 5 ) );
915 SX1280HalWriteRegister( REG_LR_RANGINGRESULTCLEARREG, regVal & ( ~( 1 << 5 ) ) );
916 }
917
SX1280RangingSetFilterNumSamples(uint8_t num)918 void SX1280RangingSetFilterNumSamples( uint8_t num )
919 {
920 // Silently set 8 as minimum value
921 SX1280HalWriteRegister( REG_LR_RANGINGFILTERWINDOWSIZE, ( num < DEFAULT_RANGING_FILTER_SIZE ) ? DEFAULT_RANGING_FILTER_SIZE : num );
922 }
923
SX1280ParseHexFileLine(char * line)924 int8_t SX1280ParseHexFileLine( char* line )
925 {
926 uint16_t addr;
927 uint16_t n;
928 uint8_t code;
929 uint8_t bytes[256];
930
931 if( SX1280GetHexFileLineFields( line, bytes, &addr, &n, &code ) != 0 )
932 {
933 if( code == 0 )
934 {
935 SX1280HalWriteRegisters( addr, bytes, n );
936 }
937 if( code == 1 )
938 { // end of file
939 //return 2;
940 }
941 if( code == 2 )
942 { // begin of file
943 //return 3;
944 }
945 }
946 else
947 {
948 return 0;
949 }
950 return 1;
951 }
952
SX1280SetRangingRole(RadioRangingRoles_t role)953 void SX1280SetRangingRole( RadioRangingRoles_t role )
954 {
955 uint8_t buf[1];
956
957 buf[0] = role;
958 SX1280HalWriteCommand( RADIO_SET_RANGING_ROLE, &buf[0], 1 );
959 }
960
SX1280GetHexFileLineFields(char * line,uint8_t * bytes,uint16_t * addr,uint16_t * num,uint8_t * code)961 int8_t SX1280GetHexFileLineFields( char* line, uint8_t *bytes, uint16_t *addr, uint16_t *num, uint8_t *code )
962 {
963 uint16_t sum, len, cksum;
964 char *ptr;
965
966 *num = 0;
967 if( line[0] != ':' )
968 {
969 return 0;
970 }
971 if( strlen( line ) < 11 )
972 {
973 return 0;
974 }
975 ptr = line + 1;
976 if( !sscanf( ptr, "%02hx", &len ) )
977 {
978 return 0;
979 }
980 ptr += 2;
981 if( strlen( line ) < ( 11 + ( len * 2 ) ) )
982 {
983 return 0;
984 }
985 if( !sscanf( ptr, "%04hx", addr ) )
986 {
987 return 0;
988 }
989 ptr += 4;
990 if( !sscanf( ptr, "%02hhx", code ) )
991 {
992 return 0;
993 }
994 ptr += 2;
995 sum = ( len & 255 ) + ( ( *addr >> 8 ) & 255 ) + ( *addr & 255 ) + ( ( *code >> 8 ) & 255 ) + ( *code & 255 );
996 while( *num != len )
997 {
998 if( !sscanf( ptr, "%02hhx", &bytes[*num] ) )
999 {
1000 return 0;
1001 }
1002 ptr += 2;
1003 sum += bytes[*num] & 255;
1004 ( *num )++;
1005 if( *num >= 256 )
1006 {
1007 return 0;
1008 }
1009 }
1010 if( !sscanf( ptr, "%02hx", &cksum ) )
1011 {
1012 return 0;
1013 }
1014 if( ( ( sum & 255 ) + ( cksum & 255 ) ) & 255 )
1015 {
1016 return 0; // checksum error
1017 }
1018
1019 return 1;
1020 }
1021
SX1280GetFrequencyError()1022 double SX1280GetFrequencyError( )
1023 {
1024 uint8_t efeRaw[3] = {0};
1025 uint32_t efe = 0;
1026 double efeHz = 0.0;
1027
1028 switch( SX1280GetPacketType( ) )
1029 {
1030 case PACKET_TYPE_LORA:
1031 case PACKET_TYPE_RANGING:
1032 efeRaw[0] = SX1280HalReadRegister( REG_LR_ESTIMATED_FREQUENCY_ERROR_MSB );
1033 efeRaw[1] = SX1280HalReadRegister( REG_LR_ESTIMATED_FREQUENCY_ERROR_MSB + 1 );
1034 efeRaw[2] = SX1280HalReadRegister( REG_LR_ESTIMATED_FREQUENCY_ERROR_MSB + 2 );
1035 efe = ( efeRaw[0]<<16 ) | ( efeRaw[1]<<8 ) | efeRaw[2];
1036 efe &= REG_LR_ESTIMATED_FREQUENCY_ERROR_MASK;
1037
1038 efeHz = 1.55 * ( double )SX1280complement2( efe, 20 ) / ( 1600.0 / ( double )SX1280GetLoRaBandwidth( ) * 1000.0 );
1039 break;
1040
1041 case PACKET_TYPE_NONE:
1042 case PACKET_TYPE_BLE:
1043 case PACKET_TYPE_FLRC:
1044 case PACKET_TYPE_GFSK:
1045 break;
1046 }
1047
1048 return efeHz;
1049 }
1050
SX1280SetPollingMode(void)1051 void SX1280SetPollingMode( void )
1052 {
1053 PollingMode = true;
1054 }
1055
SX1280GetLoRaBandwidth()1056 int32_t SX1280GetLoRaBandwidth( )
1057 {
1058 int32_t bwValue = 0;
1059
1060 switch( LoRaBandwidth )
1061 {
1062 case LORA_BW_0200:
1063 bwValue = 203125;
1064 break;
1065
1066 case LORA_BW_0400:
1067 bwValue = 406250;
1068 break;
1069
1070 case LORA_BW_0800:
1071 bwValue = 812500;
1072 break;
1073
1074 case LORA_BW_1600:
1075 bwValue = 1625000;
1076 break;
1077
1078 default:
1079 bwValue = 0;
1080 }
1081 return bwValue;
1082 }
1083
SX1280GetRangingCorrectionPerSfBwGain(const RadioLoRaSpreadingFactors_t sf,const RadioLoRaBandwidths_t bw,const int8_t gain)1084 double SX1280GetRangingCorrectionPerSfBwGain( const RadioLoRaSpreadingFactors_t sf, const RadioLoRaBandwidths_t bw, const int8_t gain){
1085 uint8_t sf_index, bw_index;
1086
1087 switch(sf){
1088 case LORA_SF5:
1089 sf_index = 0;
1090 break;
1091 case LORA_SF6:
1092 sf_index = 1;
1093 break;
1094 case LORA_SF7:
1095 sf_index = 2;
1096 break;
1097 case LORA_SF8:
1098 sf_index = 3;
1099 break;
1100 case LORA_SF9:
1101 sf_index = 4;
1102 break;
1103 case LORA_SF10:
1104 sf_index = 5;
1105 break;
1106 case LORA_SF11:
1107 sf_index = 6;
1108 break;
1109 case LORA_SF12:
1110 sf_index = 7;
1111 break;
1112 }
1113 switch(bw){
1114 case LORA_BW_0400:
1115 bw_index = 0;
1116 break;
1117 case LORA_BW_0800:
1118 bw_index = 1;
1119 break;
1120 case LORA_BW_1600:
1121 bw_index = 2;
1122 break;
1123 }
1124
1125 double correction = RangingCorrectionPerSfBwGain[sf_index][bw_index][gain];
1126 return correction;
1127 }
1128
SX1280ComputeRangingCorrectionPolynome(const RadioLoRaSpreadingFactors_t sf,const RadioLoRaBandwidths_t bw,const double median)1129 double SX1280ComputeRangingCorrectionPolynome(const RadioLoRaSpreadingFactors_t sf, const RadioLoRaBandwidths_t bw, const double median){
1130 uint8_t sf_index, bw_index;
1131
1132 switch(sf){
1133 case LORA_SF5:
1134 sf_index = 0;
1135 break;
1136 case LORA_SF6:
1137 sf_index = 1;
1138 break;
1139 case LORA_SF7:
1140 sf_index = 2;
1141 break;
1142 case LORA_SF8:
1143 sf_index = 3;
1144 break;
1145 case LORA_SF9:
1146 sf_index = 4;
1147 break;
1148 case LORA_SF10:
1149 sf_index = 5;
1150 break;
1151 case LORA_SF11:
1152 sf_index = 6;
1153 break;
1154 case LORA_SF12:
1155 sf_index = 7;
1156 break;
1157 }
1158 switch(bw){
1159 case LORA_BW_0400:
1160 bw_index = 0;
1161 break;
1162 case LORA_BW_0800:
1163 bw_index = 1;
1164 break;
1165 case LORA_BW_1600:
1166 bw_index = 2;
1167 break;
1168 }
1169 const RangingCorrectionPolynomes_t *polynome = RangingCorrectionPolynomesPerSfBw[sf_index][bw_index];
1170 double correctedValue = 0.0;
1171 double correctionCoeff = 0;
1172 for(uint8_t order = 0; order < polynome->order; order++){
1173 correctionCoeff = polynome->coefficients[order] * pow(median, polynome->order - order - 1);
1174 correctedValue += correctionCoeff;
1175 }
1176 return correctedValue;
1177 }
1178
SX1280SetInterruptMode(void)1179 void SX1280SetInterruptMode( void )
1180 {
1181 PollingMode = false;
1182 }
1183
SX1280OnDioIrq(void)1184 void SX1280OnDioIrq( void )
1185 {
1186 /*
1187 * When polling mode is activated, it is up to the application to call
1188 * ProcessIrqs( ). Otherwise, the driver automatically calls ProcessIrqs( )
1189 * on radio interrupt.
1190 */
1191 if( PollingMode == true )
1192 {
1193 IrqState = true;
1194 }
1195 else
1196 {
1197 SX1280ProcessIrqs( );
1198 }
1199 }
1200
SX1280AutoTxWillStart(void)1201 void SX1280AutoTxWillStart( void ){
1202 OperatingMode = MODE_TX;
1203 }
1204
SX1280ProcessIrqs(void)1205 void SX1280ProcessIrqs( void )
1206 {
1207 RadioPacketTypes_t packetType = PACKET_TYPE_NONE;
1208
1209 if( SX1280GetOpMode( ) == MODE_SLEEP )
1210 {
1211 return; // DIO glitch on V2b :-)
1212 }
1213
1214 if( PollingMode == true )
1215 {
1216 if( IrqState == true )
1217 {
1218 __disable_irq( );
1219 IrqState = false;
1220 __enable_irq( );
1221 }
1222 else
1223 {
1224 return;
1225 }
1226 }
1227
1228 packetType = SX1280GetPacketType( );
1229 uint16_t irqRegs = SX1280GetIrqStatus( );
1230 SX1280ClearIrqStatus( IRQ_RADIO_ALL );
1231
1232 switch( packetType )
1233 {
1234 case PACKET_TYPE_GFSK:
1235 case PACKET_TYPE_FLRC:
1236 case PACKET_TYPE_BLE:
1237 switch( OperatingMode )
1238 {
1239 case MODE_RX:
1240 if( ( irqRegs & IRQ_RX_DONE ) == IRQ_RX_DONE )
1241 {
1242 if( ( irqRegs & IRQ_CRC_ERROR ) == IRQ_CRC_ERROR )
1243 {
1244 if( ( RadioCallbacks != NULL ) && ( RadioCallbacks->rxError != NULL ) )
1245 {
1246 RadioCallbacks->rxError( IRQ_CRC_ERROR_CODE );
1247 }
1248 }
1249 else if( ( irqRegs & IRQ_SYNCWORD_ERROR ) == IRQ_SYNCWORD_ERROR )
1250 {
1251 if( ( RadioCallbacks != NULL ) && ( RadioCallbacks->rxError != NULL ) )
1252 {
1253 RadioCallbacks->rxError( IRQ_SYNCWORD_ERROR_CODE );
1254 }
1255 }
1256 else
1257 {
1258 if( ( RadioCallbacks != NULL ) && ( RadioCallbacks->rxDone != NULL ) )
1259 {
1260 RadioCallbacks->rxDone( );
1261 }
1262 }
1263 }
1264 if( ( irqRegs & IRQ_SYNCWORD_VALID ) == IRQ_SYNCWORD_VALID )
1265 {
1266 if( ( RadioCallbacks != NULL ) && ( RadioCallbacks->rxSyncWordDone != NULL ) )
1267 {
1268 RadioCallbacks->rxSyncWordDone( );
1269 }
1270 }
1271 if( ( irqRegs & IRQ_SYNCWORD_ERROR ) == IRQ_SYNCWORD_ERROR )
1272 {
1273 if( ( RadioCallbacks != NULL ) && ( RadioCallbacks->rxError != NULL ) )
1274 {
1275 RadioCallbacks->rxError( IRQ_SYNCWORD_ERROR_CODE );
1276 }
1277 }
1278 if( ( irqRegs & IRQ_RX_TX_TIMEOUT ) == IRQ_RX_TX_TIMEOUT )
1279 {
1280 if( ( RadioCallbacks != NULL ) && ( RadioCallbacks->rxTimeout != NULL ) )
1281 {
1282 RadioCallbacks->rxTimeout( );
1283 }
1284 }
1285 if( ( irqRegs & IRQ_TX_DONE ) == IRQ_TX_DONE )
1286 {
1287 if( ( RadioCallbacks != NULL ) && ( RadioCallbacks->txDone != NULL ) )
1288 {
1289 RadioCallbacks->txDone( );
1290 }
1291 }
1292 break;
1293 case MODE_TX:
1294 if( ( irqRegs & IRQ_TX_DONE ) == IRQ_TX_DONE )
1295 {
1296 if( ( RadioCallbacks != NULL ) && ( RadioCallbacks->txDone != NULL ) )
1297 {
1298 RadioCallbacks->txDone( );
1299 }
1300 }
1301 if( ( irqRegs & IRQ_RX_TX_TIMEOUT ) == IRQ_RX_TX_TIMEOUT )
1302 {
1303 if( ( RadioCallbacks != NULL ) && ( RadioCallbacks->txTimeout != NULL ) )
1304 {
1305 RadioCallbacks->txTimeout( );
1306 }
1307 }
1308 break;
1309 default:
1310 // Unexpected IRQ: silently returns
1311 break;
1312 }
1313 break;
1314 case PACKET_TYPE_LORA:
1315 switch( OperatingMode )
1316 {
1317 case MODE_RX:
1318 if( ( irqRegs & IRQ_RX_DONE ) == IRQ_RX_DONE )
1319 {
1320 if( ( irqRegs & IRQ_CRC_ERROR ) == IRQ_CRC_ERROR )
1321 {
1322 if( ( RadioCallbacks != NULL ) && ( RadioCallbacks->rxError != NULL ) )
1323 {
1324 RadioCallbacks->rxError( IRQ_CRC_ERROR_CODE );
1325 }
1326 }
1327 else
1328 {
1329 if( ( RadioCallbacks != NULL ) && ( RadioCallbacks->rxDone != NULL ) )
1330 {
1331 RadioCallbacks->rxDone( );
1332 }
1333 }
1334 }
1335 if( ( irqRegs & IRQ_HEADER_VALID ) == IRQ_HEADER_VALID )
1336 {
1337 if( ( RadioCallbacks != NULL ) && ( RadioCallbacks->rxHeaderDone != NULL ) )
1338 {
1339 RadioCallbacks->rxHeaderDone( );
1340 }
1341 }
1342 if( ( irqRegs & IRQ_HEADER_ERROR ) == IRQ_HEADER_ERROR )
1343 {
1344 if( ( RadioCallbacks != NULL ) && ( RadioCallbacks->rxError != NULL ) )
1345 {
1346 RadioCallbacks->rxError( IRQ_HEADER_ERROR_CODE );
1347 }
1348 }
1349 if( ( irqRegs & IRQ_RX_TX_TIMEOUT ) == IRQ_RX_TX_TIMEOUT )
1350 {
1351 if( ( RadioCallbacks != NULL ) && ( RadioCallbacks->rxTimeout != NULL ) )
1352 {
1353 RadioCallbacks->rxTimeout( );
1354 }
1355 }
1356 if( ( irqRegs & IRQ_RANGING_SLAVE_REQUEST_DISCARDED ) == IRQ_RANGING_SLAVE_REQUEST_DISCARDED )
1357 {
1358 if( ( RadioCallbacks != NULL ) && ( RadioCallbacks->rxError != NULL ) )
1359 {
1360 RadioCallbacks->rxError( IRQ_RANGING_ON_LORA_ERROR_CODE );
1361 }
1362 }
1363 if( ( irqRegs & IRQ_TX_DONE ) == IRQ_TX_DONE )
1364 {
1365 if( ( RadioCallbacks != NULL ) && ( RadioCallbacks->txDone != NULL ) )
1366 {
1367 RadioCallbacks->txDone( );
1368 }
1369 }
1370 break;
1371 case MODE_TX:
1372 if( ( irqRegs & IRQ_TX_DONE ) == IRQ_TX_DONE )
1373 {
1374 if( ( RadioCallbacks != NULL ) && ( RadioCallbacks->txDone != NULL ) )
1375 {
1376 RadioCallbacks->txDone( );
1377 }
1378 }
1379 if( ( irqRegs & IRQ_RX_TX_TIMEOUT ) == IRQ_RX_TX_TIMEOUT )
1380 {
1381 if( ( RadioCallbacks != NULL ) && ( RadioCallbacks->txTimeout != NULL ) )
1382 {
1383 RadioCallbacks->txTimeout( );
1384 }
1385 }
1386 break;
1387 case MODE_CAD:
1388 if( ( irqRegs & IRQ_CAD_DONE ) == IRQ_CAD_DONE )
1389 {
1390 if( ( irqRegs & IRQ_CAD_ACTIVITY_DETECTED ) == IRQ_CAD_ACTIVITY_DETECTED )
1391 {
1392 if( ( RadioCallbacks != NULL ) && ( RadioCallbacks->cadDone != NULL ) )
1393 {
1394 RadioCallbacks->cadDone( true );
1395 }
1396 }
1397 else
1398 {
1399 if( ( RadioCallbacks != NULL ) && ( RadioCallbacks->cadDone != NULL ) )
1400 {
1401 RadioCallbacks->cadDone( false );
1402 }
1403 }
1404 }
1405 else if( ( irqRegs & IRQ_RX_TX_TIMEOUT ) == IRQ_RX_TX_TIMEOUT )
1406 {
1407 if( ( RadioCallbacks != NULL ) && ( RadioCallbacks->rxTimeout != NULL ) )
1408 {
1409 RadioCallbacks->rxTimeout( );
1410 }
1411 }
1412 break;
1413 default:
1414 // Unexpected IRQ: silently returns
1415 break;
1416 }
1417 break;
1418 case PACKET_TYPE_RANGING:
1419 switch( OperatingMode )
1420 {
1421 // MODE_RX indicates an IRQ on the Slave side
1422 case MODE_RX:
1423 if( ( irqRegs & IRQ_RANGING_SLAVE_REQUEST_DISCARDED ) == IRQ_RANGING_SLAVE_REQUEST_DISCARDED )
1424 {
1425 if( ( RadioCallbacks != NULL ) && ( RadioCallbacks->rangingDone != NULL ) )
1426 {
1427 RadioCallbacks->rangingDone( IRQ_RANGING_SLAVE_ERROR_CODE );
1428 }
1429 }
1430 if( ( irqRegs & IRQ_RANGING_SLAVE_REQUEST_VALID ) == IRQ_RANGING_SLAVE_REQUEST_VALID )
1431 {
1432 if( ( RadioCallbacks != NULL ) && ( RadioCallbacks->rangingDone != NULL ) )
1433 {
1434 RadioCallbacks->rangingDone( IRQ_RANGING_SLAVE_VALID_CODE );
1435 }
1436 }
1437 if( ( irqRegs & IRQ_RANGING_SLAVE_RESPONSE_DONE ) == IRQ_RANGING_SLAVE_RESPONSE_DONE )
1438 {
1439 if( ( RadioCallbacks != NULL ) && ( RadioCallbacks->rangingDone != NULL ) )
1440 {
1441 RadioCallbacks->rangingDone( IRQ_RANGING_SLAVE_VALID_CODE );
1442 }
1443 }
1444 if( ( irqRegs & IRQ_RX_TX_TIMEOUT ) == IRQ_RX_TX_TIMEOUT )
1445 {
1446 if( ( RadioCallbacks != NULL ) && ( RadioCallbacks->rangingDone != NULL ) )
1447 {
1448 RadioCallbacks->rangingDone( IRQ_RANGING_SLAVE_ERROR_CODE );
1449 }
1450 }
1451 if( ( irqRegs & IRQ_HEADER_VALID ) == IRQ_HEADER_VALID )
1452 {
1453 if( ( RadioCallbacks != NULL ) && ( RadioCallbacks->rxHeaderDone != NULL ) )
1454 {
1455 RadioCallbacks->rxHeaderDone( );
1456 }
1457 }
1458 if( ( irqRegs & IRQ_HEADER_ERROR ) == IRQ_HEADER_ERROR )
1459 {
1460 if( ( RadioCallbacks != NULL ) && ( RadioCallbacks->rxError != NULL ) )
1461 {
1462 RadioCallbacks->rxError( IRQ_HEADER_ERROR_CODE );
1463 }
1464 }
1465 break;
1466 // MODE_TX indicates an IRQ on the Master side
1467 case MODE_TX:
1468 if( ( irqRegs & IRQ_RANGING_MASTER_RESULT_TIMEOUT ) == IRQ_RANGING_MASTER_RESULT_TIMEOUT )
1469 {
1470 if( ( RadioCallbacks != NULL ) && ( RadioCallbacks->rangingDone != NULL ) )
1471 {
1472 RadioCallbacks->rangingDone( IRQ_RANGING_MASTER_ERROR_CODE );
1473 }
1474 }
1475 if( ( irqRegs & IRQ_RANGING_MASTER_RESULT_VALID ) == IRQ_RANGING_MASTER_RESULT_VALID )
1476 {
1477 if( ( RadioCallbacks != NULL ) && ( RadioCallbacks->rangingDone != NULL ) )
1478 {
1479 RadioCallbacks->rangingDone( IRQ_RANGING_MASTER_VALID_CODE );
1480 }
1481 }
1482 break;
1483 default:
1484 // Unexpected IRQ: silently returns
1485 break;
1486 }
1487 break;
1488 default:
1489 // Unexpected IRQ: silently returns
1490 break;
1491 }
1492 }
1493