Sille Van Landschoot / SX1272Lib

Fork of SX1272Lib by Semtech

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers sx1272.cpp Source File

sx1272.cpp

00001 /*
00002  / _____)             _              | |
00003 ( (____  _____ ____ _| |_ _____  ____| |__
00004  \____ \| ___ |    (_   _) ___ |/ ___)  _ \
00005  _____) ) ____| | | || |_| ____( (___| | | |
00006 (______/|_____)_|_|_| \__)_____)\____)_| |_|
00007     (C) 2015 Semtech
00008 
00009 Description: Actual implementation of a SX1272 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 "sx1272.h"
00016 
00017 const FskBandwidth_t  SX1272::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 SX1272::SX1272( 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] = &SX1272::OnDio0Irq;
00064     this->dioIrq [1] = &SX1272::OnDio1Irq;
00065     this->dioIrq [2] = &SX1272::OnDio2Irq;
00066     this->dioIrq [3] = &SX1272::OnDio3Irq;
00067     this->dioIrq [4] = &SX1272::OnDio4Irq;
00068     this->dioIrq [5] = NULL;
00069     
00070     this->settings.State = RF_IDLE;
00071 }
00072 
00073 SX1272::~SX1272( )
00074 {
00075     delete this->rxtxBuffer;
00076     delete this->dioIrq ;
00077 }
00078 
00079 void SX1272::Init( RadioEvents_t *events )
00080 {
00081     this->RadioEvents = events;
00082 }
00083 
00084 RadioState SX1272::GetStatus ( void )
00085 {
00086     return this->settings.State;
00087 }
00088 
00089 void SX1272::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 SX1272::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 SX1272::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  * Returns the known FSK bandwidth registers value
00159  *
00160  * \param [IN] bandwidth Bandwidth value in Hz
00161  * \retval regValue Bandwidth register value.
00162  */
00163 uint8_t SX1272::GetFskBandwidthRegValue ( uint32_t bandwidth )
00164 {
00165     uint8_t i;
00166 
00167     for( i = 0; i < ( sizeof( FskBandwidths ) / sizeof( FskBandwidth_t  ) ) - 1; i++ )
00168     {
00169         if( ( bandwidth >= FskBandwidths[i].bandwidth ) && ( bandwidth < FskBandwidths[i + 1].bandwidth ) )
00170         {
00171             return FskBandwidths[i].RegValue;
00172         }
00173     }
00174     // ERROR: Value not found
00175     while( 1 );
00176 }
00177 
00178 void SX1272::SetRxConfig( RadioModems_t modem, uint32_t bandwidth,
00179                          uint32_t datarate, uint8_t coderate,
00180                          uint32_t bandwidthAfc, uint16_t preambleLen,
00181                          uint16_t symbTimeout, bool fixLen,
00182                          uint8_t payloadLen,
00183                          bool crcOn, bool freqHopOn, uint8_t hopPeriod,
00184                          bool iqInverted, bool rxContinuous )
00185 {
00186     SetModem( modem );
00187 
00188     switch( modem )
00189     {
00190     case MODEM_FSK:
00191         {
00192             this->settings.Fsk.Bandwidth = bandwidth;
00193             this->settings.Fsk.Datarate = datarate;
00194             this->settings.Fsk.BandwidthAfc = bandwidthAfc;
00195             this->settings.Fsk.FixLen = fixLen;
00196             this->settings.Fsk.PayloadLen = payloadLen;
00197             this->settings.Fsk.CrcOn = crcOn;
00198             this->settings.Fsk.IqInverted = iqInverted;
00199             this->settings.Fsk.RxContinuous = rxContinuous;
00200             this->settings.Fsk.PreambleLen = preambleLen;
00201 
00202             datarate = ( uint16_t )( ( double )XTAL_FREQ / ( double )datarate );
00203             Write( REG_BITRATEMSB, ( uint8_t )( datarate >> 8 ) );
00204             Write( REG_BITRATELSB, ( uint8_t )( datarate & 0xFF ) );
00205 
00206             Write( REG_RXBW, GetFskBandwidthRegValue ( bandwidth ) );
00207             Write( REG_AFCBW, GetFskBandwidthRegValue ( bandwidthAfc ) );
00208 
00209             Write( REG_PREAMBLEMSB, ( uint8_t )( ( preambleLen >> 8 ) & 0xFF ) );
00210             Write( REG_PREAMBLELSB, ( uint8_t )( preambleLen & 0xFF ) );
00211 
00212             if( fixLen == 1 )
00213             {
00214                 Write( REG_PAYLOADLENGTH, payloadLen );
00215             }
00216             else
00217             {
00218                 Write( REG_PAYLOADLENGTH, 0xFF ); // Set payload length to the maximum
00219             }
00220             
00221             Write( REG_PACKETCONFIG1,
00222                          ( Read( REG_PACKETCONFIG1 ) &
00223                            RF_PACKETCONFIG1_CRC_MASK &
00224                            RF_PACKETCONFIG1_PACKETFORMAT_MASK ) |
00225                            ( ( fixLen == 1 ) ? RF_PACKETCONFIG1_PACKETFORMAT_FIXED : RF_PACKETCONFIG1_PACKETFORMAT_VARIABLE ) |
00226                            ( crcOn << 4 ) );
00227         }
00228         break;
00229     case MODEM_LORA:
00230         {
00231             this->settings.LoRa.Bandwidth = bandwidth;
00232             this->settings.LoRa.Datarate = datarate;
00233             this->settings.LoRa.Coderate = coderate;
00234             this->settings.LoRa.PreambleLen = preambleLen;
00235             this->settings.LoRa.FixLen = fixLen;
00236             this->settings.LoRa.PayloadLen = payloadLen;
00237             this->settings.LoRa.CrcOn = crcOn;
00238             this->settings.LoRa.FreqHopOn = freqHopOn;
00239             this->settings.LoRa.HopPeriod = hopPeriod;
00240             this->settings.LoRa.IqInverted = iqInverted;
00241             this->settings.LoRa.RxContinuous = rxContinuous;
00242 
00243             if( datarate > 12 )
00244             {
00245                 datarate = 12;
00246             }
00247             else if( datarate < 6 )
00248             {
00249                 datarate = 6;
00250             }
00251 
00252             if( ( ( bandwidth == 0 ) && ( ( datarate == 11 ) || ( datarate == 12 ) ) ) ||
00253                 ( ( bandwidth == 1 ) && ( datarate == 12 ) ) )
00254             {
00255                 this->settings.LoRa.LowDatarateOptimize = 0x01;
00256             }
00257             else
00258             {
00259                 this->settings.LoRa.LowDatarateOptimize = 0x00;
00260             }
00261 
00262             Write( REG_LR_MODEMCONFIG1,
00263                          ( Read( REG_LR_MODEMCONFIG1 ) &
00264                            RFLR_MODEMCONFIG1_BW_MASK &
00265                            RFLR_MODEMCONFIG1_CODINGRATE_MASK &
00266                            RFLR_MODEMCONFIG1_IMPLICITHEADER_MASK &
00267                            RFLR_MODEMCONFIG1_RXPAYLOADCRC_MASK &
00268                            RFLR_MODEMCONFIG1_LOWDATARATEOPTIMIZE_MASK ) |
00269                            ( bandwidth << 6 ) | ( coderate << 3 ) |
00270                            ( fixLen << 2 ) | ( crcOn << 1 ) |
00271                            this->settings.LoRa.LowDatarateOptimize );
00272 
00273             Write( REG_LR_MODEMCONFIG2,
00274                          ( Read( REG_LR_MODEMCONFIG2 ) &
00275                            RFLR_MODEMCONFIG2_SF_MASK &
00276                            RFLR_MODEMCONFIG2_SYMBTIMEOUTMSB_MASK ) |
00277                            ( datarate << 4 ) |
00278                            ( ( symbTimeout >> 8 ) & ~RFLR_MODEMCONFIG2_SYMBTIMEOUTMSB_MASK ) );
00279 
00280             Write( REG_LR_SYMBTIMEOUTLSB, ( uint8_t )( symbTimeout & 0xFF ) );
00281 
00282             Write( REG_LR_PREAMBLEMSB, ( uint8_t )( ( preambleLen >> 8 ) & 0xFF ) );
00283             Write( REG_LR_PREAMBLELSB, ( uint8_t )( preambleLen & 0xFF ) );
00284 
00285             if( fixLen == 1 )
00286             {
00287                 Write( REG_LR_PAYLOADLENGTH, payloadLen );
00288             }
00289 
00290             if( this->settings.LoRa.FreqHopOn == true )
00291             {
00292                 Write( REG_LR_PLLHOP, ( Read( REG_LR_PLLHOP ) & RFLR_PLLHOP_FASTHOP_MASK ) | RFLR_PLLHOP_FASTHOP_ON );
00293                 Write( REG_LR_HOPPERIOD, this->settings.LoRa.HopPeriod );
00294             }
00295 
00296             if( datarate == 6 )
00297             {
00298                 Write( REG_LR_DETECTOPTIMIZE,
00299                              ( Read( REG_LR_DETECTOPTIMIZE ) &
00300                                RFLR_DETECTIONOPTIMIZE_MASK ) |
00301                                RFLR_DETECTIONOPTIMIZE_SF6 );
00302                 Write( REG_LR_DETECTIONTHRESHOLD,
00303                              RFLR_DETECTIONTHRESH_SF6 );
00304             }
00305             else
00306             {
00307                 Write( REG_LR_DETECTOPTIMIZE,
00308                              ( Read( REG_LR_DETECTOPTIMIZE ) &
00309                              RFLR_DETECTIONOPTIMIZE_MASK ) |
00310                              RFLR_DETECTIONOPTIMIZE_SF7_TO_SF12 );
00311                 Write( REG_LR_DETECTIONTHRESHOLD,
00312                              RFLR_DETECTIONTHRESH_SF7_TO_SF12 );
00313             }
00314         }
00315         break;
00316     }
00317 }
00318 #if defined ( TARGET_MOTE_L152RC )
00319 /*     PD_2=0  PD_2=1
00320 op PaB  rfo     rfo
00321 0  4.6  18.5    27.0
00322 1  5.6  21.1    28.1
00323 2  6.7  23.3    29.1
00324 3  7.7  25.3    30.1
00325 4  8.8  26.2    30.7
00326 5  9.8  27.3    31.2
00327 6  10.7 28.1    31.6
00328 7  11.7 28.6    32.2
00329 8  12.8 29.2    32.4
00330 9  13.7 29.9    32.9
00331 10 14.7 30.5    33.1
00332 11 15.6 30.8    33.4
00333 12 16.4 30.9    33.6
00334 13 17.1 31.0    33.7
00335 14 17.8 31.1    33.7
00336 15 18.4 31.1    33.7
00337 */
00338 //                           txpow:   0  1  2  3  4  5  6  7  8  9 10 11 12 13 14  15  16  17  18  19
00339 static const uint8_t PaBTable[20] = { 0, 0, 0, 0, 0, 1, 2, 3, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 14, 15 };
00340 
00341 //                           txpow:  20 21 22 23 24 25 26 27 28 29 30
00342 static const uint8_t RfoTable[11] = { 1, 1, 1, 2, 2, 3, 4, 5, 6, 8, 9 };
00343 #endif
00344 
00345 void SX1272::SetTxConfig( RadioModems_t modem, int8_t power, uint32_t fdev,
00346                         uint32_t bandwidth, uint32_t datarate,
00347                         uint8_t coderate, uint16_t preambleLen,
00348                         bool fixLen, bool crcOn, bool freqHopOn,
00349                         uint8_t hopPeriod, bool iqInverted, uint32_t timeout )
00350 {
00351     uint8_t paConfig = 0;
00352     uint8_t paDac = 0;
00353 
00354     SetModem( modem );
00355 
00356     paConfig = Read( REG_PACONFIG );
00357     paDac = Read( REG_PADAC );
00358 
00359 #if defined ( TARGET_MOTE_L152RC )
00360     if( power > 19 )
00361     {
00362         paConfig = ( paConfig & RF_PACONFIG_PASELECT_MASK ) | RF_PACONFIG_PASELECT_RFO;
00363         paConfig = ( paConfig & RFLR_PACONFIG_OUTPUTPOWER_MASK ) | RfoTable[power - 20];
00364     }
00365     else
00366     {
00367         paConfig = ( paConfig & RF_PACONFIG_PASELECT_MASK ) | RF_PACONFIG_PASELECT_PABOOST;
00368         paConfig = ( paConfig & RFLR_PACONFIG_OUTPUTPOWER_MASK ) | PaBTable[power];
00369     }
00370 #else
00371     paConfig = ( paConfig & RF_PACONFIG_PASELECT_MASK ) | GetPaSelect( this->settings.Channel );
00372 
00373     if( ( paConfig & RF_PACONFIG_PASELECT_PABOOST ) == RF_PACONFIG_PASELECT_PABOOST )
00374     {
00375         if( power > 17 )
00376         {
00377             paDac = ( paDac & RF_PADAC_20DBM_MASK ) | RF_PADAC_20DBM_ON;
00378         }
00379         else
00380         {
00381             paDac = ( paDac & RF_PADAC_20DBM_MASK ) | RF_PADAC_20DBM_OFF;
00382         }
00383         if( ( paDac & RF_PADAC_20DBM_ON ) == RF_PADAC_20DBM_ON )
00384         {
00385             if( power < 5 )
00386             {
00387                 power = 5;
00388             }
00389             if( power > 20 )
00390             {
00391                 power = 20;
00392             }
00393             paConfig = ( paConfig & RFLR_PACONFIG_OUTPUTPOWER_MASK ) | ( uint8_t )( ( uint16_t )( power - 5 ) & 0x0F );
00394         }
00395         else
00396         {
00397             if( power < 2 )
00398             {
00399                 power = 2;
00400             }
00401             if( power > 17 )
00402             {
00403                 power = 17;
00404             }
00405             paConfig = ( paConfig & RFLR_PACONFIG_OUTPUTPOWER_MASK ) | ( uint8_t )( ( uint16_t )( power - 2 ) & 0x0F );
00406         }
00407     }
00408     else
00409     {
00410         if( power < -1 )
00411         {
00412             power = -1;
00413         }
00414         if( power > 14 )
00415         {
00416             power = 14;
00417         }
00418         paConfig = ( paConfig & RFLR_PACONFIG_OUTPUTPOWER_MASK ) | ( uint8_t )( ( uint16_t )( power + 1 ) & 0x0F );
00419     }
00420 #endif
00421     Write( REG_PACONFIG, paConfig );
00422     Write( REG_PADAC, paDac );
00423 
00424     switch( modem )
00425     {
00426     case MODEM_FSK:
00427         {
00428             this->settings.Fsk.Power = power;
00429             this->settings.Fsk.Fdev = fdev;
00430             this->settings.Fsk.Bandwidth = bandwidth;
00431             this->settings.Fsk.Datarate = datarate;
00432             this->settings.Fsk.PreambleLen = preambleLen;
00433             this->settings.Fsk.FixLen = fixLen;
00434             this->settings.Fsk.CrcOn = crcOn;
00435             this->settings.Fsk.IqInverted = iqInverted;
00436             this->settings.Fsk.TxTimeout = timeout;
00437 
00438             fdev = ( uint16_t )( ( double )fdev / ( double )FREQ_STEP );
00439             Write( REG_FDEVMSB, ( uint8_t )( fdev >> 8 ) );
00440             Write( REG_FDEVLSB, ( uint8_t )( fdev & 0xFF ) );
00441 
00442             datarate = ( uint16_t )( ( double )XTAL_FREQ / ( double )datarate );
00443             Write( REG_BITRATEMSB, ( uint8_t )( datarate >> 8 ) );
00444             Write( REG_BITRATELSB, ( uint8_t )( datarate & 0xFF ) );
00445 
00446             Write( REG_PREAMBLEMSB, ( preambleLen >> 8 ) & 0x00FF );
00447             Write( REG_PREAMBLELSB, preambleLen & 0xFF );
00448 
00449             Write( REG_PACKETCONFIG1,
00450                          ( Read( REG_PACKETCONFIG1 ) &
00451                            RF_PACKETCONFIG1_CRC_MASK &
00452                            RF_PACKETCONFIG1_PACKETFORMAT_MASK ) |
00453                            ( ( fixLen == 1 ) ? RF_PACKETCONFIG1_PACKETFORMAT_FIXED : RF_PACKETCONFIG1_PACKETFORMAT_VARIABLE ) |
00454                            ( crcOn << 4 ) );
00455 
00456         }
00457         break;
00458     case MODEM_LORA:
00459         {
00460             this->settings.LoRa.Power = power;
00461             this->settings.LoRa.Bandwidth = bandwidth;
00462             this->settings.LoRa.Datarate = datarate;
00463             this->settings.LoRa.Coderate = coderate;
00464             this->settings.LoRa.PreambleLen = preambleLen;
00465             this->settings.LoRa.FixLen = fixLen;
00466             this->settings.LoRa.FreqHopOn = freqHopOn;
00467             this->settings.LoRa.HopPeriod = hopPeriod;
00468             this->settings.LoRa.CrcOn = crcOn;
00469             this->settings.LoRa.IqInverted = iqInverted;
00470             this->settings.LoRa.TxTimeout = timeout;
00471 
00472             if( datarate > 12 )
00473             {
00474                 datarate = 12;
00475             }
00476             else if( datarate < 6 )
00477             {
00478                 datarate = 6;
00479             }
00480             if( ( ( bandwidth == 0 ) && ( ( datarate == 11 ) || ( datarate == 12 ) ) ) ||
00481                 ( ( bandwidth == 1 ) && ( datarate == 12 ) ) )
00482             {
00483                 this->settings.LoRa.LowDatarateOptimize = 0x01;
00484             }
00485             else
00486             {
00487                 this->settings.LoRa.LowDatarateOptimize = 0x00;
00488             }
00489 
00490             if( this->settings.LoRa.FreqHopOn == true )
00491             {
00492                 Write( REG_LR_PLLHOP, ( Read( REG_LR_PLLHOP ) & RFLR_PLLHOP_FASTHOP_MASK ) | RFLR_PLLHOP_FASTHOP_ON );
00493                 Write( REG_LR_HOPPERIOD, this->settings.LoRa.HopPeriod );
00494             }
00495 
00496             Write( REG_LR_MODEMCONFIG1,
00497                          ( Read( REG_LR_MODEMCONFIG1 ) &
00498                            RFLR_MODEMCONFIG1_BW_MASK &
00499                            RFLR_MODEMCONFIG1_CODINGRATE_MASK &
00500                            RFLR_MODEMCONFIG1_IMPLICITHEADER_MASK &
00501                            RFLR_MODEMCONFIG1_RXPAYLOADCRC_MASK &
00502                            RFLR_MODEMCONFIG1_LOWDATARATEOPTIMIZE_MASK ) |
00503                            ( bandwidth << 6 ) | ( coderate << 3 ) |
00504                            ( fixLen << 2 ) | ( crcOn << 1 ) |
00505                            this->settings.LoRa.LowDatarateOptimize );
00506 
00507             Write( REG_LR_MODEMCONFIG2,
00508                         ( Read( REG_LR_MODEMCONFIG2 ) &
00509                           RFLR_MODEMCONFIG2_SF_MASK ) |
00510                           ( datarate << 4 ) );
00511 
00512 
00513             Write( REG_LR_PREAMBLEMSB, ( preambleLen >> 8 ) & 0x00FF );
00514             Write( REG_LR_PREAMBLELSB, preambleLen & 0xFF );
00515 
00516             if( datarate == 6 )
00517             {
00518                 Write( REG_LR_DETECTOPTIMIZE,
00519                              ( Read( REG_LR_DETECTOPTIMIZE ) &
00520                                RFLR_DETECTIONOPTIMIZE_MASK ) |
00521                                RFLR_DETECTIONOPTIMIZE_SF6 );
00522                 Write( REG_LR_DETECTIONTHRESHOLD,
00523                              RFLR_DETECTIONTHRESH_SF6 );
00524             }
00525             else
00526             {
00527                 Write( REG_LR_DETECTOPTIMIZE,
00528                              ( Read( REG_LR_DETECTOPTIMIZE ) &
00529                              RFLR_DETECTIONOPTIMIZE_MASK ) |
00530                              RFLR_DETECTIONOPTIMIZE_SF7_TO_SF12 );
00531                 Write( REG_LR_DETECTIONTHRESHOLD,
00532                              RFLR_DETECTIONTHRESH_SF7_TO_SF12 );
00533             }
00534         }
00535         break;
00536     }
00537 }
00538 
00539 double SX1272::TimeOnAir( RadioModems_t modem, uint8_t pktLen )
00540 {
00541     uint32_t airTime = 0;
00542 
00543     switch( modem )
00544     {
00545     case MODEM_FSK:
00546         {
00547             airTime = rint( ( 8 * ( this->settings.Fsk.PreambleLen +
00548                                      ( ( Read( REG_SYNCCONFIG ) & ~RF_SYNCCONFIG_SYNCSIZE_MASK ) + 1 ) +
00549                                      ( ( this->settings.Fsk.FixLen == 0x01 ) ? 0.0 : 1.0 ) +
00550                                      ( ( ( Read( REG_PACKETCONFIG1 ) & ~RF_PACKETCONFIG1_ADDRSFILTERING_MASK ) != 0x00 ) ? 1.0 : 0 ) +
00551                                      pktLen +
00552                                      ( ( this->settings.Fsk.CrcOn == 0x01 ) ? 2.0 : 0 ) ) /
00553                                      this->settings.Fsk.Datarate ) * 1e6 );
00554         }
00555         break;
00556     case MODEM_LORA:
00557         {
00558             double bw = 0.0;
00559             switch( this->settings.LoRa.Bandwidth )
00560             {
00561             case 0: // 125 kHz
00562                 bw = 125e3;
00563                 break;
00564             case 1: // 250 kHz
00565                 bw = 250e3;
00566                 break;
00567             case 2: // 500 kHz
00568                 bw = 500e3;
00569                 break;
00570             }
00571 
00572             // Symbol rate : time for one symbol (secs)
00573             double rs = bw / ( 1 << this->settings.LoRa.Datarate );
00574             double ts = 1 / rs;
00575             // time of preamble
00576             double tPreamble = ( this->settings.LoRa.PreambleLen + 4.25 ) * ts;
00577             // Symbol length of payload and time
00578             double tmp = ceil( ( 8 * pktLen - 4 * this->settings.LoRa.Datarate +
00579                                  28 + 16 * this->settings.LoRa.CrcOn -
00580                                  ( this->settings.LoRa.FixLen ? 20 : 0 ) ) /
00581                                  ( double )( 4 * this->settings.LoRa.Datarate -
00582                                  ( ( this->settings.LoRa.LowDatarateOptimize > 0 ) ? 2 : 0 ) ) ) *
00583                                  ( this->settings.LoRa.Coderate + 4 );
00584             double nPayload = 8 + ( ( tmp > 0 ) ? tmp : 0 );
00585             double tPayload = nPayload * ts;
00586             // Time on air
00587             double tOnAir = tPreamble + tPayload;
00588             // return us secs
00589             airTime = floor( tOnAir * 1e6 + 0.999 );
00590         }
00591         break;
00592     }
00593     return airTime;
00594 }
00595 
00596 void SX1272::Send( uint8_t *buffer, uint8_t size )
00597 {
00598     uint32_t txTimeout = 0;
00599 
00600     switch( this->settings.Modem )
00601     {
00602     case MODEM_FSK:
00603         {
00604             this->settings.FskPacketHandler.NbBytes = 0;
00605             this->settings.FskPacketHandler.Size = size;
00606 
00607             if( this->settings.Fsk.FixLen == false )
00608             {
00609                 WriteFifo( ( uint8_t* )&size, 1 );
00610             }
00611             else
00612             {
00613                 Write( REG_PAYLOADLENGTH, size );
00614             }
00615 
00616             if( ( size > 0 ) && ( size <= 64 ) )
00617             {
00618                 this->settings.FskPacketHandler.ChunkSize = size;
00619             }
00620             else
00621             {
00622                 memcpy( rxtxBuffer, buffer, size );
00623                 this->settings.FskPacketHandler.ChunkSize = 32;
00624             }
00625 
00626             // Write payload buffer
00627             WriteFifo( buffer, this->settings.FskPacketHandler.ChunkSize );
00628             this->settings.FskPacketHandler.NbBytes += this->settings.FskPacketHandler.ChunkSize;
00629             txTimeout = this->settings.Fsk.TxTimeout;
00630         }
00631         break;
00632     case MODEM_LORA:
00633         {
00634             if( this->settings.LoRa.IqInverted == true )
00635             {
00636                 Write( REG_LR_INVERTIQ, ( ( Read( REG_LR_INVERTIQ ) & RFLR_INVERTIQ_TX_MASK & RFLR_INVERTIQ_RX_MASK ) | RFLR_INVERTIQ_RX_OFF | RFLR_INVERTIQ_TX_ON ) );
00637                 Write( REG_LR_INVERTIQ2, RFLR_INVERTIQ2_ON );
00638             }
00639             else
00640             {
00641                 Write( REG_LR_INVERTIQ, ( ( Read( REG_LR_INVERTIQ ) & RFLR_INVERTIQ_TX_MASK & RFLR_INVERTIQ_RX_MASK ) | RFLR_INVERTIQ_RX_OFF | RFLR_INVERTIQ_TX_OFF ) );
00642                 Write( REG_LR_INVERTIQ2, RFLR_INVERTIQ2_OFF );
00643             }
00644 
00645             this->settings.LoRaPacketHandler.Size = size;
00646 
00647             // Initializes the payload size
00648             Write( REG_LR_PAYLOADLENGTH, size );
00649 
00650             // Full buffer used for Tx
00651             Write( REG_LR_FIFOTXBASEADDR, 0 );
00652             Write( REG_LR_FIFOADDRPTR, 0 );
00653 
00654             // FIFO operations can not take place in Sleep mode
00655             if( ( Read( REG_OPMODE ) & ~RF_OPMODE_MASK ) == RF_OPMODE_SLEEP )
00656             {
00657                 Standby( );
00658                 wait_ms( 1 );
00659             }
00660             // Write payload buffer
00661             WriteFifo( buffer, size );
00662             txTimeout = this->settings.LoRa.TxTimeout;
00663         }
00664         break;
00665     }
00666 
00667     Tx( txTimeout );
00668 }
00669 
00670 void SX1272::Sleep( void )
00671 {
00672     txTimeoutTimer .detach(  );
00673     rxTimeoutTimer.detach( );
00674 
00675     SetOpMode( RF_OPMODE_SLEEP );
00676     this->settings.State = RF_IDLE;
00677 }
00678 
00679 void SX1272::Standby( void )
00680 {
00681     txTimeoutTimer .detach(  );
00682     rxTimeoutTimer.detach( );
00683 
00684     SetOpMode( RF_OPMODE_STANDBY );
00685     this->settings.State = RF_IDLE;
00686 }
00687 
00688 void SX1272::Rx( uint32_t timeout )
00689 {
00690     bool rxContinuous = false;
00691     
00692     switch( this->settings.Modem )
00693     {
00694     case MODEM_FSK:
00695         {
00696             rxContinuous = this->settings.Fsk.RxContinuous;
00697 
00698             // DIO0=PayloadReady
00699             // DIO1=FifoLevel
00700             // DIO2=SyncAddr
00701             // DIO3=FifoEmpty
00702             // DIO4=Preamble
00703             // DIO5=ModeReady
00704             Write( REG_DIOMAPPING1, ( Read( REG_DIOMAPPING1 ) & RF_DIOMAPPING1_DIO0_MASK &
00705                                                                             RF_DIOMAPPING1_DIO1_MASK &
00706                                                                             RF_DIOMAPPING1_DIO2_MASK ) |
00707                                                                             RF_DIOMAPPING1_DIO0_00 |
00708                                                                             RF_DIOMAPPING1_DIO1_00 |
00709                                                                             RF_DIOMAPPING1_DIO2_11 );
00710 
00711             Write( REG_DIOMAPPING2, ( Read( REG_DIOMAPPING2 ) & RF_DIOMAPPING2_DIO4_MASK &
00712                                                                             RF_DIOMAPPING2_MAP_MASK ) |
00713                                                                             RF_DIOMAPPING2_DIO4_11 |
00714                                                                             RF_DIOMAPPING2_MAP_PREAMBLEDETECT );
00715 
00716             this->settings.FskPacketHandler.FifoThresh = Read( REG_FIFOTHRESH ) & 0x3F;
00717 
00718             Write( REG_RXCONFIG, RF_RXCONFIG_AFCAUTO_ON | RF_RXCONFIG_AGCAUTO_ON | RF_RXCONFIG_RXTRIGER_PREAMBLEDETECT );
00719 
00720             this->settings.FskPacketHandler.PreambleDetected = false;
00721             this->settings.FskPacketHandler.SyncWordDetected = false;
00722             this->settings.FskPacketHandler.NbBytes = 0;
00723             this->settings.FskPacketHandler.Size = 0;
00724         }
00725         break;
00726     case MODEM_LORA:
00727         {
00728             if( this->settings.LoRa.IqInverted == true )
00729             {
00730                 Write( REG_LR_INVERTIQ, ( ( Read( REG_LR_INVERTIQ ) & RFLR_INVERTIQ_TX_MASK & RFLR_INVERTIQ_RX_MASK ) | RFLR_INVERTIQ_RX_ON | RFLR_INVERTIQ_TX_OFF ) );
00731                 Write( REG_LR_INVERTIQ2, RFLR_INVERTIQ2_ON );
00732             }
00733             else
00734             {
00735                 Write( REG_LR_INVERTIQ, ( ( Read( REG_LR_INVERTIQ ) & RFLR_INVERTIQ_TX_MASK & RFLR_INVERTIQ_RX_MASK ) | RFLR_INVERTIQ_RX_OFF | RFLR_INVERTIQ_TX_OFF ) );
00736                 Write( REG_LR_INVERTIQ2, RFLR_INVERTIQ2_OFF );
00737             }
00738 
00739             rxContinuous = this->settings.LoRa.RxContinuous;
00740 
00741             if( this->settings.LoRa.FreqHopOn == true )
00742             {
00743                 Write( REG_LR_IRQFLAGSMASK, //RFLR_IRQFLAGS_RXTIMEOUT |
00744                                                   //RFLR_IRQFLAGS_RXDONE |
00745                                                   //RFLR_IRQFLAGS_PAYLOADCRCERROR |
00746                                                   RFLR_IRQFLAGS_VALIDHEADER |
00747                                                   RFLR_IRQFLAGS_TXDONE |
00748                                                   RFLR_IRQFLAGS_CADDONE |
00749                                                   //RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL |
00750                                                   RFLR_IRQFLAGS_CADDETECTED );
00751 
00752                 // DIO0=RxDone, DIO2=FhssChangeChannel
00753                 Write( REG_DIOMAPPING1, ( Read( REG_DIOMAPPING1 ) & RFLR_DIOMAPPING1_DIO0_MASK & RFLR_DIOMAPPING1_DIO2_MASK  ) | RFLR_DIOMAPPING1_DIO0_00 | RFLR_DIOMAPPING1_DIO2_00 );
00754             }
00755             else
00756             {
00757                 Write( REG_LR_IRQFLAGSMASK, //RFLR_IRQFLAGS_RXTIMEOUT |
00758                                                   //RFLR_IRQFLAGS_RXDONE |
00759                                                   //RFLR_IRQFLAGS_PAYLOADCRCERROR |
00760                                                   RFLR_IRQFLAGS_VALIDHEADER |
00761                                                   RFLR_IRQFLAGS_TXDONE |
00762                                                   RFLR_IRQFLAGS_CADDONE |
00763                                                   RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL |
00764                                                   RFLR_IRQFLAGS_CADDETECTED );
00765 
00766                 // DIO0=RxDone
00767                 Write( REG_DIOMAPPING1, ( Read( REG_DIOMAPPING1 ) & RFLR_DIOMAPPING1_DIO0_MASK ) | RFLR_DIOMAPPING1_DIO0_00 );
00768             }
00769             Write( REG_LR_FIFORXBASEADDR, 0 );
00770             Write( REG_LR_FIFOADDRPTR, 0 );
00771         }
00772         break;
00773     }
00774 
00775     memset( rxtxBuffer, 0, ( size_t )RX_BUFFER_SIZE );
00776 
00777     this->settings.State = RF_RX_RUNNING;
00778     if( timeout != 0 )
00779     {
00780         rxTimeoutTimer.attach_us( this, &SX1272::OnTimeoutIrq, timeout );
00781     }
00782 
00783     if( this->settings.Modem == MODEM_FSK )
00784     {
00785         SetOpMode( RF_OPMODE_RECEIVER );
00786 
00787         if( rxContinuous == false )
00788         {
00789             rxTimeoutSyncWord.attach_us( this, &SX1272::OnTimeoutIrq, ceil( ( 8.0 * ( this->settings.Fsk.PreambleLen +
00790                                                              ( ( Read( REG_SYNCCONFIG ) &
00791                                                                 ~RF_SYNCCONFIG_SYNCSIZE_MASK ) +
00792                                                                 1.0 ) + 10.0 ) /
00793                                                              ( double )this->settings.Fsk.Datarate ) * 1e6 ) + 4000 );
00794         }
00795     }
00796     else
00797     {
00798         if( rxContinuous == true )
00799         {
00800             SetOpMode( RFLR_OPMODE_RECEIVER );
00801         }
00802         else
00803         {
00804             SetOpMode( RFLR_OPMODE_RECEIVER_SINGLE );
00805         }
00806     }
00807 }
00808 
00809 void SX1272::Tx( uint32_t timeout )
00810 {
00811 
00812     switch( this->settings.Modem )
00813     {
00814     case MODEM_FSK:
00815         {
00816             // DIO0=PacketSent
00817             // DIO1=FifoEmpty
00818             // DIO2=FifoFull
00819             // DIO3=FifoEmpty
00820             // DIO4=LowBat
00821             // DIO5=ModeReady
00822             Write( REG_DIOMAPPING1, ( Read( REG_DIOMAPPING1 ) & RF_DIOMAPPING1_DIO0_MASK &
00823                                                                             RF_DIOMAPPING1_DIO1_MASK &
00824                                                                             RF_DIOMAPPING1_DIO2_MASK ) |
00825                                                                             RF_DIOMAPPING1_DIO1_01 );
00826 
00827             Write( REG_DIOMAPPING2, ( Read( REG_DIOMAPPING2 ) & RF_DIOMAPPING2_DIO4_MASK &
00828                                                                             RF_DIOMAPPING2_MAP_MASK ) );
00829             this->settings.FskPacketHandler.FifoThresh = Read( REG_FIFOTHRESH ) & 0x3F;
00830         }
00831         break;
00832     case MODEM_LORA:
00833         {
00834             if( this->settings.LoRa.FreqHopOn == true )
00835             {
00836                 Write( REG_LR_IRQFLAGSMASK, RFLR_IRQFLAGS_RXTIMEOUT |
00837                                                   RFLR_IRQFLAGS_RXDONE |
00838                                                   RFLR_IRQFLAGS_PAYLOADCRCERROR |
00839                                                   RFLR_IRQFLAGS_VALIDHEADER |
00840                                                   //RFLR_IRQFLAGS_TXDONE |
00841                                                   RFLR_IRQFLAGS_CADDONE |
00842                                                   //RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL |
00843                                                   RFLR_IRQFLAGS_CADDETECTED );
00844 
00845                 // DIO0=TxDone, DIO2=FhssChangeChannel
00846                 Write( REG_DIOMAPPING1, ( Read( REG_DIOMAPPING1 ) & RFLR_DIOMAPPING1_DIO0_MASK & RFLR_DIOMAPPING1_DIO2_MASK ) | RFLR_DIOMAPPING1_DIO0_01 | RFLR_DIOMAPPING1_DIO2_00 );
00847             }
00848             else
00849             {
00850                 Write( REG_LR_IRQFLAGSMASK, RFLR_IRQFLAGS_RXTIMEOUT |
00851                                                   RFLR_IRQFLAGS_RXDONE |
00852                                                   RFLR_IRQFLAGS_PAYLOADCRCERROR |
00853                                                   RFLR_IRQFLAGS_VALIDHEADER |
00854                                                   //RFLR_IRQFLAGS_TXDONE |
00855                                                   RFLR_IRQFLAGS_CADDONE |
00856                                                   RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL |
00857                                                   RFLR_IRQFLAGS_CADDETECTED );
00858 
00859                 // DIO0=TxDone
00860                 Write( REG_DIOMAPPING1, ( Read( REG_DIOMAPPING1 ) & RFLR_DIOMAPPING1_DIO0_MASK ) | RFLR_DIOMAPPING1_DIO0_01 );
00861             }
00862         }
00863         break;
00864     }
00865 
00866     this->settings.State = RF_TX_RUNNING;
00867     txTimeoutTimer .attach_us( this, &SX1272::OnTimeoutIrq, timeout );
00868     SetOpMode( RF_OPMODE_TRANSMITTER );
00869 }
00870 
00871 void SX1272::StartCad( void )
00872 {
00873     switch( this->settings.Modem )
00874     {
00875     case MODEM_FSK:
00876         {
00877 
00878         }
00879         break;
00880     case MODEM_LORA:
00881         {
00882             Write( REG_LR_IRQFLAGSMASK, RFLR_IRQFLAGS_RXTIMEOUT |
00883                                         RFLR_IRQFLAGS_RXDONE |
00884                                         RFLR_IRQFLAGS_PAYLOADCRCERROR |
00885                                         RFLR_IRQFLAGS_VALIDHEADER |
00886                                         RFLR_IRQFLAGS_TXDONE |
00887                                         //RFLR_IRQFLAGS_CADDONE |
00888                                         RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL // |
00889                                         //RFLR_IRQFLAGS_CADDETECTED
00890                                         );
00891 
00892             // DIO3=CADDone
00893             Write( REG_DIOMAPPING1, ( Read( REG_DIOMAPPING1 ) & RFLR_DIOMAPPING1_DIO0_MASK ) | RFLR_DIOMAPPING1_DIO0_00 );
00894 
00895             this->settings.State = RF_CAD;
00896             SetOpMode( RFLR_OPMODE_CAD );
00897         }
00898         break;
00899     default:
00900         break;
00901     }
00902 }
00903 
00904 int16_t SX1272::GetRssi( RadioModems_t modem )
00905 {
00906     int16_t rssi = 0;
00907 
00908     switch( modem )
00909     {
00910     case MODEM_FSK:
00911         rssi = -( Read( REG_RSSIVALUE ) >> 1 );
00912         break;
00913     case MODEM_LORA:
00914         rssi = RSSI_OFFSET + Read( REG_LR_RSSIVALUE );
00915         break;
00916     default:
00917         rssi = -1;
00918         break;
00919     }
00920     return rssi;
00921 }
00922 
00923 void SX1272::SetOpMode( uint8_t opMode )
00924 {
00925     currentOpMode = opMode; // Update global variable
00926     
00927     if( opMode == RF_OPMODE_SLEEP )
00928     {
00929         SetAntSwLowPower( true );
00930     }
00931     else
00932     {
00933         SetAntSwLowPower( false );
00934         if( opMode == RF_OPMODE_TRANSMITTER )
00935         {
00936             SetAntSw( 1 );
00937         }
00938         else
00939         {
00940             SetAntSw( 0 );
00941         }
00942     }
00943     Write( REG_OPMODE, ( Read( REG_OPMODE ) & RF_OPMODE_MASK ) | opMode );
00944 }
00945 
00946 void SX1272::SetModem( RadioModems_t modem )
00947 {
00948     if( this->settings.Modem == modem )
00949     {
00950         return;
00951     }
00952 
00953     this->settings.Modem = modem;
00954     switch( this->settings.Modem )
00955     {
00956     default:
00957     case MODEM_FSK:
00958         SetOpMode( RF_OPMODE_SLEEP );
00959         Write( REG_OPMODE, ( Read( REG_OPMODE ) & RFLR_OPMODE_LONGRANGEMODE_MASK ) | RFLR_OPMODE_LONGRANGEMODE_OFF );
00960     
00961         Write( REG_DIOMAPPING1, 0x00 );
00962         Write( REG_DIOMAPPING2, 0x30 ); // DIO5=ModeReady
00963         break;
00964     case MODEM_LORA:
00965         SetOpMode( RF_OPMODE_SLEEP );
00966         Write( REG_OPMODE, ( Read( REG_OPMODE ) & RFLR_OPMODE_LONGRANGEMODE_MASK ) | RFLR_OPMODE_LONGRANGEMODE_ON );
00967 
00968         Write( REG_DIOMAPPING1, 0x00 );
00969         Write( REG_DIOMAPPING2, 0x00 );
00970         break;
00971     }
00972 }
00973 
00974 void SX1272::SetMaxPayloadLength( RadioModems_t modem, uint8_t max )
00975 {
00976     this->SetModem( modem );
00977 
00978     switch( modem )
00979     {
00980     case MODEM_FSK:
00981         if( this->settings.Fsk.FixLen == false )
00982         {
00983             this->Write( REG_PAYLOADLENGTH, max );
00984         }
00985         break;
00986     case MODEM_LORA:
00987         this->Write( REG_LR_PAYLOADMAXLENGTH, max );
00988         break;
00989     }
00990 }
00991 
00992 void SX1272::OnTimeoutIrq( void )
00993 {
00994     switch( this->settings.State )
00995     {
00996     case RF_RX_RUNNING:
00997         if( this->settings.Modem == MODEM_FSK )
00998         {
00999             this->settings.FskPacketHandler.PreambleDetected = false;
01000             this->settings.FskPacketHandler.SyncWordDetected = false;
01001             this->settings.FskPacketHandler.NbBytes = 0;
01002             this->settings.FskPacketHandler.Size = 0;
01003 
01004             // Clear Irqs
01005             Write( REG_IRQFLAGS1, RF_IRQFLAGS1_RSSI |
01006                                         RF_IRQFLAGS1_PREAMBLEDETECT |
01007                                         RF_IRQFLAGS1_SYNCADDRESSMATCH );
01008             Write( REG_IRQFLAGS2, RF_IRQFLAGS2_FIFOOVERRUN );
01009 
01010             if( this->settings.Fsk.RxContinuous == true )
01011             {
01012                 // Continuous mode restart Rx chain
01013                 Write( REG_RXCONFIG, Read( REG_RXCONFIG ) | RF_RXCONFIG_RESTARTRXWITHOUTPLLLOCK );
01014                 rxTimeoutSyncWord.attach_us( this, &SX1272::OnTimeoutIrq, ceil( ( 8.0 * ( this->settings.Fsk.PreambleLen +
01015                                                              ( ( Read( REG_SYNCCONFIG ) &
01016                                                                 ~RF_SYNCCONFIG_SYNCSIZE_MASK ) +
01017                                                              1.0 ) + 10.0 ) /
01018                                                             ( double )this->settings.Fsk.Datarate ) * 1e6 ) + 4000 );
01019             }
01020             else
01021             {
01022                 this->settings.State = RF_IDLE;
01023                 rxTimeoutSyncWord.detach( );
01024             }
01025         }
01026         if( ( this->RadioEvents != NULL ) && ( this->RadioEvents->RxTimeout != NULL ) )
01027         {
01028             this->RadioEvents->RxTimeout( );
01029         }
01030         break;
01031     case RF_TX_RUNNING:
01032         this->settings.State = RF_IDLE;
01033         if( ( this->RadioEvents != NULL ) && ( this->RadioEvents->TxTimeout != NULL ) )
01034         {
01035             this->RadioEvents->TxTimeout( );
01036         }
01037         break;
01038     default:
01039         break;
01040     }
01041 }
01042 
01043 void SX1272::OnDio0Irq( void )
01044 {
01045     volatile uint8_t irqFlags = 0;
01046 
01047     switch( this->settings.State )
01048     {
01049         case RF_RX_RUNNING:
01050             //TimerStop( &RxTimeoutTimer );
01051             // RxDone interrupt
01052             switch( this->settings.Modem )
01053             {
01054             case MODEM_FSK:
01055                 if( this->settings.Fsk.CrcOn == true )
01056                 {
01057                     irqFlags = Read( REG_IRQFLAGS2 );
01058                     if( ( irqFlags & RF_IRQFLAGS2_CRCOK ) != RF_IRQFLAGS2_CRCOK )
01059                     {
01060                         // Clear Irqs
01061                         Write( REG_IRQFLAGS1, RF_IRQFLAGS1_RSSI |
01062                                                     RF_IRQFLAGS1_PREAMBLEDETECT |
01063                                                     RF_IRQFLAGS1_SYNCADDRESSMATCH );
01064                         Write( REG_IRQFLAGS2, RF_IRQFLAGS2_FIFOOVERRUN );
01065 
01066                         rxTimeoutTimer.detach( );
01067 
01068                         if( this->settings.Fsk.RxContinuous == false )
01069                         {
01070                             rxTimeoutSyncWord.detach( );
01071                             this->settings.State = RF_IDLE;
01072                         }
01073                         else
01074                         {
01075                             // Continuous mode restart Rx chain
01076                             Write( REG_RXCONFIG, Read( REG_RXCONFIG ) | RF_RXCONFIG_RESTARTRXWITHOUTPLLLOCK );
01077                             rxTimeoutSyncWord.attach_us( this, &SX1272::OnTimeoutIrq, ceil( ( 8.0 * ( this->settings.Fsk.PreambleLen +
01078                                                                          ( ( Read( REG_SYNCCONFIG ) &
01079                                                                             ~RF_SYNCCONFIG_SYNCSIZE_MASK ) +
01080                                                                          1.0 ) + 10.0 ) /
01081                                                                         ( double )this->settings.Fsk.Datarate ) * 1e6 ) + 4000 );
01082                         }
01083 
01084 
01085                         if( ( this->RadioEvents != NULL ) && ( this->RadioEvents->RxError != NULL ) )
01086                         {
01087                             this->RadioEvents->RxError( );
01088                         }
01089                         this->settings.FskPacketHandler.PreambleDetected = false;
01090                         this->settings.FskPacketHandler.SyncWordDetected = false;
01091                         this->settings.FskPacketHandler.NbBytes = 0;
01092                         this->settings.FskPacketHandler.Size = 0;
01093                         break;
01094                     }
01095                 }
01096 
01097                 // Read received packet size
01098                 if( ( this->settings.FskPacketHandler.Size == 0 ) && ( this->settings.FskPacketHandler.NbBytes == 0 ) )
01099                 {
01100                     if( this->settings.Fsk.FixLen == false )
01101                     {
01102                         ReadFifo( ( uint8_t* )&this->settings.FskPacketHandler.Size, 1 );
01103                     }
01104                     else
01105                     {
01106                         this->settings.FskPacketHandler.Size = Read( REG_PAYLOADLENGTH );
01107                     }
01108                     ReadFifo( rxtxBuffer + this->settings.FskPacketHandler.NbBytes, this->settings.FskPacketHandler.Size - this->settings.FskPacketHandler.NbBytes );
01109                     this->settings.FskPacketHandler.NbBytes += ( this->settings.FskPacketHandler.Size - this->settings.FskPacketHandler.NbBytes );
01110                 }
01111                 else
01112                 {
01113                     ReadFifo( rxtxBuffer + this->settings.FskPacketHandler.NbBytes, this->settings.FskPacketHandler.Size - this->settings.FskPacketHandler.NbBytes );
01114                     this->settings.FskPacketHandler.NbBytes += ( this->settings.FskPacketHandler.Size - this->settings.FskPacketHandler.NbBytes );
01115                 }
01116 
01117                 rxTimeoutTimer.detach( );
01118 
01119                 if( this->settings.Fsk.RxContinuous == false )
01120                 {
01121                     this->settings.State = RF_IDLE;
01122                     rxTimeoutSyncWord.detach( );
01123                 }
01124                 else
01125                 {
01126                     // Continuous mode restart Rx chain
01127                     Write( REG_RXCONFIG, Read( REG_RXCONFIG ) | RF_RXCONFIG_RESTARTRXWITHOUTPLLLOCK );
01128                     rxTimeoutSyncWord.attach_us( this, &SX1272::OnTimeoutIrq, ceil( ( 8.0 * ( this->settings.Fsk.PreambleLen +
01129                                                                  ( ( Read( REG_SYNCCONFIG ) &
01130                                                                     ~RF_SYNCCONFIG_SYNCSIZE_MASK ) +
01131                                                                  1.0 ) + 10.0 ) /
01132                                                                 ( double )this->settings.Fsk.Datarate ) * 1e6 ) + 4000 );
01133                 }
01134 
01135                 if( ( this->RadioEvents != NULL ) && ( this->RadioEvents->RxDone != NULL ) )
01136                 {
01137                     this->RadioEvents->RxDone( rxtxBuffer, this->settings.FskPacketHandler.Size, this->settings.FskPacketHandler.RssiValue, 0 );
01138                 }
01139                 this->settings.FskPacketHandler.PreambleDetected = false;
01140                 this->settings.FskPacketHandler.SyncWordDetected = false;
01141                 this->settings.FskPacketHandler.NbBytes = 0;
01142                 this->settings.FskPacketHandler.Size = 0;
01143                 break;
01144             case MODEM_LORA:
01145                 {
01146                     int8_t snr = 0;
01147 
01148                     // Clear Irq
01149                     Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_RXDONE );
01150 
01151                     irqFlags = Read( REG_LR_IRQFLAGS );
01152                     if( ( irqFlags & RFLR_IRQFLAGS_PAYLOADCRCERROR_MASK ) == RFLR_IRQFLAGS_PAYLOADCRCERROR )
01153                     {
01154                         // Clear Irq
01155                         Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_PAYLOADCRCERROR );
01156 
01157                         if( this->settings.LoRa.RxContinuous == false )
01158                         {
01159                             this->settings.State = RF_IDLE;
01160                         }
01161                         rxTimeoutTimer.detach( );
01162 
01163                         if( ( this->RadioEvents != NULL ) && ( this->RadioEvents->RxError != NULL ) )
01164                         {
01165                             this->RadioEvents->RxError( );
01166                         }
01167                         break;
01168                     }
01169 
01170                     this->settings.LoRaPacketHandler.SnrValue = Read( REG_LR_PKTSNRVALUE );
01171                     if( this->settings.LoRaPacketHandler.SnrValue & 0x80 ) // The SNR sign bit is 1
01172                     {
01173                         // Invert and divide by 4
01174                         snr = ( ( ~this->settings.LoRaPacketHandler.SnrValue + 1 ) & 0xFF ) >> 2;
01175                         snr = -snr;
01176                     }
01177                     else
01178                     {
01179                         // Divide by 4
01180                         snr = ( this->settings.LoRaPacketHandler.SnrValue & 0xFF ) >> 2;
01181                     }
01182 
01183                     int16_t rssi = Read( REG_LR_PKTRSSIVALUE );
01184                     if( snr < 0 )
01185                     {
01186                         this->settings.LoRaPacketHandler.RssiValue = RSSI_OFFSET + rssi + ( rssi >> 4 ) +
01187                                                                       snr;
01188                     }
01189                     else
01190                     {
01191                         this->settings.LoRaPacketHandler.RssiValue = RSSI_OFFSET + rssi + ( rssi >> 4 );
01192                     }
01193 
01194                     this->settings.LoRaPacketHandler.Size = Read( REG_LR_RXNBBYTES );
01195                     ReadFifo( rxtxBuffer, this->settings.LoRaPacketHandler.Size );
01196 
01197                     if( this->settings.LoRa.RxContinuous == false )
01198                     {
01199                         this->settings.State = RF_IDLE;
01200                     }
01201                     rxTimeoutTimer.detach( );
01202 
01203                     if( ( this->RadioEvents != NULL ) && ( this->RadioEvents->RxDone != NULL ) )
01204                     {
01205                         this->RadioEvents->RxDone( rxtxBuffer, this->settings.LoRaPacketHandler.Size, this->settings.LoRaPacketHandler.RssiValue, this->settings.LoRaPacketHandler.SnrValue );
01206                     }
01207                 }
01208                 break;
01209             default:
01210                 break;
01211             }
01212             break;
01213         case RF_TX_RUNNING:
01214             txTimeoutTimer .detach( );
01215             // TxDone interrupt
01216             switch( this->settings.Modem )
01217             {
01218             case MODEM_LORA:
01219                 // Clear Irq
01220                 Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_TXDONE );
01221                 // Intentional fall through
01222             case MODEM_FSK:
01223             default:
01224                 this->settings.State = RF_IDLE;
01225                 if( ( this->RadioEvents != NULL ) && ( this->RadioEvents->TxDone != NULL ) )
01226                 {
01227                     this->RadioEvents->TxDone( );
01228                 }
01229                 break;
01230             }
01231             break;
01232         default:
01233             break;
01234     }
01235 }
01236 
01237 void SX1272::OnDio1Irq( void )
01238 {
01239     switch( this->settings.State )
01240     {
01241         case RF_RX_RUNNING:
01242             switch( this->settings.Modem )
01243             {
01244             case MODEM_FSK:
01245                 // FifoLevel interrupt
01246                 // Read received packet size
01247                 if( ( this->settings.FskPacketHandler.Size == 0 ) && ( this->settings.FskPacketHandler.NbBytes == 0 ) )
01248                 {
01249                     if( this->settings.Fsk.FixLen == false )
01250                     {
01251                         ReadFifo( ( uint8_t* )&this->settings.FskPacketHandler.Size, 1 );
01252                     }
01253                     else
01254                     {
01255                         this->settings.FskPacketHandler.Size = Read( REG_PAYLOADLENGTH );
01256                     }
01257                 }
01258 
01259                 if( ( this->settings.FskPacketHandler.Size - this->settings.FskPacketHandler.NbBytes ) > this->settings.FskPacketHandler.FifoThresh )
01260                 {
01261                     ReadFifo( ( rxtxBuffer + this->settings.FskPacketHandler.NbBytes ), this->settings.FskPacketHandler.FifoThresh );
01262                     this->settings.FskPacketHandler.NbBytes += this->settings.FskPacketHandler.FifoThresh;
01263                 }
01264                 else
01265                 {
01266                     ReadFifo( ( rxtxBuffer + this->settings.FskPacketHandler.NbBytes ), this->settings.FskPacketHandler.Size - this->settings.FskPacketHandler.NbBytes );
01267                     this->settings.FskPacketHandler.NbBytes += ( this->settings.FskPacketHandler.Size - this->settings.FskPacketHandler.NbBytes );
01268                 }
01269                 break;
01270             case MODEM_LORA:
01271                 // Sync time out
01272                 rxTimeoutTimer.detach( );
01273                 this->settings.State = RF_IDLE;
01274                 if( ( this->RadioEvents != NULL ) && ( this->RadioEvents->RxTimeout != NULL ) )
01275                 {
01276                     this->RadioEvents->RxTimeout( );
01277                 }
01278                 break;
01279             default:
01280                 break;
01281             }
01282             break;
01283         case RF_TX_RUNNING:
01284             switch( this->settings.Modem )
01285             {
01286             case MODEM_FSK:
01287                 // FifoEmpty interrupt
01288                 if( ( this->settings.FskPacketHandler.Size - this->settings.FskPacketHandler.NbBytes ) > this->settings.FskPacketHandler.ChunkSize )
01289                 {
01290                     WriteFifo( ( rxtxBuffer + this->settings.FskPacketHandler.NbBytes ), this->settings.FskPacketHandler.ChunkSize );
01291                     this->settings.FskPacketHandler.NbBytes += this->settings.FskPacketHandler.ChunkSize;
01292                 }
01293                 else
01294                 {
01295                     // Write the last chunk of data
01296                     WriteFifo( rxtxBuffer + this->settings.FskPacketHandler.NbBytes, this->settings.FskPacketHandler.Size - this->settings.FskPacketHandler.NbBytes );
01297                     this->settings.FskPacketHandler.NbBytes += this->settings.FskPacketHandler.Size - this->settings.FskPacketHandler.NbBytes;
01298                 }
01299                 break;
01300             case MODEM_LORA:
01301                 break;
01302             default:
01303                 break;
01304             }
01305             break;
01306         default:
01307             break;
01308     }
01309 }
01310 
01311 void SX1272::OnDio2Irq( void )
01312 {
01313     switch( this->settings.State )
01314     {
01315         case RF_RX_RUNNING:
01316             switch( this->settings.Modem )
01317             {
01318             case MODEM_FSK:
01319                 if( ( this->settings.FskPacketHandler.PreambleDetected == true ) && ( this->settings.FskPacketHandler.SyncWordDetected == false ) )
01320                 {
01321                     rxTimeoutSyncWord.detach( );
01322 
01323                     this->settings.FskPacketHandler.SyncWordDetected = true;
01324 
01325                     this->settings.FskPacketHandler.RssiValue = -( Read( REG_RSSIVALUE ) >> 1 );
01326 
01327                     this->settings.FskPacketHandler.AfcValue = ( int32_t )( double )( ( ( uint16_t )Read( REG_AFCMSB ) << 8 ) |
01328                                                                            ( uint16_t )Read( REG_AFCLSB ) ) *
01329                                                                            ( double )FREQ_STEP;
01330                     this->settings.FskPacketHandler.RxGain = ( Read( REG_LNA ) >> 5 ) & 0x07;
01331                 }
01332                 break;
01333             case MODEM_LORA:
01334                 if( this->settings.LoRa.FreqHopOn == true )
01335                 {
01336                     // Clear Irq
01337                     Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL );
01338 
01339                     if( ( this->RadioEvents != NULL ) && ( this->RadioEvents->FhssChangeChannel != NULL ) )
01340                     {
01341                         this->RadioEvents->FhssChangeChannel( ( Read( REG_LR_HOPCHANNEL ) & RFLR_HOPCHANNEL_CHANNEL_MASK ) );
01342                     }
01343                 }
01344                 break;
01345             default:
01346                 break;
01347             }
01348             break;
01349         case RF_TX_RUNNING:
01350             switch( this->settings.Modem )
01351             {
01352             case MODEM_FSK:
01353                 break;
01354             case MODEM_LORA:
01355                 if( this->settings.LoRa.FreqHopOn == true )
01356                 {
01357                     // Clear Irq
01358                     Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL );
01359 
01360                     if( ( this->RadioEvents != NULL ) && ( this->RadioEvents->FhssChangeChannel != NULL ) )
01361                     {
01362                         this->RadioEvents->FhssChangeChannel( ( Read( REG_LR_HOPCHANNEL ) & RFLR_HOPCHANNEL_CHANNEL_MASK ) );
01363                     }
01364                 }
01365                 break;
01366             default:
01367                 break;
01368             }
01369             break;
01370         default:
01371             break;
01372     }
01373 }
01374 
01375 void SX1272::OnDio3Irq( void )
01376 {
01377     switch( this->settings.Modem )
01378     {
01379     case MODEM_FSK:
01380         break;
01381     case MODEM_LORA:
01382         if( ( Read( REG_LR_IRQFLAGS ) & RFLR_IRQFLAGS_CADDETECTED ) == RFLR_IRQFLAGS_CADDETECTED )
01383         {
01384             // Clear Irq
01385             Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_CADDETECTED | RFLR_IRQFLAGS_CADDONE );
01386             if( ( this->RadioEvents != NULL ) && ( this->RadioEvents->CadDone != NULL ) )
01387             {
01388                 this->RadioEvents->CadDone( true );
01389             }
01390         }
01391         else
01392         {
01393             // Clear Irq
01394             Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_CADDONE );
01395             if( ( this->RadioEvents != NULL ) && ( this->RadioEvents->CadDone != NULL ) )
01396             {
01397                 this->RadioEvents->CadDone( false );
01398             }
01399         }
01400         break;
01401     default:
01402         break;
01403     }
01404 }
01405 
01406 void SX1272::OnDio4Irq( void )
01407 {
01408     switch( this->settings.Modem )
01409     {
01410     case MODEM_FSK:
01411         {
01412             if( this->settings.FskPacketHandler.PreambleDetected == false )
01413             {
01414                 this->settings.FskPacketHandler.PreambleDetected = true;
01415             }
01416         }
01417         break;
01418     case MODEM_LORA:
01419         break;
01420     default:
01421         break;
01422     }
01423 }
01424 
01425 void SX1272::OnDio5Irq( void )
01426 {
01427     switch( this->settings.Modem )
01428     {
01429     case MODEM_FSK:
01430         break;
01431     case MODEM_LORA:
01432         break;
01433     default:
01434         break;
01435     }
01436 }