20171208

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 Bandwidth
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->rxtxBuffer = new uint8_t[RX_BUFFER_SIZE];
00056 
00057     this->RadioEvents = events;
00058 
00059     this->dioIrq  = new DioIrqHandler[6];
00060 
00061     this->dioIrq [0] = &SX1276::OnDio0Irq;
00062     this->dioIrq [1] = &SX1276::OnDio1Irq;
00063     this->dioIrq [2] = &SX1276::OnDio2Irq;
00064     this->dioIrq [3] = &SX1276::OnDio3Irq;
00065     this->dioIrq [4] = &SX1276::OnDio4Irq;
00066     this->dioIrq [5] = NULL;
00067 
00068     this->settings.State = RF_IDLE;
00069 }
00070 
00071 SX1276::~SX1276( )
00072 {
00073     delete this->rxtxBuffer;
00074     delete this->dioIrq ;
00075 }
00076 
00077 void SX1276::Init( RadioEvents_t *events )
00078 {
00079     this->RadioEvents = events;
00080 }
00081 
00082 RadioState SX1276::GetStatus ( void )
00083 {
00084     return this->settings.State;
00085 }
00086 
00087 void SX1276::SetChannel( uint32_t freq )
00088 {
00089     this->settings.Channel = freq;
00090     freq = ( uint32_t )( ( double )freq / ( double )FREQ_STEP );
00091     Write( REG_FRFMSB, ( uint8_t )( ( freq >> 16 ) & 0xFF ) );
00092     Write( REG_FRFMID, ( uint8_t )( ( freq >> 8 ) & 0xFF ) );
00093     Write( REG_FRFLSB, ( uint8_t )( freq & 0xFF ) );
00094 }
00095 
00096 bool SX1276::IsChannelFree( RadioModems_t modem, uint32_t freq, int16_t rssiThresh )
00097 {
00098     int16_t rssi = 0;
00099 
00100     SetModem( modem );
00101 
00102     SetChannel( freq );
00103 
00104     SetOpMode( RF_OPMODE_RECEIVER );
00105 
00106     wait_ms( 1 );
00107 
00108     rssi = GetRssi( modem );
00109 
00110     Sleep( );
00111 
00112     if( rssi > rssiThresh )
00113     {
00114         return false;
00115     }
00116     return true;
00117 }
00118 
00119 uint32_t SX1276::Random( void )
00120 {
00121     uint8_t i;
00122     uint32_t rnd = 0;
00123 
00124     /*
00125      * Radio setup for random number generation
00126      */
00127     // Set LoRa modem ON
00128     SetModem( MODEM_LORA );
00129 
00130     // Disable LoRa modem interrupts
00131     Write( REG_LR_IRQFLAGSMASK, RFLR_IRQFLAGS_RXTIMEOUT |
00132                   RFLR_IRQFLAGS_RXDONE |
00133                   RFLR_IRQFLAGS_PAYLOADCRCERROR |
00134                   RFLR_IRQFLAGS_VALIDHEADER |
00135                   RFLR_IRQFLAGS_TXDONE |
00136                   RFLR_IRQFLAGS_CADDONE |
00137                   RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL |
00138                   RFLR_IRQFLAGS_CADDETECTED );
00139 
00140     // Set radio in continuous reception
00141     SetOpMode( RF_OPMODE_RECEIVER );
00142 
00143     for( i = 0; i < 32; i++ )
00144     {
00145         wait_ms( 1 );
00146         // Unfiltered RSSI value reading. Only takes the LSB value
00147         rnd |= ( ( uint32_t )Read( REG_LR_RSSIWIDEBAND ) & 0x01 ) << i;
00148     }
00149 
00150     Sleep( );
00151 
00152     return rnd;
00153 }
00154 
00155 /*!
00156  * Performs the Rx chain calibration for LF and HF bands
00157  * \remark Must be called just after the reset so all registers are at their
00158  *         default values
00159  */
00160 void SX1276::RxChainCalibration ( void )
00161 {
00162     uint8_t regPaConfigInitVal;
00163     uint32_t initialFreq;
00164 
00165     // Save context
00166     regPaConfigInitVal = this->Read( REG_PACONFIG );
00167     initialFreq = ( double )( ( ( uint32_t )this->Read( REG_FRFMSB ) << 16 ) |
00168                               ( ( uint32_t )this->Read( REG_FRFMID ) << 8 ) |
00169                               ( ( uint32_t )this->Read( REG_FRFLSB ) ) ) * ( double )FREQ_STEP;
00170 
00171     // Cut the PA just in case, RFO output, power = -1 dBm
00172     this->Write( REG_PACONFIG, 0x00 );
00173 
00174     // Launch Rx chain calibration for LF band
00175     Write ( REG_IMAGECAL, ( Read( REG_IMAGECAL ) & RF_IMAGECAL_IMAGECAL_MASK ) | RF_IMAGECAL_IMAGECAL_START );
00176     while( ( Read( REG_IMAGECAL ) & RF_IMAGECAL_IMAGECAL_RUNNING ) == RF_IMAGECAL_IMAGECAL_RUNNING )
00177     {
00178     }
00179 
00180     // Sets a Frequency in HF band
00181     SetChannel( 868000000 );
00182 
00183     // Launch Rx chain calibration for HF band
00184     Write ( REG_IMAGECAL, ( Read( REG_IMAGECAL ) & RF_IMAGECAL_IMAGECAL_MASK ) | RF_IMAGECAL_IMAGECAL_START );
00185     while( ( Read( REG_IMAGECAL ) & RF_IMAGECAL_IMAGECAL_RUNNING ) == RF_IMAGECAL_IMAGECAL_RUNNING )
00186     {
00187     }
00188 
00189     // Restore context
00190     this->Write( REG_PACONFIG, regPaConfigInitVal );
00191     SetChannel( initialFreq );
00192 }
00193 
00194 /*!
00195  * Returns the known FSK bandwidth registers value
00196  *
00197  * \param [IN] bandwidth Bandwidth value in Hz
00198  * \retval regValue Bandwidth register value.
00199  */
00200 uint8_t SX1276::GetFskBandwidthRegValue ( uint32_t bandwidth )
00201 {
00202     uint8_t i;
00203 
00204     for( i = 0; i < ( sizeof( FskBandwidths ) / sizeof( FskBandwidth_t  ) ) - 1; i++ )
00205     {
00206         if( ( bandwidth >= FskBandwidths[i].bandwidth ) && ( bandwidth < FskBandwidths[i + 1].bandwidth ) )
00207         {
00208             return FskBandwidths[i].RegValue;
00209         }
00210     }
00211     // ERROR: Value not found
00212     while( 1 );
00213 }
00214 
00215 void SX1276::SetRxConfig( RadioModems_t modem, uint32_t bandwidth,
00216                          uint32_t datarate, uint8_t coderate,
00217                          uint32_t bandwidthAfc, uint16_t preambleLen,
00218                          uint16_t symbTimeout, bool fixLen,
00219                          uint8_t payloadLen,
00220                          bool crcOn, bool freqHopOn, uint8_t hopPeriod,
00221                          bool iqInverted, bool rxContinuous )
00222 {
00223     SetModem( modem );
00224 
00225     switch( modem )
00226     {
00227     case MODEM_FSK:
00228         {
00229             this->settings.Fsk.Bandwidth = bandwidth;
00230             this->settings.Fsk.Datarate = datarate;
00231             this->settings.Fsk.BandwidthAfc = bandwidthAfc;
00232             this->settings.Fsk.FixLen = fixLen;
00233             this->settings.Fsk.PayloadLen = payloadLen;
00234             this->settings.Fsk.CrcOn = crcOn;
00235             this->settings.Fsk.IqInverted = iqInverted;
00236             this->settings.Fsk.RxContinuous = rxContinuous;
00237             this->settings.Fsk.PreambleLen = preambleLen;
00238             this->settings.Fsk.RxSingleTimeout = symbTimeout * ( ( 1.0 / ( double )datarate ) * 8.0 ) * 1e3;
00239 
00240             datarate = ( uint16_t )( ( double )XTAL_FREQ / ( double )datarate );
00241             Write( REG_BITRATEMSB, ( uint8_t )( datarate >> 8 ) );
00242             Write( REG_BITRATELSB, ( uint8_t )( datarate & 0xFF ) );
00243 
00244             Write( REG_RXBW, GetFskBandwidthRegValue ( bandwidth ) );
00245             Write( REG_AFCBW, GetFskBandwidthRegValue ( bandwidthAfc ) );
00246 
00247             Write( REG_PREAMBLEMSB, ( uint8_t )( ( preambleLen >> 8 ) & 0xFF ) );
00248             Write( REG_PREAMBLELSB, ( uint8_t )( preambleLen & 0xFF ) );
00249 
00250             if( fixLen == 1 )
00251             {
00252                 Write( REG_PAYLOADLENGTH, payloadLen );
00253             }
00254             else
00255             {
00256                 Write( REG_PAYLOADLENGTH, 0xFF ); // Set payload length to the maximum
00257             }
00258             
00259             Write( REG_PACKETCONFIG1,
00260                          ( Read( REG_PACKETCONFIG1 ) &
00261                            RF_PACKETCONFIG1_CRC_MASK &
00262                            RF_PACKETCONFIG1_PACKETFORMAT_MASK ) |
00263                            ( ( fixLen == 1 ) ? RF_PACKETCONFIG1_PACKETFORMAT_FIXED : RF_PACKETCONFIG1_PACKETFORMAT_VARIABLE ) |
00264                            ( crcOn << 4 ) );
00265             Write( REG_PACKETCONFIG2, ( Read( REG_PACKETCONFIG2 ) | RF_PACKETCONFIG2_DATAMODE_PACKET ) );
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     SetModem( modem );
00392 
00393     SetRfTxPower( power );
00394 
00395     switch( modem )
00396     {
00397     case MODEM_FSK:
00398         {
00399             this->settings.Fsk.Power = power;
00400             this->settings.Fsk.Fdev = fdev;
00401             this->settings.Fsk.Bandwidth = bandwidth;
00402             this->settings.Fsk.Datarate = datarate;
00403             this->settings.Fsk.PreambleLen = preambleLen;
00404             this->settings.Fsk.FixLen = fixLen;
00405             this->settings.Fsk.CrcOn = crcOn;
00406             this->settings.Fsk.IqInverted = iqInverted;
00407             this->settings.Fsk.TxTimeout = timeout;
00408 
00409             fdev = ( uint16_t )( ( double )fdev / ( double )FREQ_STEP );
00410             Write( REG_FDEVMSB, ( uint8_t )( fdev >> 8 ) );
00411             Write( REG_FDEVLSB, ( uint8_t )( fdev & 0xFF ) );
00412 
00413             datarate = ( uint16_t )( ( double )XTAL_FREQ / ( double )datarate );
00414             Write( REG_BITRATEMSB, ( uint8_t )( datarate >> 8 ) );
00415             Write( REG_BITRATELSB, ( uint8_t )( datarate & 0xFF ) );
00416 
00417             Write( REG_PREAMBLEMSB, ( preambleLen >> 8 ) & 0x00FF );
00418             Write( REG_PREAMBLELSB, preambleLen & 0xFF );
00419 
00420             Write( REG_PACKETCONFIG1,
00421                          ( Read( REG_PACKETCONFIG1 ) &
00422                            RF_PACKETCONFIG1_CRC_MASK &
00423                            RF_PACKETCONFIG1_PACKETFORMAT_MASK ) |
00424                            ( ( fixLen == 1 ) ? RF_PACKETCONFIG1_PACKETFORMAT_FIXED : RF_PACKETCONFIG1_PACKETFORMAT_VARIABLE ) |
00425                            ( crcOn << 4 ) );
00426             Write( REG_PACKETCONFIG2, ( Read( REG_PACKETCONFIG2 ) | RF_PACKETCONFIG2_DATAMODE_PACKET ) );
00427         }
00428         break;
00429     case MODEM_LORA:
00430         {
00431             this->settings.LoRa.Power = power;
00432             if( bandwidth > 2 )
00433             {
00434                 // Fatal error: When using LoRa modem only bandwidths 125, 250 and 500 kHz are supported
00435                 while( 1 );
00436             }
00437             bandwidth += 7;
00438             this->settings.LoRa.Bandwidth = bandwidth;
00439             this->settings.LoRa.Datarate = datarate;
00440             this->settings.LoRa.Coderate = coderate;
00441             this->settings.LoRa.PreambleLen = preambleLen;
00442             this->settings.LoRa.FixLen = fixLen;
00443             this->settings.LoRa.FreqHopOn = freqHopOn;
00444             this->settings.LoRa.HopPeriod = hopPeriod;
00445             this->settings.LoRa.CrcOn = crcOn;
00446             this->settings.LoRa.IqInverted = iqInverted;
00447             this->settings.LoRa.TxTimeout = timeout;
00448 
00449             if( datarate > 12 )
00450             {
00451                 datarate = 12;
00452             }
00453             else if( datarate < 6 )
00454             {
00455                 datarate = 6;
00456             }
00457             if( ( ( bandwidth == 7 ) && ( ( datarate == 11 ) || ( datarate == 12 ) ) ) ||
00458                 ( ( bandwidth == 8 ) && ( datarate == 12 ) ) )
00459             {
00460                 this->settings.LoRa.LowDatarateOptimize = 0x01;
00461             }
00462             else
00463             {
00464                 this->settings.LoRa.LowDatarateOptimize = 0x00;
00465             }
00466 
00467             if( this->settings.LoRa.FreqHopOn == true )
00468             {
00469                 Write( REG_LR_PLLHOP, ( Read( REG_LR_PLLHOP ) & RFLR_PLLHOP_FASTHOP_MASK ) | RFLR_PLLHOP_FASTHOP_ON );
00470                 Write( REG_LR_HOPPERIOD, this->settings.LoRa.HopPeriod );
00471             }
00472 
00473             Write( REG_LR_MODEMCONFIG1,
00474                          ( Read( REG_LR_MODEMCONFIG1 ) &
00475                            RFLR_MODEMCONFIG1_BW_MASK &
00476                            RFLR_MODEMCONFIG1_CODINGRATE_MASK &
00477                            RFLR_MODEMCONFIG1_IMPLICITHEADER_MASK ) |
00478                            ( bandwidth << 4 ) | ( coderate << 1 ) |
00479                            fixLen );
00480 
00481             Write( REG_LR_MODEMCONFIG2,
00482                          ( Read( REG_LR_MODEMCONFIG2 ) &
00483                            RFLR_MODEMCONFIG2_SF_MASK &
00484                            RFLR_MODEMCONFIG2_RXPAYLOADCRC_MASK ) |
00485                            ( datarate << 4 ) | ( crcOn << 2 ) );
00486 
00487             Write( REG_LR_MODEMCONFIG3,
00488                          ( Read( REG_LR_MODEMCONFIG3 ) &
00489                            RFLR_MODEMCONFIG3_LOWDATARATEOPTIMIZE_MASK ) |
00490                            ( this->settings.LoRa.LowDatarateOptimize << 3 ) );
00491 
00492             Write( REG_LR_PREAMBLEMSB, ( preambleLen >> 8 ) & 0x00FF );
00493             Write( REG_LR_PREAMBLELSB, preambleLen & 0xFF );
00494 
00495             if( datarate == 6 )
00496             {
00497                 Write( REG_LR_DETECTOPTIMIZE,
00498                              ( Read( REG_LR_DETECTOPTIMIZE ) &
00499                                RFLR_DETECTIONOPTIMIZE_MASK ) |
00500                                RFLR_DETECTIONOPTIMIZE_SF6 );
00501                 Write( REG_LR_DETECTIONTHRESHOLD,
00502                              RFLR_DETECTIONTHRESH_SF6 );
00503             }
00504             else
00505             {
00506                 Write( REG_LR_DETECTOPTIMIZE,
00507                              ( Read( REG_LR_DETECTOPTIMIZE ) &
00508                              RFLR_DETECTIONOPTIMIZE_MASK ) |
00509                              RFLR_DETECTIONOPTIMIZE_SF7_TO_SF12 );
00510                 Write( REG_LR_DETECTIONTHRESHOLD,
00511                              RFLR_DETECTIONTHRESH_SF7_TO_SF12 );
00512             }
00513         }
00514         break;
00515     }
00516 }
00517 
00518 uint32_t SX1276::TimeOnAir( RadioModems_t modem, uint8_t pktLen )
00519 {
00520     uint32_t airTime = 0;
00521 
00522     switch( modem )
00523     {
00524     case MODEM_FSK:
00525         {
00526             airTime = rint( ( 8 * ( this->settings.Fsk.PreambleLen +
00527                                      ( ( Read( REG_SYNCCONFIG ) & ~RF_SYNCCONFIG_SYNCSIZE_MASK ) + 1 ) +
00528                                      ( ( this->settings.Fsk.FixLen == 0x01 ) ? 0.0 : 1.0 ) +
00529                                      ( ( ( Read( REG_PACKETCONFIG1 ) & ~RF_PACKETCONFIG1_ADDRSFILTERING_MASK ) != 0x00 ) ? 1.0 : 0 ) +
00530                                      pktLen +
00531                                      ( ( this->settings.Fsk.CrcOn == 0x01 ) ? 2.0 : 0 ) ) /
00532                                      this->settings.Fsk.Datarate ) * 1e3 );
00533         }
00534         break;
00535     case MODEM_LORA:
00536         {
00537             double bw = 0.0;
00538             // REMARK: When using LoRa modem only bandwidths 125, 250 and 500 kHz are supported
00539             switch( this->settings.LoRa.Bandwidth )
00540             {
00541             //case 0: // 7.8 kHz
00542             //    bw = 78e2;
00543             //    break;
00544             //case 1: // 10.4 kHz
00545             //    bw = 104e2;
00546             //    break;
00547             //case 2: // 15.6 kHz
00548             //    bw = 156e2;
00549             //    break;
00550             //case 3: // 20.8 kHz
00551             //    bw = 208e2;
00552             //    break;
00553             //case 4: // 31.2 kHz
00554             //    bw = 312e2;
00555             //    break;
00556             //case 5: // 41.4 kHz
00557             //    bw = 414e2;
00558             //    break;
00559             //case 6: // 62.5 kHz
00560             //    bw = 625e2;
00561             //    break;
00562             case 7: // 125 kHz
00563                 bw = 125e3;
00564                 break;
00565             case 8: // 250 kHz
00566                 bw = 250e3;
00567                 break;
00568             case 9: // 500 kHz
00569                 bw = 500e3;
00570                 break;
00571             }
00572 
00573             // Symbol rate : time for one symbol (secs)
00574             double rs = bw / ( 1 << this->settings.LoRa.Datarate );
00575             double ts = 1 / rs;
00576             // time of preamble
00577             double tPreamble = ( this->settings.LoRa.PreambleLen + 4.25 ) * ts;
00578             // Symbol length of payload and time
00579             double tmp = ceil( ( 8 * pktLen - 4 * this->settings.LoRa.Datarate +
00580                                  28 + 16 * this->settings.LoRa.CrcOn -
00581                                  ( this->settings.LoRa.FixLen ? 20 : 0 ) ) /
00582                                  ( double )( 4 * ( this->settings.LoRa.Datarate -
00583                                  ( ( this->settings.LoRa.LowDatarateOptimize > 0 ) ? 2 : 0 ) ) ) ) *
00584                                  ( this->settings.LoRa.Coderate + 4 );
00585             double nPayload = 8 + ( ( tmp > 0 ) ? tmp : 0 );
00586             double tPayload = nPayload * ts;
00587             // Time on air
00588             double tOnAir = tPreamble + tPayload;
00589             // return ms secs
00590             airTime = floor( tOnAir * 1e3 + 0.999 );
00591         }
00592         break;
00593     }
00594     return airTime;
00595 }
00596 
00597 void SX1276::Send( uint8_t *buffer, uint8_t size )
00598 {
00599     uint32_t txTimeout = 0;
00600 
00601     switch( this->settings.Modem )
00602     {
00603     case MODEM_FSK:
00604         {
00605             this->settings.FskPacketHandler.NbBytes = 0;
00606             this->settings.FskPacketHandler.Size = size;
00607 
00608             if( this->settings.Fsk.FixLen == false )
00609             {
00610                 WriteFifo( ( uint8_t* )&size, 1 );
00611             }
00612             else
00613             {
00614                 Write( REG_PAYLOADLENGTH, size );
00615             }
00616 
00617             if( ( size > 0 ) && ( size <= 64 ) )
00618             {
00619                 this->settings.FskPacketHandler.ChunkSize = size;
00620             }
00621             else
00622             {
00623                 memcpy( rxtxBuffer, buffer, size );
00624                 this->settings.FskPacketHandler.ChunkSize = 32;
00625             }
00626 
00627             // Write payload buffer
00628             WriteFifo( buffer, this->settings.FskPacketHandler.ChunkSize );
00629             this->settings.FskPacketHandler.NbBytes += this->settings.FskPacketHandler.ChunkSize;
00630             txTimeout = this->settings.Fsk.TxTimeout;
00631         }
00632         break;
00633     case MODEM_LORA:
00634         {
00635             if( this->settings.LoRa.IqInverted == true )
00636             {
00637                 Write( REG_LR_INVERTIQ, ( ( Read( REG_LR_INVERTIQ ) & RFLR_INVERTIQ_TX_MASK & RFLR_INVERTIQ_RX_MASK ) | RFLR_INVERTIQ_RX_OFF | RFLR_INVERTIQ_TX_ON ) );
00638                 Write( REG_LR_INVERTIQ2, RFLR_INVERTIQ2_ON );
00639             }
00640             else
00641             {
00642                 Write( REG_LR_INVERTIQ, ( ( Read( REG_LR_INVERTIQ ) & RFLR_INVERTIQ_TX_MASK & RFLR_INVERTIQ_RX_MASK ) | RFLR_INVERTIQ_RX_OFF | RFLR_INVERTIQ_TX_OFF ) );
00643                 Write( REG_LR_INVERTIQ2, RFLR_INVERTIQ2_OFF );
00644             }
00645 
00646             this->settings.LoRaPacketHandler.Size = size;
00647 
00648             // Initializes the payload size
00649             Write( REG_LR_PAYLOADLENGTH, size );
00650 
00651             // Full buffer used for Tx
00652             Write( REG_LR_FIFOTXBASEADDR, 0 );
00653             Write( REG_LR_FIFOADDRPTR, 0 );
00654 
00655             // FIFO operations can not take place in Sleep mode
00656             if( ( Read( REG_OPMODE ) & ~RF_OPMODE_MASK ) == RF_OPMODE_SLEEP )
00657             {
00658                 Standby( );
00659                 wait_ms( 1 );
00660             }
00661             // Write payload buffer
00662             WriteFifo( buffer, size );
00663             txTimeout = this->settings.LoRa.TxTimeout;
00664         }
00665         break;
00666     }
00667 
00668     Tx( txTimeout );
00669 }
00670 
00671 void SX1276::Sleep( void )
00672 {
00673     txTimeoutTimer .detach( );
00674     rxTimeoutTimer.detach( );
00675 
00676     SetOpMode( RF_OPMODE_SLEEP );
00677     this->settings.State = RF_IDLE;
00678 }
00679 
00680 void SX1276::Standby( void )
00681 {
00682     txTimeoutTimer .detach( );
00683     rxTimeoutTimer.detach( );
00684 
00685     SetOpMode( RF_OPMODE_STANDBY );
00686     this->settings.State = RF_IDLE;
00687 }
00688 
00689 void SX1276::Rx( uint32_t timeout )
00690 {
00691     bool rxContinuous = false;
00692 
00693     switch( this->settings.Modem )
00694     {
00695     case MODEM_FSK:
00696         {
00697             rxContinuous = this->settings.Fsk.RxContinuous;
00698 
00699             // DIO0=PayloadReady
00700             // DIO1=FifoLevel
00701             // DIO2=SyncAddr
00702             // DIO3=FifoEmpty
00703             // DIO4=Preamble
00704             // DIO5=ModeReady
00705             Write( REG_DIOMAPPING1, ( Read( REG_DIOMAPPING1 ) & RF_DIOMAPPING1_DIO0_MASK &
00706                                                                             RF_DIOMAPPING1_DIO1_MASK &
00707                                                                             RF_DIOMAPPING1_DIO2_MASK ) |
00708                                                                             RF_DIOMAPPING1_DIO0_00 |
00709                                                                             RF_DIOMAPPING1_DIO1_00 |
00710                                                                             RF_DIOMAPPING1_DIO2_11 );
00711 
00712             Write( REG_DIOMAPPING2, ( Read( REG_DIOMAPPING2 ) & RF_DIOMAPPING2_DIO4_MASK &
00713                                                                             RF_DIOMAPPING2_MAP_MASK ) |
00714                                                                             RF_DIOMAPPING2_DIO4_11 |
00715                                                                             RF_DIOMAPPING2_MAP_PREAMBLEDETECT );
00716 
00717             this->settings.FskPacketHandler.FifoThresh = Read( REG_FIFOTHRESH ) & 0x3F;
00718 
00719             Write( REG_RXCONFIG, RF_RXCONFIG_AFCAUTO_ON | RF_RXCONFIG_AGCAUTO_ON | RF_RXCONFIG_RXTRIGER_PREAMBLEDETECT );
00720 
00721             this->settings.FskPacketHandler.PreambleDetected = false;
00722             this->settings.FskPacketHandler.SyncWordDetected = false;
00723             this->settings.FskPacketHandler.NbBytes = 0;
00724             this->settings.FskPacketHandler.Size = 0;
00725         }
00726         break;
00727     case MODEM_LORA:
00728         {
00729             if( this->settings.LoRa.IqInverted == true )
00730             {
00731                 Write( REG_LR_INVERTIQ, ( ( Read( REG_LR_INVERTIQ ) & RFLR_INVERTIQ_TX_MASK & RFLR_INVERTIQ_RX_MASK ) | RFLR_INVERTIQ_RX_ON | RFLR_INVERTIQ_TX_OFF ) );
00732                 Write( REG_LR_INVERTIQ2, RFLR_INVERTIQ2_ON );
00733             }
00734             else
00735             {
00736                 Write( REG_LR_INVERTIQ, ( ( Read( REG_LR_INVERTIQ ) & RFLR_INVERTIQ_TX_MASK & RFLR_INVERTIQ_RX_MASK ) | RFLR_INVERTIQ_RX_OFF | RFLR_INVERTIQ_TX_OFF ) );
00737                 Write( REG_LR_INVERTIQ2, RFLR_INVERTIQ2_OFF );
00738             }
00739 
00740             // ERRATA 2.3 - Receiver Spurious Reception of a LoRa Signal
00741             if( this->settings.LoRa.Bandwidth < 9 )
00742             {
00743                 Write( REG_LR_DETECTOPTIMIZE, Read( REG_LR_DETECTOPTIMIZE ) & 0x7F );
00744                 Write( REG_LR_TEST30, 0x00 );
00745                 switch( this->settings.LoRa.Bandwidth )
00746                 {
00747                 case 0: // 7.8 kHz
00748                     Write( REG_LR_TEST2F, 0x48 );
00749                     SetChannel(this->settings.Channel + 7.81e3 );
00750                     break;
00751                 case 1: // 10.4 kHz
00752                     Write( REG_LR_TEST2F, 0x44 );
00753                     SetChannel(this->settings.Channel + 10.42e3 );
00754                     break;
00755                 case 2: // 15.6 kHz
00756                     Write( REG_LR_TEST2F, 0x44 );
00757                     SetChannel(this->settings.Channel + 15.62e3 );
00758                     break;
00759                 case 3: // 20.8 kHz
00760                     Write( REG_LR_TEST2F, 0x44 );
00761                     SetChannel(this->settings.Channel + 20.83e3 );
00762                     break;
00763                 case 4: // 31.2 kHz
00764                     Write( REG_LR_TEST2F, 0x44 );
00765                     SetChannel(this->settings.Channel + 31.25e3 );
00766                     break;
00767                 case 5: // 41.4 kHz
00768                     Write( REG_LR_TEST2F, 0x44 );
00769                     SetChannel(this->settings.Channel + 41.67e3 );
00770                     break;
00771                 case 6: // 62.5 kHz
00772                     Write( REG_LR_TEST2F, 0x40 );
00773                     break;
00774                 case 7: // 125 kHz
00775                     Write( REG_LR_TEST2F, 0x40 );
00776                     break;
00777                 case 8: // 250 kHz
00778                     Write( REG_LR_TEST2F, 0x40 );
00779                     break;
00780                 }
00781             }
00782             else
00783             {
00784                 Write( REG_LR_DETECTOPTIMIZE, Read( REG_LR_DETECTOPTIMIZE ) | 0x80 );
00785             }
00786 
00787             rxContinuous = this->settings.LoRa.RxContinuous;
00788 
00789             if( this->settings.LoRa.FreqHopOn == true )
00790             {
00791                 Write( REG_LR_IRQFLAGSMASK, //RFLR_IRQFLAGS_RXTIMEOUT |
00792                                                   //RFLR_IRQFLAGS_RXDONE |
00793                                                   //RFLR_IRQFLAGS_PAYLOADCRCERROR |
00794                                                   RFLR_IRQFLAGS_VALIDHEADER |
00795                                                   RFLR_IRQFLAGS_TXDONE |
00796                                                   RFLR_IRQFLAGS_CADDONE |
00797                                                   //RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL |
00798                                                   RFLR_IRQFLAGS_CADDETECTED );
00799 
00800                 // DIO0=RxDone, DIO2=FhssChangeChannel
00801                 Write( REG_DIOMAPPING1, ( Read( REG_DIOMAPPING1 ) & RFLR_DIOMAPPING1_DIO0_MASK & RFLR_DIOMAPPING1_DIO2_MASK  ) | RFLR_DIOMAPPING1_DIO0_00 | RFLR_DIOMAPPING1_DIO2_00 );
00802             }
00803             else
00804             {
00805                 Write( REG_LR_IRQFLAGSMASK, //RFLR_IRQFLAGS_RXTIMEOUT |
00806                                                   //RFLR_IRQFLAGS_RXDONE |
00807                                                   //RFLR_IRQFLAGS_PAYLOADCRCERROR |
00808                                                   RFLR_IRQFLAGS_VALIDHEADER |
00809                                                   RFLR_IRQFLAGS_TXDONE |
00810                                                   RFLR_IRQFLAGS_CADDONE |
00811                                                   RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL |
00812                                                   RFLR_IRQFLAGS_CADDETECTED );
00813 
00814                 // DIO0=RxDone
00815                 Write( REG_DIOMAPPING1, ( Read( REG_DIOMAPPING1 ) & RFLR_DIOMAPPING1_DIO0_MASK ) | RFLR_DIOMAPPING1_DIO0_00 );
00816             }
00817             Write( REG_LR_FIFORXBASEADDR, 0 );
00818             Write( REG_LR_FIFOADDRPTR, 0 );
00819         }
00820         break;
00821     }
00822 
00823     memset( rxtxBuffer, 0, ( size_t )RX_BUFFER_SIZE );
00824 
00825     this->settings.State = RF_RX_RUNNING;
00826     if( timeout != 0 )
00827     {
00828         rxTimeoutTimer.attach_us( mbed::callback( this, &SX1276::OnTimeoutIrq ), timeout * 1e3 );
00829     }
00830 
00831     if( this->settings.Modem == MODEM_FSK )
00832     {
00833         SetOpMode( RF_OPMODE_RECEIVER );
00834 
00835         if( rxContinuous == false )
00836         {
00837             rxTimeoutSyncWord.attach_us( mbed::callback( this, &SX1276::OnTimeoutIrq ),
00838                                          this->settings.Fsk.RxSingleTimeout * 1e3 );
00839         }
00840     }
00841     else
00842     {
00843         if( rxContinuous == true )
00844         {
00845             SetOpMode( RFLR_OPMODE_RECEIVER );
00846         }
00847         else
00848         {
00849             SetOpMode( RFLR_OPMODE_RECEIVER_SINGLE );
00850         }
00851     }
00852 }
00853 
00854 void SX1276::Tx( uint32_t timeout )
00855 {
00856 
00857     switch( this->settings.Modem )
00858     {
00859     case MODEM_FSK:
00860         {
00861             // DIO0=PacketSent
00862             // DIO1=FifoEmpty
00863             // DIO2=FifoFull
00864             // DIO3=FifoEmpty
00865             // DIO4=LowBat
00866             // DIO5=ModeReady
00867             Write( REG_DIOMAPPING1, ( Read( REG_DIOMAPPING1 ) & RF_DIOMAPPING1_DIO0_MASK &
00868                                                                             RF_DIOMAPPING1_DIO1_MASK &
00869                                                                             RF_DIOMAPPING1_DIO2_MASK ) |
00870                                                                             RF_DIOMAPPING1_DIO1_01 );
00871 
00872             Write( REG_DIOMAPPING2, ( Read( REG_DIOMAPPING2 ) & RF_DIOMAPPING2_DIO4_MASK &
00873                                                                             RF_DIOMAPPING2_MAP_MASK ) );
00874             this->settings.FskPacketHandler.FifoThresh = Read( REG_FIFOTHRESH ) & 0x3F;
00875         }
00876         break;
00877     case MODEM_LORA:
00878         {
00879             if( this->settings.LoRa.FreqHopOn == true )
00880             {
00881                 Write( REG_LR_IRQFLAGSMASK, RFLR_IRQFLAGS_RXTIMEOUT |
00882                                                   RFLR_IRQFLAGS_RXDONE |
00883                                                   RFLR_IRQFLAGS_PAYLOADCRCERROR |
00884                                                   RFLR_IRQFLAGS_VALIDHEADER |
00885                                                   //RFLR_IRQFLAGS_TXDONE |
00886                                                   RFLR_IRQFLAGS_CADDONE |
00887                                                   //RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL |
00888                                                   RFLR_IRQFLAGS_CADDETECTED );
00889 
00890                 // DIO0=TxDone, DIO2=FhssChangeChannel
00891                 Write( REG_DIOMAPPING1, ( Read( REG_DIOMAPPING1 ) & RFLR_DIOMAPPING1_DIO0_MASK & RFLR_DIOMAPPING1_DIO2_MASK ) | RFLR_DIOMAPPING1_DIO0_01 | RFLR_DIOMAPPING1_DIO2_00 );
00892             }
00893             else
00894             {
00895                 Write( REG_LR_IRQFLAGSMASK, RFLR_IRQFLAGS_RXTIMEOUT |
00896                                                   RFLR_IRQFLAGS_RXDONE |
00897                                                   RFLR_IRQFLAGS_PAYLOADCRCERROR |
00898                                                   RFLR_IRQFLAGS_VALIDHEADER |
00899                                                   //RFLR_IRQFLAGS_TXDONE |
00900                                                   RFLR_IRQFLAGS_CADDONE |
00901                                                   RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL |
00902                                                   RFLR_IRQFLAGS_CADDETECTED );
00903 
00904                 // DIO0=TxDone
00905                 Write( REG_DIOMAPPING1, ( Read( REG_DIOMAPPING1 ) & RFLR_DIOMAPPING1_DIO0_MASK ) | RFLR_DIOMAPPING1_DIO0_01 );
00906             }
00907         }
00908         break;
00909     }
00910 
00911     this->settings.State = RF_TX_RUNNING;
00912     txTimeoutTimer .attach_us( mbed::callback( this, &SX1276::OnTimeoutIrq ), timeout * 1e3 );
00913     SetOpMode( RF_OPMODE_TRANSMITTER );
00914 }
00915 
00916 void SX1276::StartCad( void )
00917 {
00918     switch( this->settings.Modem )
00919     {
00920     case MODEM_FSK:
00921         {
00922 
00923         }
00924         break;
00925     case MODEM_LORA:
00926         {
00927             Write( REG_LR_IRQFLAGSMASK, RFLR_IRQFLAGS_RXTIMEOUT |
00928                                         RFLR_IRQFLAGS_RXDONE |
00929                                         RFLR_IRQFLAGS_PAYLOADCRCERROR |
00930                                         RFLR_IRQFLAGS_VALIDHEADER |
00931                                         RFLR_IRQFLAGS_TXDONE |
00932                                         //RFLR_IRQFLAGS_CADDONE |
00933                                         RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL // |
00934                                         //RFLR_IRQFLAGS_CADDETECTED
00935                                         );
00936 
00937             // DIO3=CADDone
00938             Write( REG_DIOMAPPING1, ( Read( REG_DIOMAPPING1 ) & RFLR_DIOMAPPING1_DIO3_MASK ) | RFLR_DIOMAPPING1_DIO3_00 );
00939 
00940             this->settings.State = RF_CAD;
00941             SetOpMode( RFLR_OPMODE_CAD );
00942         }
00943         break;
00944     default:
00945         break;
00946     }
00947 }
00948 
00949 void SX1276::SetTxContinuousWave( uint32_t freq, int8_t power, uint16_t time )
00950 {
00951     uint32_t timeout = ( uint32_t )( time * 1e6 );
00952 
00953     SetChannel( freq );
00954 
00955     SetTxConfig( MODEM_FSK, power, 0, 0, 4800, 0, 5, false, false, 0, 0, 0, timeout );
00956 
00957     Write( REG_PACKETCONFIG2, ( Read( REG_PACKETCONFIG2 ) & RF_PACKETCONFIG2_DATAMODE_MASK ) );
00958     // Disable radio interrupts
00959     Write( REG_DIOMAPPING1, RF_DIOMAPPING1_DIO0_11 | RF_DIOMAPPING1_DIO1_11 );
00960     Write( REG_DIOMAPPING2, RF_DIOMAPPING2_DIO4_10 | RF_DIOMAPPING2_DIO5_10 );
00961 
00962     this->settings.State = RF_TX_RUNNING;
00963     txTimeoutTimer .attach_us( mbed::callback( this, &SX1276::OnTimeoutIrq ), timeout );
00964     SetOpMode( RF_OPMODE_TRANSMITTER );
00965 }
00966 
00967 int16_t SX1276::GetRssi( RadioModems_t modem )
00968 {
00969     int16_t rssi = 0;
00970 
00971     switch( modem )
00972     {
00973     case MODEM_FSK:
00974         rssi = -( Read( REG_RSSIVALUE ) >> 1 );
00975         break;
00976     case MODEM_LORA:
00977         if( this->settings.Channel > RF_MID_BAND_THRESH )
00978         {
00979             rssi = RSSI_OFFSET_HF + Read( REG_LR_RSSIVALUE );
00980         }
00981         else
00982         {
00983             rssi = RSSI_OFFSET_LF + Read( REG_LR_RSSIVALUE );
00984         }
00985         break;
00986     default:
00987         rssi = -1;
00988         break;
00989     }
00990     return rssi;
00991 }
00992 
00993 void SX1276::SetOpMode( uint8_t opMode )
00994 {
00995     if( opMode == RF_OPMODE_SLEEP )
00996     {
00997         SetAntSwLowPower( true );
00998     }
00999     else
01000     {
01001         SetAntSwLowPower( false );
01002         SetAntSw( opMode );
01003     }
01004     Write( REG_OPMODE, ( Read( REG_OPMODE ) & RF_OPMODE_MASK ) | opMode );
01005 }
01006 
01007 void SX1276::SetModem( RadioModems_t modem )
01008 {
01009     if( ( Read( REG_OPMODE ) & RFLR_OPMODE_LONGRANGEMODE_ON ) != 0 )
01010     {
01011         this->settings.Modem = MODEM_LORA;
01012     }
01013     else
01014     {
01015         this->settings.Modem = MODEM_FSK;
01016     }
01017 
01018     if( this->settings.Modem == modem )
01019     {
01020         return;
01021     }
01022 
01023     this->settings.Modem = modem;
01024     switch( this->settings.Modem )
01025     {
01026     default:
01027     case MODEM_FSK:
01028         Sleep( );
01029         Write( REG_OPMODE, ( Read( REG_OPMODE ) & RFLR_OPMODE_LONGRANGEMODE_MASK ) | RFLR_OPMODE_LONGRANGEMODE_OFF );
01030 
01031         Write( REG_DIOMAPPING1, 0x00 );
01032         Write( REG_DIOMAPPING2, 0x30 ); // DIO5=ModeReady
01033         break;
01034     case MODEM_LORA:
01035         Sleep( );
01036         Write( REG_OPMODE, ( Read( REG_OPMODE ) & RFLR_OPMODE_LONGRANGEMODE_MASK ) | RFLR_OPMODE_LONGRANGEMODE_ON );
01037 
01038         Write( REG_DIOMAPPING1, 0x00 );
01039         Write( REG_DIOMAPPING2, 0x00 );
01040         break;
01041     }
01042 }
01043 
01044 void SX1276::SetMaxPayloadLength( RadioModems_t modem, uint8_t max )
01045 {
01046     this->SetModem( modem );
01047 
01048     switch( modem )
01049     {
01050     case MODEM_FSK:
01051         if( this->settings.Fsk.FixLen == false )
01052         {
01053             this->Write( REG_PAYLOADLENGTH, max );
01054         }
01055         break;
01056     case MODEM_LORA:
01057         this->Write( REG_LR_PAYLOADMAXLENGTH, max );
01058         break;
01059     }
01060 }
01061 
01062 void SX1276::SetPublicNetwork( bool enable )
01063 {
01064     SetModem( MODEM_LORA );
01065     this->settings.LoRa.PublicNetwork = enable;
01066     if( enable == true )
01067     {
01068         // Change LoRa modem SyncWord
01069         Write( REG_LR_SYNCWORD, LORA_MAC_PUBLIC_SYNCWORD );
01070     }
01071     else
01072     {
01073         // Change LoRa modem SyncWord
01074         Write( REG_LR_SYNCWORD, LORA_MAC_PRIVATE_SYNCWORD );
01075     }
01076 }
01077 
01078 void SX1276::OnTimeoutIrq( void )
01079 {
01080     switch( this->settings.State )
01081     {
01082     case RF_RX_RUNNING:
01083         if( this->settings.Modem == MODEM_FSK )
01084         {
01085             this->settings.FskPacketHandler.PreambleDetected = false;
01086             this->settings.FskPacketHandler.SyncWordDetected = false;
01087             this->settings.FskPacketHandler.NbBytes = 0;
01088             this->settings.FskPacketHandler.Size = 0;
01089 
01090             // Clear Irqs
01091             Write( REG_IRQFLAGS1, RF_IRQFLAGS1_RSSI |
01092                                         RF_IRQFLAGS1_PREAMBLEDETECT |
01093                                         RF_IRQFLAGS1_SYNCADDRESSMATCH );
01094             Write( REG_IRQFLAGS2, RF_IRQFLAGS2_FIFOOVERRUN );
01095 
01096             if( this->settings.Fsk.RxContinuous == true )
01097             {
01098                 // Continuous mode restart Rx chain
01099                 Write( REG_RXCONFIG, Read( REG_RXCONFIG ) | RF_RXCONFIG_RESTARTRXWITHOUTPLLLOCK );
01100                 rxTimeoutSyncWord.attach_us( mbed::callback( this, &SX1276::OnTimeoutIrq ),
01101                                              this->settings.Fsk.RxSingleTimeout * 1e3 );
01102             }
01103             else
01104             {
01105                 this->settings.State = RF_IDLE;
01106                 rxTimeoutSyncWord.detach( );
01107             }
01108         }
01109         if( ( this->RadioEvents != NULL ) && ( this->RadioEvents->RxTimeout != NULL ) )
01110         {
01111             this->RadioEvents->RxTimeout( );
01112         }
01113         break;
01114     case RF_TX_RUNNING:
01115         // Tx timeout shouldn't happen.
01116         // But it has been observed that when it happens it is a result of a corrupted SPI transfer
01117         // it depends on the platform design.
01118         // 
01119         // The workaround is to put the radio in a known state. Thus, we re-initialize it.
01120 
01121         // BEGIN WORKAROUND
01122 
01123         // Reset the radio
01124         Reset( );
01125 
01126         // Calibrate Rx chain
01127         RxChainCalibration ( );
01128 
01129         // Initialize radio default values
01130         SetOpMode( RF_OPMODE_SLEEP );
01131 
01132         RadioRegistersInit( );
01133 
01134         SetModem( MODEM_FSK );
01135 
01136         // Restore previous network type setting.
01137         SetPublicNetwork( this->settings.LoRa.PublicNetwork );
01138         // END WORKAROUND
01139 
01140         this->settings.State = RF_IDLE;
01141         if( ( this->RadioEvents != NULL ) && ( this->RadioEvents->TxTimeout != NULL ) )
01142         {
01143             this->RadioEvents->TxTimeout( );
01144         }
01145         break;
01146     default:
01147         break;
01148     }
01149 }
01150 
01151 void SX1276::OnDio0Irq( void )
01152 {
01153     volatile uint8_t irqFlags = 0;
01154 
01155     switch( this->settings.State )
01156     {
01157         case RF_RX_RUNNING:
01158             //TimerStop( &RxTimeoutTimer );
01159             // RxDone interrupt
01160             switch( this->settings.Modem )
01161             {
01162             case MODEM_FSK:
01163                 if( this->settings.Fsk.CrcOn == true )
01164                 {
01165                     irqFlags = Read( REG_IRQFLAGS2 );
01166                     if( ( irqFlags & RF_IRQFLAGS2_CRCOK ) != RF_IRQFLAGS2_CRCOK )
01167                     {
01168                         // Clear Irqs
01169                         Write( REG_IRQFLAGS1, RF_IRQFLAGS1_RSSI |
01170                                                     RF_IRQFLAGS1_PREAMBLEDETECT |
01171                                                     RF_IRQFLAGS1_SYNCADDRESSMATCH );
01172                         Write( REG_IRQFLAGS2, RF_IRQFLAGS2_FIFOOVERRUN );
01173 
01174                         rxTimeoutTimer.detach( );
01175 
01176                         if( this->settings.Fsk.RxContinuous == false )
01177                         {
01178                             rxTimeoutSyncWord.detach( );
01179                             this->settings.State = RF_IDLE;
01180                         }
01181                         else
01182                         {
01183                             // Continuous mode restart Rx chain
01184                             Write( REG_RXCONFIG, Read( REG_RXCONFIG ) | RF_RXCONFIG_RESTARTRXWITHOUTPLLLOCK );
01185                             rxTimeoutSyncWord.attach_us( mbed::callback( this, &SX1276::OnTimeoutIrq ),
01186                                                          this->settings.Fsk.RxSingleTimeout * 1e3 );
01187                         }
01188 
01189                         if( ( this->RadioEvents != NULL ) && ( this->RadioEvents->RxError != NULL ) )
01190                         {
01191                             this->RadioEvents->RxError( );
01192                         }
01193                         this->settings.FskPacketHandler.PreambleDetected = false;
01194                         this->settings.FskPacketHandler.SyncWordDetected = false;
01195                         this->settings.FskPacketHandler.NbBytes = 0;
01196                         this->settings.FskPacketHandler.Size = 0;
01197                         break;
01198                     }
01199                 }
01200 
01201                 // Read received packet size
01202                 if( ( this->settings.FskPacketHandler.Size == 0 ) && ( this->settings.FskPacketHandler.NbBytes == 0 ) )
01203                 {
01204                     if( this->settings.Fsk.FixLen == false )
01205                     {
01206                         ReadFifo( ( uint8_t* )&this->settings.FskPacketHandler.Size, 1 );
01207                     }
01208                     else
01209                     {
01210                         this->settings.FskPacketHandler.Size = Read( REG_PAYLOADLENGTH );
01211                     }
01212                     ReadFifo( rxtxBuffer + this->settings.FskPacketHandler.NbBytes, this->settings.FskPacketHandler.Size - this->settings.FskPacketHandler.NbBytes );
01213                     this->settings.FskPacketHandler.NbBytes += ( this->settings.FskPacketHandler.Size - this->settings.FskPacketHandler.NbBytes );
01214                 }
01215                 else
01216                 {
01217                     ReadFifo( rxtxBuffer + this->settings.FskPacketHandler.NbBytes, this->settings.FskPacketHandler.Size - this->settings.FskPacketHandler.NbBytes );
01218                     this->settings.FskPacketHandler.NbBytes += ( this->settings.FskPacketHandler.Size - this->settings.FskPacketHandler.NbBytes );
01219                 }
01220 
01221                 rxTimeoutTimer.detach( );
01222 
01223                 if( this->settings.Fsk.RxContinuous == false )
01224                 {
01225                     this->settings.State = RF_IDLE;
01226                     rxTimeoutSyncWord.detach( );
01227                 }
01228                 else
01229                 {
01230                     // Continuous mode restart Rx chain
01231                     Write( REG_RXCONFIG, Read( REG_RXCONFIG ) | RF_RXCONFIG_RESTARTRXWITHOUTPLLLOCK );
01232                     rxTimeoutSyncWord.attach_us( mbed::callback( this, &SX1276::OnTimeoutIrq ),
01233                                                  this->settings.Fsk.RxSingleTimeout * 1e3 );
01234                 }
01235 
01236                 if( ( this->RadioEvents != NULL ) && ( this->RadioEvents->RxDone != NULL ) )
01237                 {
01238                     this->RadioEvents->RxDone( rxtxBuffer, this->settings.FskPacketHandler.Size, this->settings.FskPacketHandler.RssiValue, 0 );
01239                 }
01240                 this->settings.FskPacketHandler.PreambleDetected = false;
01241                 this->settings.FskPacketHandler.SyncWordDetected = false;
01242                 this->settings.FskPacketHandler.NbBytes = 0;
01243                 this->settings.FskPacketHandler.Size = 0;
01244                 break;
01245             case MODEM_LORA:
01246                 {
01247                     int8_t snr = 0;
01248 
01249                     // Clear Irq
01250                     Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_RXDONE );
01251 
01252                     irqFlags = Read( REG_LR_IRQFLAGS );
01253                     if( ( irqFlags & RFLR_IRQFLAGS_PAYLOADCRCERROR_MASK ) == RFLR_IRQFLAGS_PAYLOADCRCERROR )
01254                     {
01255                         // Clear Irq
01256                         Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_PAYLOADCRCERROR );
01257 
01258                         if( this->settings.LoRa.RxContinuous == false )
01259                         {
01260                             this->settings.State = RF_IDLE;
01261                         }
01262                         rxTimeoutTimer.detach( );
01263 
01264                         if( ( this->RadioEvents != NULL ) && ( this->RadioEvents->RxError != NULL ) )
01265                         {
01266                             this->RadioEvents->RxError( );
01267                         }
01268                         break;
01269                     }
01270 
01271                     this->settings.LoRaPacketHandler.SnrValue = Read( REG_LR_PKTSNRVALUE );
01272                     if( this->settings.LoRaPacketHandler.SnrValue & 0x80 ) // The SNR sign bit is 1
01273                     {
01274                         // Invert and divide by 4
01275                         snr = ( ( ~this->settings.LoRaPacketHandler.SnrValue + 1 ) & 0xFF ) >> 2;
01276                         snr = -snr;
01277                     }
01278                     else
01279                     {
01280                         // Divide by 4
01281                         snr = ( this->settings.LoRaPacketHandler.SnrValue & 0xFF ) >> 2;
01282                     }
01283 
01284                     int16_t rssi = Read( REG_LR_PKTRSSIVALUE );
01285                     if( snr < 0 )
01286                     {
01287                         if( this->settings.Channel > RF_MID_BAND_THRESH )
01288                         {
01289                             this->settings.LoRaPacketHandler.RssiValue = RSSI_OFFSET_HF + rssi + ( rssi >> 4 ) +
01290                                                                           snr;
01291                         }
01292                         else
01293                         {
01294                             this->settings.LoRaPacketHandler.RssiValue = RSSI_OFFSET_LF + rssi + ( rssi >> 4 ) +
01295                                                                           snr;
01296                         }
01297                     }
01298                     else
01299                     {
01300                         if( this->settings.Channel > RF_MID_BAND_THRESH )
01301                         {
01302                             this->settings.LoRaPacketHandler.RssiValue = RSSI_OFFSET_HF + rssi + ( rssi >> 4 );
01303                         }
01304                         else
01305                         {
01306                             this->settings.LoRaPacketHandler.RssiValue = RSSI_OFFSET_LF + rssi + ( rssi >> 4 );
01307                         }
01308                     }
01309 
01310                     this->settings.LoRaPacketHandler.Size = Read( REG_LR_RXNBBYTES );
01311                     ReadFifo( rxtxBuffer, this->settings.LoRaPacketHandler.Size );
01312 
01313                     if( this->settings.LoRa.RxContinuous == false )
01314                     {
01315                         this->settings.State = RF_IDLE;
01316                     }
01317                     rxTimeoutTimer.detach( );
01318 
01319                     if( ( this->RadioEvents != NULL ) && ( this->RadioEvents->RxDone != NULL ) )
01320                     {
01321                         this->RadioEvents->RxDone( rxtxBuffer, this->settings.LoRaPacketHandler.Size, this->settings.LoRaPacketHandler.RssiValue, this->settings.LoRaPacketHandler.SnrValue );
01322                     }
01323                 }
01324                 break;
01325             default:
01326                 break;
01327             }
01328             break;
01329         case RF_TX_RUNNING:
01330             txTimeoutTimer .detach( );
01331             // TxDone interrupt
01332             switch( this->settings.Modem )
01333             {
01334             case MODEM_LORA:
01335                 // Clear Irq
01336                 Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_TXDONE );
01337                 // Intentional fall through
01338             case MODEM_FSK:
01339             default:
01340                 this->settings.State = RF_IDLE;
01341                 if( ( this->RadioEvents != NULL ) && ( this->RadioEvents->TxDone != NULL ) )
01342                 {
01343                     this->RadioEvents->TxDone( );
01344                 }
01345                 break;
01346             }
01347             break;
01348         default:
01349             break;
01350     }
01351 }
01352 
01353 void SX1276::OnDio1Irq( void )
01354 {
01355     switch( this->settings.State )
01356     {
01357         case RF_RX_RUNNING:
01358             switch( this->settings.Modem )
01359             {
01360             case MODEM_FSK:
01361                 // FifoLevel interrupt
01362                 // Read received packet size
01363                 if( ( this->settings.FskPacketHandler.Size == 0 ) && ( this->settings.FskPacketHandler.NbBytes == 0 ) )
01364                 {
01365                     if( this->settings.Fsk.FixLen == false )
01366                     {
01367                         ReadFifo( ( uint8_t* )&this->settings.FskPacketHandler.Size, 1 );
01368                     }
01369                     else
01370                     {
01371                         this->settings.FskPacketHandler.Size = Read( REG_PAYLOADLENGTH );
01372                     }
01373                 }
01374 
01375                 if( ( this->settings.FskPacketHandler.Size - this->settings.FskPacketHandler.NbBytes ) > this->settings.FskPacketHandler.FifoThresh )
01376                 {
01377                     ReadFifo( ( rxtxBuffer + this->settings.FskPacketHandler.NbBytes ), this->settings.FskPacketHandler.FifoThresh );
01378                     this->settings.FskPacketHandler.NbBytes += this->settings.FskPacketHandler.FifoThresh;
01379                 }
01380                 else
01381                 {
01382                     ReadFifo( ( rxtxBuffer + this->settings.FskPacketHandler.NbBytes ), this->settings.FskPacketHandler.Size - this->settings.FskPacketHandler.NbBytes );
01383                     this->settings.FskPacketHandler.NbBytes += ( this->settings.FskPacketHandler.Size - this->settings.FskPacketHandler.NbBytes );
01384                 }
01385                 break;
01386             case MODEM_LORA:
01387                 // Sync time out
01388                 rxTimeoutTimer.detach( );
01389                 // Clear Irq
01390                 Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_RXTIMEOUT );
01391 
01392                 this->settings.State = RF_IDLE;
01393                 if( ( this->RadioEvents != NULL ) && ( this->RadioEvents->RxTimeout != NULL ) )
01394                 {
01395                     this->RadioEvents->RxTimeout( );
01396                 }
01397                 break;
01398             default:
01399                 break;
01400             }
01401             break;
01402         case RF_TX_RUNNING:
01403             switch( this->settings.Modem )
01404             {
01405             case MODEM_FSK:
01406                 // FifoEmpty interrupt
01407                 if( ( this->settings.FskPacketHandler.Size - this->settings.FskPacketHandler.NbBytes ) > this->settings.FskPacketHandler.ChunkSize )
01408                 {
01409                     WriteFifo( ( rxtxBuffer + this->settings.FskPacketHandler.NbBytes ), this->settings.FskPacketHandler.ChunkSize );
01410                     this->settings.FskPacketHandler.NbBytes += this->settings.FskPacketHandler.ChunkSize;
01411                 }
01412                 else
01413                 {
01414                     // Write the last chunk of data
01415                     WriteFifo( rxtxBuffer + this->settings.FskPacketHandler.NbBytes, this->settings.FskPacketHandler.Size - this->settings.FskPacketHandler.NbBytes );
01416                     this->settings.FskPacketHandler.NbBytes += this->settings.FskPacketHandler.Size - this->settings.FskPacketHandler.NbBytes;
01417                 }
01418                 break;
01419             case MODEM_LORA:
01420                 break;
01421             default:
01422                 break;
01423             }
01424             break;
01425         default:
01426             break;
01427     }
01428 }
01429 
01430 void SX1276::OnDio2Irq( void )
01431 {
01432     switch( this->settings.State )
01433     {
01434         case RF_RX_RUNNING:
01435             switch( this->settings.Modem )
01436             {
01437             case MODEM_FSK:
01438                 // Checks if DIO4 is connected. If it is not PreambleDtected is set to true.
01439                 if( this->dioIrq [4] == NULL )
01440                 {
01441                     this->settings.FskPacketHandler.PreambleDetected = true;
01442                 }
01443 
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 }