LoRa gateway to link to Raspberry - Working ok

Fork of SX1276GenericLib by Helmut Tschemernjak

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         case MODEM_LORA:
01086             mtuSize = RX_BUFFER_SIZE;
01087             break;
01088         default:
01089             mtuSize = -1;
01090             break;
01091     }
01092     return mtuSize;
01093 }
01094 
01095 int16_t SX1276::GetRssi( RadioModems_t modem )
01096 {
01097     int16_t rssi = 0;
01098 
01099     switch( modem )
01100     {
01101     case MODEM_FSK:
01102         rssi = -( Read( REG_RSSIVALUE ) >> 1 );
01103         break;
01104     case MODEM_LORA:
01105         if( this->settings.Channel > RF_MID_BAND_THRESH )
01106         {
01107             rssi = RSSI_OFFSET_HF + Read( REG_LR_RSSIVALUE );
01108         }
01109         else
01110         {
01111             rssi = RSSI_OFFSET_LF + Read( REG_LR_RSSIVALUE );
01112         }
01113         break;
01114     default:
01115         rssi = -1;
01116         break;
01117     }
01118     return rssi;
01119 }
01120 
01121 int32_t SX1276::GetFrequencyError(RadioModems_t modem )
01122 {
01123     int32_t val = 0;
01124     
01125     if (modem != MODEM_LORA)
01126         return 0;
01127     
01128     val = (Read(REG_LR_FEIMSB) & 0b1111) << 16; // high word, 4 valid bits only
01129     val |= ((Read(REG_LR_FEIMID) << 8) | Read(REG_LR_FEILSB)); // high byte, low byte
01130     if (val & 0x80000) //convert sign bit
01131         val |= 0xfff00000;
01132     
01133     int32_t bandwidth = 0;
01134     for (int i = 0; i < (int)(sizeof(LoRaBandwidths) / sizeof(BandwidthMap )) -1; i++ ) {
01135         if (LoRaBandwidths[i].RegValue == this->settings.LoRa.Bandwidth) {
01136             bandwidth = LoRaBandwidths[i].bandwidth;
01137             break;
01138         }
01139     }
01140     if (!bandwidth)
01141         return 0;
01142     
01143     float bandWidthkHz = (float)bandwidth/1000;
01144     
01145     int32_t hz = (((float)val * (float)(1<<24)) / ((float)XTAL_FREQ)) * (bandWidthkHz / 500.0);
01146         
01147     return hz;
01148 }
01149 
01150 
01151 void SX1276::SetOpMode( uint8_t opMode )
01152 {
01153     if( opMode == RF_OPMODE_SLEEP )
01154     {
01155         SetAntSwLowPower( true );
01156     }
01157     else
01158     {
01159         SetAntSwLowPower( false );
01160         SetAntSw( opMode );
01161     }
01162     Write( REG_OPMODE, ( Read( REG_OPMODE ) & RF_OPMODE_MASK ) | opMode );
01163 }
01164 
01165 void SX1276::SetModem( RadioModems_t modem )
01166 {
01167     if( ( Read( REG_OPMODE ) & RFLR_OPMODE_LONGRANGEMODE_ON ) != 0 )
01168     {
01169         this->settings.Modem = MODEM_LORA;
01170     }
01171     else
01172     {
01173         this->settings.Modem = MODEM_FSK;
01174     }
01175     
01176     if( this->settings.Modem == modem )
01177     {
01178         return;
01179     }
01180 
01181     this->settings.Modem = modem;
01182     switch( this->settings.Modem )
01183     {
01184     default:
01185     case MODEM_FSK:
01186         Sleep( );
01187         Write( REG_OPMODE, ( Read( REG_OPMODE ) & RFLR_OPMODE_LONGRANGEMODE_MASK ) | RFLR_OPMODE_LONGRANGEMODE_OFF );
01188     
01189         Write( REG_DIOMAPPING1, 0x00 );
01190         Write( REG_DIOMAPPING2, 0x30 ); // DIO5=ModeReady
01191         break;
01192     case MODEM_LORA:
01193         Sleep( );
01194         Write( REG_OPMODE, ( Read( REG_OPMODE ) & RFLR_OPMODE_LONGRANGEMODE_MASK ) | RFLR_OPMODE_LONGRANGEMODE_ON );
01195 
01196         Write( REG_DIOMAPPING1, 0x00 );
01197         Write( REG_DIOMAPPING2, 0x00 );
01198         break;
01199     }
01200 }
01201 
01202 void SX1276::SetMaxPayloadLength( RadioModems_t modem, uint8_t max )
01203 {
01204     this->SetModem( modem );
01205 
01206     switch( modem )
01207     {
01208     case MODEM_FSK:
01209         if( this->settings.Fsk.FixLen == false )
01210         {
01211             this->Write( REG_PAYLOADLENGTH, max );
01212         }
01213         break;
01214     case MODEM_LORA:
01215         this->Write( REG_LR_PAYLOADMAXLENGTH, max );
01216         break;
01217     }
01218 }
01219 
01220 void SX1276::SetPublicNetwork( bool enable )
01221 {
01222     SetModem( MODEM_LORA );
01223     this->settings.LoRa.PublicNetwork = enable;
01224     if( enable == true )
01225     {
01226         // Change LoRa modem SyncWord
01227         Write( REG_LR_SYNCWORD, LORA_MAC_PUBLIC_SYNCWORD );
01228     }
01229     else
01230     {
01231         // Change LoRa modem SyncWord
01232         Write( REG_LR_SYNCWORD, LORA_MAC_PRIVATE_SYNCWORD );
01233     }
01234 }
01235 
01236 
01237 void SX1276::OnTimeoutIrq( void )
01238 {
01239     switch( this->settings.State )
01240     {
01241     case RF_RX_RUNNING:
01242         if( this->settings.Modem == MODEM_FSK )
01243         {
01244             this->settings.FskPacketHandler.PreambleDetected = false;
01245             this->settings.FskPacketHandler.SyncWordDetected = false;
01246             this->settings.FskPacketHandler.NbBytes = 0;
01247             this->settings.FskPacketHandler.Size = 0;
01248 
01249             // Clear Irqs
01250             Write( REG_IRQFLAGS1, RF_IRQFLAGS1_RSSI |
01251                                         RF_IRQFLAGS1_PREAMBLEDETECT |
01252                                         RF_IRQFLAGS1_SYNCADDRESSMATCH );
01253             Write( REG_IRQFLAGS2, RF_IRQFLAGS2_FIFOOVERRUN );
01254 
01255             if( this->settings.Fsk.RxContinuous == true )
01256             {
01257                 // Continuous mode restart Rx chain
01258                 Write( REG_RXCONFIG, Read( REG_RXCONFIG ) | RF_RXCONFIG_RESTARTRXWITHOUTPLLLOCK );
01259                 SetTimeout(RXTimeoutSyncWordTimer, &SX1276::OnTimeoutIrq, this->settings.Fsk.RxSingleTimeout * 1e3);
01260             }
01261             else
01262             {
01263                 this->settings.State = RF_IDLE;
01264                 SetTimeout(RXTimeoutSyncWordTimer, NULL);
01265             }
01266         }
01267         if (this->RadioEvents && this->RadioEvents->RxTimeout)
01268         {
01269             this->RadioEvents->RxTimeout(this, this->RadioEvents->userThisPtr, this->RadioEvents->userData);
01270         }
01271         break;
01272     case RF_TX_RUNNING:
01273         // Tx timeout shouldn't happen.
01274         // But it has been observed that when it happens it is a result of a corrupted SPI transfer
01275         // it depends on the platform design.
01276         //
01277         // The workaround is to put the radio in a known state. Thus, we re-initialize it.
01278         // BEGIN WORKAROUND
01279 
01280         // Reset the radio
01281         Reset( );
01282 
01283         // Calibrate Rx chain
01284         RxChainCalibration ( );
01285 
01286         // Initialize radio default values
01287         SetOpMode( RF_OPMODE_SLEEP );
01288 
01289         RadioRegistersInit( );
01290 
01291         SetModem( MODEM_FSK );
01292 
01293         // Restore previous network type setting.
01294         SetPublicNetwork( this->settings.LoRa.PublicNetwork );
01295         // END WORKAROUND
01296             
01297         this->settings.State = RF_IDLE;
01298         if (this->RadioEvents && this->RadioEvents->TxTimeout)
01299         {
01300             this->RadioEvents->TxTimeout(this, this->RadioEvents->userThisPtr, this->RadioEvents->userData);
01301         }
01302         break;
01303     default:
01304         break;
01305     }
01306 }
01307 
01308 void SX1276::OnDio0Irq( void )
01309 {
01310     volatile uint8_t irqFlags = 0;
01311 
01312     switch( this->settings.State )
01313     {
01314         case RF_RX_RUNNING:
01315             //TimerStop( &RxTimeoutTimer );
01316             // RxDone interrupt
01317             switch( this->settings.Modem )
01318             {
01319             case MODEM_FSK:
01320                 if( this->settings.Fsk.CrcOn == true )
01321                 {
01322                     irqFlags = Read( REG_IRQFLAGS2 );
01323                     if( ( irqFlags & RF_IRQFLAGS2_CRCOK ) != RF_IRQFLAGS2_CRCOK )
01324                     {
01325                         // Clear Irqs
01326                         Write( REG_IRQFLAGS1, RF_IRQFLAGS1_RSSI |
01327                                                     RF_IRQFLAGS1_PREAMBLEDETECT |
01328                                                     RF_IRQFLAGS1_SYNCADDRESSMATCH );
01329                         Write( REG_IRQFLAGS2, RF_IRQFLAGS2_FIFOOVERRUN );
01330 
01331                         SetTimeout(RXTimeoutTimer, NULL);
01332 
01333                         if( this->settings.Fsk.RxContinuous == false )
01334                         {
01335                             SetTimeout(RXTimeoutSyncWordTimer, NULL);
01336                             this->settings.State = RF_IDLE;
01337                         }
01338                         else
01339                         {
01340                             // Continuous mode restart Rx chain
01341                             Write( REG_RXCONFIG, Read( REG_RXCONFIG ) | RF_RXCONFIG_RESTARTRXWITHOUTPLLLOCK );
01342                             SetTimeout(RXTimeoutSyncWordTimer, &SX1276::OnTimeoutIrq, this->settings.Fsk.RxSingleTimeout * 1e3);
01343                         }
01344 
01345                         if (this->RadioEvents && this->RadioEvents->RxError)
01346                         {
01347                             this->RadioEvents->RxError(this, this->RadioEvents->userThisPtr, this->RadioEvents->userData);
01348                         }
01349                         this->settings.FskPacketHandler.PreambleDetected = false;
01350                         this->settings.FskPacketHandler.SyncWordDetected = false;
01351                         this->settings.FskPacketHandler.NbBytes = 0;
01352                         this->settings.FskPacketHandler.Size = 0;
01353                         break;
01354                     }
01355                 }
01356 
01357                 // Read received packet size
01358                 if( ( this->settings.FskPacketHandler.Size == 0 ) && ( this->settings.FskPacketHandler.NbBytes == 0 ) )
01359                 {
01360                     if( this->settings.Fsk.FixLen == false )
01361                     {
01362                         ReadFifo( ( uint8_t* )&this->settings.FskPacketHandler.Size, 1 );
01363                     }
01364                     else
01365                     {
01366                         this->settings.FskPacketHandler.Size = Read( REG_PAYLOADLENGTH );
01367                     }
01368                     ReadFifo( rxtxBuffer + this->settings.FskPacketHandler.NbBytes, this->settings.FskPacketHandler.Size - this->settings.FskPacketHandler.NbBytes );
01369                     this->settings.FskPacketHandler.NbBytes += ( this->settings.FskPacketHandler.Size - this->settings.FskPacketHandler.NbBytes );
01370                 }
01371                 else
01372                 {
01373                     ReadFifo( rxtxBuffer + this->settings.FskPacketHandler.NbBytes, this->settings.FskPacketHandler.Size - this->settings.FskPacketHandler.NbBytes );
01374                     this->settings.FskPacketHandler.NbBytes += ( this->settings.FskPacketHandler.Size - this->settings.FskPacketHandler.NbBytes );
01375                 }
01376 
01377                 SetTimeout(RXTimeoutTimer, NULL);
01378                     
01379                 if( this->settings.Fsk.RxContinuous == false )
01380                 {
01381                     this->settings.State = RF_IDLE;
01382                     SetTimeout(RXTimeoutSyncWordTimer, NULL);
01383                 }
01384                 else
01385                 {
01386                     // Continuous mode restart Rx chain
01387                     Write( REG_RXCONFIG, Read( REG_RXCONFIG ) | RF_RXCONFIG_RESTARTRXWITHOUTPLLLOCK );
01388                     SetTimeout(RXTimeoutSyncWordTimer, &SX1276::OnTimeoutIrq, this->settings.Fsk.RxSingleTimeout * 1e3);
01389                 }
01390 
01391                 if (this->RadioEvents && this->RadioEvents->RxDone)
01392                 {
01393                     this->RadioEvents->RxDone(this, this->RadioEvents->userThisPtr, this->RadioEvents->userData, rxtxBuffer, this->settings.FskPacketHandler.Size, this->settings.FskPacketHandler.RssiValue, 0 );
01394                 }
01395                 this->settings.FskPacketHandler.PreambleDetected = false;
01396                 this->settings.FskPacketHandler.SyncWordDetected = false;
01397                 this->settings.FskPacketHandler.NbBytes = 0;
01398                 this->settings.FskPacketHandler.Size = 0;
01399                 break;
01400             case MODEM_LORA:
01401                 {
01402                     int8_t snr = 0;
01403 
01404                     // Clear Irq
01405                     Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_RXDONE );
01406 
01407                     irqFlags = Read( REG_LR_IRQFLAGS );
01408                     if( ( irqFlags & RFLR_IRQFLAGS_PAYLOADCRCERROR_MASK ) == RFLR_IRQFLAGS_PAYLOADCRCERROR )
01409                     {
01410                         // Clear Irq
01411                         Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_PAYLOADCRCERROR );
01412 
01413                         if( this->settings.LoRa.RxContinuous == false )
01414                         {
01415                             this->settings.State = RF_IDLE;
01416                         }
01417                         SetTimeout(RXTimeoutTimer, NULL);
01418                         
01419                         if(this->RadioEvents && this->RadioEvents->RxError)
01420                         {
01421                             this->RadioEvents->RxError(this, this->RadioEvents->userThisPtr, this->RadioEvents->userData);
01422                         }
01423                         break;
01424                     }
01425 
01426                     this->settings.LoRaPacketHandler.SnrValue = Read( REG_LR_PKTSNRVALUE );
01427                     if( this->settings.LoRaPacketHandler.SnrValue & 0x80 ) // The SNR sign bit is 1
01428                     {
01429                         // Invert and divide by 4
01430                         snr = ( ( ~this->settings.LoRaPacketHandler.SnrValue + 1 ) & 0xFF ) >> 2;
01431                         snr = -snr;
01432                     }
01433                     else
01434                     {
01435                         // Divide by 4
01436                         snr = ( this->settings.LoRaPacketHandler.SnrValue & 0xFF ) >> 2;
01437                     }
01438 
01439                     int16_t rssi = Read( REG_LR_PKTRSSIVALUE );
01440                     if( snr < 0 )
01441                     {
01442                         if( this->settings.Channel > RF_MID_BAND_THRESH )
01443                         {
01444                             this->settings.LoRaPacketHandler.RssiValue = RSSI_OFFSET_HF + rssi + ( rssi >> 4 ) +
01445                                                                           snr;
01446                         }
01447                         else
01448                         {
01449                             this->settings.LoRaPacketHandler.RssiValue = RSSI_OFFSET_LF + rssi + ( rssi >> 4 ) +
01450                                                                           snr;
01451                         }
01452                     }
01453                     else
01454                     {
01455                         if( this->settings.Channel > RF_MID_BAND_THRESH )
01456                         {
01457                             this->settings.LoRaPacketHandler.RssiValue = RSSI_OFFSET_HF + rssi + ( rssi >> 4 );
01458                         }
01459                         else
01460                         {
01461                             this->settings.LoRaPacketHandler.RssiValue = RSSI_OFFSET_LF + rssi + ( rssi >> 4 );
01462                         }
01463                     }
01464 
01465                     this->settings.LoRaPacketHandler.Size = Read( REG_LR_RXNBBYTES );
01466                     ReadFifo( rxtxBuffer, this->settings.LoRaPacketHandler.Size );
01467 
01468                     if( this->settings.LoRa.RxContinuous == false )
01469                     {
01470                         this->settings.State = RF_IDLE;
01471                     }
01472                     SetTimeout(RXTimeoutTimer, NULL);
01473                     
01474                     if(this->RadioEvents && this->RadioEvents->RxDone)
01475                     {
01476                         this->RadioEvents->RxDone(this, this->RadioEvents->userThisPtr, this->RadioEvents->userData, rxtxBuffer, this->settings.LoRaPacketHandler.Size, this->settings.LoRaPacketHandler.RssiValue, this->settings.LoRaPacketHandler.SnrValue );
01477                     }
01478                 }
01479                 break;
01480             default:
01481                 break;
01482             }
01483             break;
01484         case RF_TX_RUNNING:
01485             SetTimeout(TXTimeoutTimer, NULL);
01486             // TxDone interrupt
01487             switch( this->settings.Modem )
01488             {
01489             case MODEM_LORA:
01490                 // Clear Irq
01491                 Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_TXDONE );
01492                 // Intentional fall through
01493             case MODEM_FSK:
01494             default:
01495                 this->settings.State = RF_IDLE;
01496                 if (this->RadioEvents && this->RadioEvents->TxDone)
01497                 {
01498                     this->RadioEvents->TxDone(this, this->RadioEvents->userThisPtr, this->RadioEvents->userData);
01499                 }
01500                 break;
01501             }
01502             break;
01503         case RF_CAD:
01504             // CadDone interrupt
01505             switch( this->settings.Modem ) {
01506             case MODEM_LORA:
01507             {
01508                 if( ( Read( REG_LR_IRQFLAGS ) & RFLR_IRQFLAGS_CADDETECTED ) == RFLR_IRQFLAGS_CADDETECTED )
01509                 {
01510                     // Clear Irq
01511                     Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_CADDETECTED | RFLR_IRQFLAGS_CADDONE );
01512                     if (this->RadioEvents && this->RadioEvents->CadDone)
01513                     {
01514                         this->RadioEvents->CadDone(this, this->RadioEvents->userThisPtr, this->RadioEvents->userData, true );
01515                     }
01516                 } else {
01517                     // Clear Irq
01518                     Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_CADDONE );
01519                     if (this->RadioEvents && this->RadioEvents->CadDone)
01520                     {
01521                         this->RadioEvents->CadDone(this, this->RadioEvents->userThisPtr, this->RadioEvents->userData, false );
01522                     }
01523                 }
01524             }
01525             case MODEM_FSK:
01526             default:
01527             this->settings.State = RF_IDLE;
01528                 break;
01529         }
01530         default:
01531             break;
01532     }
01533 }
01534 
01535 void SX1276::OnDio1Irq( void )
01536 {
01537     switch( this->settings.State )
01538     {
01539         case RF_RX_RUNNING:
01540             switch( this->settings.Modem )
01541             {
01542             case MODEM_FSK:
01543                 // FifoLevel interrupt
01544                 // Read received packet size
01545                 if( ( this->settings.FskPacketHandler.Size == 0 ) && ( this->settings.FskPacketHandler.NbBytes == 0 ) )
01546                 {
01547                     if( this->settings.Fsk.FixLen == false )
01548                     {
01549                         ReadFifo( ( uint8_t* )&this->settings.FskPacketHandler.Size, 1 );
01550                     }
01551                     else
01552                     {
01553                         this->settings.FskPacketHandler.Size = Read( REG_PAYLOADLENGTH );
01554                     }
01555                 }
01556 
01557                 if( ( this->settings.FskPacketHandler.Size - this->settings.FskPacketHandler.NbBytes ) > this->settings.FskPacketHandler.FifoThresh )
01558                 {
01559                     ReadFifo( ( rxtxBuffer + this->settings.FskPacketHandler.NbBytes ), this->settings.FskPacketHandler.FifoThresh );
01560                     this->settings.FskPacketHandler.NbBytes += this->settings.FskPacketHandler.FifoThresh;
01561                 }
01562                 else
01563                 {
01564                     ReadFifo( ( rxtxBuffer + this->settings.FskPacketHandler.NbBytes ), this->settings.FskPacketHandler.Size - this->settings.FskPacketHandler.NbBytes );
01565                     this->settings.FskPacketHandler.NbBytes += ( this->settings.FskPacketHandler.Size - this->settings.FskPacketHandler.NbBytes );
01566                 }
01567                 break;
01568             case MODEM_LORA:
01569                 // Sync time out
01570                 SetTimeout(RXTimeoutTimer, NULL);
01571                 // Clear Irq
01572                 Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_RXTIMEOUT );
01573 
01574                 this->settings.State = RF_IDLE;
01575                 if (this->RadioEvents &&  this->RadioEvents->RxTimeout)
01576                 {
01577                     this->RadioEvents->RxTimeout(this, this->RadioEvents->userThisPtr, this->RadioEvents->userData);
01578                 }
01579                 break;
01580             default:
01581                 break;
01582             }
01583             break;
01584         case RF_TX_RUNNING:
01585             switch( this->settings.Modem )
01586             {
01587             case MODEM_FSK:
01588                 // FifoEmpty interrupt
01589                 if( ( this->settings.FskPacketHandler.Size - this->settings.FskPacketHandler.NbBytes ) > this->settings.FskPacketHandler.ChunkSize )
01590                 {
01591                     WriteFifo( ( rxtxBuffer + this->settings.FskPacketHandler.NbBytes ), this->settings.FskPacketHandler.ChunkSize );
01592                     this->settings.FskPacketHandler.NbBytes += this->settings.FskPacketHandler.ChunkSize;
01593                 }
01594                 else
01595                 {
01596                     // Write the last chunk of data
01597                     WriteFifo( rxtxBuffer + this->settings.FskPacketHandler.NbBytes, this->settings.FskPacketHandler.Size - this->settings.FskPacketHandler.NbBytes );
01598                     this->settings.FskPacketHandler.NbBytes += this->settings.FskPacketHandler.Size - this->settings.FskPacketHandler.NbBytes;
01599                 }
01600                 break;
01601             case MODEM_LORA:
01602                 break;
01603             default:
01604                 break;
01605             }
01606             break;
01607         default:
01608             break;
01609     }
01610 }
01611 
01612 void SX1276::OnDio2Irq( void )
01613 {
01614     switch( this->settings.State )
01615     {
01616         case RF_RX_RUNNING:
01617             switch( this->settings.Modem )
01618             {
01619             case MODEM_FSK:
01620                 // Checks if DIO4 is connected. If it is not PreambleDtected is set to true.
01621                 if( this->dioIrq [4] == NULL )
01622                 {
01623                     this->settings.FskPacketHandler.PreambleDetected = true;
01624                 }
01625 
01626                 if( ( this->settings.FskPacketHandler.PreambleDetected == true ) && ( this->settings.FskPacketHandler.SyncWordDetected == false ) )
01627                 {
01628                     SetTimeout(RXTimeoutSyncWordTimer, NULL);
01629                     
01630                     this->settings.FskPacketHandler.SyncWordDetected = true;
01631 
01632                     this->settings.FskPacketHandler.RssiValue = -( Read( REG_RSSIVALUE ) >> 1 );
01633 
01634                     this->settings.FskPacketHandler.AfcValue = ( int32_t )( double )( ( ( uint16_t )Read( REG_AFCMSB ) << 8 ) |
01635                                                                            ( uint16_t )Read( REG_AFCLSB ) ) *
01636                                                                            ( double )FREQ_STEP;
01637                     this->settings.FskPacketHandler.RxGain = ( Read( REG_LNA ) >> 5 ) & 0x07;
01638                 }
01639                 break;
01640             case MODEM_LORA:
01641                 if( this->settings.LoRa.FreqHopOn == true )
01642                 {
01643                     // Clear Irq
01644                     Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL );
01645 
01646                     if (this->RadioEvents &&  this->RadioEvents->FhssChangeChannel)
01647                     {
01648                         this->RadioEvents->FhssChangeChannel(this, this->RadioEvents->userThisPtr, this->RadioEvents->userData, ( Read( REG_LR_HOPCHANNEL ) & RFLR_HOPCHANNEL_CHANNEL_MASK ) );
01649                     }
01650                 }
01651                 break;
01652             default:
01653                 break;
01654             }
01655             break;
01656         case RF_TX_RUNNING:
01657             switch( this->settings.Modem )
01658             {
01659             case MODEM_FSK:
01660                 break;
01661             case MODEM_LORA:
01662                 if( this->settings.LoRa.FreqHopOn == true )
01663                 {
01664                     // Clear Irq
01665                     Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL );
01666 
01667                     if (this->RadioEvents && this->RadioEvents->FhssChangeChannel)
01668                     {
01669                         this->RadioEvents->FhssChangeChannel(this, this->RadioEvents->userThisPtr, this->RadioEvents->userData, ( Read( REG_LR_HOPCHANNEL ) & RFLR_HOPCHANNEL_CHANNEL_MASK ) );
01670                     }
01671                 }
01672                 break;
01673             default:
01674                 break;
01675             }
01676             break;
01677         default:
01678             break;
01679     }
01680 }
01681 
01682 void SX1276::OnDio3Irq( void )
01683 {
01684     switch( this->settings.Modem )
01685     {
01686     case MODEM_FSK:
01687         break;
01688     case MODEM_LORA:
01689         if( ( Read( REG_LR_IRQFLAGS ) & RFLR_IRQFLAGS_CADDETECTED ) == RFLR_IRQFLAGS_CADDETECTED )
01690         {
01691             // Clear Irq
01692             Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_CADDETECTED | RFLR_IRQFLAGS_CADDONE );
01693             if (this->RadioEvents && this->RadioEvents->CadDone)
01694             {
01695                 this->RadioEvents->CadDone(this, this->RadioEvents->userThisPtr, this->RadioEvents->userData, true );
01696             }
01697         }
01698         else
01699         {
01700             // Clear Irq
01701             Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_CADDONE );
01702             if (this->RadioEvents && this->RadioEvents->CadDone)
01703             {
01704                 this->RadioEvents->CadDone(this, this->RadioEvents->userThisPtr, this->RadioEvents->userData, false );
01705             }
01706         }
01707         break;
01708     default:
01709         break;
01710     }
01711 }
01712 
01713 void SX1276::OnDio4Irq( void )
01714 {
01715     switch( this->settings.Modem )
01716     {
01717     case MODEM_FSK:
01718         {
01719             if( this->settings.FskPacketHandler.PreambleDetected == false )
01720             {
01721                 this->settings.FskPacketHandler.PreambleDetected = true;
01722             }
01723         }
01724         break;
01725     case MODEM_LORA:
01726         break;
01727     default:
01728         break;
01729     }
01730 }
01731 
01732 void SX1276::OnDio5Irq( void )
01733 {
01734     switch( this->settings.Modem )
01735     {
01736     case MODEM_FSK:
01737         break;
01738     case MODEM_LORA:
01739         break;
01740     default:
01741         break;
01742     }
01743 }