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

SX1276MB1xAS