first draft

Dependents:   LoRaWAN-demo-72_tjm frdm_LoRa_Connect_Woodstream_Demo_tjm frdm_LoRa_Connect_Woodstream_Demo_jlc

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