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