SX1276GenericLib to support sx1276 bassed LoRa modules, including HopeRF RFM95, Murata CMWX1ZZABZ and Semtech SX1276MB1MAS/SX1276MB1LAS modules

Dependents:   DISCO-L072CZ-LRWAN1_LoRa_PingPong DISCO-L072CZ-LRWAN1_LoRa_PingPong DISCO-L072CZ-LRWAN1_LoRa_PingPong DISCO-L072CZ-LRWAN1_LoRa_USB_Rx ... more

Fork of SX1276Lib by Semtech

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