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 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 91 void SX1280Init( RadioCallbacks_t *callbacks ) 92 { 93 RadioCallbacks = callbacks; 94 95 SX1280HalInit( DioIrq ); 96 } 97 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 106 uint16_t SX1280GetFirmwareVersion( void ) 107 { 108 return( ( ( SX1280HalReadRegister( REG_LR_FIRMWARE_VERSION_MSB ) ) << 8 ) | ( SX1280HalReadRegister( REG_LR_FIRMWARE_VERSION_MSB + 1 ) ) ); 109 } 110 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 121 RadioOperatingModes_t SX1280GetOpMode( void ) 122 { 123 return OperatingMode; 124 } 125 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 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 150 void SX1280SetFs( void ) 151 { 152 SX1280HalWriteCommand( RADIO_SET_FS, 0, 0 ); 153 OperatingMode = MODE_FS; 154 } 155 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 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 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 212 void SX1280SetCad( void ) 213 { 214 SX1280HalWriteCommand( RADIO_SET_CAD, 0, 0 ); 215 OperatingMode = MODE_CAD; 216 } 217 218 void SX1280SetTxContinuousWave( void ) 219 { 220 SX1280HalWriteCommand( RADIO_SET_TXCONTINUOUSWAVE, 0, 0 ); 221 } 222 223 void SX1280SetTxContinuousPreamble( void ) 224 { 225 SX1280HalWriteCommand( RADIO_SET_TXCONTINUOUSPREAMBLE, 0, 0 ); 226 } 227 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 236 RadioPacketTypes_t SX1280GetPacketType( void ) 237 { 238 return PacketType; 239 } 240 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 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 264 void SX1280SetCadParams( RadioLoRaCadSymbols_t cadSymbolNum ) 265 { 266 SX1280HalWriteCommand( RADIO_SET_CADPARAMS, ( uint8_t* )&cadSymbolNum, 1 ); 267 OperatingMode = MODE_CAD; 268 } 269 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 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 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 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 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 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 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 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 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 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 566 void SX1280SetRegulatorMode( RadioRegulatorModes_t mode ) 567 { 568 SX1280HalWriteCommand( RADIO_SET_REGULATORMODE, ( uint8_t* )&mode, 1 ); 569 } 570 571 void SX1280SetSaveContext( void ) 572 { 573 SX1280HalWriteCommand( RADIO_SET_SAVECONTEXT, 0, 0 ); 574 } 575 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 586 void SX1280StopAutoTx( void ) 587 { 588 uint8_t buf[2] = {0x00, 0x00}; 589 SX1280HalWriteCommand( RADIO_SET_AUTOTX, buf, 2 ); 590 } 591 592 void SX1280SetAutoFS( uint8_t enable ) 593 { 594 SX1280HalWriteCommand( RADIO_SET_AUTOFS, &enable, 1 ); 595 } 596 597 void SX1280SetLongPreamble( uint8_t enable ) 598 { 599 SX1280HalWriteCommand( RADIO_SET_LONGPREAMBLE, &enable, 1 ); 600 } 601 602 void SX1280SetPayload( uint8_t *buffer, uint8_t size ) 603 { 604 SX1280HalWriteBuffer( 0x00, buffer, size ); 605 } 606 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 620 void SX1280SendPayload( uint8_t *payload, uint8_t size, TickTime_t timeout ) 621 { 622 SX1280SetPayload( payload, size ); 623 SX1280SetTx( timeout ); 624 } 625 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 699 void SX1280SetSyncWordErrorTolerance( uint8_t ErrorBits ) 700 { 701 ErrorBits = ( SX1280HalReadRegister( REG_LR_SYNCWORDTOLERANCE ) & 0xF0 ) | ( ErrorBits & 0x0F ); 702 SX1280HalWriteRegister( REG_LR_SYNCWORDTOLERANCE, ErrorBits ); 703 } 704 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 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 732 void SX1280SetBleAdvertizerAccessAddress( void ) 733 { 734 SX1280SetBleAccessAddress( BLE_ADVERTIZER_ACCESS_ADDRESS ); 735 } 736 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 1051 void SX1280SetPollingMode( void ) 1052 { 1053 PollingMode = true; 1054 } 1055 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 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 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 1179 void SX1280SetInterruptMode( void ) 1180 { 1181 PollingMode = false; 1182 } 1183 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 1201 void SX1280AutoTxWillStart( void ){ 1202 OperatingMode = MODE_TX; 1203 } 1204 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