Driver for the SX1276 RF Transceiver
Dependents: LoRa_PIR LoRaWAN-lmic-app SX1276PingPong LoRaWAN-lmic-app ... more
sx1276.cpp
00001 /* 00002 / _____) _ | | 00003 ( (____ _____ ____ _| |_ _____ ____| |__ 00004 \____ \| ___ | (_ _) ___ |/ ___) _ \ 00005 _____) ) ____| | | || |_| ____( (___| | | | 00006 (______/|_____)_|_|_| \__)_____)\____)_| |_| 00007 (C) 2014 Semtech 00008 00009 Description: Actual implementation of a SX1276 radio, inherits Radio 00010 00011 License: Revised BSD License, see LICENSE.TXT file include in the project 00012 00013 Maintainers: Miguel Luis, Gregory Cristian and Nicolas Huguenin 00014 */ 00015 #include "sx1276.h" 00016 00017 const FskBandwidth_t SX1276::FskBandwidths[] = 00018 { 00019 { 2600 , 0x17 }, 00020 { 3100 , 0x0F }, 00021 { 3900 , 0x07 }, 00022 { 5200 , 0x16 }, 00023 { 6300 , 0x0E }, 00024 { 7800 , 0x06 }, 00025 { 10400 , 0x15 }, 00026 { 12500 , 0x0D }, 00027 { 15600 , 0x05 }, 00028 { 20800 , 0x14 }, 00029 { 25000 , 0x0C }, 00030 { 31300 , 0x04 }, 00031 { 41700 , 0x13 }, 00032 { 50000 , 0x0B }, 00033 { 62500 , 0x03 }, 00034 { 83333 , 0x12 }, 00035 { 100000, 0x0A }, 00036 { 125000, 0x02 }, 00037 { 166700, 0x11 }, 00038 { 200000, 0x09 }, 00039 { 250000, 0x01 }, 00040 { 300000, 0x00 }, // Invalid Bandwidth 00041 }; 00042 00043 00044 SX1276::SX1276( RadioEvents_t *events, 00045 PinName mosi, PinName miso, PinName sclk, PinName nss, PinName reset, 00046 PinName dio0, PinName dio1, PinName dio2, PinName dio3, PinName dio4, PinName dio5 ) 00047 : Radio ( events ), 00048 spi( mosi, miso, sclk ), 00049 nss( nss ), 00050 reset( reset ), 00051 dio0( dio0 ), dio1( dio1 ), dio2( dio2 ), dio3( dio3 ), dio4( dio4 ), dio5( dio5 ), 00052 isRadioActive( false ) 00053 { 00054 wait_ms( 10 ); 00055 this->rxtxBuffer = new uint8_t[RX_BUFFER_SIZE]; 00056 00057 this->RadioEvents = events; 00058 00059 this->dioIrq = new DioIrqHandler[6]; 00060 00061 this->dioIrq [0] = &SX1276::OnDio0Irq; 00062 this->dioIrq [1] = &SX1276::OnDio1Irq; 00063 this->dioIrq [2] = &SX1276::OnDio2Irq; 00064 this->dioIrq [3] = &SX1276::OnDio3Irq; 00065 this->dioIrq [4] = &SX1276::OnDio4Irq; 00066 this->dioIrq [5] = NULL; 00067 00068 this->settings.State = RF_IDLE; 00069 } 00070 00071 SX1276::~SX1276( ) 00072 { 00073 delete this->rxtxBuffer; 00074 delete this->dioIrq ; 00075 } 00076 00077 void SX1276::Init( RadioEvents_t *events ) 00078 { 00079 this->RadioEvents = events; 00080 } 00081 00082 RadioState SX1276::GetStatus ( void ) 00083 { 00084 return this->settings.State; 00085 } 00086 00087 void SX1276::SetChannel( uint32_t freq ) 00088 { 00089 this->settings.Channel = freq; 00090 freq = ( uint32_t )( ( double )freq / ( double )FREQ_STEP ); 00091 Write( REG_FRFMSB, ( uint8_t )( ( freq >> 16 ) & 0xFF ) ); 00092 Write( REG_FRFMID, ( uint8_t )( ( freq >> 8 ) & 0xFF ) ); 00093 Write( REG_FRFLSB, ( uint8_t )( freq & 0xFF ) ); 00094 } 00095 00096 bool SX1276::IsChannelFree( RadioModems_t modem, uint32_t freq, int16_t rssiThresh ) 00097 { 00098 int16_t rssi = 0; 00099 00100 SetModem( modem ); 00101 00102 SetChannel( freq ); 00103 00104 SetOpMode( RF_OPMODE_RECEIVER ); 00105 00106 wait_ms( 1 ); 00107 00108 rssi = GetRssi( modem ); 00109 00110 Sleep( ); 00111 00112 if( rssi > rssiThresh ) 00113 { 00114 return false; 00115 } 00116 return true; 00117 } 00118 00119 uint32_t SX1276::Random( void ) 00120 { 00121 uint8_t i; 00122 uint32_t rnd = 0; 00123 00124 /* 00125 * Radio setup for random number generation 00126 */ 00127 // Set LoRa modem ON 00128 SetModem( MODEM_LORA ); 00129 00130 // Disable LoRa modem interrupts 00131 Write( REG_LR_IRQFLAGSMASK, RFLR_IRQFLAGS_RXTIMEOUT | 00132 RFLR_IRQFLAGS_RXDONE | 00133 RFLR_IRQFLAGS_PAYLOADCRCERROR | 00134 RFLR_IRQFLAGS_VALIDHEADER | 00135 RFLR_IRQFLAGS_TXDONE | 00136 RFLR_IRQFLAGS_CADDONE | 00137 RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL | 00138 RFLR_IRQFLAGS_CADDETECTED ); 00139 00140 // Set radio in continuous reception 00141 SetOpMode( RF_OPMODE_RECEIVER ); 00142 00143 for( i = 0; i < 32; i++ ) 00144 { 00145 wait_ms( 1 ); 00146 // Unfiltered RSSI value reading. Only takes the LSB value 00147 rnd |= ( ( uint32_t )Read( REG_LR_RSSIWIDEBAND ) & 0x01 ) << i; 00148 } 00149 00150 Sleep( ); 00151 00152 return rnd; 00153 } 00154 00155 /*! 00156 * Performs the Rx chain calibration for LF and HF bands 00157 * \remark Must be called just after the reset so all registers are at their 00158 * default values 00159 */ 00160 void SX1276::RxChainCalibration ( void ) 00161 { 00162 uint8_t regPaConfigInitVal; 00163 uint32_t initialFreq; 00164 00165 // Save context 00166 regPaConfigInitVal = this->Read( REG_PACONFIG ); 00167 initialFreq = ( double )( ( ( uint32_t )this->Read( REG_FRFMSB ) << 16 ) | 00168 ( ( uint32_t )this->Read( REG_FRFMID ) << 8 ) | 00169 ( ( uint32_t )this->Read( REG_FRFLSB ) ) ) * ( double )FREQ_STEP; 00170 00171 // Cut the PA just in case, RFO output, power = -1 dBm 00172 this->Write( REG_PACONFIG, 0x00 ); 00173 00174 // Launch Rx chain calibration for LF band 00175 Write ( REG_IMAGECAL, ( Read( REG_IMAGECAL ) & RF_IMAGECAL_IMAGECAL_MASK ) | RF_IMAGECAL_IMAGECAL_START ); 00176 while( ( Read( REG_IMAGECAL ) & RF_IMAGECAL_IMAGECAL_RUNNING ) == RF_IMAGECAL_IMAGECAL_RUNNING ) 00177 { 00178 } 00179 00180 // Sets a Frequency in HF band 00181 SetChannel( 868000000 ); 00182 00183 // Launch Rx chain calibration for HF band 00184 Write ( REG_IMAGECAL, ( Read( REG_IMAGECAL ) & RF_IMAGECAL_IMAGECAL_MASK ) | RF_IMAGECAL_IMAGECAL_START ); 00185 while( ( Read( REG_IMAGECAL ) & RF_IMAGECAL_IMAGECAL_RUNNING ) == RF_IMAGECAL_IMAGECAL_RUNNING ) 00186 { 00187 } 00188 00189 // Restore context 00190 this->Write( REG_PACONFIG, regPaConfigInitVal ); 00191 SetChannel( initialFreq ); 00192 } 00193 00194 /*! 00195 * Returns the known FSK bandwidth registers value 00196 * 00197 * \param [IN] bandwidth Bandwidth value in Hz 00198 * \retval regValue Bandwidth register value. 00199 */ 00200 uint8_t SX1276::GetFskBandwidthRegValue ( uint32_t bandwidth ) 00201 { 00202 uint8_t i; 00203 00204 for( i = 0; i < ( sizeof( FskBandwidths ) / sizeof( FskBandwidth_t ) ) - 1; i++ ) 00205 { 00206 if( ( bandwidth >= FskBandwidths[i].bandwidth ) && ( bandwidth < FskBandwidths[i + 1].bandwidth ) ) 00207 { 00208 return FskBandwidths[i].RegValue; 00209 } 00210 } 00211 // ERROR: Value not found 00212 while( 1 ); 00213 } 00214 00215 void SX1276::SetRxConfig( RadioModems_t modem, uint32_t bandwidth, 00216 uint32_t datarate, uint8_t coderate, 00217 uint32_t bandwidthAfc, uint16_t preambleLen, 00218 uint16_t symbTimeout, bool fixLen, 00219 uint8_t payloadLen, 00220 bool crcOn, bool freqHopOn, uint8_t hopPeriod, 00221 bool iqInverted, bool rxContinuous ) 00222 { 00223 SetModem( modem ); 00224 00225 switch( modem ) 00226 { 00227 case MODEM_FSK: 00228 { 00229 this->settings.Fsk.Bandwidth = bandwidth; 00230 this->settings.Fsk.Datarate = datarate; 00231 this->settings.Fsk.BandwidthAfc = bandwidthAfc; 00232 this->settings.Fsk.FixLen = fixLen; 00233 this->settings.Fsk.PayloadLen = payloadLen; 00234 this->settings.Fsk.CrcOn = crcOn; 00235 this->settings.Fsk.IqInverted = iqInverted; 00236 this->settings.Fsk.RxContinuous = rxContinuous; 00237 this->settings.Fsk.PreambleLen = preambleLen; 00238 this->settings.Fsk.RxSingleTimeout = symbTimeout * ( ( 1.0 / ( double )datarate ) * 8.0 ) * 1e3; 00239 00240 datarate = ( uint16_t )( ( double )XTAL_FREQ / ( double )datarate ); 00241 Write( REG_BITRATEMSB, ( uint8_t )( datarate >> 8 ) ); 00242 Write( REG_BITRATELSB, ( uint8_t )( datarate & 0xFF ) ); 00243 00244 Write( REG_RXBW, GetFskBandwidthRegValue ( bandwidth ) ); 00245 Write( REG_AFCBW, GetFskBandwidthRegValue ( bandwidthAfc ) ); 00246 00247 Write( REG_PREAMBLEMSB, ( uint8_t )( ( preambleLen >> 8 ) & 0xFF ) ); 00248 Write( REG_PREAMBLELSB, ( uint8_t )( preambleLen & 0xFF ) ); 00249 00250 if( fixLen == 1 ) 00251 { 00252 Write( REG_PAYLOADLENGTH, payloadLen ); 00253 } 00254 else 00255 { 00256 Write( REG_PAYLOADLENGTH, 0xFF ); // Set payload length to the maximum 00257 } 00258 00259 Write( REG_PACKETCONFIG1, 00260 ( Read( REG_PACKETCONFIG1 ) & 00261 RF_PACKETCONFIG1_CRC_MASK & 00262 RF_PACKETCONFIG1_PACKETFORMAT_MASK ) | 00263 ( ( fixLen == 1 ) ? RF_PACKETCONFIG1_PACKETFORMAT_FIXED : RF_PACKETCONFIG1_PACKETFORMAT_VARIABLE ) | 00264 ( crcOn << 4 ) ); 00265 Write( REG_PACKETCONFIG2, ( Read( REG_PACKETCONFIG2 ) | RF_PACKETCONFIG2_DATAMODE_PACKET ) ); 00266 } 00267 break; 00268 case MODEM_LORA: 00269 { 00270 if( bandwidth > 2 ) 00271 { 00272 // Fatal error: When using LoRa modem only bandwidths 125, 250 and 500 kHz are supported 00273 while( 1 ); 00274 } 00275 bandwidth += 7; 00276 this->settings.LoRa.Bandwidth = bandwidth; 00277 this->settings.LoRa.Datarate = datarate; 00278 this->settings.LoRa.Coderate = coderate; 00279 this->settings.LoRa.PreambleLen = preambleLen; 00280 this->settings.LoRa.FixLen = fixLen; 00281 this->settings.LoRa.PayloadLen = payloadLen; 00282 this->settings.LoRa.CrcOn = crcOn; 00283 this->settings.LoRa.FreqHopOn = freqHopOn; 00284 this->settings.LoRa.HopPeriod = hopPeriod; 00285 this->settings.LoRa.IqInverted = iqInverted; 00286 this->settings.LoRa.RxContinuous = rxContinuous; 00287 00288 if( datarate > 12 ) 00289 { 00290 datarate = 12; 00291 } 00292 else if( datarate < 6 ) 00293 { 00294 datarate = 6; 00295 } 00296 00297 if( ( ( bandwidth == 7 ) && ( ( datarate == 11 ) || ( datarate == 12 ) ) ) || 00298 ( ( bandwidth == 8 ) && ( datarate == 12 ) ) ) 00299 { 00300 this->settings.LoRa.LowDatarateOptimize = 0x01; 00301 } 00302 else 00303 { 00304 this->settings.LoRa.LowDatarateOptimize = 0x00; 00305 } 00306 00307 Write( REG_LR_MODEMCONFIG1, 00308 ( Read( REG_LR_MODEMCONFIG1 ) & 00309 RFLR_MODEMCONFIG1_BW_MASK & 00310 RFLR_MODEMCONFIG1_CODINGRATE_MASK & 00311 RFLR_MODEMCONFIG1_IMPLICITHEADER_MASK ) | 00312 ( bandwidth << 4 ) | ( coderate << 1 ) | 00313 fixLen ); 00314 00315 Write( REG_LR_MODEMCONFIG2, 00316 ( Read( REG_LR_MODEMCONFIG2 ) & 00317 RFLR_MODEMCONFIG2_SF_MASK & 00318 RFLR_MODEMCONFIG2_RXPAYLOADCRC_MASK & 00319 RFLR_MODEMCONFIG2_SYMBTIMEOUTMSB_MASK ) | 00320 ( datarate << 4 ) | ( crcOn << 2 ) | 00321 ( ( symbTimeout >> 8 ) & ~RFLR_MODEMCONFIG2_SYMBTIMEOUTMSB_MASK ) ); 00322 00323 Write( REG_LR_MODEMCONFIG3, 00324 ( Read( REG_LR_MODEMCONFIG3 ) & 00325 RFLR_MODEMCONFIG3_LOWDATARATEOPTIMIZE_MASK ) | 00326 ( this->settings.LoRa.LowDatarateOptimize << 3 ) ); 00327 00328 Write( REG_LR_SYMBTIMEOUTLSB, ( uint8_t )( symbTimeout & 0xFF ) ); 00329 00330 Write( REG_LR_PREAMBLEMSB, ( uint8_t )( ( preambleLen >> 8 ) & 0xFF ) ); 00331 Write( REG_LR_PREAMBLELSB, ( uint8_t )( preambleLen & 0xFF ) ); 00332 00333 if( fixLen == 1 ) 00334 { 00335 Write( REG_LR_PAYLOADLENGTH, payloadLen ); 00336 } 00337 00338 if( this->settings.LoRa.FreqHopOn == true ) 00339 { 00340 Write( REG_LR_PLLHOP, ( Read( REG_LR_PLLHOP ) & RFLR_PLLHOP_FASTHOP_MASK ) | RFLR_PLLHOP_FASTHOP_ON ); 00341 Write( REG_LR_HOPPERIOD, this->settings.LoRa.HopPeriod ); 00342 } 00343 00344 if( ( bandwidth == 9 ) && ( this->settings.Channel > RF_MID_BAND_THRESH ) ) 00345 { 00346 // ERRATA 2.1 - Sensitivity Optimization with a 500 kHz Bandwidth 00347 Write( REG_LR_TEST36, 0x02 ); 00348 Write( REG_LR_TEST3A, 0x64 ); 00349 } 00350 else if( bandwidth == 9 ) 00351 { 00352 // ERRATA 2.1 - Sensitivity Optimization with a 500 kHz Bandwidth 00353 Write( REG_LR_TEST36, 0x02 ); 00354 Write( REG_LR_TEST3A, 0x7F ); 00355 } 00356 else 00357 { 00358 // ERRATA 2.1 - Sensitivity Optimization with a 500 kHz Bandwidth 00359 Write( REG_LR_TEST36, 0x03 ); 00360 } 00361 00362 if( datarate == 6 ) 00363 { 00364 Write( REG_LR_DETECTOPTIMIZE, 00365 ( Read( REG_LR_DETECTOPTIMIZE ) & 00366 RFLR_DETECTIONOPTIMIZE_MASK ) | 00367 RFLR_DETECTIONOPTIMIZE_SF6 ); 00368 Write( REG_LR_DETECTIONTHRESHOLD, 00369 RFLR_DETECTIONTHRESH_SF6 ); 00370 } 00371 else 00372 { 00373 Write( REG_LR_DETECTOPTIMIZE, 00374 ( Read( REG_LR_DETECTOPTIMIZE ) & 00375 RFLR_DETECTIONOPTIMIZE_MASK ) | 00376 RFLR_DETECTIONOPTIMIZE_SF7_TO_SF12 ); 00377 Write( REG_LR_DETECTIONTHRESHOLD, 00378 RFLR_DETECTIONTHRESH_SF7_TO_SF12 ); 00379 } 00380 } 00381 break; 00382 } 00383 } 00384 00385 void SX1276::SetTxConfig( RadioModems_t modem, int8_t power, uint32_t fdev, 00386 uint32_t bandwidth, uint32_t datarate, 00387 uint8_t coderate, uint16_t preambleLen, 00388 bool fixLen, bool crcOn, bool freqHopOn, 00389 uint8_t hopPeriod, bool iqInverted, uint32_t timeout ) 00390 { 00391 SetModem( modem ); 00392 00393 SetRfTxPower( power ); 00394 00395 switch( modem ) 00396 { 00397 case MODEM_FSK: 00398 { 00399 this->settings.Fsk.Power = power; 00400 this->settings.Fsk.Fdev = fdev; 00401 this->settings.Fsk.Bandwidth = bandwidth; 00402 this->settings.Fsk.Datarate = datarate; 00403 this->settings.Fsk.PreambleLen = preambleLen; 00404 this->settings.Fsk.FixLen = fixLen; 00405 this->settings.Fsk.CrcOn = crcOn; 00406 this->settings.Fsk.IqInverted = iqInverted; 00407 this->settings.Fsk.TxTimeout = timeout; 00408 00409 fdev = ( uint16_t )( ( double )fdev / ( double )FREQ_STEP ); 00410 Write( REG_FDEVMSB, ( uint8_t )( fdev >> 8 ) ); 00411 Write( REG_FDEVLSB, ( uint8_t )( fdev & 0xFF ) ); 00412 00413 datarate = ( uint16_t )( ( double )XTAL_FREQ / ( double )datarate ); 00414 Write( REG_BITRATEMSB, ( uint8_t )( datarate >> 8 ) ); 00415 Write( REG_BITRATELSB, ( uint8_t )( datarate & 0xFF ) ); 00416 00417 Write( REG_PREAMBLEMSB, ( preambleLen >> 8 ) & 0x00FF ); 00418 Write( REG_PREAMBLELSB, preambleLen & 0xFF ); 00419 00420 Write( REG_PACKETCONFIG1, 00421 ( Read( REG_PACKETCONFIG1 ) & 00422 RF_PACKETCONFIG1_CRC_MASK & 00423 RF_PACKETCONFIG1_PACKETFORMAT_MASK ) | 00424 ( ( fixLen == 1 ) ? RF_PACKETCONFIG1_PACKETFORMAT_FIXED : RF_PACKETCONFIG1_PACKETFORMAT_VARIABLE ) | 00425 ( crcOn << 4 ) ); 00426 Write( REG_PACKETCONFIG2, ( Read( REG_PACKETCONFIG2 ) | RF_PACKETCONFIG2_DATAMODE_PACKET ) ); 00427 } 00428 break; 00429 case MODEM_LORA: 00430 { 00431 this->settings.LoRa.Power = power; 00432 if( bandwidth > 2 ) 00433 { 00434 // Fatal error: When using LoRa modem only bandwidths 125, 250 and 500 kHz are supported 00435 while( 1 ); 00436 } 00437 bandwidth += 7; 00438 this->settings.LoRa.Bandwidth = bandwidth; 00439 this->settings.LoRa.Datarate = datarate; 00440 this->settings.LoRa.Coderate = coderate; 00441 this->settings.LoRa.PreambleLen = preambleLen; 00442 this->settings.LoRa.FixLen = fixLen; 00443 this->settings.LoRa.FreqHopOn = freqHopOn; 00444 this->settings.LoRa.HopPeriod = hopPeriod; 00445 this->settings.LoRa.CrcOn = crcOn; 00446 this->settings.LoRa.IqInverted = iqInverted; 00447 this->settings.LoRa.TxTimeout = timeout; 00448 00449 if( datarate > 12 ) 00450 { 00451 datarate = 12; 00452 } 00453 else if( datarate < 6 ) 00454 { 00455 datarate = 6; 00456 } 00457 if( ( ( bandwidth == 7 ) && ( ( datarate == 11 ) || ( datarate == 12 ) ) ) || 00458 ( ( bandwidth == 8 ) && ( datarate == 12 ) ) ) 00459 { 00460 this->settings.LoRa.LowDatarateOptimize = 0x01; 00461 } 00462 else 00463 { 00464 this->settings.LoRa.LowDatarateOptimize = 0x00; 00465 } 00466 00467 if( this->settings.LoRa.FreqHopOn == true ) 00468 { 00469 Write( REG_LR_PLLHOP, ( Read( REG_LR_PLLHOP ) & RFLR_PLLHOP_FASTHOP_MASK ) | RFLR_PLLHOP_FASTHOP_ON ); 00470 Write( REG_LR_HOPPERIOD, this->settings.LoRa.HopPeriod ); 00471 } 00472 00473 Write( REG_LR_MODEMCONFIG1, 00474 ( Read( REG_LR_MODEMCONFIG1 ) & 00475 RFLR_MODEMCONFIG1_BW_MASK & 00476 RFLR_MODEMCONFIG1_CODINGRATE_MASK & 00477 RFLR_MODEMCONFIG1_IMPLICITHEADER_MASK ) | 00478 ( bandwidth << 4 ) | ( coderate << 1 ) | 00479 fixLen ); 00480 00481 Write( REG_LR_MODEMCONFIG2, 00482 ( Read( REG_LR_MODEMCONFIG2 ) & 00483 RFLR_MODEMCONFIG2_SF_MASK & 00484 RFLR_MODEMCONFIG2_RXPAYLOADCRC_MASK ) | 00485 ( datarate << 4 ) | ( crcOn << 2 ) ); 00486 00487 Write( REG_LR_MODEMCONFIG3, 00488 ( Read( REG_LR_MODEMCONFIG3 ) & 00489 RFLR_MODEMCONFIG3_LOWDATARATEOPTIMIZE_MASK ) | 00490 ( this->settings.LoRa.LowDatarateOptimize << 3 ) ); 00491 00492 Write( REG_LR_PREAMBLEMSB, ( preambleLen >> 8 ) & 0x00FF ); 00493 Write( REG_LR_PREAMBLELSB, preambleLen & 0xFF ); 00494 00495 if( datarate == 6 ) 00496 { 00497 Write( REG_LR_DETECTOPTIMIZE, 00498 ( Read( REG_LR_DETECTOPTIMIZE ) & 00499 RFLR_DETECTIONOPTIMIZE_MASK ) | 00500 RFLR_DETECTIONOPTIMIZE_SF6 ); 00501 Write( REG_LR_DETECTIONTHRESHOLD, 00502 RFLR_DETECTIONTHRESH_SF6 ); 00503 } 00504 else 00505 { 00506 Write( REG_LR_DETECTOPTIMIZE, 00507 ( Read( REG_LR_DETECTOPTIMIZE ) & 00508 RFLR_DETECTIONOPTIMIZE_MASK ) | 00509 RFLR_DETECTIONOPTIMIZE_SF7_TO_SF12 ); 00510 Write( REG_LR_DETECTIONTHRESHOLD, 00511 RFLR_DETECTIONTHRESH_SF7_TO_SF12 ); 00512 } 00513 } 00514 break; 00515 } 00516 } 00517 00518 uint32_t SX1276::TimeOnAir( RadioModems_t modem, uint8_t pktLen ) 00519 { 00520 uint32_t airTime = 0; 00521 00522 switch( modem ) 00523 { 00524 case MODEM_FSK: 00525 { 00526 airTime = rint( ( 8 * ( this->settings.Fsk.PreambleLen + 00527 ( ( Read( REG_SYNCCONFIG ) & ~RF_SYNCCONFIG_SYNCSIZE_MASK ) + 1 ) + 00528 ( ( this->settings.Fsk.FixLen == 0x01 ) ? 0.0 : 1.0 ) + 00529 ( ( ( Read( REG_PACKETCONFIG1 ) & ~RF_PACKETCONFIG1_ADDRSFILTERING_MASK ) != 0x00 ) ? 1.0 : 0 ) + 00530 pktLen + 00531 ( ( this->settings.Fsk.CrcOn == 0x01 ) ? 2.0 : 0 ) ) / 00532 this->settings.Fsk.Datarate ) * 1e3 ); 00533 } 00534 break; 00535 case MODEM_LORA: 00536 { 00537 double bw = 0.0; 00538 // REMARK: When using LoRa modem only bandwidths 125, 250 and 500 kHz are supported 00539 switch( this->settings.LoRa.Bandwidth ) 00540 { 00541 //case 0: // 7.8 kHz 00542 // bw = 78e2; 00543 // break; 00544 //case 1: // 10.4 kHz 00545 // bw = 104e2; 00546 // break; 00547 //case 2: // 15.6 kHz 00548 // bw = 156e2; 00549 // break; 00550 //case 3: // 20.8 kHz 00551 // bw = 208e2; 00552 // break; 00553 //case 4: // 31.2 kHz 00554 // bw = 312e2; 00555 // break; 00556 //case 5: // 41.4 kHz 00557 // bw = 414e2; 00558 // break; 00559 //case 6: // 62.5 kHz 00560 // bw = 625e2; 00561 // break; 00562 case 7: // 125 kHz 00563 bw = 125e3; 00564 break; 00565 case 8: // 250 kHz 00566 bw = 250e3; 00567 break; 00568 case 9: // 500 kHz 00569 bw = 500e3; 00570 break; 00571 } 00572 00573 // Symbol rate : time for one symbol (secs) 00574 double rs = bw / ( 1 << this->settings.LoRa.Datarate ); 00575 double ts = 1 / rs; 00576 // time of preamble 00577 double tPreamble = ( this->settings.LoRa.PreambleLen + 4.25 ) * ts; 00578 // Symbol length of payload and time 00579 double tmp = ceil( ( 8 * pktLen - 4 * this->settings.LoRa.Datarate + 00580 28 + 16 * this->settings.LoRa.CrcOn - 00581 ( this->settings.LoRa.FixLen ? 20 : 0 ) ) / 00582 ( double )( 4 * ( this->settings.LoRa.Datarate - 00583 ( ( this->settings.LoRa.LowDatarateOptimize > 0 ) ? 2 : 0 ) ) ) ) * 00584 ( this->settings.LoRa.Coderate + 4 ); 00585 double nPayload = 8 + ( ( tmp > 0 ) ? tmp : 0 ); 00586 double tPayload = nPayload * ts; 00587 // Time on air 00588 double tOnAir = tPreamble + tPayload; 00589 // return ms secs 00590 airTime = floor( tOnAir * 1e3 + 0.999 ); 00591 } 00592 break; 00593 } 00594 return airTime; 00595 } 00596 00597 void SX1276::Send( uint8_t *buffer, uint8_t size ) 00598 { 00599 uint32_t txTimeout = 0; 00600 00601 switch( this->settings.Modem ) 00602 { 00603 case MODEM_FSK: 00604 { 00605 this->settings.FskPacketHandler.NbBytes = 0; 00606 this->settings.FskPacketHandler.Size = size; 00607 00608 if( this->settings.Fsk.FixLen == false ) 00609 { 00610 WriteFifo( ( uint8_t* )&size, 1 ); 00611 } 00612 else 00613 { 00614 Write( REG_PAYLOADLENGTH, size ); 00615 } 00616 00617 if( ( size > 0 ) && ( size <= 64 ) ) 00618 { 00619 this->settings.FskPacketHandler.ChunkSize = size; 00620 } 00621 else 00622 { 00623 memcpy( rxtxBuffer, buffer, size ); 00624 this->settings.FskPacketHandler.ChunkSize = 32; 00625 } 00626 00627 // Write payload buffer 00628 WriteFifo( buffer, this->settings.FskPacketHandler.ChunkSize ); 00629 this->settings.FskPacketHandler.NbBytes += this->settings.FskPacketHandler.ChunkSize; 00630 txTimeout = this->settings.Fsk.TxTimeout; 00631 } 00632 break; 00633 case MODEM_LORA: 00634 { 00635 if( this->settings.LoRa.IqInverted == true ) 00636 { 00637 Write( REG_LR_INVERTIQ, ( ( Read( REG_LR_INVERTIQ ) & RFLR_INVERTIQ_TX_MASK & RFLR_INVERTIQ_RX_MASK ) | RFLR_INVERTIQ_RX_OFF | RFLR_INVERTIQ_TX_ON ) ); 00638 Write( REG_LR_INVERTIQ2, RFLR_INVERTIQ2_ON ); 00639 } 00640 else 00641 { 00642 Write( REG_LR_INVERTIQ, ( ( Read( REG_LR_INVERTIQ ) & RFLR_INVERTIQ_TX_MASK & RFLR_INVERTIQ_RX_MASK ) | RFLR_INVERTIQ_RX_OFF | RFLR_INVERTIQ_TX_OFF ) ); 00643 Write( REG_LR_INVERTIQ2, RFLR_INVERTIQ2_OFF ); 00644 } 00645 00646 this->settings.LoRaPacketHandler.Size = size; 00647 00648 // Initializes the payload size 00649 Write( REG_LR_PAYLOADLENGTH, size ); 00650 00651 // Full buffer used for Tx 00652 Write( REG_LR_FIFOTXBASEADDR, 0 ); 00653 Write( REG_LR_FIFOADDRPTR, 0 ); 00654 00655 // FIFO operations can not take place in Sleep mode 00656 if( ( Read( REG_OPMODE ) & ~RF_OPMODE_MASK ) == RF_OPMODE_SLEEP ) 00657 { 00658 Standby( ); 00659 wait_ms( 1 ); 00660 } 00661 // Write payload buffer 00662 WriteFifo( buffer, size ); 00663 txTimeout = this->settings.LoRa.TxTimeout; 00664 } 00665 break; 00666 } 00667 00668 Tx( txTimeout ); 00669 } 00670 00671 void SX1276::Sleep( void ) 00672 { 00673 txTimeoutTimer .detach( ); 00674 rxTimeoutTimer.detach( ); 00675 00676 SetOpMode( RF_OPMODE_SLEEP ); 00677 this->settings.State = RF_IDLE; 00678 } 00679 00680 void SX1276::Standby( void ) 00681 { 00682 txTimeoutTimer .detach( ); 00683 rxTimeoutTimer.detach( ); 00684 00685 SetOpMode( RF_OPMODE_STANDBY ); 00686 this->settings.State = RF_IDLE; 00687 } 00688 00689 void SX1276::Rx( uint32_t timeout ) 00690 { 00691 bool rxContinuous = false; 00692 00693 switch( this->settings.Modem ) 00694 { 00695 case MODEM_FSK: 00696 { 00697 rxContinuous = this->settings.Fsk.RxContinuous; 00698 00699 // DIO0=PayloadReady 00700 // DIO1=FifoLevel 00701 // DIO2=SyncAddr 00702 // DIO3=FifoEmpty 00703 // DIO4=Preamble 00704 // DIO5=ModeReady 00705 Write( REG_DIOMAPPING1, ( Read( REG_DIOMAPPING1 ) & RF_DIOMAPPING1_DIO0_MASK & 00706 RF_DIOMAPPING1_DIO1_MASK & 00707 RF_DIOMAPPING1_DIO2_MASK ) | 00708 RF_DIOMAPPING1_DIO0_00 | 00709 RF_DIOMAPPING1_DIO1_00 | 00710 RF_DIOMAPPING1_DIO2_11 ); 00711 00712 Write( REG_DIOMAPPING2, ( Read( REG_DIOMAPPING2 ) & RF_DIOMAPPING2_DIO4_MASK & 00713 RF_DIOMAPPING2_MAP_MASK ) | 00714 RF_DIOMAPPING2_DIO4_11 | 00715 RF_DIOMAPPING2_MAP_PREAMBLEDETECT ); 00716 00717 this->settings.FskPacketHandler.FifoThresh = Read( REG_FIFOTHRESH ) & 0x3F; 00718 00719 Write( REG_RXCONFIG, RF_RXCONFIG_AFCAUTO_ON | RF_RXCONFIG_AGCAUTO_ON | RF_RXCONFIG_RXTRIGER_PREAMBLEDETECT ); 00720 00721 this->settings.FskPacketHandler.PreambleDetected = false; 00722 this->settings.FskPacketHandler.SyncWordDetected = false; 00723 this->settings.FskPacketHandler.NbBytes = 0; 00724 this->settings.FskPacketHandler.Size = 0; 00725 } 00726 break; 00727 case MODEM_LORA: 00728 { 00729 if( this->settings.LoRa.IqInverted == true ) 00730 { 00731 Write( REG_LR_INVERTIQ, ( ( Read( REG_LR_INVERTIQ ) & RFLR_INVERTIQ_TX_MASK & RFLR_INVERTIQ_RX_MASK ) | RFLR_INVERTIQ_RX_ON | RFLR_INVERTIQ_TX_OFF ) ); 00732 Write( REG_LR_INVERTIQ2, RFLR_INVERTIQ2_ON ); 00733 } 00734 else 00735 { 00736 Write( REG_LR_INVERTIQ, ( ( Read( REG_LR_INVERTIQ ) & RFLR_INVERTIQ_TX_MASK & RFLR_INVERTIQ_RX_MASK ) | RFLR_INVERTIQ_RX_OFF | RFLR_INVERTIQ_TX_OFF ) ); 00737 Write( REG_LR_INVERTIQ2, RFLR_INVERTIQ2_OFF ); 00738 } 00739 00740 // ERRATA 2.3 - Receiver Spurious Reception of a LoRa Signal 00741 if( this->settings.LoRa.Bandwidth < 9 ) 00742 { 00743 Write( REG_LR_DETECTOPTIMIZE, Read( REG_LR_DETECTOPTIMIZE ) & 0x7F ); 00744 Write( REG_LR_TEST30, 0x00 ); 00745 switch( this->settings.LoRa.Bandwidth ) 00746 { 00747 case 0: // 7.8 kHz 00748 Write( REG_LR_TEST2F, 0x48 ); 00749 SetChannel(this->settings.Channel + 7.81e3 ); 00750 break; 00751 case 1: // 10.4 kHz 00752 Write( REG_LR_TEST2F, 0x44 ); 00753 SetChannel(this->settings.Channel + 10.42e3 ); 00754 break; 00755 case 2: // 15.6 kHz 00756 Write( REG_LR_TEST2F, 0x44 ); 00757 SetChannel(this->settings.Channel + 15.62e3 ); 00758 break; 00759 case 3: // 20.8 kHz 00760 Write( REG_LR_TEST2F, 0x44 ); 00761 SetChannel(this->settings.Channel + 20.83e3 ); 00762 break; 00763 case 4: // 31.2 kHz 00764 Write( REG_LR_TEST2F, 0x44 ); 00765 SetChannel(this->settings.Channel + 31.25e3 ); 00766 break; 00767 case 5: // 41.4 kHz 00768 Write( REG_LR_TEST2F, 0x44 ); 00769 SetChannel(this->settings.Channel + 41.67e3 ); 00770 break; 00771 case 6: // 62.5 kHz 00772 Write( REG_LR_TEST2F, 0x40 ); 00773 break; 00774 case 7: // 125 kHz 00775 Write( REG_LR_TEST2F, 0x40 ); 00776 break; 00777 case 8: // 250 kHz 00778 Write( REG_LR_TEST2F, 0x40 ); 00779 break; 00780 } 00781 } 00782 else 00783 { 00784 Write( REG_LR_DETECTOPTIMIZE, Read( REG_LR_DETECTOPTIMIZE ) | 0x80 ); 00785 } 00786 00787 rxContinuous = this->settings.LoRa.RxContinuous; 00788 00789 if( this->settings.LoRa.FreqHopOn == true ) 00790 { 00791 Write( REG_LR_IRQFLAGSMASK, //RFLR_IRQFLAGS_RXTIMEOUT | 00792 //RFLR_IRQFLAGS_RXDONE | 00793 //RFLR_IRQFLAGS_PAYLOADCRCERROR | 00794 RFLR_IRQFLAGS_VALIDHEADER | 00795 RFLR_IRQFLAGS_TXDONE | 00796 RFLR_IRQFLAGS_CADDONE | 00797 //RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL | 00798 RFLR_IRQFLAGS_CADDETECTED ); 00799 00800 // DIO0=RxDone, DIO2=FhssChangeChannel 00801 Write( REG_DIOMAPPING1, ( Read( REG_DIOMAPPING1 ) & RFLR_DIOMAPPING1_DIO0_MASK & RFLR_DIOMAPPING1_DIO2_MASK ) | RFLR_DIOMAPPING1_DIO0_00 | RFLR_DIOMAPPING1_DIO2_00 ); 00802 } 00803 else 00804 { 00805 Write( REG_LR_IRQFLAGSMASK, //RFLR_IRQFLAGS_RXTIMEOUT | 00806 //RFLR_IRQFLAGS_RXDONE | 00807 //RFLR_IRQFLAGS_PAYLOADCRCERROR | 00808 RFLR_IRQFLAGS_VALIDHEADER | 00809 RFLR_IRQFLAGS_TXDONE | 00810 RFLR_IRQFLAGS_CADDONE | 00811 RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL | 00812 RFLR_IRQFLAGS_CADDETECTED ); 00813 00814 // DIO0=RxDone 00815 Write( REG_DIOMAPPING1, ( Read( REG_DIOMAPPING1 ) & RFLR_DIOMAPPING1_DIO0_MASK ) | RFLR_DIOMAPPING1_DIO0_00 ); 00816 } 00817 Write( REG_LR_FIFORXBASEADDR, 0 ); 00818 Write( REG_LR_FIFOADDRPTR, 0 ); 00819 } 00820 break; 00821 } 00822 00823 memset( rxtxBuffer, 0, ( size_t )RX_BUFFER_SIZE ); 00824 00825 this->settings.State = RF_RX_RUNNING; 00826 if( timeout != 0 ) 00827 { 00828 rxTimeoutTimer.attach_us( mbed::callback( this, &SX1276::OnTimeoutIrq ), timeout * 1e3 ); 00829 } 00830 00831 if( this->settings.Modem == MODEM_FSK ) 00832 { 00833 SetOpMode( RF_OPMODE_RECEIVER ); 00834 00835 if( rxContinuous == false ) 00836 { 00837 rxTimeoutSyncWord.attach_us( mbed::callback( this, &SX1276::OnTimeoutIrq ), 00838 this->settings.Fsk.RxSingleTimeout * 1e3 ); 00839 } 00840 } 00841 else 00842 { 00843 if( rxContinuous == true ) 00844 { 00845 SetOpMode( RFLR_OPMODE_RECEIVER ); 00846 } 00847 else 00848 { 00849 SetOpMode( RFLR_OPMODE_RECEIVER_SINGLE ); 00850 } 00851 } 00852 } 00853 00854 void SX1276::Tx( uint32_t timeout ) 00855 { 00856 00857 switch( this->settings.Modem ) 00858 { 00859 case MODEM_FSK: 00860 { 00861 // DIO0=PacketSent 00862 // DIO1=FifoEmpty 00863 // DIO2=FifoFull 00864 // DIO3=FifoEmpty 00865 // DIO4=LowBat 00866 // DIO5=ModeReady 00867 Write( REG_DIOMAPPING1, ( Read( REG_DIOMAPPING1 ) & RF_DIOMAPPING1_DIO0_MASK & 00868 RF_DIOMAPPING1_DIO1_MASK & 00869 RF_DIOMAPPING1_DIO2_MASK ) | 00870 RF_DIOMAPPING1_DIO1_01 ); 00871 00872 Write( REG_DIOMAPPING2, ( Read( REG_DIOMAPPING2 ) & RF_DIOMAPPING2_DIO4_MASK & 00873 RF_DIOMAPPING2_MAP_MASK ) ); 00874 this->settings.FskPacketHandler.FifoThresh = Read( REG_FIFOTHRESH ) & 0x3F; 00875 } 00876 break; 00877 case MODEM_LORA: 00878 { 00879 if( this->settings.LoRa.FreqHopOn == true ) 00880 { 00881 Write( REG_LR_IRQFLAGSMASK, RFLR_IRQFLAGS_RXTIMEOUT | 00882 RFLR_IRQFLAGS_RXDONE | 00883 RFLR_IRQFLAGS_PAYLOADCRCERROR | 00884 RFLR_IRQFLAGS_VALIDHEADER | 00885 //RFLR_IRQFLAGS_TXDONE | 00886 RFLR_IRQFLAGS_CADDONE | 00887 //RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL | 00888 RFLR_IRQFLAGS_CADDETECTED ); 00889 00890 // DIO0=TxDone, DIO2=FhssChangeChannel 00891 Write( REG_DIOMAPPING1, ( Read( REG_DIOMAPPING1 ) & RFLR_DIOMAPPING1_DIO0_MASK & RFLR_DIOMAPPING1_DIO2_MASK ) | RFLR_DIOMAPPING1_DIO0_01 | RFLR_DIOMAPPING1_DIO2_00 ); 00892 } 00893 else 00894 { 00895 Write( REG_LR_IRQFLAGSMASK, RFLR_IRQFLAGS_RXTIMEOUT | 00896 RFLR_IRQFLAGS_RXDONE | 00897 RFLR_IRQFLAGS_PAYLOADCRCERROR | 00898 RFLR_IRQFLAGS_VALIDHEADER | 00899 //RFLR_IRQFLAGS_TXDONE | 00900 RFLR_IRQFLAGS_CADDONE | 00901 RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL | 00902 RFLR_IRQFLAGS_CADDETECTED ); 00903 00904 // DIO0=TxDone 00905 Write( REG_DIOMAPPING1, ( Read( REG_DIOMAPPING1 ) & RFLR_DIOMAPPING1_DIO0_MASK ) | RFLR_DIOMAPPING1_DIO0_01 ); 00906 } 00907 } 00908 break; 00909 } 00910 00911 this->settings.State = RF_TX_RUNNING; 00912 txTimeoutTimer .attach_us( mbed::callback( this, &SX1276::OnTimeoutIrq ), timeout * 1e3 ); 00913 SetOpMode( RF_OPMODE_TRANSMITTER ); 00914 } 00915 00916 void SX1276::StartCad( void ) 00917 { 00918 switch( this->settings.Modem ) 00919 { 00920 case MODEM_FSK: 00921 { 00922 00923 } 00924 break; 00925 case MODEM_LORA: 00926 { 00927 Write( REG_LR_IRQFLAGSMASK, RFLR_IRQFLAGS_RXTIMEOUT | 00928 RFLR_IRQFLAGS_RXDONE | 00929 RFLR_IRQFLAGS_PAYLOADCRCERROR | 00930 RFLR_IRQFLAGS_VALIDHEADER | 00931 RFLR_IRQFLAGS_TXDONE | 00932 //RFLR_IRQFLAGS_CADDONE | 00933 RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL // | 00934 //RFLR_IRQFLAGS_CADDETECTED 00935 ); 00936 00937 // DIO3=CADDone 00938 Write( REG_DIOMAPPING1, ( Read( REG_DIOMAPPING1 ) & RFLR_DIOMAPPING1_DIO3_MASK ) | RFLR_DIOMAPPING1_DIO3_00 ); 00939 00940 this->settings.State = RF_CAD; 00941 SetOpMode( RFLR_OPMODE_CAD ); 00942 } 00943 break; 00944 default: 00945 break; 00946 } 00947 } 00948 00949 void SX1276::SetTxContinuousWave( uint32_t freq, int8_t power, uint16_t time ) 00950 { 00951 uint32_t timeout = ( uint32_t )( time * 1e6 ); 00952 00953 SetChannel( freq ); 00954 00955 SetTxConfig( MODEM_FSK, power, 0, 0, 4800, 0, 5, false, false, 0, 0, 0, timeout ); 00956 00957 Write( REG_PACKETCONFIG2, ( Read( REG_PACKETCONFIG2 ) & RF_PACKETCONFIG2_DATAMODE_MASK ) ); 00958 // Disable radio interrupts 00959 Write( REG_DIOMAPPING1, RF_DIOMAPPING1_DIO0_11 | RF_DIOMAPPING1_DIO1_11 ); 00960 Write( REG_DIOMAPPING2, RF_DIOMAPPING2_DIO4_10 | RF_DIOMAPPING2_DIO5_10 ); 00961 00962 this->settings.State = RF_TX_RUNNING; 00963 txTimeoutTimer .attach_us( mbed::callback( this, &SX1276::OnTimeoutIrq ), timeout ); 00964 SetOpMode( RF_OPMODE_TRANSMITTER ); 00965 } 00966 00967 int16_t SX1276::GetRssi( RadioModems_t modem ) 00968 { 00969 int16_t rssi = 0; 00970 00971 switch( modem ) 00972 { 00973 case MODEM_FSK: 00974 rssi = -( Read( REG_RSSIVALUE ) >> 1 ); 00975 break; 00976 case MODEM_LORA: 00977 if( this->settings.Channel > RF_MID_BAND_THRESH ) 00978 { 00979 rssi = RSSI_OFFSET_HF + Read( REG_LR_RSSIVALUE ); 00980 } 00981 else 00982 { 00983 rssi = RSSI_OFFSET_LF + Read( REG_LR_RSSIVALUE ); 00984 } 00985 break; 00986 default: 00987 rssi = -1; 00988 break; 00989 } 00990 return rssi; 00991 } 00992 00993 void SX1276::SetOpMode( uint8_t opMode ) 00994 { 00995 if( opMode == RF_OPMODE_SLEEP ) 00996 { 00997 SetAntSwLowPower( true ); 00998 } 00999 else 01000 { 01001 SetAntSwLowPower( false ); 01002 SetAntSw( opMode ); 01003 } 01004 Write( REG_OPMODE, ( Read( REG_OPMODE ) & RF_OPMODE_MASK ) | opMode ); 01005 } 01006 01007 void SX1276::SetModem( RadioModems_t modem ) 01008 { 01009 if( ( Read( REG_OPMODE ) & RFLR_OPMODE_LONGRANGEMODE_ON ) != 0 ) 01010 { 01011 this->settings.Modem = MODEM_LORA; 01012 } 01013 else 01014 { 01015 this->settings.Modem = MODEM_FSK; 01016 } 01017 01018 if( this->settings.Modem == modem ) 01019 { 01020 return; 01021 } 01022 01023 this->settings.Modem = modem; 01024 switch( this->settings.Modem ) 01025 { 01026 default: 01027 case MODEM_FSK: 01028 Sleep( ); 01029 Write( REG_OPMODE, ( Read( REG_OPMODE ) & RFLR_OPMODE_LONGRANGEMODE_MASK ) | RFLR_OPMODE_LONGRANGEMODE_OFF ); 01030 01031 Write( REG_DIOMAPPING1, 0x00 ); 01032 Write( REG_DIOMAPPING2, 0x30 ); // DIO5=ModeReady 01033 break; 01034 case MODEM_LORA: 01035 Sleep( ); 01036 Write( REG_OPMODE, ( Read( REG_OPMODE ) & RFLR_OPMODE_LONGRANGEMODE_MASK ) | RFLR_OPMODE_LONGRANGEMODE_ON ); 01037 01038 Write( REG_DIOMAPPING1, 0x00 ); 01039 Write( REG_DIOMAPPING2, 0x00 ); 01040 break; 01041 } 01042 } 01043 01044 void SX1276::SetMaxPayloadLength( RadioModems_t modem, uint8_t max ) 01045 { 01046 this->SetModem( modem ); 01047 01048 switch( modem ) 01049 { 01050 case MODEM_FSK: 01051 if( this->settings.Fsk.FixLen == false ) 01052 { 01053 this->Write( REG_PAYLOADLENGTH, max ); 01054 } 01055 break; 01056 case MODEM_LORA: 01057 this->Write( REG_LR_PAYLOADMAXLENGTH, max ); 01058 break; 01059 } 01060 } 01061 01062 void SX1276::SetPublicNetwork( bool enable ) 01063 { 01064 SetModem( MODEM_LORA ); 01065 this->settings.LoRa.PublicNetwork = enable; 01066 if( enable == true ) 01067 { 01068 // Change LoRa modem SyncWord 01069 Write( REG_LR_SYNCWORD, LORA_MAC_PUBLIC_SYNCWORD ); 01070 } 01071 else 01072 { 01073 // Change LoRa modem SyncWord 01074 Write( REG_LR_SYNCWORD, LORA_MAC_PRIVATE_SYNCWORD ); 01075 } 01076 } 01077 01078 void SX1276::OnTimeoutIrq( void ) 01079 { 01080 switch( this->settings.State ) 01081 { 01082 case RF_RX_RUNNING: 01083 if( this->settings.Modem == MODEM_FSK ) 01084 { 01085 this->settings.FskPacketHandler.PreambleDetected = false; 01086 this->settings.FskPacketHandler.SyncWordDetected = false; 01087 this->settings.FskPacketHandler.NbBytes = 0; 01088 this->settings.FskPacketHandler.Size = 0; 01089 01090 // Clear Irqs 01091 Write( REG_IRQFLAGS1, RF_IRQFLAGS1_RSSI | 01092 RF_IRQFLAGS1_PREAMBLEDETECT | 01093 RF_IRQFLAGS1_SYNCADDRESSMATCH ); 01094 Write( REG_IRQFLAGS2, RF_IRQFLAGS2_FIFOOVERRUN ); 01095 01096 if( this->settings.Fsk.RxContinuous == true ) 01097 { 01098 // Continuous mode restart Rx chain 01099 Write( REG_RXCONFIG, Read( REG_RXCONFIG ) | RF_RXCONFIG_RESTARTRXWITHOUTPLLLOCK ); 01100 rxTimeoutSyncWord.attach_us( mbed::callback( this, &SX1276::OnTimeoutIrq ), 01101 this->settings.Fsk.RxSingleTimeout * 1e3 ); 01102 } 01103 else 01104 { 01105 this->settings.State = RF_IDLE; 01106 rxTimeoutSyncWord.detach( ); 01107 } 01108 } 01109 if( ( this->RadioEvents != NULL ) && ( this->RadioEvents->RxTimeout != NULL ) ) 01110 { 01111 this->RadioEvents->RxTimeout( ); 01112 } 01113 break; 01114 case RF_TX_RUNNING: 01115 // Tx timeout shouldn't happen. 01116 // But it has been observed that when it happens it is a result of a corrupted SPI transfer 01117 // it depends on the platform design. 01118 // 01119 // The workaround is to put the radio in a known state. Thus, we re-initialize it. 01120 01121 // BEGIN WORKAROUND 01122 01123 // Reset the radio 01124 Reset( ); 01125 01126 // Calibrate Rx chain 01127 RxChainCalibration ( ); 01128 01129 // Initialize radio default values 01130 SetOpMode( RF_OPMODE_SLEEP ); 01131 01132 RadioRegistersInit( ); 01133 01134 SetModem( MODEM_FSK ); 01135 01136 // Restore previous network type setting. 01137 SetPublicNetwork( this->settings.LoRa.PublicNetwork ); 01138 // END WORKAROUND 01139 01140 this->settings.State = RF_IDLE; 01141 if( ( this->RadioEvents != NULL ) && ( this->RadioEvents->TxTimeout != NULL ) ) 01142 { 01143 this->RadioEvents->TxTimeout( ); 01144 } 01145 break; 01146 default: 01147 break; 01148 } 01149 } 01150 01151 void SX1276::OnDio0Irq( void ) 01152 { 01153 volatile uint8_t irqFlags = 0; 01154 01155 switch( this->settings.State ) 01156 { 01157 case RF_RX_RUNNING: 01158 //TimerStop( &RxTimeoutTimer ); 01159 // RxDone interrupt 01160 switch( this->settings.Modem ) 01161 { 01162 case MODEM_FSK: 01163 if( this->settings.Fsk.CrcOn == true ) 01164 { 01165 irqFlags = Read( REG_IRQFLAGS2 ); 01166 if( ( irqFlags & RF_IRQFLAGS2_CRCOK ) != RF_IRQFLAGS2_CRCOK ) 01167 { 01168 // Clear Irqs 01169 Write( REG_IRQFLAGS1, RF_IRQFLAGS1_RSSI | 01170 RF_IRQFLAGS1_PREAMBLEDETECT | 01171 RF_IRQFLAGS1_SYNCADDRESSMATCH ); 01172 Write( REG_IRQFLAGS2, RF_IRQFLAGS2_FIFOOVERRUN ); 01173 01174 rxTimeoutTimer.detach( ); 01175 01176 if( this->settings.Fsk.RxContinuous == false ) 01177 { 01178 rxTimeoutSyncWord.detach( ); 01179 this->settings.State = RF_IDLE; 01180 } 01181 else 01182 { 01183 // Continuous mode restart Rx chain 01184 Write( REG_RXCONFIG, Read( REG_RXCONFIG ) | RF_RXCONFIG_RESTARTRXWITHOUTPLLLOCK ); 01185 rxTimeoutSyncWord.attach_us( mbed::callback( this, &SX1276::OnTimeoutIrq ), 01186 this->settings.Fsk.RxSingleTimeout * 1e3 ); 01187 } 01188 01189 if( ( this->RadioEvents != NULL ) && ( this->RadioEvents->RxError != NULL ) ) 01190 { 01191 this->RadioEvents->RxError( ); 01192 } 01193 this->settings.FskPacketHandler.PreambleDetected = false; 01194 this->settings.FskPacketHandler.SyncWordDetected = false; 01195 this->settings.FskPacketHandler.NbBytes = 0; 01196 this->settings.FskPacketHandler.Size = 0; 01197 break; 01198 } 01199 } 01200 01201 // Read received packet size 01202 if( ( this->settings.FskPacketHandler.Size == 0 ) && ( this->settings.FskPacketHandler.NbBytes == 0 ) ) 01203 { 01204 if( this->settings.Fsk.FixLen == false ) 01205 { 01206 ReadFifo( ( uint8_t* )&this->settings.FskPacketHandler.Size, 1 ); 01207 } 01208 else 01209 { 01210 this->settings.FskPacketHandler.Size = Read( REG_PAYLOADLENGTH ); 01211 } 01212 ReadFifo( rxtxBuffer + this->settings.FskPacketHandler.NbBytes, this->settings.FskPacketHandler.Size - this->settings.FskPacketHandler.NbBytes ); 01213 this->settings.FskPacketHandler.NbBytes += ( this->settings.FskPacketHandler.Size - this->settings.FskPacketHandler.NbBytes ); 01214 } 01215 else 01216 { 01217 ReadFifo( rxtxBuffer + this->settings.FskPacketHandler.NbBytes, this->settings.FskPacketHandler.Size - this->settings.FskPacketHandler.NbBytes ); 01218 this->settings.FskPacketHandler.NbBytes += ( this->settings.FskPacketHandler.Size - this->settings.FskPacketHandler.NbBytes ); 01219 } 01220 01221 rxTimeoutTimer.detach( ); 01222 01223 if( this->settings.Fsk.RxContinuous == false ) 01224 { 01225 this->settings.State = RF_IDLE; 01226 rxTimeoutSyncWord.detach( ); 01227 } 01228 else 01229 { 01230 // Continuous mode restart Rx chain 01231 Write( REG_RXCONFIG, Read( REG_RXCONFIG ) | RF_RXCONFIG_RESTARTRXWITHOUTPLLLOCK ); 01232 rxTimeoutSyncWord.attach_us( mbed::callback( this, &SX1276::OnTimeoutIrq ), 01233 this->settings.Fsk.RxSingleTimeout * 1e3 ); 01234 } 01235 01236 if( ( this->RadioEvents != NULL ) && ( this->RadioEvents->RxDone != NULL ) ) 01237 { 01238 this->RadioEvents->RxDone( rxtxBuffer, this->settings.FskPacketHandler.Size, this->settings.FskPacketHandler.RssiValue, 0 ); 01239 } 01240 this->settings.FskPacketHandler.PreambleDetected = false; 01241 this->settings.FskPacketHandler.SyncWordDetected = false; 01242 this->settings.FskPacketHandler.NbBytes = 0; 01243 this->settings.FskPacketHandler.Size = 0; 01244 break; 01245 case MODEM_LORA: 01246 { 01247 int8_t snr = 0; 01248 01249 // Clear Irq 01250 Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_RXDONE ); 01251 01252 irqFlags = Read( REG_LR_IRQFLAGS ); 01253 if( ( irqFlags & RFLR_IRQFLAGS_PAYLOADCRCERROR_MASK ) == RFLR_IRQFLAGS_PAYLOADCRCERROR ) 01254 { 01255 // Clear Irq 01256 Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_PAYLOADCRCERROR ); 01257 01258 if( this->settings.LoRa.RxContinuous == false ) 01259 { 01260 this->settings.State = RF_IDLE; 01261 } 01262 rxTimeoutTimer.detach( ); 01263 01264 if( ( this->RadioEvents != NULL ) && ( this->RadioEvents->RxError != NULL ) ) 01265 { 01266 this->RadioEvents->RxError( ); 01267 } 01268 break; 01269 } 01270 01271 this->settings.LoRaPacketHandler.SnrValue = Read( REG_LR_PKTSNRVALUE ); 01272 if( this->settings.LoRaPacketHandler.SnrValue & 0x80 ) // The SNR sign bit is 1 01273 { 01274 // Invert and divide by 4 01275 snr = ( ( ~this->settings.LoRaPacketHandler.SnrValue + 1 ) & 0xFF ) >> 2; 01276 snr = -snr; 01277 } 01278 else 01279 { 01280 // Divide by 4 01281 snr = ( this->settings.LoRaPacketHandler.SnrValue & 0xFF ) >> 2; 01282 } 01283 01284 int16_t rssi = Read( REG_LR_PKTRSSIVALUE ); 01285 if( snr < 0 ) 01286 { 01287 if( this->settings.Channel > RF_MID_BAND_THRESH ) 01288 { 01289 this->settings.LoRaPacketHandler.RssiValue = RSSI_OFFSET_HF + rssi + ( rssi >> 4 ) + 01290 snr; 01291 } 01292 else 01293 { 01294 this->settings.LoRaPacketHandler.RssiValue = RSSI_OFFSET_LF + rssi + ( rssi >> 4 ) + 01295 snr; 01296 } 01297 } 01298 else 01299 { 01300 if( this->settings.Channel > RF_MID_BAND_THRESH ) 01301 { 01302 this->settings.LoRaPacketHandler.RssiValue = RSSI_OFFSET_HF + rssi + ( rssi >> 4 ); 01303 } 01304 else 01305 { 01306 this->settings.LoRaPacketHandler.RssiValue = RSSI_OFFSET_LF + rssi + ( rssi >> 4 ); 01307 } 01308 } 01309 01310 this->settings.LoRaPacketHandler.Size = Read( REG_LR_RXNBBYTES ); 01311 ReadFifo( rxtxBuffer, this->settings.LoRaPacketHandler.Size ); 01312 01313 if( this->settings.LoRa.RxContinuous == false ) 01314 { 01315 this->settings.State = RF_IDLE; 01316 } 01317 rxTimeoutTimer.detach( ); 01318 01319 if( ( this->RadioEvents != NULL ) && ( this->RadioEvents->RxDone != NULL ) ) 01320 { 01321 this->RadioEvents->RxDone( rxtxBuffer, this->settings.LoRaPacketHandler.Size, this->settings.LoRaPacketHandler.RssiValue, this->settings.LoRaPacketHandler.SnrValue ); 01322 } 01323 } 01324 break; 01325 default: 01326 break; 01327 } 01328 break; 01329 case RF_TX_RUNNING: 01330 txTimeoutTimer .detach( ); 01331 // TxDone interrupt 01332 switch( this->settings.Modem ) 01333 { 01334 case MODEM_LORA: 01335 // Clear Irq 01336 Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_TXDONE ); 01337 // Intentional fall through 01338 case MODEM_FSK: 01339 default: 01340 this->settings.State = RF_IDLE; 01341 if( ( this->RadioEvents != NULL ) && ( this->RadioEvents->TxDone != NULL ) ) 01342 { 01343 this->RadioEvents->TxDone( ); 01344 } 01345 break; 01346 } 01347 break; 01348 default: 01349 break; 01350 } 01351 } 01352 01353 void SX1276::OnDio1Irq( void ) 01354 { 01355 switch( this->settings.State ) 01356 { 01357 case RF_RX_RUNNING: 01358 switch( this->settings.Modem ) 01359 { 01360 case MODEM_FSK: 01361 // FifoLevel interrupt 01362 // Read received packet size 01363 if( ( this->settings.FskPacketHandler.Size == 0 ) && ( this->settings.FskPacketHandler.NbBytes == 0 ) ) 01364 { 01365 if( this->settings.Fsk.FixLen == false ) 01366 { 01367 ReadFifo( ( uint8_t* )&this->settings.FskPacketHandler.Size, 1 ); 01368 } 01369 else 01370 { 01371 this->settings.FskPacketHandler.Size = Read( REG_PAYLOADLENGTH ); 01372 } 01373 } 01374 01375 if( ( this->settings.FskPacketHandler.Size - this->settings.FskPacketHandler.NbBytes ) > this->settings.FskPacketHandler.FifoThresh ) 01376 { 01377 ReadFifo( ( rxtxBuffer + this->settings.FskPacketHandler.NbBytes ), this->settings.FskPacketHandler.FifoThresh ); 01378 this->settings.FskPacketHandler.NbBytes += this->settings.FskPacketHandler.FifoThresh; 01379 } 01380 else 01381 { 01382 ReadFifo( ( rxtxBuffer + this->settings.FskPacketHandler.NbBytes ), this->settings.FskPacketHandler.Size - this->settings.FskPacketHandler.NbBytes ); 01383 this->settings.FskPacketHandler.NbBytes += ( this->settings.FskPacketHandler.Size - this->settings.FskPacketHandler.NbBytes ); 01384 } 01385 break; 01386 case MODEM_LORA: 01387 // Sync time out 01388 rxTimeoutTimer.detach( ); 01389 // Clear Irq 01390 Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_RXTIMEOUT ); 01391 01392 this->settings.State = RF_IDLE; 01393 if( ( this->RadioEvents != NULL ) && ( this->RadioEvents->RxTimeout != NULL ) ) 01394 { 01395 this->RadioEvents->RxTimeout( ); 01396 } 01397 break; 01398 default: 01399 break; 01400 } 01401 break; 01402 case RF_TX_RUNNING: 01403 switch( this->settings.Modem ) 01404 { 01405 case MODEM_FSK: 01406 // FifoEmpty interrupt 01407 if( ( this->settings.FskPacketHandler.Size - this->settings.FskPacketHandler.NbBytes ) > this->settings.FskPacketHandler.ChunkSize ) 01408 { 01409 WriteFifo( ( rxtxBuffer + this->settings.FskPacketHandler.NbBytes ), this->settings.FskPacketHandler.ChunkSize ); 01410 this->settings.FskPacketHandler.NbBytes += this->settings.FskPacketHandler.ChunkSize; 01411 } 01412 else 01413 { 01414 // Write the last chunk of data 01415 WriteFifo( rxtxBuffer + this->settings.FskPacketHandler.NbBytes, this->settings.FskPacketHandler.Size - this->settings.FskPacketHandler.NbBytes ); 01416 this->settings.FskPacketHandler.NbBytes += this->settings.FskPacketHandler.Size - this->settings.FskPacketHandler.NbBytes; 01417 } 01418 break; 01419 case MODEM_LORA: 01420 break; 01421 default: 01422 break; 01423 } 01424 break; 01425 default: 01426 break; 01427 } 01428 } 01429 01430 void SX1276::OnDio2Irq( void ) 01431 { 01432 switch( this->settings.State ) 01433 { 01434 case RF_RX_RUNNING: 01435 switch( this->settings.Modem ) 01436 { 01437 case MODEM_FSK: 01438 // Checks if DIO4 is connected. If it is not PreambleDtected is set to true. 01439 if( this->dioIrq [4] == NULL ) 01440 { 01441 this->settings.FskPacketHandler.PreambleDetected = true; 01442 } 01443 01444 if( ( this->settings.FskPacketHandler.PreambleDetected == true ) && ( this->settings.FskPacketHandler.SyncWordDetected == false ) ) 01445 { 01446 rxTimeoutSyncWord.detach( ); 01447 01448 this->settings.FskPacketHandler.SyncWordDetected = true; 01449 01450 this->settings.FskPacketHandler.RssiValue = -( Read( REG_RSSIVALUE ) >> 1 ); 01451 01452 this->settings.FskPacketHandler.AfcValue = ( int32_t )( double )( ( ( uint16_t )Read( REG_AFCMSB ) << 8 ) | 01453 ( uint16_t )Read( REG_AFCLSB ) ) * 01454 ( double )FREQ_STEP; 01455 this->settings.FskPacketHandler.RxGain = ( Read( REG_LNA ) >> 5 ) & 0x07; 01456 } 01457 break; 01458 case MODEM_LORA: 01459 if( this->settings.LoRa.FreqHopOn == true ) 01460 { 01461 // Clear Irq 01462 Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL ); 01463 01464 if( ( this->RadioEvents != NULL ) && ( this->RadioEvents->FhssChangeChannel != NULL ) ) 01465 { 01466 this->RadioEvents->FhssChangeChannel( ( Read( REG_LR_HOPCHANNEL ) & RFLR_HOPCHANNEL_CHANNEL_MASK ) ); 01467 } 01468 } 01469 break; 01470 default: 01471 break; 01472 } 01473 break; 01474 case RF_TX_RUNNING: 01475 switch( this->settings.Modem ) 01476 { 01477 case MODEM_FSK: 01478 break; 01479 case MODEM_LORA: 01480 if( this->settings.LoRa.FreqHopOn == true ) 01481 { 01482 // Clear Irq 01483 Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL ); 01484 01485 if( ( this->RadioEvents != NULL ) && ( this->RadioEvents->FhssChangeChannel != NULL ) ) 01486 { 01487 this->RadioEvents->FhssChangeChannel( ( Read( REG_LR_HOPCHANNEL ) & RFLR_HOPCHANNEL_CHANNEL_MASK ) ); 01488 } 01489 } 01490 break; 01491 default: 01492 break; 01493 } 01494 break; 01495 default: 01496 break; 01497 } 01498 } 01499 01500 void SX1276::OnDio3Irq( void ) 01501 { 01502 switch( this->settings.Modem ) 01503 { 01504 case MODEM_FSK: 01505 break; 01506 case MODEM_LORA: 01507 if( ( Read( REG_LR_IRQFLAGS ) & RFLR_IRQFLAGS_CADDETECTED ) == RFLR_IRQFLAGS_CADDETECTED ) 01508 { 01509 // Clear Irq 01510 Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_CADDETECTED | RFLR_IRQFLAGS_CADDONE ); 01511 if( ( this->RadioEvents != NULL ) && ( this->RadioEvents->CadDone != NULL ) ) 01512 { 01513 this->RadioEvents->CadDone( true ); 01514 } 01515 } 01516 else 01517 { 01518 // Clear Irq 01519 Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_CADDONE ); 01520 if( ( this->RadioEvents != NULL ) && ( this->RadioEvents->CadDone != NULL ) ) 01521 { 01522 this->RadioEvents->CadDone( false ); 01523 } 01524 } 01525 break; 01526 default: 01527 break; 01528 } 01529 } 01530 01531 void SX1276::OnDio4Irq( void ) 01532 { 01533 switch( this->settings.Modem ) 01534 { 01535 case MODEM_FSK: 01536 { 01537 if( this->settings.FskPacketHandler.PreambleDetected == false ) 01538 { 01539 this->settings.FskPacketHandler.PreambleDetected = true; 01540 } 01541 } 01542 break; 01543 case MODEM_LORA: 01544 break; 01545 default: 01546 break; 01547 } 01548 } 01549 01550 void SX1276::OnDio5Irq( void ) 01551 { 01552 switch( this->settings.Modem ) 01553 { 01554 case MODEM_FSK: 01555 break; 01556 case MODEM_LORA: 01557 break; 01558 default: 01559 break; 01560 } 01561 }
Generated on Tue Jul 12 2022 20:53:59 by
![doxygen](doxygen.png)