pin pong

Dependents:   SX1272PingPong

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