I-O DATA DEV2 / Private_lora_SX1276

Dependents:   Nucleo_Private_LoRa

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers sx1276.cpp Source File

sx1276.cpp

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