Gregory Cristian / SX1276Lib

Dependents:   LoRaWAN_actility LoRaWAN_MBED LoRaWANSharedTest

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers sx1276.cpp Source File

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 }