sanfan-lora

Fork of SX1276Lib by lzbp li

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers sx1276.cpp Source File

sx1276.cpp

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