Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of SX1280Lib by
sx1280.cpp
00001 /* 00002 ______ _ 00003 / _____) _ | | 00004 ( (____ _____ ____ _| |_ _____ ____| |__ 00005 \____ \| ___ | (_ _) ___ |/ ___) _ \ 00006 _____) ) ____| | | || |_| ____( (___| | | | 00007 (______/|_____)_|_|_| \__)_____)\____)_| |_| 00008 (C)2016 Semtech 00009 00010 Description: Driver for SX1280 devices 00011 00012 License: Revised BSD License, see LICENSE.TXT file include in the project 00013 00014 Maintainer: Miguel Luis, Gregory Cristian and Matthieu Verdy 00015 */ 00016 #include "mbed.h" 00017 #include "sx1280.h" 00018 #include "sx1280-hal.h" 00019 00020 /*! 00021 * \brief ContinuousMode and SingleMode are two particular values for TickTime. 00022 * The ContinuousMode keeps the radio in Rx or Tx mode, even after successfull reception 00023 * or transmission. It should never generate Timeout interrupt. 00024 * The SingleMode lets the radio enought time to make one reception or transmission. 00025 * No Timeout interrupt is generated, and the radio fall in StandBy mode after 00026 * reception or transmission. 00027 */ 00028 TickTime_t ContinuousMode = { RADIO_TICK_SIZE_0015_US, 0xFFFF }; 00029 TickTime_t SingleMode = { RADIO_TICK_SIZE_0015_US, 0xFFFF }; 00030 00031 /*! 00032 * \brief Radio registers definition 00033 * 00034 */ 00035 typedef struct 00036 { 00037 uint16_t Addr; //!< The address of the register 00038 uint8_t Value; //!< The value of the register 00039 }RadioRegisters_t; 00040 00041 /*! 00042 * \brief Radio hardware registers initialization definition 00043 */ 00044 #define RADIO_INIT_REGISTERS_VALUE { } 00045 00046 /*! 00047 * \brief Radio hardware registers initialization 00048 */ 00049 const RadioRegisters_t RadioRegsInit[] = RADIO_INIT_REGISTERS_VALUE; 00050 00051 void SX1280::Init( void ) 00052 { 00053 Reset( ); 00054 IoIrqInit( dioIrq ); 00055 Wakeup( ); 00056 SetRegistersDefault( ); 00057 } 00058 00059 void SX1280::SetRegistersDefault( void ) 00060 { 00061 for( int16_t i = 0; i < sizeof( RadioRegsInit ) / sizeof( RadioRegisters_t ); i++ ) 00062 { 00063 WriteRegister( RadioRegsInit[i].Addr, RadioRegsInit[i].Value ); 00064 } 00065 } 00066 00067 uint16_t SX1280::GetFirmwareVersion( void ) 00068 { 00069 return( ( ( ReadRegister( 0xA8 ) ) << 8 ) | ( ReadRegister( 0xA9 ) ) ); 00070 } 00071 00072 RadioStatus_t SX1280::GetStatus( void ) 00073 { 00074 uint8_t stat = 0; 00075 RadioStatus_t status; 00076 00077 ReadCommand( RADIO_GET_STATUS, ( uint8_t * )&stat, 1 ); 00078 status.Value = stat; 00079 return( status ); 00080 } 00081 00082 RadioOperatingModes_t SX1280::GetOpMode( void ) 00083 { 00084 return( OperatingMode ); 00085 } 00086 00087 void SX1280::SetSleep( SleepParams_t sleepConfig ) 00088 { 00089 uint8_t sleep = ( sleepConfig.WakeUpRTC << 3 ) | 00090 ( sleepConfig.InstructionRamRetention << 2 ) | 00091 ( sleepConfig.DataBufferRetention << 1 ) | 00092 ( sleepConfig.DataRamRetention ); 00093 00094 OperatingMode = MODE_SLEEP; 00095 WriteCommand( RADIO_SET_SLEEP, &sleep, 1 ); 00096 } 00097 00098 void SX1280::SetStandby( RadioStandbyModes_t standbyConfig ) 00099 { 00100 WriteCommand( RADIO_SET_STANDBY, ( uint8_t* )&standbyConfig, 1 ); 00101 if( standbyConfig == STDBY_RC ) 00102 { 00103 OperatingMode = MODE_STDBY_RC; 00104 } 00105 else 00106 { 00107 OperatingMode = MODE_STDBY_XOSC; 00108 } 00109 } 00110 00111 void SX1280::SetFs( void ) 00112 { 00113 WriteCommand( RADIO_SET_FS, 0, 0 ); 00114 OperatingMode = MODE_FS; 00115 } 00116 00117 void SX1280::SetTx( TickTime_t timeout ) 00118 { 00119 uint8_t buf[3]; 00120 buf[0] = timeout.Step; 00121 buf[1] = ( uint8_t )( ( timeout.NbSteps >> 8 ) & 0x00FF ); 00122 buf[2] = ( uint8_t )( timeout.NbSteps & 0x00FF ); 00123 00124 ClearIrqStatus( IRQ_RADIO_ALL ); 00125 00126 // If the radio is doing ranging operations, then apply the specific calls 00127 // prior to SetTx 00128 if( GetPacketType( ) == PACKET_TYPE_RANGING ) 00129 { 00130 SetRangingRole( RADIO_RANGING_ROLE_MASTER ); 00131 } 00132 WriteCommand( RADIO_SET_TX, buf, 3 ); 00133 OperatingMode = MODE_TX; 00134 } 00135 00136 void SX1280::SetRx( TickTime_t timeout ) 00137 { 00138 uint8_t buf[3]; 00139 buf[0] = timeout.Step; 00140 buf[1] = ( uint8_t )( ( timeout.NbSteps >> 8 ) & 0x00FF ); 00141 buf[2] = ( uint8_t )( timeout.NbSteps & 0x00FF ); 00142 00143 ClearIrqStatus( IRQ_RADIO_ALL ); 00144 00145 // If the radio is doing ranging operations, then apply the specific calls 00146 // prior to SetRx 00147 if( GetPacketType( ) == PACKET_TYPE_RANGING ) 00148 { 00149 SetRangingRole( RADIO_RANGING_ROLE_SLAVE ); 00150 } 00151 WriteCommand( RADIO_SET_RX, buf, 3 ); 00152 OperatingMode = MODE_RX; 00153 } 00154 00155 void SX1280::SetRxDutyCycle( RadioTickSizes_t step, uint16_t nbStepRx, uint16_t nbStepSleep ) 00156 { 00157 uint8_t buf[5]; 00158 00159 buf[0] = step; 00160 buf[1] = ( uint8_t )( ( nbStepRx >> 8 ) & 0x00FF ); 00161 buf[2] = ( uint8_t )( nbStepRx & 0x00FF ); 00162 buf[3] = ( uint8_t )( ( nbStepSleep >> 8 ) & 0x00FF ); 00163 buf[4] = ( uint8_t )( nbStepSleep & 0x00FF ); 00164 WriteCommand( RADIO_SET_RXDUTYCYCLE, buf, 5 ); 00165 OperatingMode = MODE_RX; 00166 } 00167 00168 void SX1280::SetCad( void ) 00169 { 00170 WriteCommand( RADIO_SET_CAD, 0, 0 ); 00171 OperatingMode = MODE_CAD; 00172 } 00173 00174 void SX1280::SetTxContinuousWave( void ) 00175 { 00176 WriteCommand( RADIO_SET_TXCONTINUOUSWAVE, 0, 0 ); 00177 } 00178 00179 void SX1280::SetTxContinuousPreamble( void ) 00180 { 00181 WriteCommand( RADIO_SET_TXCONTINUOUSPREAMBLE, 0, 0 ); 00182 } 00183 00184 void SX1280::SetPacketType( RadioPacketTypes_t packetType ) 00185 { 00186 // Save packet type internally to avoid questioning the radio 00187 this->PacketType = packetType; 00188 00189 WriteCommand( RADIO_SET_PACKETTYPE, ( uint8_t* )&packetType, 1 ); 00190 } 00191 00192 RadioPacketTypes_t SX1280::GetPacketType( void ) 00193 { 00194 return this->PacketType; 00195 } 00196 00197 void SX1280::SetRfFrequency( uint32_t frequency ) 00198 { 00199 uint8_t buf[3]; 00200 uint32_t freq = 0; 00201 00202 freq = ( uint32_t )( ( double )frequency / ( double )FREQ_STEP ); 00203 buf[0] = ( uint8_t )( ( freq >> 16 ) & 0xFF ); 00204 buf[1] = ( uint8_t )( ( freq >> 8 ) & 0xFF ); 00205 buf[2] = ( uint8_t )( freq & 0xFF ); 00206 WriteCommand( RADIO_SET_RFFREQUENCY, buf, 3 ); 00207 } 00208 00209 void SX1280::SetTxParams( int8_t power, RadioRampTimes_t rampTime ) 00210 { 00211 uint8_t buf[2]; 00212 00213 // The power value to send on SPI/UART is in the range [0..31] and the 00214 // physical output power is in the range [-18..13]dBm 00215 buf[0] = power + 18; 00216 buf[1] = ( uint8_t )rampTime; 00217 WriteCommand( RADIO_SET_TXPARAMS, buf, 2 ); 00218 } 00219 00220 void SX1280::SetCadParams( RadioLoRaCadSymbols_t cadSymbolNum ) 00221 { 00222 WriteCommand( RADIO_SET_CADPARAMS, ( uint8_t* )&cadSymbolNum, 1 ); 00223 OperatingMode = MODE_CAD; 00224 } 00225 00226 void SX1280::SetBufferBaseAddresses( uint8_t txBaseAddress, uint8_t rxBaseAddress ) 00227 { 00228 uint8_t buf[2]; 00229 00230 buf[0] = txBaseAddress; 00231 buf[1] = rxBaseAddress; 00232 WriteCommand( RADIO_SET_BUFFERBASEADDRESS, buf, 2 ); 00233 } 00234 00235 void SX1280::SetModulationParams( ModulationParams_t *modulationParams ) 00236 { 00237 uint8_t buf[3]; 00238 00239 // Check if required configuration corresponds to the stored packet type 00240 // If not, silently update radio packet type 00241 if( this->PacketType != modulationParams->PacketType ) 00242 { 00243 this->SetPacketType( modulationParams->PacketType ); 00244 } 00245 00246 switch( modulationParams->PacketType ) 00247 { 00248 case PACKET_TYPE_GFSK: 00249 buf[0] = modulationParams->Params.Gfsk.BitrateBandwidth; 00250 buf[1] = modulationParams->Params.Gfsk.ModulationIndex; 00251 buf[2] = modulationParams->Params.Gfsk.ModulationShaping; 00252 break; 00253 case PACKET_TYPE_LORA: 00254 case PACKET_TYPE_RANGING: 00255 buf[0] = modulationParams->Params.LoRa.SpreadingFactor; 00256 buf[1] = modulationParams->Params.LoRa.Bandwidth; 00257 buf[2] = modulationParams->Params.LoRa.CodingRate; 00258 this->LoRaBandwidth = modulationParams->Params.LoRa.Bandwidth; 00259 break; 00260 case PACKET_TYPE_FLRC: 00261 buf[0] = modulationParams->Params.Flrc.BitrateBandwidth; 00262 buf[1] = modulationParams->Params.Flrc.CodingRate; 00263 buf[2] = modulationParams->Params.Flrc.ModulationShaping; 00264 break; 00265 case PACKET_TYPE_BLE: 00266 buf[0] = modulationParams->Params.Ble.BitrateBandwidth; 00267 buf[1] = modulationParams->Params.Ble.ModulationIndex; 00268 buf[2] = modulationParams->Params.Ble.ModulationShaping; 00269 break; 00270 case PACKET_TYPE_NONE: 00271 buf[0] = NULL; 00272 buf[1] = NULL; 00273 buf[2] = NULL; 00274 break; 00275 } 00276 WriteCommand( RADIO_SET_MODULATIONPARAMS, buf, 3 ); 00277 } 00278 00279 void SX1280::SetPacketParams( PacketParams_t *packetParams ) 00280 { 00281 uint8_t buf[7]; 00282 // Check if required configuration corresponds to the stored packet type 00283 // If not, silently update radio packet type 00284 if( this->PacketType != packetParams->PacketType ) 00285 { 00286 this->SetPacketType( packetParams->PacketType ); 00287 } 00288 00289 switch( packetParams->PacketType ) 00290 { 00291 case PACKET_TYPE_GFSK: 00292 buf[0] = packetParams->Params.Gfsk.PreambleLength; 00293 buf[1] = packetParams->Params.Gfsk.SyncWordLength; 00294 buf[2] = packetParams->Params.Gfsk.SyncWordMatch; 00295 buf[3] = packetParams->Params.Gfsk.HeaderType; 00296 buf[4] = packetParams->Params.Gfsk.PayloadLength; 00297 buf[5] = packetParams->Params.Gfsk.CrcLength; 00298 buf[6] = packetParams->Params.Gfsk.Whitening; 00299 break; 00300 case PACKET_TYPE_LORA: 00301 case PACKET_TYPE_RANGING: 00302 buf[0] = packetParams->Params.LoRa.PreambleLength; 00303 buf[1] = packetParams->Params.LoRa.HeaderType; 00304 buf[2] = packetParams->Params.LoRa.PayloadLength; 00305 buf[3] = packetParams->Params.LoRa.CrcMode; 00306 buf[4] = packetParams->Params.LoRa.InvertIQ; 00307 buf[5] = NULL; 00308 buf[6] = NULL; 00309 break; 00310 case PACKET_TYPE_FLRC: 00311 buf[0] = packetParams->Params.Flrc.PreambleLength; 00312 buf[1] = packetParams->Params.Flrc.SyncWordLength; 00313 buf[2] = packetParams->Params.Flrc.SyncWordMatch; 00314 buf[3] = packetParams->Params.Flrc.HeaderType; 00315 buf[4] = packetParams->Params.Flrc.PayloadLength; 00316 buf[5] = packetParams->Params.Flrc.CrcLength; 00317 buf[6] = packetParams->Params.Flrc.Whitening; 00318 break; 00319 case PACKET_TYPE_BLE: 00320 buf[0] = packetParams->Params.Ble.ConnectionState; 00321 buf[1] = packetParams->Params.Ble.CrcField; 00322 buf[2] = packetParams->Params.Ble.BlePacketType; 00323 buf[3] = packetParams->Params.Ble.Whitening; 00324 buf[4] = NULL; 00325 buf[5] = NULL; 00326 buf[6] = NULL; 00327 break; 00328 case PACKET_TYPE_NONE: 00329 buf[0] = NULL; 00330 buf[1] = NULL; 00331 buf[2] = NULL; 00332 buf[3] = NULL; 00333 buf[4] = NULL; 00334 buf[5] = NULL; 00335 buf[6] = NULL; 00336 break; 00337 } 00338 WriteCommand( RADIO_SET_PACKETPARAMS, buf, 7 ); 00339 } 00340 00341 void SX1280::GetRxBufferStatus( uint8_t *payloadLength, uint8_t *rxStartBufferPointer ) 00342 { 00343 uint8_t status[2]; 00344 00345 ReadCommand( RADIO_GET_RXBUFFERSTATUS, status, 2 ); 00346 00347 // In case of LORA fixed header, the payloadLength is obtained by reading 00348 // the register REG_LR_PAYLOADLENGTH 00349 if( ( this -> GetPacketType( ) == PACKET_TYPE_LORA ) && ( ReadRegister( REG_LR_PACKETPARAMS ) >> 7 == 1 ) ) 00350 { 00351 *payloadLength = ReadRegister( REG_LR_PAYLOADLENGTH ); 00352 } 00353 else 00354 { 00355 *payloadLength = status[0]; 00356 } 00357 00358 *rxStartBufferPointer = status[1]; 00359 } 00360 00361 void SX1280::GetPacketStatus( PacketStatus_t *pktStatus ) 00362 { 00363 uint8_t status[5]; 00364 00365 ReadCommand( RADIO_GET_PACKETSTATUS, status, 5 ); 00366 00367 pktStatus->packetType = this -> GetPacketType( ); 00368 switch( pktStatus->packetType ) 00369 { 00370 case PACKET_TYPE_GFSK: 00371 pktStatus->Gfsk.RssiSync = -( status[1] / 2 ); 00372 00373 pktStatus->Gfsk.ErrorStatus.SyncError = ( status[2] >> 6 ) & 0x01; 00374 pktStatus->Gfsk.ErrorStatus.LengthError = ( status[2] >> 5 ) & 0x01; 00375 pktStatus->Gfsk.ErrorStatus.CrcError = ( status[2] >> 4 ) & 0x01; 00376 pktStatus->Gfsk.ErrorStatus.AbortError = ( status[2] >> 3 ) & 0x01; 00377 pktStatus->Gfsk.ErrorStatus.HeaderReceived = ( status[2] >> 2 ) & 0x01; 00378 pktStatus->Gfsk.ErrorStatus.PacketReceived = ( status[2] >> 1 ) & 0x01; 00379 pktStatus->Gfsk.ErrorStatus.PacketControlerBusy = status[2] & 0x01; 00380 00381 pktStatus->Gfsk.TxRxStatus.RxNoAck = ( status[3] >> 5 ) & 0x01; 00382 pktStatus->Gfsk.TxRxStatus.PacketSent = status[3] & 0x01; 00383 00384 pktStatus->Gfsk.SyncAddrStatus = status[4] & 0x07; 00385 break; 00386 00387 case PACKET_TYPE_LORA: 00388 case PACKET_TYPE_RANGING: 00389 pktStatus->LoRa.RssiPkt = -( status[0] / 2 ); 00390 ( status[1] < 128 ) ? ( pktStatus->LoRa.SnrPkt = status[1] / 4 ) : ( pktStatus->LoRa.SnrPkt = ( ( status[1] - 256 ) /4 ) ); 00391 00392 pktStatus->LoRa.ErrorStatus.SyncError = ( status[2] >> 6 ) & 0x01; 00393 pktStatus->LoRa.ErrorStatus.LengthError = ( status[2] >> 5 ) & 0x01; 00394 pktStatus->LoRa.ErrorStatus.CrcError = ( status[2] >> 4 ) & 0x01; 00395 pktStatus->LoRa.ErrorStatus.AbortError = ( status[2] >> 3 ) & 0x01; 00396 pktStatus->LoRa.ErrorStatus.HeaderReceived = ( status[2] >> 2 ) & 0x01; 00397 pktStatus->LoRa.ErrorStatus.PacketReceived = ( status[2] >> 1 ) & 0x01; 00398 pktStatus->LoRa.ErrorStatus.PacketControlerBusy = status[2] & 0x01; 00399 00400 pktStatus->LoRa.TxRxStatus.RxNoAck = ( status[3] >> 5 ) & 0x01; 00401 pktStatus->LoRa.TxRxStatus.PacketSent = status[3] & 0x01; 00402 00403 pktStatus->LoRa.SyncAddrStatus = status[4] & 0x07; 00404 break; 00405 00406 case PACKET_TYPE_FLRC: 00407 pktStatus->Flrc.RssiSync = -( status[1] / 2 ); 00408 00409 pktStatus->Flrc.ErrorStatus.SyncError = ( status[2] >> 6 ) & 0x01; 00410 pktStatus->Flrc.ErrorStatus.LengthError = ( status[2] >> 5 ) & 0x01; 00411 pktStatus->Flrc.ErrorStatus.CrcError = ( status[2] >> 4 ) & 0x01; 00412 pktStatus->Flrc.ErrorStatus.AbortError = ( status[2] >> 3 ) & 0x01; 00413 pktStatus->Flrc.ErrorStatus.HeaderReceived = ( status[2] >> 2 ) & 0x01; 00414 pktStatus->Flrc.ErrorStatus.PacketReceived = ( status[2] >> 1 ) & 0x01; 00415 pktStatus->Flrc.ErrorStatus.PacketControlerBusy = status[2] & 0x01; 00416 00417 pktStatus->Flrc.TxRxStatus.RxPid = ( status[3] >> 6 ) & 0x03; 00418 pktStatus->Flrc.TxRxStatus.RxNoAck = ( status[3] >> 5 ) & 0x01; 00419 pktStatus->Flrc.TxRxStatus.RxPidErr = ( status[3] >> 4 ) & 0x01; 00420 pktStatus->Flrc.TxRxStatus.PacketSent = status[3] & 0x01; 00421 00422 pktStatus->Flrc.SyncAddrStatus = status[4] & 0x07; 00423 break; 00424 00425 case PACKET_TYPE_BLE: 00426 pktStatus->Ble.RssiSync = -( status[1] / 2 ); 00427 00428 pktStatus->Ble.ErrorStatus.SyncError = ( status[2] >> 6 ) & 0x01; 00429 pktStatus->Ble.ErrorStatus.LengthError = ( status[2] >> 5 ) & 0x01; 00430 pktStatus->Ble.ErrorStatus.CrcError = ( status[2] >> 4 ) & 0x01; 00431 pktStatus->Ble.ErrorStatus.AbortError = ( status[2] >> 3 ) & 0x01; 00432 pktStatus->Ble.ErrorStatus.HeaderReceived = ( status[2] >> 2 ) & 0x01; 00433 pktStatus->Ble.ErrorStatus.PacketReceived = ( status[2] >> 1 ) & 0x01; 00434 pktStatus->Ble.ErrorStatus.PacketControlerBusy = status[2] & 0x01; 00435 00436 pktStatus->Ble.TxRxStatus.PacketSent = status[3] & 0x01; 00437 00438 pktStatus->Ble.SyncAddrStatus = status[4] & 0x07; 00439 break; 00440 00441 case PACKET_TYPE_NONE: 00442 // In that specific case, we set everything in the pktStatus to zeros 00443 // and reset the packet type accordingly 00444 memset( pktStatus, 0, sizeof( PacketStatus_t ) ); 00445 pktStatus->packetType = PACKET_TYPE_NONE; 00446 break; 00447 } 00448 } 00449 00450 int8_t SX1280::GetRssiInst( void ) 00451 { 00452 uint8_t raw = 0; 00453 00454 ReadCommand( RADIO_GET_RSSIINST, &raw, 1 ); 00455 00456 return ( int8_t ) ( -raw / 2 ); 00457 } 00458 00459 void SX1280::SetDioIrqParams( uint16_t irqMask, uint16_t dio1Mask, uint16_t dio2Mask, uint16_t dio3Mask ) 00460 { 00461 uint8_t buf[8]; 00462 00463 buf[0] = ( uint8_t )( ( irqMask >> 8 ) & 0x00FF ); 00464 buf[1] = ( uint8_t )( irqMask & 0x00FF ); 00465 buf[2] = ( uint8_t )( ( dio1Mask >> 8 ) & 0x00FF ); 00466 buf[3] = ( uint8_t )( dio1Mask & 0x00FF ); 00467 buf[4] = ( uint8_t )( ( dio2Mask >> 8 ) & 0x00FF ); 00468 buf[5] = ( uint8_t )( dio2Mask & 0x00FF ); 00469 buf[6] = ( uint8_t )( ( dio3Mask >> 8 ) & 0x00FF ); 00470 buf[7] = ( uint8_t )( dio3Mask & 0x00FF ); 00471 WriteCommand( RADIO_SET_DIOIRQPARAMS, buf, 8 ); 00472 } 00473 00474 uint16_t SX1280::GetIrqStatus( void ) 00475 { 00476 uint8_t irqStatus[2]; 00477 ReadCommand( RADIO_GET_IRQSTATUS, irqStatus, 2 ); 00478 return ( irqStatus[0] << 8 ) | irqStatus[1]; 00479 } 00480 00481 void SX1280::ClearIrqStatus( uint16_t irq ) 00482 { 00483 uint8_t buf[2]; 00484 00485 buf[0] = ( uint8_t )( ( ( uint16_t )irq >> 8 ) & 0x00FF ); 00486 buf[1] = ( uint8_t )( ( uint16_t )irq & 0x00FF ); 00487 WriteCommand( RADIO_CLR_IRQSTATUS, buf, 2 ); 00488 } 00489 00490 void SX1280::Calibrate( CalibrationParams_t calibParam ) 00491 { 00492 uint8_t cal = ( calibParam.ADCBulkPEnable << 5 ) | 00493 ( calibParam.ADCBulkNEnable << 4 ) | 00494 ( calibParam.ADCPulseEnable << 3 ) | 00495 ( calibParam.PLLEnable << 2 ) | 00496 ( calibParam.RC13MEnable << 1 ) | 00497 ( calibParam.RC64KEnable ); 00498 WriteCommand( RADIO_CALIBRATE, &cal, 1 ); 00499 } 00500 00501 void SX1280::SetRegulatorMode( RadioRegulatorModes_t mode ) 00502 { 00503 WriteCommand( RADIO_SET_REGULATORMODE, ( uint8_t* )&mode, 1 ); 00504 } 00505 00506 void SX1280::SetSaveContext( void ) 00507 { 00508 WriteCommand( RADIO_SET_SAVECONTEXT, 0, 0 ); 00509 } 00510 00511 void SX1280::SetAutoTx( uint16_t time ) 00512 { 00513 uint16_t compensatedTime = time - ( uint16_t )AUTO_TX_OFFSET; 00514 uint8_t buf[2]; 00515 00516 buf[0] = ( uint8_t )( ( compensatedTime >> 8 ) & 0x00FF ); 00517 buf[1] = ( uint8_t )( compensatedTime & 0x00FF ); 00518 WriteCommand( RADIO_SET_AUTOTX, buf, 2 ); 00519 } 00520 00521 void SX1280::SetAutoFs( bool enableAutoFs ) 00522 { 00523 WriteCommand( RADIO_SET_AUTORX, ( uint8_t * )&enableAutoFs, 1 ); 00524 } 00525 00526 void SX1280::SetLongPreamble( bool enable ) 00527 { 00528 WriteCommand( RADIO_SET_LONGPREAMBLE, ( uint8_t * )&enable, 1 ); 00529 } 00530 00531 void SX1280::SetPayload( uint8_t *buffer, uint8_t size, uint8_t offset ) 00532 { 00533 WriteBuffer( offset, buffer, size ); 00534 } 00535 00536 uint8_t SX1280::GetPayload( uint8_t *buffer, uint8_t *size , uint8_t maxSize ) 00537 { 00538 uint8_t offset; 00539 00540 GetRxBufferStatus( size, &offset ); 00541 if( *size > maxSize ) 00542 { 00543 return 1; 00544 } 00545 ReadBuffer( offset, buffer, *size ); 00546 return 0; 00547 } 00548 00549 void SX1280::SendPayload( uint8_t *payload, uint8_t size, TickTime_t timeout, uint8_t offset ) 00550 { 00551 SetPayload( payload, size, offset ); 00552 SetTx( timeout ); 00553 } 00554 00555 uint8_t SX1280::SetSyncWord( uint8_t syncWordIdx, uint8_t *syncWord ) 00556 { 00557 uint16_t addr; 00558 uint8_t syncwordSize = 0; 00559 00560 switch( GetPacketType( ) ) 00561 { 00562 case PACKET_TYPE_GFSK: 00563 syncwordSize = 5; 00564 switch( syncWordIdx ) 00565 { 00566 case 1: 00567 addr = REG_LR_SYNCWORDBASEADDRESS1; 00568 break; 00569 case 2: 00570 addr = REG_LR_SYNCWORDBASEADDRESS2; 00571 break; 00572 case 3: 00573 addr = REG_LR_SYNCWORDBASEADDRESS3; 00574 break; 00575 default: 00576 return 1; 00577 } 00578 break; 00579 case PACKET_TYPE_FLRC: 00580 // For FLRC packet type, the SyncWord is one byte shorter and 00581 // the base address is shifted by one byte 00582 syncwordSize = 4; 00583 switch( syncWordIdx ) 00584 { 00585 case 1: 00586 addr = REG_LR_SYNCWORDBASEADDRESS1 + 1; 00587 break; 00588 case 2: 00589 addr = REG_LR_SYNCWORDBASEADDRESS2 + 1; 00590 break; 00591 case 3: 00592 addr = REG_LR_SYNCWORDBASEADDRESS3 + 1; 00593 break; 00594 default: 00595 return 1; 00596 } 00597 break; 00598 case PACKET_TYPE_BLE: 00599 // For Ble packet type, only the first SyncWord is used and its 00600 // address is shifted by one byte 00601 syncwordSize = 4; 00602 switch( syncWordIdx ) 00603 { 00604 case 1: 00605 addr = REG_LR_SYNCWORDBASEADDRESS1 + 1; 00606 break; 00607 default: 00608 return 1; 00609 } 00610 break; 00611 default: 00612 return 1; 00613 } 00614 WriteRegister( addr, syncWord, syncwordSize ); 00615 return 0; 00616 } 00617 00618 void SX1280::SetSyncWordErrorTolerance( uint8_t ErrorBits ) 00619 { 00620 ErrorBits = ( ReadRegister( REG_LR_SYNCWORDTOLERANCE ) & 0xF0 ) | ( ErrorBits & 0x0F ); 00621 WriteRegister( REG_LR_SYNCWORDTOLERANCE, ErrorBits ); 00622 } 00623 00624 void SX1280::SetCrcSeed( uint16_t seed ) 00625 { 00626 uint8_t val[2]; 00627 00628 val[0] = ( uint8_t )( seed >> 8 ) & 0xFF; 00629 val[1] = ( uint8_t )( seed & 0xFF ); 00630 00631 switch( GetPacketType( ) ) 00632 { 00633 case PACKET_TYPE_GFSK: 00634 case PACKET_TYPE_FLRC: 00635 WriteRegister( REG_LR_CRCSEEDBASEADDR, val, 2 ); 00636 break; 00637 default: 00638 break; 00639 } 00640 } 00641 00642 void SX1280::SetCrcPolynomial( uint16_t polynomial ) 00643 { 00644 uint8_t val[2]; 00645 00646 val[0] = ( uint8_t )( polynomial >> 8 ) & 0xFF; 00647 val[1] = ( uint8_t )( polynomial & 0xFF ); 00648 00649 switch( GetPacketType( ) ) 00650 { 00651 case PACKET_TYPE_GFSK: 00652 case PACKET_TYPE_FLRC: 00653 WriteRegister( REG_LR_CRCPOLYBASEADDR, val, 2 ); 00654 break; 00655 default: 00656 break; 00657 } 00658 } 00659 00660 void SX1280::SetWhiteningSeed( uint8_t seed ) 00661 { 00662 switch( GetPacketType( ) ) 00663 { 00664 case PACKET_TYPE_GFSK: 00665 case PACKET_TYPE_FLRC: 00666 case PACKET_TYPE_BLE: 00667 WriteRegister( REG_LR_WHITSEEDBASEADDR, seed ); 00668 break; 00669 default: 00670 break; 00671 } 00672 } 00673 00674 void SX1280::SetRangingIdLength( RadioRangingIdCheckLengths_t length ) 00675 { 00676 switch( GetPacketType( ) ) 00677 { 00678 case PACKET_TYPE_RANGING: 00679 WriteRegister( REG_LR_RANGINGIDCHECKLENGTH, ( ( ( ( uint8_t )length ) & 0x03 ) << 6 ) | ( ReadRegister( REG_LR_RANGINGIDCHECKLENGTH ) & 0x3F ) ); 00680 break; 00681 default: 00682 break; 00683 } 00684 } 00685 00686 void SX1280::SetDeviceRangingAddress( uint32_t address ) 00687 { 00688 uint8_t addrArray[] = { address >> 24, address >> 16, address >> 8, address }; 00689 00690 switch( GetPacketType( ) ) 00691 { 00692 case PACKET_TYPE_RANGING: 00693 WriteRegister( REG_LR_DEVICERANGINGADDR, addrArray, 4 ); 00694 break; 00695 default: 00696 break; 00697 } 00698 } 00699 00700 void SX1280::SetRangingRequestAddress( uint32_t address ) 00701 { 00702 uint8_t addrArray[] = { address >> 24, address >> 16, address >> 8, address }; 00703 00704 switch( GetPacketType( ) ) 00705 { 00706 case PACKET_TYPE_RANGING: 00707 WriteRegister( REG_LR_REQUESTRANGINGADDR, addrArray, 4 ); 00708 break; 00709 default: 00710 break; 00711 } 00712 } 00713 00714 double SX1280::GetRangingResult( RadioRangingResultTypes_t resultType ) 00715 { 00716 uint32_t valLsb = 0; 00717 double val = 0.0; 00718 00719 switch( GetPacketType( ) ) 00720 { 00721 case PACKET_TYPE_RANGING: 00722 this->SetStandby( STDBY_XOSC ); 00723 this->WriteRegister( 0x97F, this->ReadRegister( 0x97F ) | ( 1 << 1 ) ); // enable LORA modem clock 00724 WriteRegister( REG_LR_RANGINGRESULTCONFIG, ( ReadRegister( REG_LR_RANGINGRESULTCONFIG ) & MASK_RANGINGMUXSEL ) | ( ( ( ( uint8_t )resultType ) & 0x03 ) << 4 ) ); 00725 valLsb = ( ( ReadRegister( REG_LR_RANGINGRESULTBASEADDR ) << 16 ) | ( ReadRegister( REG_LR_RANGINGRESULTBASEADDR + 1 ) << 8 ) | ( ReadRegister( REG_LR_RANGINGRESULTBASEADDR + 2 ) ) ); 00726 this->SetStandby( STDBY_RC ); 00727 00728 // Convertion from LSB to distance. For explanation on the formula, refer to Datasheet of SX1280 00729 switch( resultType ) 00730 { 00731 case RANGING_RESULT_RAW: 00732 // Convert the ranging LSB to distance in meter 00733 // The theoretical conversion from register value to distance [m] is given by: 00734 //distance [m] = ( complement2( register ) * 150 ) / ( 2^12 * bandwidth[MHz] ) ) 00735 // The API provide BW in [Hz] so the implemented formula is complement2( register ) / bandwidth[Hz] * A, 00736 // where A = 150 / (2^12 / 1e6) = 36621.09 00737 val = ( double )complement2( valLsb, 24 ) / ( double )this->GetLoRaBandwidth( ) * 36621.09375; 00738 break; 00739 00740 case RANGING_RESULT_AVERAGED: 00741 case RANGING_RESULT_DEBIASED: 00742 case RANGING_RESULT_FILTERED: 00743 val = ( double )valLsb * 20.0 / 100.0; 00744 break; 00745 default: 00746 val = 0.0; 00747 } 00748 break; 00749 default: 00750 break; 00751 } 00752 return val; 00753 } 00754 00755 void SX1280::SetRangingCalibration( uint16_t cal ) 00756 { 00757 switch( GetPacketType( ) ) 00758 { 00759 case PACKET_TYPE_RANGING: 00760 WriteRegister( REG_LR_RANGINGRERXTXDELAYCAL, ( uint8_t )( ( cal >> 8 ) & 0xFF ) ); 00761 WriteRegister( REG_LR_RANGINGRERXTXDELAYCAL + 1, ( uint8_t )( ( cal ) & 0xFF ) ); 00762 break; 00763 default: 00764 break; 00765 } 00766 } 00767 00768 void SX1280::RangingClearFilterResult( void ) 00769 { 00770 uint8_t regVal = ReadRegister( REG_LR_RANGINGRESULTCLEARREG ); 00771 00772 // To clear result, set bit 5 to 1 then to 0 00773 WriteRegister( REG_LR_RANGINGRESULTCLEARREG, regVal | ( 1 << 5 ) ); 00774 WriteRegister( REG_LR_RANGINGRESULTCLEARREG, regVal & ( ~( 1 << 5 ) ) ); 00775 } 00776 00777 void SX1280::RangingSetFilterNumSamples( uint8_t num ) 00778 { 00779 // Silently set 8 as minimum value 00780 WriteRegister( REG_LR_RANGINGFILTERWINDOWSIZE, ( num < DEFAULT_RANGING_FILTER_SIZE ) ? DEFAULT_RANGING_FILTER_SIZE : num ); 00781 } 00782 00783 void SX1280::SetRangingRole( RadioRangingRoles_t role ) 00784 { 00785 uint8_t buf[1]; 00786 00787 buf[0] = role; 00788 WriteCommand( RADIO_SET_RANGING_ROLE, &buf[0], 1 ); 00789 } 00790 00791 double SX1280::GetFrequencyError( ) 00792 { 00793 uint8_t efeRaw[3] = {0}; 00794 uint32_t efe = 0; 00795 double efeHz = 0.0; 00796 00797 switch( this->GetPacketType( ) ) 00798 { 00799 case PACKET_TYPE_LORA: 00800 case PACKET_TYPE_RANGING: 00801 efeRaw[0] = this->ReadRegister( REG_LR_ESTIMATED_FREQUENCY_ERROR_MSB ); 00802 efeRaw[1] = this->ReadRegister( REG_LR_ESTIMATED_FREQUENCY_ERROR_MSB + 1 ); 00803 efeRaw[2] = this->ReadRegister( REG_LR_ESTIMATED_FREQUENCY_ERROR_MSB + 2 ); 00804 efe = ( efeRaw[0]<<16 ) | ( efeRaw[1]<<8 ) | efeRaw[2]; 00805 efe &= REG_LR_ESTIMATED_FREQUENCY_ERROR_MASK; 00806 00807 efeHz = 1.55 * ( double )complement2( efe, 20 ) / ( 1600.0 / ( double )this->GetLoRaBandwidth( ) * 1000.0 ); 00808 break; 00809 00810 case PACKET_TYPE_NONE: 00811 case PACKET_TYPE_BLE: 00812 case PACKET_TYPE_FLRC: 00813 case PACKET_TYPE_GFSK: 00814 break; 00815 } 00816 00817 return efeHz; 00818 } 00819 00820 void SX1280::SetPollingMode( void ) 00821 { 00822 this->PollingMode = true; 00823 } 00824 00825 int32_t SX1280::complement2( const uint32_t num, const uint8_t bitCnt ) 00826 { 00827 int32_t retVal = ( int32_t )num; 00828 if( num >= 2<<( bitCnt - 2 ) ) 00829 { 00830 retVal -= 2<<( bitCnt - 1 ); 00831 } 00832 return retVal; 00833 } 00834 00835 int32_t SX1280::GetLoRaBandwidth( ) 00836 { 00837 int32_t bwValue = 0; 00838 00839 switch( this->LoRaBandwidth ) 00840 { 00841 case LORA_BW_0200: 00842 bwValue = 203125; 00843 break; 00844 case LORA_BW_0400: 00845 bwValue = 406250; 00846 break; 00847 case LORA_BW_0800: 00848 bwValue = 812500; 00849 break; 00850 case LORA_BW_1600: 00851 bwValue = 1625000; 00852 break; 00853 default: 00854 bwValue = 0; 00855 } 00856 return bwValue; 00857 } 00858 00859 void SX1280::SetInterruptMode( void ) 00860 { 00861 this->PollingMode = false; 00862 } 00863 00864 void SX1280::OnDioIrq( void ) 00865 { 00866 /* 00867 * When polling mode is activated, it is up to the application to call 00868 * ProcessIrqs( ). Otherwise, the driver automatically calls ProcessIrqs( ) 00869 * on radio interrupt. 00870 */ 00871 if( this->PollingMode == true ) 00872 { 00873 this->IrqState = true; 00874 } 00875 else 00876 { 00877 this->ProcessIrqs( ); 00878 } 00879 } 00880 00881 void SX1280::ProcessIrqs( void ) 00882 { 00883 RadioPacketTypes_t packetType = PACKET_TYPE_NONE; 00884 00885 if( this->PollingMode == true ) 00886 { 00887 if( this->IrqState == true ) 00888 { 00889 __disable_irq( ); 00890 this->IrqState = false; 00891 __enable_irq( ); 00892 } 00893 else 00894 { 00895 return; 00896 } 00897 } 00898 00899 packetType = GetPacketType( ); 00900 uint16_t irqRegs = GetIrqStatus( ); 00901 ClearIrqStatus( IRQ_RADIO_ALL ); 00902 00903 #if( SX1280_DEBUG == 1 ) 00904 DigitalOut TEST_PIN_1( D14 ); 00905 DigitalOut TEST_PIN_2( D15 ); 00906 for( int i = 0x8000; i != 0; i >>= 1 ) 00907 { 00908 TEST_PIN_2 = 0; 00909 TEST_PIN_1 = ( ( irqRegs & i ) != 0 ) ? 1 : 0; 00910 TEST_PIN_2 = 1; 00911 } 00912 TEST_PIN_1 = 0; 00913 TEST_PIN_2 = 0; 00914 #endif 00915 00916 switch( packetType ) 00917 { 00918 case PACKET_TYPE_GFSK: 00919 case PACKET_TYPE_FLRC: 00920 case PACKET_TYPE_BLE: 00921 switch( OperatingMode ) 00922 { 00923 case MODE_RX: 00924 if( ( irqRegs & IRQ_RX_DONE ) == IRQ_RX_DONE ) 00925 { 00926 if( ( irqRegs & IRQ_CRC_ERROR ) == IRQ_CRC_ERROR ) 00927 { 00928 if( rxError != NULL ) 00929 { 00930 rxError( IRQ_CRC_ERROR_CODE ); 00931 } 00932 } 00933 else if( ( irqRegs & IRQ_SYNCWORD_ERROR ) == IRQ_SYNCWORD_ERROR ) 00934 { 00935 if( rxError != NULL ) 00936 { 00937 rxError( IRQ_SYNCWORD_ERROR_CODE ); 00938 } 00939 } 00940 else 00941 { 00942 if( rxDone != NULL ) 00943 { 00944 rxDone( ); 00945 } 00946 } 00947 } 00948 if( ( irqRegs & IRQ_SYNCWORD_VALID ) == IRQ_SYNCWORD_VALID ) 00949 { 00950 if( rxSyncWordDone != NULL ) 00951 { 00952 rxSyncWordDone( ); 00953 } 00954 } 00955 if( ( irqRegs & IRQ_SYNCWORD_ERROR ) == IRQ_SYNCWORD_ERROR ) 00956 { 00957 if( rxError != NULL ) 00958 { 00959 rxError( IRQ_SYNCWORD_ERROR_CODE ); 00960 } 00961 } 00962 if( ( irqRegs & IRQ_RX_TX_TIMEOUT ) == IRQ_RX_TX_TIMEOUT ) 00963 { 00964 if( rxTimeout != NULL ) 00965 { 00966 rxTimeout( ); 00967 } 00968 } 00969 break; 00970 case MODE_TX: 00971 if( ( irqRegs & IRQ_TX_DONE ) == IRQ_TX_DONE ) 00972 { 00973 if( txDone != NULL ) 00974 { 00975 txDone( ); 00976 } 00977 } 00978 if( ( irqRegs & IRQ_RX_TX_TIMEOUT ) == IRQ_RX_TX_TIMEOUT ) 00979 { 00980 if( txTimeout != NULL ) 00981 { 00982 txTimeout( ); 00983 } 00984 } 00985 break; 00986 default: 00987 // Unexpected IRQ: silently returns 00988 break; 00989 } 00990 break; 00991 case PACKET_TYPE_LORA: 00992 switch( OperatingMode ) 00993 { 00994 case MODE_RX: 00995 if( ( irqRegs & IRQ_RX_DONE ) == IRQ_RX_DONE ) 00996 { 00997 if( ( irqRegs & IRQ_CRC_ERROR ) == IRQ_CRC_ERROR ) 00998 { 00999 if( rxError != NULL ) 01000 { 01001 rxError( IRQ_CRC_ERROR_CODE ); 01002 } 01003 } 01004 else 01005 { 01006 if( rxDone != NULL ) 01007 { 01008 rxDone( ); 01009 } 01010 } 01011 } 01012 if( ( irqRegs & IRQ_HEADER_VALID ) == IRQ_HEADER_VALID ) 01013 { 01014 if( rxHeaderDone != NULL ) 01015 { 01016 rxHeaderDone( ); 01017 } 01018 } 01019 if( ( irqRegs & IRQ_HEADER_ERROR ) == IRQ_HEADER_ERROR ) 01020 { 01021 if( rxError != NULL ) 01022 { 01023 rxError( IRQ_HEADER_ERROR_CODE ); 01024 } 01025 } 01026 if( ( irqRegs & IRQ_RX_TX_TIMEOUT ) == IRQ_RX_TX_TIMEOUT ) 01027 { 01028 if( rxTimeout != NULL ) 01029 { 01030 rxTimeout( ); 01031 } 01032 } 01033 if( ( irqRegs & IRQ_RANGING_SLAVE_REQUEST_DISCARDED ) == IRQ_RANGING_SLAVE_REQUEST_DISCARDED ) 01034 { 01035 if( rxError != NULL ) 01036 { 01037 rxError( IRQ_RANGING_ON_LORA_ERROR_CODE ); 01038 } 01039 } 01040 break; 01041 case MODE_TX: 01042 if( ( irqRegs & IRQ_TX_DONE ) == IRQ_TX_DONE ) 01043 { 01044 if( txDone != NULL ) 01045 { 01046 txDone( ); 01047 } 01048 } 01049 if( ( irqRegs & IRQ_RX_TX_TIMEOUT ) == IRQ_RX_TX_TIMEOUT ) 01050 { 01051 if( txTimeout != NULL ) 01052 { 01053 txTimeout( ); 01054 } 01055 } 01056 break; 01057 case MODE_CAD: 01058 if( ( irqRegs & IRQ_CAD_DONE ) == IRQ_CAD_DONE ) 01059 { 01060 if( ( irqRegs & IRQ_CAD_ACTIVITY_DETECTED ) == IRQ_CAD_ACTIVITY_DETECTED ) 01061 { 01062 if( cadDone != NULL ) 01063 { 01064 cadDone( true ); 01065 } 01066 } 01067 else 01068 { 01069 if( cadDone != NULL ) 01070 { 01071 cadDone( false ); 01072 } 01073 } 01074 } 01075 else if( ( irqRegs & IRQ_RX_TX_TIMEOUT ) == IRQ_RX_TX_TIMEOUT ) 01076 { 01077 if( rxTimeout != NULL ) 01078 { 01079 rxTimeout( ); 01080 } 01081 } 01082 break; 01083 default: 01084 // Unexpected IRQ: silently returns 01085 break; 01086 } 01087 break; 01088 case PACKET_TYPE_RANGING: 01089 switch( OperatingMode ) 01090 { 01091 // MODE_RX indicates an IRQ on the Slave side 01092 case MODE_RX: 01093 if( ( irqRegs & IRQ_RANGING_SLAVE_REQUEST_DISCARDED ) == IRQ_RANGING_SLAVE_REQUEST_DISCARDED ) 01094 { 01095 if( rangingDone != NULL ) 01096 { 01097 rangingDone( IRQ_RANGING_SLAVE_ERROR_CODE ); 01098 } 01099 } 01100 if( ( irqRegs & IRQ_RANGING_SLAVE_REQUEST_VALID ) == IRQ_RANGING_SLAVE_REQUEST_VALID ) 01101 { 01102 if( rangingDone != NULL ) 01103 { 01104 rangingDone( IRQ_RANGING_SLAVE_VALID_CODE ); 01105 } 01106 } 01107 if( ( irqRegs & IRQ_RANGING_SLAVE_RESPONSE_DONE ) == IRQ_RANGING_SLAVE_RESPONSE_DONE ) 01108 { 01109 if( rangingDone != NULL ) 01110 { 01111 rangingDone( IRQ_RANGING_SLAVE_VALID_CODE ); 01112 } 01113 } 01114 if( ( irqRegs & IRQ_RX_TX_TIMEOUT ) == IRQ_RX_TX_TIMEOUT ) 01115 { 01116 if( rangingDone != NULL ) 01117 { 01118 rangingDone( IRQ_RANGING_SLAVE_ERROR_CODE ); 01119 } 01120 } 01121 if( ( irqRegs & IRQ_HEADER_VALID ) == IRQ_HEADER_VALID ) 01122 { 01123 if( rxHeaderDone != NULL ) 01124 { 01125 rxHeaderDone( ); 01126 } 01127 } 01128 if( ( irqRegs & IRQ_HEADER_ERROR ) == IRQ_HEADER_ERROR ) 01129 { 01130 if( rxError != NULL ) 01131 { 01132 rxError( IRQ_HEADER_ERROR_CODE ); 01133 } 01134 } 01135 break; 01136 // MODE_TX indicates an IRQ on the Master side 01137 case MODE_TX: 01138 if( ( irqRegs & IRQ_RANGING_MASTER_RESULT_TIMEOUT ) == IRQ_RANGING_MASTER_RESULT_TIMEOUT ) 01139 { 01140 if( rangingDone != NULL ) 01141 { 01142 rangingDone( IRQ_RANGING_MASTER_ERROR_CODE ); 01143 } 01144 } 01145 if( ( irqRegs & IRQ_RANGING_MASTER_RESULT_VALID ) == IRQ_RANGING_MASTER_RESULT_VALID ) 01146 { 01147 if( rangingDone != NULL ) 01148 { 01149 rangingDone( IRQ_RANGING_MASTER_VALID_CODE ); 01150 } 01151 } 01152 break; 01153 default: 01154 // Unexpected IRQ: silently returns 01155 break; 01156 } 01157 break; 01158 default: 01159 // Unexpected IRQ: silently returns 01160 break; 01161 } 01162 }
Generated on Thu Jul 21 2022 00:08:48 by
1.7.2
