Add support of Nucleo-F446RE

Dependents:   Aloha LoRaBaseStation

Fork of SX1276Lib by Semtech

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers sx1276.cpp Source File

sx1276.cpp

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