Driver for the SX1276 RF Transceiver

Dependents:   LoRa_PIR LoRaWAN-lmic-app SX1276PingPong LoRaWAN-lmic-app ... more

Files at this revision

API Documentation at this revision

Comitter:
mluis
Date:
Thu Nov 26 16:55:15 2015 +0000
Parent:
21:2e496deb7858
Child:
23:1e143575df0f
Child:
26:d09a8ef807e2
Commit message:
Synchronized the drivers with GitHub version.; Mainly added errata note recommendations

Changed in this revision

enums/enums.h Show annotated file Show diff for this revision Revisions of this file
radio/radio.cpp Show annotated file Show diff for this revision Revisions of this file
radio/radio.h Show annotated file Show diff for this revision Revisions of this file
registers/sx1276Regs-Fsk.h Show annotated file Show diff for this revision Revisions of this file
registers/sx1276Regs-LoRa.h Show annotated file Show diff for this revision Revisions of this file
sx1276/sx1276-hal.cpp Show annotated file Show diff for this revision Revisions of this file
sx1276/sx1276-hal.h Show annotated file Show diff for this revision Revisions of this file
sx1276/sx1276.cpp Show annotated file Show diff for this revision Revisions of this file
sx1276/sx1276.h Show annotated file Show diff for this revision Revisions of this file
typedefs/typedefs.h Show annotated file Show diff for this revision Revisions of this file
--- a/enums/enums.h	Thu Nov 26 10:39:03 2015 +0000
+++ b/enums/enums.h	Thu Nov 26 16:55:15 2015 +0000
@@ -4,7 +4,7 @@
  \____ \| ___ |    (_   _) ___ |/ ___)  _ \
  _____) ) ____| | | || |_| ____( (___| | | |
 (______/|_____)_|_|_| \__)_____)\____)_| |_|
-    ( C )2014 Semtech
+    (C) 2014 Semtech
 
 Description: -
 
@@ -127,4 +127,3 @@
 
 
 #endif //__ENUMS_H__
-
--- a/radio/radio.cpp	Thu Nov 26 10:39:03 2015 +0000
+++ b/radio/radio.cpp	Thu Nov 26 16:55:15 2015 +0000
@@ -4,7 +4,7 @@
  \____ \| ___ |    (_   _) ___ |/ ___)  _ \
  _____) ) ____| | | || |_| ____( (___| | | |
 (______/|_____)_|_|_| \__)_____)\____)_| |_|
-    ( C )2014 Semtech
+    (C) 2014 Semtech
 
 Description: Interface for the radios, contains the main functions that a radio needs, and 5 callback functions
 
--- a/radio/radio.h	Thu Nov 26 10:39:03 2015 +0000
+++ b/radio/radio.h	Thu Nov 26 16:55:15 2015 +0000
@@ -4,7 +4,7 @@
  \____ \| ___ |    (_   _) ___ |/ ___)  _ \
  _____) ) ____| | | || |_| ____( (___| | | |
 (______/|_____)_|_|_| \__)_____)\____)_| |_|
-    ( C )2014 Semtech
+    (C) 2014 Semtech
 
 Description: Interface for the radios, contains the main functions that a radio needs, and 5 callback functions
 
@@ -109,7 +109,7 @@
      *
      * @param [IN] modem Modem to be used [0: FSK, 1: LoRa] 
      */
-    virtual void SetModem( ModemType modem ) = 0;
+    virtual void SetModem( RadioModems_t modem ) = 0;
 
     /*!
      * @brief Sets the channel frequency
@@ -127,7 +127,7 @@
      *
      * @retval isFree         [true: Channel is free, false: Channel is not free]
      */
-    virtual bool IsChannelFree( ModemType modem, uint32_t freq, int8_t rssiThresh ) = 0;
+    virtual bool IsChannelFree( RadioModems_t modem, uint32_t freq, int16_t rssiThresh ) = 0;
     
     /*!
      * @brief Generates a 32 bits random value based on the RSSI readings
@@ -176,7 +176,7 @@
      * @param [IN] rxContinuous Sets the reception in continuous mode
      *                          [false: single mode, true: continuous mode]
      */
-    virtual void SetRxConfig ( ModemType modem, uint32_t bandwidth,
+    virtual void SetRxConfig ( RadioModems_t modem, uint32_t bandwidth,
                                uint32_t datarate, uint8_t coderate,
                                uint32_t bandwidthAfc, uint16_t preambleLen,
                                uint16_t symbTimeout, bool fixLen,
@@ -213,7 +213,7 @@
      *                          LoRa: [0: not inverted, 1: inverted]
      * @param [IN] timeout      Transmission timeout [us]
      */
-    virtual void SetTxConfig( ModemType modem, int8_t power, uint32_t fdev,
+    virtual void SetTxConfig( RadioModems_t modem, int8_t power, uint32_t fdev,
                               uint32_t bandwidth, uint32_t datarate,
                               uint8_t coderate, uint16_t preambleLen,
                               bool fixLen, bool crcOn, bool freqHopOn,
@@ -237,7 +237,7 @@
      *
      * @retval airTime        Computed airTime for the given packet payload length
      */
-    virtual double TimeOnAir ( ModemType modem, uint8_t pktLen ) = 0;
+    virtual double TimeOnAir ( RadioModems_t modem, uint8_t pktLen ) = 0;
     
     /*!
      * @brief Sends the buffer of size. Prepares the packet to be sent and sets
@@ -282,7 +282,7 @@
      *
      * @retval rssiValue Current RSSI value in [dBm]
      */
-    virtual int16_t GetRssi ( ModemType modem ) = 0;
+    virtual int16_t GetRssi ( RadioModems_t modem ) = 0;
     
     /*!
      * @brief Writes the radio register at the specified address
@@ -340,7 +340,7 @@
      * @param [IN] modem      Radio modem to be used [0: FSK, 1: LoRa]
      * @param [IN] max        Maximum payload length in bytes
      */
-    virtual void SetMaxPayloadLength( ModemType modem, uint8_t max ) = 0;
+    virtual void SetMaxPayloadLength( RadioModems_t modem, uint8_t max ) = 0;
 };
 
 #endif // __RADIO_H__
--- a/registers/sx1276Regs-Fsk.h	Thu Nov 26 10:39:03 2015 +0000
+++ b/registers/sx1276Regs-Fsk.h	Thu Nov 26 16:55:15 2015 +0000
@@ -4,7 +4,7 @@
  \____ \| ___ |    (_   _) ___ |/ ___)  _ \
  _____) ) ____| | | || |_| ____( (___| | | |
 (______/|_____)_|_|_| \__)_____)\____)_| |_|
-    ( C )2014 Semtech
+    (C) 2014 Semtech
 
 Description: SX1276 FSK modem registers and bits definitions
 
@@ -145,7 +145,7 @@
 #define RF_OPMODE_RECEIVER                          0x05
 
 /*!
- * RegBitRate ( bits/sec )
+ * RegBitRate (bits/sec)
  */
 #define RF_BITRATEMSB_1200_BPS                      0x68
 #define RF_BITRATELSB_1200_BPS                      0x2B
@@ -187,7 +187,7 @@
 #define RF_BITRATELSB_32768_BPS                     0xD1
 
 /*!
- * RegFdev ( Hz )
+ * RegFdev (Hz)
  */
 #define RF_FDEVMSB_2000_HZ                          0x00
 #define RF_FDEVLSB_2000_HZ                          0x21
@@ -253,7 +253,7 @@
 #define RF_FDEVLSB_200000_HZ                        0xCD
 
 /*!
- * RegFrf ( MHz )
+ * RegFrf (MHz)
  */
 #define RF_FRFMSB_863_MHZ                           0xD7
 #define RF_FRFMID_863_MHZ                           0xC0
@@ -533,7 +533,7 @@
 #define RF_RSSITHRESH_THRESHOLD                     0xFF  // Default
 
 /*!
- * RegRssiValue ( Read Only )
+ * RegRssiValue (Read Only)
  */
 
 /*!
@@ -636,19 +636,19 @@
 #define RF_AFCFEI_AFCAUTOCLEAR_OFF                  0x00  // Default
 
 /*!
- * RegAfcMsb ( Read Only )
+ * RegAfcMsb (Read Only)
  */
  
 /*!
- * RegAfcLsb ( Read Only )
+ * RegAfcLsb (Read Only)
  */
 
 /*!
- * RegFeiMsb ( Read Only )
+ * RegFeiMsb (Read Only)
  */
 
 /*!
- * RegFeiLsb ( Read Only )
+ * RegFeiLsb (Read Only)
  */
 
 /*!
@@ -962,7 +962,7 @@
 #define RF_IMAGECAL_TEMPMONITOR_OFF                 0x01
 
 /*!
- * RegTemp ( Read Only )
+ * RegTemp (Read Only)
  */
 
 /*!
@@ -1067,7 +1067,7 @@
 #define RF_DIOMAPPING2_MAP_RSSI                     0x00  // Default
 
 /*!
- * RegVersion ( Read Only )
+ * RegVersion (Read Only)
  */
 
 /*!
@@ -1126,4 +1126,3 @@
 #define RF_PLL_BANDWIDTH_300                        0xC0  // Default
 
 #endif // __SX1276_REGS_FSK_H__
-
--- a/registers/sx1276Regs-LoRa.h	Thu Nov 26 10:39:03 2015 +0000
+++ b/registers/sx1276Regs-LoRa.h	Thu Nov 26 16:55:15 2015 +0000
@@ -4,7 +4,7 @@
  \____ \| ___ |    (_   _) ___ |/ ___)  _ \
  _____) ) ____| | | || |_| ____( (___| | | |
 (______/|_____)_|_|_| \__)_____)\____)_| |_|
-    ( C )2014 Semtech
+    (C) 2014 Semtech
 
 Description: SX1276 LoRa modem registers and bits definitions
 
@@ -63,10 +63,15 @@
 #define REG_LR_FEIMID                               0x29
 #define REG_LR_FEILSB                               0x2A
 #define REG_LR_RSSIWIDEBAND                         0x2C
+#define REG_LR_TEST2F                               0x2F
+#define REG_LR_TEST30                               0x30
 #define REG_LR_DETECTOPTIMIZE                       0x31
 #define REG_LR_INVERTIQ                             0x33
+#define REG_LR_TEST36                               0x36
 #define REG_LR_DETECTIONTHRESHOLD                   0x37
 #define REG_LR_SYNCWORD                             0x39
+#define REG_LR_TEST3A                               0x3A
+#define REG_LR_INVERTIQ2                            0x3B
 
 // end of documented register in datasheet
 // I/O settings
@@ -123,7 +128,7 @@
 #define RFLR_OPMODE_CAD                             0x07 
 
 /*!
- * RegFrf ( MHz )
+ * RegFrf (MHz)
  */
 #define RFLR_FRFMSB_434_MHZ                         0x6C // Default
 #define RFLR_FRFMID_434_MHZ                         0x80 // Default
@@ -236,7 +241,7 @@
 #define RFLR_FIFORXBASEADDR                         0x00 // Default
 
 /*!
- * RegFifoRxCurrentAddr ( Read Only )
+ * RegFifoRxCurrentAddr (Read Only)
  */
 
 /*!
@@ -264,50 +269,45 @@
 #define RFLR_IRQFLAGS_CADDETECTED                   0x01 
 
 /*!
- * RegFifoRxNbBytes ( Read Only )
+ * RegFifoRxNbBytes (Read Only)
  */
- 
+
 /*!
- * RegRxHeaderCntValueMsb ( Read Only )
+ * RegRxHeaderCntValueMsb (Read Only)
  */
- 
+
 /*!
- * RegRxHeaderCntValueLsb ( Read Only )
+ * RegRxHeaderCntValueLsb (Read Only)
  */
- 
- 
+
 /*!
- * RegRxPacketCntValueMsb ( Read Only )
+ * RegRxPacketCntValueMsb (Read Only)
  */
- 
- 
+
 /*!
- * RegRxPacketCntValueLsb ( Read Only )
+ * RegRxPacketCntValueLsb (Read Only)
  */
- 
- 
+
 /*!
- * RegModemStat ( Read Only )
+ * RegModemStat (Read Only)
  */
 #define RFLR_MODEMSTAT_RX_CR_MASK                   0x1F 
 #define RFLR_MODEMSTAT_MODEM_STATUS_MASK            0xE0 
  
 /*!
- * RegPktSnrValue ( Read Only )
- */
-
- 
- /*!
- * RegPktRssiValue ( Read Only )
- */
- 
- 
-/*!
- * RegRssiValue ( Read Only )
+ * RegPktSnrValue (Read Only)
  */
 
 /*!
- * RegHopChannel ( Read Only )
+ * RegPktRssiValue (Read Only)
+ */
+
+/*!
+ * RegRssiValue (Read Only)
+ */
+
+/*!
+ * RegHopChannel (Read Only)
  */
 #define RFLR_HOPCHANNEL_PLL_LOCK_TIMEOUT_MASK       0x7F 
 #define RFLR_HOPCHANNEL_PLL_LOCK_FAIL               0x80 
@@ -318,7 +318,7 @@
 #define RFLR_HOPCHANNEL_CRCONPAYLOAD_OFF            0x00 // Default
 
 #define RFLR_HOPCHANNEL_CHANNEL_MASK                0x3F 
- 
+
 /*!
  * RegModemConfig1
  */
@@ -365,7 +365,7 @@
 #define RFLR_MODEMCONFIG2_RXPAYLOADCRC_OFF          0x00 // Default
  
 #define RFLR_MODEMCONFIG2_SYMBTIMEOUTMSB_MASK       0xFC 
-#define RFLR_MODEMCONFIG2_SYMBTIMEOUTMSB            0x00 // Default                                      
+#define RFLR_MODEMCONFIG2_SYMBTIMEOUTMSB            0x00 // Default
 
 /*!
  * RegSymbTimeoutLsb
@@ -398,7 +398,7 @@
 #define RFLR_HOPPERIOD_FREQFOPPINGPERIOD            0x00 // Default
 
 /*!
- * RegFifoRxByteAddr ( Read Only )
+ * RegFifoRxByteAddr (Read Only)
  */
 
 /*!
@@ -413,19 +413,19 @@
 #define RFLR_MODEMCONFIG3_AGCAUTO_OFF               0x00 
 
 /*!
- * RegFeiMsb ( Read Only )
+ * RegFeiMsb (Read Only)
  */
 
 /*!
- * RegFeiMid ( Read Only )
+ * RegFeiMid (Read Only)
  */
 
 /*!
- * RegFeiLsb ( Read Only )
+ * RegFeiLsb (Read Only)
  */
 
 /*!
- * RegRssiWideband ( Read Only )
+ * RegRssiWideband (Read Only)
  */
 
 /*!
@@ -452,6 +452,12 @@
 #define RFLR_DETECTIONTHRESH_SF6                    0x0C
 
 /*!
+ * RegInvertIQ2
+ */
+#define RFLR_INVERTIQ2_ON                           0x19
+#define RFLR_INVERTIQ2_OFF                          0x1D
+
+/*!
  * RegDioMapping1
  */
 #define RFLR_DIOMAPPING1_DIO0_MASK                  0x3F
@@ -498,7 +504,7 @@
 #define RFLR_DIOMAPPING2_MAP_RSSI                   0x00  // Default
 
 /*!
- * RegVersion ( Read Only )
+ * RegVersion (Read Only)
  */
 
 /*!
@@ -557,4 +563,3 @@
 #define RF_PLL_BANDWIDTH_300                        0xC0  // Default
 
 #endif // __SX1276_REGS_LORA_H__
-
--- a/sx1276/sx1276-hal.cpp	Thu Nov 26 10:39:03 2015 +0000
+++ b/sx1276/sx1276-hal.cpp	Thu Nov 26 16:55:15 2015 +0000
@@ -4,7 +4,7 @@
  \____ \| ___ |    (_   _) ___ |/ ___)  _ \
  _____) ) ____| | | || |_| ____( (___| | | |
 (______/|_____)_|_|_| \__)_____)\____)_| |_|
-    ( C )2014 Semtech
+    (C) 2014 Semtech
 
 Description: -
 
@@ -14,24 +14,7 @@
 */
 #include "sx1276-hal.h"
 
-const RadioRegisters_t SX1276MB1xAS::RadioRegsInit[] = 
-{                                                 
-    { MODEM_FSK , REG_LNA                , 0x23 },
-    { MODEM_FSK , REG_RXCONFIG           , 0x1E },
-    { MODEM_FSK , REG_RSSICONFIG         , 0xD2 },
-    { MODEM_FSK , REG_PREAMBLEDETECT     , 0xAA },
-    { MODEM_FSK , REG_OSC                , 0x07 },
-    { MODEM_FSK , REG_SYNCCONFIG         , 0x12 },
-    { MODEM_FSK , REG_SYNCVALUE1         , 0xC1 },
-    { MODEM_FSK , REG_SYNCVALUE2         , 0x94 },
-    { MODEM_FSK , REG_SYNCVALUE3         , 0xC1 },
-    { MODEM_FSK , REG_PACKETCONFIG1      , 0xD8 },
-    { MODEM_FSK , REG_FIFOTHRESH         , 0x8F },
-    { MODEM_FSK , REG_IMAGECAL           , 0x02 },
-    { MODEM_FSK , REG_DIOMAPPING1        , 0x00 },
-    { MODEM_FSK , REG_DIOMAPPING2        , 0x30 },
-    { MODEM_LORA, REG_LR_PAYLOADMAXLENGTH, 0x40 },  
-};
+const RadioRegisters_t SX1276MB1xAS::RadioRegsInit[] = RADIO_INIT_REGISTERS_VALUE;
 
 SX1276MB1xAS::SX1276MB1xAS( RadioEvents_t *events,
                             PinName mosi, PinName miso, PinName sclk, PinName nss, PinName reset,
@@ -130,7 +113,8 @@
     SpiInit( );
 }
 
-void SX1276MB1xAS::RadioRegistersInit( ){
+void SX1276MB1xAS::RadioRegistersInit( )
+{
     uint8_t i = 0;
     for( i = 0; i < sizeof( RadioRegsInit ) / sizeof( RadioRegisters_t ); i++ )
     {
@@ -156,13 +140,13 @@
 
 void SX1276MB1xAS::IoIrqInit( DioIrqHandler *irqHandlers )
 {
-    #if( defined ( TARGET_NUCLEO_L152RE ) ||  defined ( TARGET_LPC11U6X ) )
-        dio0.mode(PullDown);
-        dio1.mode(PullDown);   
-        dio2.mode(PullDown);
-        dio3.mode(PullDown); 
-        dio4.mode(PullDown); 
-    #endif
+#if( defined ( TARGET_NUCLEO_L152RE ) ||  defined ( TARGET_LPC11U6X ) )
+    dio0.mode(PullDown);
+    dio1.mode(PullDown);   
+    dio2.mode(PullDown);
+    dio3.mode(PullDown); 
+    dio4.mode(PullDown); 
+#endif
     dio0.rise( this, static_cast< TriggerMB1xAS > ( irqHandlers[0] ) );
     dio1.rise( this, static_cast< TriggerMB1xAS > ( irqHandlers[1] ) );
     dio2.rise( this, static_cast< TriggerMB1xAS > ( irqHandlers[2] ) );
--- a/sx1276/sx1276-hal.h	Thu Nov 26 10:39:03 2015 +0000
+++ b/sx1276/sx1276-hal.h	Thu Nov 26 16:55:15 2015 +0000
@@ -4,7 +4,7 @@
  \____ \| ___ |    (_   _) ___ |/ ___)  _ \
  _____) ) ____| | | || |_| ____( (___| | | |
 (______/|_____)_|_|_| \__)_____)\____)_| |_|
-    ( C )2014 Semtech
+    (C) 2014 Semtech
 
 Description: -
 
@@ -16,6 +16,30 @@
 #define __SX1276_HAL_H__
 #include "sx1276.h"
 
+/*!
+ * \brief Radio hardware registers initialization definition
+ *
+ * \remark Can be automatically generated by the SX1276 GUI (not yet implemented)
+ */
+#define RADIO_INIT_REGISTERS_VALUE                \
+{                                                 \
+    { MODEM_FSK , REG_LNA                , 0x23 },\
+    { MODEM_FSK , REG_RXCONFIG           , 0x1E },\
+    { MODEM_FSK , REG_RSSICONFIG         , 0xD2 },\
+    { MODEM_FSK , REG_PREAMBLEDETECT     , 0xAA },\
+    { MODEM_FSK , REG_OSC                , 0x07 },\
+    { MODEM_FSK , REG_SYNCCONFIG         , 0x12 },\
+    { MODEM_FSK , REG_SYNCVALUE1         , 0xC1 },\
+    { MODEM_FSK , REG_SYNCVALUE2         , 0x94 },\
+    { MODEM_FSK , REG_SYNCVALUE3         , 0xC1 },\
+    { MODEM_FSK , REG_PACKETCONFIG1      , 0xD8 },\
+    { MODEM_FSK , REG_FIFOTHRESH         , 0x8F },\
+    { MODEM_FSK , REG_IMAGECAL           , 0x02 },\
+    { MODEM_FSK , REG_DIOMAPPING1        , 0x00 },\
+    { MODEM_FSK , REG_DIOMAPPING2        , 0x30 },\
+    { MODEM_LORA, REG_LR_PAYLOADMAXLENGTH, 0x40 },\
+}                                                 \
+
 /*! 
  * Actual implementation of a SX1276 radio, includes some modifications to make it compatible with the MB1 LAS board
  */
@@ -37,7 +61,9 @@
             PinName mosi, PinName miso, PinName sclk, PinName nss, PinName reset,
             PinName dio0, PinName dio1, PinName dio2, PinName dio3, PinName dio4, PinName dio5,
             PinName antSwitch ); 
-            SX1276MB1xAS( RadioEvents_t *events );
+    
+    SX1276MB1xAS( RadioEvents_t *events );
+    
     virtual ~SX1276MB1xAS( ) { };
     
     protected:
--- a/sx1276/sx1276.cpp	Thu Nov 26 10:39:03 2015 +0000
+++ b/sx1276/sx1276.cpp	Thu Nov 26 16:55:15 2015 +0000
@@ -4,7 +4,7 @@
  \____ \| ___ |    (_   _) ___ |/ ___)  _ \
  _____) ) ____| | | || |_| ____( (___| | | |
 (______/|_____)_|_|_| \__)_____)\____)_| |_|
-    ( C )2014 Semtech
+    (C) 2014 Semtech
 
 Description: Actual implementation of a SX1276 radio, inherits Radio
 
@@ -81,40 +81,6 @@
     this->RadioEvents = events;
 }
 
-void SX1276::RxChainCalibration( void )
-{
-    uint8_t regPaConfigInitVal;
-    uint32_t initialFreq;
-
-    // Save context
-    regPaConfigInitVal = this->Read( REG_PACONFIG );
-    initialFreq = ( double )( ( ( uint32_t )this->Read( REG_FRFMSB ) << 16 ) |
-                              ( ( uint32_t )this->Read( REG_FRFMID ) << 8 ) |
-                              ( ( uint32_t )this->Read( REG_FRFLSB ) ) ) * ( double )FREQ_STEP;
-
-    // Cut the PA just in case, RFO output, power = -1 dBm
-    this->Write( REG_PACONFIG, 0x00 );
-
-    // Launch Rx chain calibration for LF band
-    Write ( REG_IMAGECAL, ( Read( REG_IMAGECAL ) & RF_IMAGECAL_IMAGECAL_MASK ) | RF_IMAGECAL_IMAGECAL_START );
-    while( ( Read( REG_IMAGECAL ) & RF_IMAGECAL_IMAGECAL_RUNNING ) == RF_IMAGECAL_IMAGECAL_RUNNING )
-    {
-    }
-
-    // Sets a Frequency in HF band
-    settings.Channel=  868000000 ;
-
-    // Launch Rx chain calibration for HF band 
-    Write ( REG_IMAGECAL, ( Read( REG_IMAGECAL ) & RF_IMAGECAL_IMAGECAL_MASK ) | RF_IMAGECAL_IMAGECAL_START );
-    while( ( Read( REG_IMAGECAL ) & RF_IMAGECAL_IMAGECAL_RUNNING ) == RF_IMAGECAL_IMAGECAL_RUNNING )
-    {
-    }
-
-    // Restore context
-    this->Write( REG_PACONFIG, regPaConfigInitVal );
-    SetChannel( initialFreq );
-}
-
 RadioState SX1276::GetStatus( void )
 {
     return this->settings.State;
@@ -129,7 +95,7 @@
     Write( REG_FRFLSB, ( uint8_t )( freq & 0xFF ) );
 }
 
-bool SX1276::IsChannelFree( ModemType modem, uint32_t freq, int8_t rssiThresh )
+bool SX1276::IsChannelFree( RadioModems_t modem, uint32_t freq, int16_t rssiThresh )
 {
     int16_t rssi = 0;
     
@@ -145,7 +111,7 @@
     
     Sleep( );
     
-    if( rssi > ( int16_t )rssiThresh )
+    if( rssi > rssiThresh )
     {
         return false;
     }
@@ -189,6 +155,45 @@
 }
 
 /*!
+ * Performs the Rx chain calibration for LF and HF bands
+ * \remark Must be called just after the reset so all registers are at their
+ *         default values
+ */
+void SX1276::RxChainCalibration( void )
+{
+    uint8_t regPaConfigInitVal;
+    uint32_t initialFreq;
+
+    // Save context
+    regPaConfigInitVal = this->Read( REG_PACONFIG );
+    initialFreq = ( double )( ( ( uint32_t )this->Read( REG_FRFMSB ) << 16 ) |
+                              ( ( uint32_t )this->Read( REG_FRFMID ) << 8 ) |
+                              ( ( uint32_t )this->Read( REG_FRFLSB ) ) ) * ( double )FREQ_STEP;
+
+    // Cut the PA just in case, RFO output, power = -1 dBm
+    this->Write( REG_PACONFIG, 0x00 );
+
+    // Launch Rx chain calibration for LF band
+    Write ( REG_IMAGECAL, ( Read( REG_IMAGECAL ) & RF_IMAGECAL_IMAGECAL_MASK ) | RF_IMAGECAL_IMAGECAL_START );
+    while( ( Read( REG_IMAGECAL ) & RF_IMAGECAL_IMAGECAL_RUNNING ) == RF_IMAGECAL_IMAGECAL_RUNNING )
+    {
+    }
+
+    // Sets a Frequency in HF band
+    SetChannel( 868000000 );
+
+    // Launch Rx chain calibration for HF band 
+    Write ( REG_IMAGECAL, ( Read( REG_IMAGECAL ) & RF_IMAGECAL_IMAGECAL_MASK ) | RF_IMAGECAL_IMAGECAL_START );
+    while( ( Read( REG_IMAGECAL ) & RF_IMAGECAL_IMAGECAL_RUNNING ) == RF_IMAGECAL_IMAGECAL_RUNNING )
+    {
+    }
+
+    // Restore context
+    this->Write( REG_PACONFIG, regPaConfigInitVal );
+    SetChannel( initialFreq );
+}
+
+/*!
  * Returns the known FSK bandwidth registers value
  *
  * \param [IN] bandwidth Bandwidth value in Hz
@@ -209,7 +214,7 @@
     while( 1 );
 }
 
-void SX1276::SetRxConfig( ModemType modem, uint32_t bandwidth,
+void SX1276::SetRxConfig( RadioModems_t modem, uint32_t bandwidth,
                          uint32_t datarate, uint8_t coderate,
                          uint32_t bandwidthAfc, uint16_t preambleLen,
                          uint16_t symbTimeout, bool fixLen,
@@ -242,6 +247,11 @@
 
             Write( REG_PREAMBLEMSB, ( uint8_t )( ( preambleLen >> 8 ) & 0xFF ) );
             Write( REG_PREAMBLELSB, ( uint8_t )( preambleLen & 0xFF ) );
+            
+            if( fixLen == 1 )
+            {
+                Write( REG_PAYLOADLENGTH, payloadLen );
+            }
 
             Write( REG_PACKETCONFIG1,
                          ( Read( REG_PACKETCONFIG1 ) & 
@@ -249,10 +259,6 @@
                            RF_PACKETCONFIG1_PACKETFORMAT_MASK ) |
                            ( ( fixLen == 1 ) ? RF_PACKETCONFIG1_PACKETFORMAT_FIXED : RF_PACKETCONFIG1_PACKETFORMAT_VARIABLE ) |
                            ( crcOn << 4 ) );
-            if( fixLen == 1 )
-            {
-                Write( REG_PAYLOADLENGTH, payloadLen );
-            }
         }
         break;
     case MODEM_LORA:
@@ -266,6 +272,7 @@
             this->settings.LoRa.Bandwidth = bandwidth;
             this->settings.LoRa.Datarate = datarate;
             this->settings.LoRa.Coderate = coderate;
+            this->settings.LoRa.PreambleLen = preambleLen;
             this->settings.LoRa.FixLen = fixLen;
             this->settings.LoRa.PayloadLen = payloadLen;
             this->settings.LoRa.CrcOn = crcOn;
@@ -273,7 +280,7 @@
             this->settings.LoRa.HopPeriod = hopPeriod;
             this->settings.LoRa.IqInverted = iqInverted;
             this->settings.LoRa.RxContinuous = rxContinuous;
-            
+
             if( datarate > 12 )
             {
                 datarate = 12;
@@ -330,6 +337,24 @@
                 Write( REG_LR_HOPPERIOD, this->settings.LoRa.HopPeriod );
             }
 
+            if( ( bandwidth == 9 ) && ( RF_MID_BAND_THRESH ) )
+            {
+                // ERRATA 2.1 - Sensitivity Optimization with a 500 kHz Bandwidth 
+                Write( REG_LR_TEST36, 0x02 );
+                Write( REG_LR_TEST3A, 0x64 );
+            }
+            else if( bandwidth == 9 )
+            {
+                // ERRATA 2.1 - Sensitivity Optimization with a 500 kHz Bandwidth
+                Write( REG_LR_TEST36, 0x02 );
+                Write( REG_LR_TEST3A, 0x7F );
+            }
+            else
+            {
+                // ERRATA 2.1 - Sensitivity Optimization with a 500 kHz Bandwidth
+                Write( REG_LR_TEST36, 0x03 );
+            }
+            
             if( datarate == 6 )
             {
                 Write( REG_LR_DETECTOPTIMIZE, 
@@ -353,7 +378,7 @@
     }
 }
 
-void SX1276::SetTxConfig( ModemType modem, int8_t power, uint32_t fdev, 
+void SX1276::SetTxConfig( RadioModems_t modem, int8_t power, uint32_t fdev, 
                         uint32_t bandwidth, uint32_t datarate,
                         uint8_t coderate, uint16_t preambleLen,
                         bool fixLen, bool crcOn, bool freqHopOn, 
@@ -451,6 +476,7 @@
                            RF_PACKETCONFIG1_PACKETFORMAT_MASK ) |
                            ( ( fixLen == 1 ) ? RF_PACKETCONFIG1_PACKETFORMAT_FIXED : RF_PACKETCONFIG1_PACKETFORMAT_VARIABLE ) |
                            ( crcOn << 4 ) );
+        
         }
         break;
     case MODEM_LORA:
@@ -467,9 +493,9 @@
             this->settings.LoRa.Coderate = coderate;
             this->settings.LoRa.PreambleLen = preambleLen;
             this->settings.LoRa.FixLen = fixLen;
-            this->settings.LoRa.CrcOn = crcOn;
             this->settings.LoRa.FreqHopOn = freqHopOn;
             this->settings.LoRa.HopPeriod = hopPeriod;
+            this->settings.LoRa.CrcOn = crcOn;
             this->settings.LoRa.IqInverted = iqInverted;
             this->settings.LoRa.TxTimeout = timeout;
 
@@ -490,13 +516,13 @@
             {
                 this->settings.LoRa.LowDatarateOptimize = 0x00;
             }
-            
+
             if( this->settings.LoRa.FreqHopOn == true )
             {
                 Write( REG_LR_PLLHOP, ( Read( REG_LR_PLLHOP ) & RFLR_PLLHOP_FASTHOP_MASK ) | RFLR_PLLHOP_FASTHOP_ON );
                 Write( REG_LR_HOPPERIOD, this->settings.LoRa.HopPeriod );
             }
-            
+
             Write( REG_LR_MODEMCONFIG1, 
                          ( Read( REG_LR_MODEMCONFIG1 ) &
                            RFLR_MODEMCONFIG1_BW_MASK &
@@ -542,15 +568,15 @@
     }
 }
 
-double SX1276::TimeOnAir( ModemType modem, uint8_t pktLen )
+double SX1276::TimeOnAir( RadioModems_t modem, uint8_t pktLen )
 {
-    double airTime = 0.0;
+    uint32_t airTime = 0;
 
     switch( modem )
     {
     case MODEM_FSK:
         {
-            airTime = ceil( ( 8 * ( this->settings.Fsk.PreambleLen +
+            airTime = rint( ( 8 * ( this->settings.Fsk.PreambleLen +
                                      ( ( Read( REG_SYNCCONFIG ) & ~RF_SYNCCONFIG_SYNCSIZE_MASK ) + 1 ) +
                                      ( ( this->settings.Fsk.FixLen == 0x01 ) ? 0.0 : 1.0 ) +
                                      ( ( ( Read( REG_PACKETCONFIG1 ) & ~RF_PACKETCONFIG1_ADDRSFILTERING_MASK ) != 0x00 ) ? 1.0 : 0 ) +
@@ -607,7 +633,7 @@
                                  28 + 16 * this->settings.LoRa.CrcOn -
                                  ( this->settings.LoRa.FixLen ? 20 : 0 ) ) /
                                  ( double )( 4 * this->settings.LoRa.Datarate -
-                                 ( ( this->settings.LoRa.LowDatarateOptimize > 0 ) ? 8 : 0 ) ) ) *
+                                 ( ( this->settings.LoRa.LowDatarateOptimize > 0 ) ? 2 : 0 ) ) ) *
                                  ( this->settings.LoRa.Coderate + 4 );
             double nPayload = 8 + ( ( tmp > 0 ) ? tmp : 0 );
             double tPayload = nPayload * ts;
@@ -625,8 +651,6 @@
 {
     uint32_t txTimeout = 0;
 
-    this->settings.State = RF_IDLE;
-
     switch( this->settings.Modem )
     {
     case MODEM_FSK:
@@ -663,10 +687,12 @@
             if( this->settings.LoRa.IqInverted == true )
             {
                 Write( REG_LR_INVERTIQ, ( ( Read( REG_LR_INVERTIQ ) & RFLR_INVERTIQ_TX_MASK & RFLR_INVERTIQ_RX_MASK ) | RFLR_INVERTIQ_RX_OFF | RFLR_INVERTIQ_TX_ON ) );
+                Write( REG_LR_INVERTIQ2, RFLR_INVERTIQ2_ON );
             }
             else
             {
                 Write( REG_LR_INVERTIQ, ( ( Read( REG_LR_INVERTIQ ) & RFLR_INVERTIQ_TX_MASK & RFLR_INVERTIQ_RX_MASK ) | RFLR_INVERTIQ_RX_OFF | RFLR_INVERTIQ_TX_OFF ) );
+                Write( REG_LR_INVERTIQ2, RFLR_INVERTIQ2_OFF );
             }      
         
             this->settings.LoRaPacketHandler.Size = size;
@@ -696,23 +722,26 @@
 
 void SX1276::Sleep( void )
 {
-    // Initialize driver timeout timers
     txTimeoutTimer.detach(  );
     rxTimeoutTimer.detach( );
+
     SetOpMode( RF_OPMODE_SLEEP );
+    this->settings.State = RF_IDLE;
 }
 
 void SX1276::Standby( void )
 {
     txTimeoutTimer.detach(  );
     rxTimeoutTimer.detach( );
+
     SetOpMode( RF_OPMODE_STANDBY );
+    this->settings.State = RF_IDLE;
 }
 
 void SX1276::Rx( uint32_t timeout )
 {
     bool rxContinuous = false;
-
+    
     switch( this->settings.Modem )
     {
     case MODEM_FSK:
@@ -725,7 +754,7 @@
             // DIO3=FifoEmpty
             // DIO4=Preamble
             // DIO5=ModeReady
-            Write( REG_DIOMAPPING1, ( Read( REG_DIOMAPPING1 ) & RF_DIOMAPPING1_DIO0_MASK & RF_DIOMAPPING1_DIO1_MASK &
+            Write( REG_DIOMAPPING1, ( Read( REG_DIOMAPPING1 ) & RF_DIOMAPPING1_DIO0_MASK &
                                                                             RF_DIOMAPPING1_DIO2_MASK ) |
                                                                             RF_DIOMAPPING1_DIO0_00 |
                                                                             RF_DIOMAPPING1_DIO2_11 );
@@ -748,24 +777,74 @@
             if( this->settings.LoRa.IqInverted == true )
             {
                 Write( REG_LR_INVERTIQ, ( ( Read( REG_LR_INVERTIQ ) & RFLR_INVERTIQ_TX_MASK & RFLR_INVERTIQ_RX_MASK ) | RFLR_INVERTIQ_RX_ON | RFLR_INVERTIQ_TX_OFF ) );
+                Write( REG_LR_INVERTIQ2, RFLR_INVERTIQ2_ON );
             }
             else
             {
                 Write( REG_LR_INVERTIQ, ( ( Read( REG_LR_INVERTIQ ) & RFLR_INVERTIQ_TX_MASK & RFLR_INVERTIQ_RX_MASK ) | RFLR_INVERTIQ_RX_OFF | RFLR_INVERTIQ_TX_OFF ) );
+                Write( REG_LR_INVERTIQ2, RFLR_INVERTIQ2_OFF );
             }         
         
+
+            // ERRATA 2.3 - Receiver Spurious Reception of a LoRa Signal
+            if( this->settings.LoRa.Bandwidth < 9 )
+            {
+                Write( REG_LR_DETECTOPTIMIZE, Read( REG_LR_DETECTOPTIMIZE ) & 0x7F );
+                Write( REG_LR_TEST30, 0x00 );
+                switch( this->settings.LoRa.Bandwidth )
+                {
+                case 0: // 7.8 kHz
+                    Write( REG_LR_TEST2F, 0x48 );
+                    SetChannel(this->settings.Channel + 7.81e3 );
+                    break;
+                case 1: // 10.4 kHz
+                    Write( REG_LR_TEST2F, 0x44 );
+                    SetChannel(this->settings.Channel + 10.42e3 );
+                    break;
+                case 2: // 15.6 kHz
+                    Write( REG_LR_TEST2F, 0x44 );
+                    SetChannel(this->settings.Channel + 15.62e3 );
+                    break;
+                case 3: // 20.8 kHz
+                    Write( REG_LR_TEST2F, 0x44 );
+                    SetChannel(this->settings.Channel + 20.83e3 );
+                    break;
+                case 4: // 31.2 kHz
+                    Write( REG_LR_TEST2F, 0x44 );
+                    SetChannel(this->settings.Channel + 31.25e3 );
+                    break;
+                case 5: // 41.4 kHz
+                    Write( REG_LR_TEST2F, 0x44 );
+                    SetChannel(this->settings.Channel + 41.67e3 );
+                    break;
+                case 6: // 62.5 kHz
+                    Write( REG_LR_TEST2F, 0x40 );
+                    break;
+                case 7: // 125 kHz
+                    Write( REG_LR_TEST2F, 0x40 );
+                    break;
+                case 8: // 250 kHz
+                    Write( REG_LR_TEST2F, 0x40 );
+                    break;
+                }
+            }
+            else
+            {
+                Write( REG_LR_DETECTOPTIMIZE, Read( REG_LR_DETECTOPTIMIZE ) | 0x80 );
+            }
+
             rxContinuous = this->settings.LoRa.RxContinuous;
             
             if( this->settings.LoRa.FreqHopOn == true )
             {
                 Write( REG_LR_IRQFLAGSMASK, //RFLR_IRQFLAGS_RXTIMEOUT |
-                                              //RFLR_IRQFLAGS_RXDONE |
-                                              //RFLR_IRQFLAGS_PAYLOADCRCERROR |
-                                              RFLR_IRQFLAGS_VALIDHEADER |
-                                              RFLR_IRQFLAGS_TXDONE |
-                                              RFLR_IRQFLAGS_CADDONE |
-                                              //RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL |
-                                              RFLR_IRQFLAGS_CADDETECTED );
+                                                  //RFLR_IRQFLAGS_RXDONE |
+                                                  //RFLR_IRQFLAGS_PAYLOADCRCERROR |
+                                                  RFLR_IRQFLAGS_VALIDHEADER |
+                                                  RFLR_IRQFLAGS_TXDONE |
+                                                  RFLR_IRQFLAGS_CADDONE |
+                                                  //RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL |
+                                                  RFLR_IRQFLAGS_CADDETECTED );
                                               
                 // DIO0=RxDone, DIO2=FhssChangeChannel
                 Write( REG_DIOMAPPING1, ( Read( REG_DIOMAPPING1 ) & RFLR_DIOMAPPING1_DIO0_MASK & RFLR_DIOMAPPING1_DIO2_MASK  ) | RFLR_DIOMAPPING1_DIO0_00 | RFLR_DIOMAPPING1_DIO2_00 );
@@ -773,18 +852,17 @@
             else
             {
                 Write( REG_LR_IRQFLAGSMASK, //RFLR_IRQFLAGS_RXTIMEOUT |
-                                              //RFLR_IRQFLAGS_RXDONE |
-                                              //RFLR_IRQFLAGS_PAYLOADCRCERROR |
-                                              RFLR_IRQFLAGS_VALIDHEADER |
-                                              RFLR_IRQFLAGS_TXDONE |
-                                              RFLR_IRQFLAGS_CADDONE |
-                                              RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL |
-                                              RFLR_IRQFLAGS_CADDETECTED );
+                                                  //RFLR_IRQFLAGS_RXDONE |
+                                                  //RFLR_IRQFLAGS_PAYLOADCRCERROR |
+                                                  RFLR_IRQFLAGS_VALIDHEADER |
+                                                  RFLR_IRQFLAGS_TXDONE |
+                                                  RFLR_IRQFLAGS_CADDONE |
+                                                  RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL |
+                                                  RFLR_IRQFLAGS_CADDETECTED );
                                               
                 // DIO0=RxDone
                 Write( REG_DIOMAPPING1, ( Read( REG_DIOMAPPING1 ) & RFLR_DIOMAPPING1_DIO0_MASK ) | RFLR_DIOMAPPING1_DIO0_00 );
             }
-            
             Write( REG_LR_FIFORXBASEADDR, 0 );
             Write( REG_LR_FIFOADDRPTR, 0 );
         }
@@ -808,8 +886,8 @@
             rxTimeoutSyncWord.attach_us( this, &SX1276::OnTimeoutIrq, ( 8.0 * ( this->settings.Fsk.PreambleLen +
                                                          ( ( Read( REG_SYNCCONFIG ) &
                                                             ~RF_SYNCCONFIG_SYNCSIZE_MASK ) +
-                                                         1.0 ) + 1.0 ) /
-                                                        ( double )this->settings.Fsk.Datarate ) * 1e6 ) ;
+                                                         1.0 ) + 10.0 ) /
+                                                        ( double )this->settings.Fsk.Datarate ) * 1e6 );
         }
     }
     else
@@ -826,7 +904,8 @@
 }
 
 void SX1276::Tx( uint32_t timeout )
-{ 
+{
+
     switch( this->settings.Modem )
     {
     case MODEM_FSK:
@@ -837,7 +916,7 @@
             // DIO3=FifoEmpty
             // DIO4=LowBat
             // DIO5=ModeReady
-            Write( REG_DIOMAPPING1, ( Read( REG_DIOMAPPING1 ) & RF_DIOMAPPING1_DIO0_MASK & RF_DIOMAPPING1_DIO1_MASK &
+            Write( REG_DIOMAPPING1, ( Read( REG_DIOMAPPING1 ) & RF_DIOMAPPING1_DIO0_MASK &
                                                                             RF_DIOMAPPING1_DIO2_MASK ) );
 
             Write( REG_DIOMAPPING2, ( Read( REG_DIOMAPPING2 ) & RF_DIOMAPPING2_DIO4_MASK &
@@ -847,36 +926,33 @@
         break;
     case MODEM_LORA:
         {
-        
             if( this->settings.LoRa.FreqHopOn == true )
             {
                 Write( REG_LR_IRQFLAGSMASK, RFLR_IRQFLAGS_RXTIMEOUT |
-                                              RFLR_IRQFLAGS_RXDONE |
-                                              RFLR_IRQFLAGS_PAYLOADCRCERROR |
-                                              RFLR_IRQFLAGS_VALIDHEADER |
-                                              //RFLR_IRQFLAGS_TXDONE |
-                                              RFLR_IRQFLAGS_CADDONE |
-                                              //RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL |
-                                              RFLR_IRQFLAGS_CADDETECTED );
+                                                  RFLR_IRQFLAGS_RXDONE |
+                                                  RFLR_IRQFLAGS_PAYLOADCRCERROR |
+                                                  RFLR_IRQFLAGS_VALIDHEADER |
+                                                  //RFLR_IRQFLAGS_TXDONE |
+                                                  RFLR_IRQFLAGS_CADDONE |
+                                                  //RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL |
+                                                  RFLR_IRQFLAGS_CADDETECTED );
                                               
-                // DIO0=TxDone
-                Write( REG_DIOMAPPING1, ( Read( REG_DIOMAPPING1 ) & RFLR_DIOMAPPING1_DIO0_MASK ) | RFLR_DIOMAPPING1_DIO0_01 );
-                // DIO2=FhssChangeChannel
-                Write( REG_DIOMAPPING1, ( Read( REG_DIOMAPPING1 ) & RFLR_DIOMAPPING1_DIO2_MASK ) | RFLR_DIOMAPPING1_DIO2_00 );  
+                // DIO0=TxDone, DIO2=FhssChangeChannel
+                Write( REG_DIOMAPPING1, ( Read( REG_DIOMAPPING1 ) & RFLR_DIOMAPPING1_DIO0_MASK & RFLR_DIOMAPPING1_DIO2_MASK ) | RFLR_DIOMAPPING1_DIO0_01 | RFLR_DIOMAPPING1_DIO2_00 );
             }
             else
             {
                 Write( REG_LR_IRQFLAGSMASK, RFLR_IRQFLAGS_RXTIMEOUT |
-                                              RFLR_IRQFLAGS_RXDONE |
-                                              RFLR_IRQFLAGS_PAYLOADCRCERROR |
-                                              RFLR_IRQFLAGS_VALIDHEADER |
-                                              //RFLR_IRQFLAGS_TXDONE |
-                                              RFLR_IRQFLAGS_CADDONE |
-                                              RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL |
-                                              RFLR_IRQFLAGS_CADDETECTED );
-                                              
+                                                  RFLR_IRQFLAGS_RXDONE |
+                                                  RFLR_IRQFLAGS_PAYLOADCRCERROR |
+                                                  RFLR_IRQFLAGS_VALIDHEADER |
+                                                  //RFLR_IRQFLAGS_TXDONE |
+                                                  RFLR_IRQFLAGS_CADDONE |
+                                                  RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL |
+                                                  RFLR_IRQFLAGS_CADDETECTED );
+
                 // DIO0=TxDone
-                Write( REG_DIOMAPPING1, ( Read( REG_DIOMAPPING1 ) & RFLR_DIOMAPPING1_DIO0_MASK ) | RFLR_DIOMAPPING1_DIO0_01 ); 
+                Write( REG_DIOMAPPING1, ( Read( REG_DIOMAPPING1 ) & RFLR_DIOMAPPING1_DIO0_MASK ) | RFLR_DIOMAPPING1_DIO0_01 );
             }
         }
         break;
@@ -920,7 +996,7 @@
     }
 }
 
-int16_t SX1276::GetRssi( ModemType modem )
+int16_t SX1276::GetRssi( RadioModems_t modem )
 {
     int16_t rssi = 0;
 
@@ -971,34 +1047,35 @@
     }
 }
 
-void SX1276::SetModem( ModemType modem )
+void SX1276::SetModem( RadioModems_t modem )
 {
-    if( this->settings.Modem != modem )
+    if( this->settings.Modem == modem )
+    {
+        return;
+    }
+
+    this->settings.Modem = modem;
+    switch( this->settings.Modem )
     {
-        this->settings.Modem = modem;
-        switch( this->settings.Modem )
-        {
-        default:
-        case MODEM_FSK:
-            SetOpMode( RF_OPMODE_SLEEP );
-            Write( REG_OPMODE, ( Read( REG_OPMODE ) & RFLR_OPMODE_LONGRANGEMODE_MASK ) | RFLR_OPMODE_LONGRANGEMODE_OFF );
-        
-            Write( REG_DIOMAPPING1, 0x00 );
-            Write( REG_DIOMAPPING2, 0x30 ); // DIO5=ModeReady
-            break;
-        case MODEM_LORA:
-            SetOpMode( RF_OPMODE_SLEEP );
-            Write( REG_OPMODE, ( Read( REG_OPMODE ) & RFLR_OPMODE_LONGRANGEMODE_MASK ) | RFLR_OPMODE_LONGRANGEMODE_ON );
-            Write( 0x30, 0x00 ); //  IF = 0
-            Write( REG_LR_DETECTOPTIMIZE, ( Read( REG_LR_DETECTOPTIMIZE ) & 0x7F ) ); // Manual IF
-            Write( REG_DIOMAPPING1, 0x00 );
-            Write( REG_DIOMAPPING2, 0x00 );
-            break;
-        }
+    default:
+    case MODEM_FSK:
+        SetOpMode( RF_OPMODE_SLEEP );
+        Write( REG_OPMODE, ( Read( REG_OPMODE ) & RFLR_OPMODE_LONGRANGEMODE_MASK ) | RFLR_OPMODE_LONGRANGEMODE_OFF );
+    
+        Write( REG_DIOMAPPING1, 0x00 );
+        Write( REG_DIOMAPPING2, 0x30 ); // DIO5=ModeReady
+        break;
+    case MODEM_LORA:
+        SetOpMode( RF_OPMODE_SLEEP );
+        Write( REG_OPMODE, ( Read( REG_OPMODE ) & RFLR_OPMODE_LONGRANGEMODE_MASK ) | RFLR_OPMODE_LONGRANGEMODE_ON );
+
+        Write( REG_DIOMAPPING1, 0x00 );
+        Write( REG_DIOMAPPING2, 0x00 );
+        break;
     }
 }
 
-void SX1276::SetMaxPayloadLength( ModemType modem, uint8_t max )
+void SX1276::SetMaxPayloadLength( RadioModems_t modem, uint8_t max )
 {
     this->SetModem( modem );
 
@@ -1045,14 +1122,14 @@
                 rxTimeoutSyncWord.detach( );
             }
         }
-        if( ( this->RadioEvents->RxTimeout != NULL ) )
+        if( ( this->RadioEvents != NULL ) && ( this->RadioEvents->RxTimeout != NULL ) )
         {
             this->RadioEvents->RxTimeout( );
         }
         break;
     case RF_TX_RUNNING:
         this->settings.State = RF_IDLE;
-        if( ( this->RadioEvents->TxTimeout != NULL ) )
+        if( ( this->RadioEvents != NULL ) && ( this->RadioEvents->TxTimeout != NULL ) )
         {
             this->RadioEvents->TxTimeout( );
         }
@@ -1065,7 +1142,7 @@
 void SX1276::OnDio0Irq( void )
 {
     volatile uint8_t irqFlags = 0;
-  
+
     switch( this->settings.State )
     {                
         case RF_RX_RUNNING:
@@ -1091,7 +1168,7 @@
                             rxTimeoutSyncWord.attach_us( this, &SX1276::OnTimeoutIrq, (  8.0 * ( this->settings.Fsk.PreambleLen +
                                                              ( ( Read( REG_SYNCCONFIG ) &
                                                                 ~RF_SYNCCONFIG_SYNCSIZE_MASK ) +
-                                                             1.0 ) + 1.0 ) /
+                                                             1.0 ) + 10.0 ) /
                                                             ( double )this->settings.Fsk.Datarate ) * 1e6 ) ;
                         }
                         else
@@ -1101,9 +1178,9 @@
                         }
                         rxTimeoutTimer.detach( );
     
-                        if( ( this->RadioEvents->RxError != NULL ) )
+                        if( ( this->RadioEvents != NULL ) && ( this->RadioEvents->RxError != NULL ) )
                         {
-                            this->RadioEvents->RxError( ); 
+                            this->RadioEvents->RxError( );
                         }
                         this->settings.FskPacketHandler.PreambleDetected = false;
                         this->settings.FskPacketHandler.SyncWordDetected = false;
@@ -1139,7 +1216,7 @@
                     rxTimeoutSyncWord.attach_us( this, &SX1276::OnTimeoutIrq, ( 8.0 * ( this->settings.Fsk.PreambleLen +
                                                          ( ( Read( REG_SYNCCONFIG ) &
                                                             ~RF_SYNCCONFIG_SYNCSIZE_MASK ) +
-                                                         1.0 ) + 1.0 ) /
+                                                         1.0 ) + 10.0 ) /
                                                         ( double )this->settings.Fsk.Datarate ) * 1e6 ) ;
                 }
                 else
@@ -1149,7 +1226,7 @@
                 }
                 rxTimeoutTimer.detach( );
 
-                if( ( this->RadioEvents->RxDone != NULL ) )
+                if( ( this->RadioEvents != NULL ) && ( this->RadioEvents->RxDone != NULL ) )
                 {
                     this->RadioEvents->RxDone( rxBuffer, this->settings.FskPacketHandler.Size, this->settings.FskPacketHandler.RssiValue, 0 ); 
                 } 
@@ -1160,7 +1237,7 @@
                 break;
             case MODEM_LORA:
                 {
-                    uint8_t snr = 0;
+                    int8_t snr = 0;
 
                     // Clear Irq
                     Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_RXDONE );
@@ -1177,9 +1254,9 @@
                         }
                         rxTimeoutTimer.detach( );
 
-                        if( ( this->RadioEvents->RxError != NULL ) )
+                        if( ( this->RadioEvents != NULL ) && ( this->RadioEvents->RxError != NULL ) )
                         {
-                            this->RadioEvents->RxError( ); 
+                            this->RadioEvents->RxError( );
                         }
                         break;
                     }
@@ -1198,7 +1275,7 @@
                     }
 
                     int16_t rssi = Read( REG_LR_PKTRSSIVALUE );
-                    if( this->settings.LoRaPacketHandler.SnrValue < 0 )
+                    if( snr < 0 )
                     {
                         if( this->settings.Channel > RF_MID_BAND_THRESH )
                         {
@@ -1232,7 +1309,7 @@
                     }
                     rxTimeoutTimer.detach( );
 
-                    if( ( this->RadioEvents->RxDone != NULL ) )
+                    if( ( this->RadioEvents != NULL ) && ( this->RadioEvents->RxDone != NULL ) )
                     {
                         this->RadioEvents->RxDone( rxBuffer, this->settings.LoRaPacketHandler.Size, this->settings.LoRaPacketHandler.RssiValue, this->settings.LoRaPacketHandler.SnrValue );
                     }
@@ -1254,9 +1331,9 @@
             case MODEM_FSK:
             default:
                 this->settings.State = RF_IDLE;
-                if( ( this->RadioEvents->TxDone != NULL ) )
+                if( ( this->RadioEvents != NULL ) && ( this->RadioEvents->TxDone != NULL ) )
                 {
-                    this->RadioEvents->TxDone( ); 
+                    this->RadioEvents->TxDone( );
                 } 
                 break;
             }
@@ -1303,7 +1380,7 @@
                 // Sync time out
                 rxTimeoutTimer.detach( );
                 this->settings.State = RF_IDLE;
-                if( ( this->RadioEvents->RxTimeout != NULL ) )
+                if( ( this->RadioEvents != NULL ) && ( this->RadioEvents->RxTimeout != NULL ) )
                 {
                     this->RadioEvents->RxTimeout( );
                 }
@@ -1334,7 +1411,7 @@
             default:
                 break;
             }
-            break;      
+            break;
         default:
             break;
     }
@@ -1368,11 +1445,11 @@
                     // Clear Irq
                     Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL );
                     
-                    if( ( this->RadioEvents->FhssChangeChannel != NULL ) )
+                    if( ( this->RadioEvents != NULL ) && ( this->RadioEvents->FhssChangeChannel != NULL ) )
                     {
                         this->RadioEvents->FhssChangeChannel( ( Read( REG_LR_HOPCHANNEL ) & RFLR_HOPCHANNEL_CHANNEL_MASK ) );
                     }
-                }    
+                }
                 break;
             default:
                 break;
@@ -1389,16 +1466,16 @@
                     // Clear Irq
                     Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL );
                     
-                    if( ( this->RadioEvents->FhssChangeChannel != NULL ) )
+                    if( ( this->RadioEvents != NULL ) && ( this->RadioEvents->FhssChangeChannel != NULL ) )
                     {
                         this->RadioEvents->FhssChangeChannel( ( Read( REG_LR_HOPCHANNEL ) & RFLR_HOPCHANNEL_CHANNEL_MASK ) );
                     }
-                }    
+                }
                 break;
             default:
                 break;
             }
-            break;      
+            break;
         default:
             break;
     }
@@ -1411,11 +1488,11 @@
     case MODEM_FSK:
         break;
     case MODEM_LORA:
-        if( ( Read( REG_LR_IRQFLAGS ) & 0x01 ) == 0x01 )
+        if( ( Read( REG_LR_IRQFLAGS ) & RFLR_IRQFLAGS_CADDETECTED ) == RFLR_IRQFLAGS_CADDETECTED )
         {
             // Clear Irq
-            Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_CADDETECTED_MASK | RFLR_IRQFLAGS_CADDONE);
-            if( ( this->RadioEvents->CadDone != NULL ) )
+            Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_CADDETECTED | RFLR_IRQFLAGS_CADDONE );
+            if( ( this->RadioEvents != NULL ) && ( this->RadioEvents->CadDone != NULL ) )
             {
                 this->RadioEvents->CadDone( true );
             }
@@ -1424,7 +1501,7 @@
         {        
             // Clear Irq
             Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_CADDONE );
-            if( ( this->RadioEvents->CadDone != NULL ) )
+            if( ( this->RadioEvents != NULL ) && ( this->RadioEvents->CadDone != NULL ) )
             {
                 this->RadioEvents->CadDone( false );
             }
--- a/sx1276/sx1276.h	Thu Nov 26 10:39:03 2015 +0000
+++ b/sx1276/sx1276.h	Thu Nov 26 16:55:15 2015 +0000
@@ -4,7 +4,7 @@
  \____ \| ___ |    (_   _) ___ |/ ___)  _ \
  _____) ) ____| | | || |_| ____( (___| | | |
 (______/|_____)_|_|_| \__)_____)\____)_| |_|
-    ( C )2014 Semtech
+    (C) 2014 Semtech
 
 Description: Actual implementation of a SX1276 radio, inherits Radio
 
@@ -33,10 +33,6 @@
 
 #define RX_BUFFER_SIZE                              256
 
-#define DEFAULT_TIMEOUT                             200 //usec
-#define RSSI_OFFSET                                 -139.0
-
-
 /*!
  * Constant values need to compute the RSSI value
  */
@@ -137,7 +133,7 @@
      *
      * @param [IN] modem Modem to be used [0: FSK, 1: LoRa] 
      */
-    virtual void SetModem( ModemType modem );
+    virtual void SetModem( RadioModems_t modem );
 
     /*!
      * @brief Sets the channel frequency
@@ -155,7 +151,7 @@
      *
      * @retval isFree         [true: Channel is free, false: Channel is not free]
      */
-    virtual bool IsChannelFree( ModemType modem, uint32_t freq, int8_t rssiThresh );
+    virtual bool IsChannelFree( RadioModems_t modem, uint32_t freq, int16_t rssiThresh );
     
     /*!
      * @brief Generates a 32 bits random value based on the RSSI readings
@@ -204,7 +200,7 @@
      * @param [IN] rxContinuous Sets the reception in continuous mode
      *                          [false: single mode, true: continuous mode]
      */
-    virtual void SetRxConfig ( ModemType modem, uint32_t bandwidth,
+    virtual void SetRxConfig ( RadioModems_t modem, uint32_t bandwidth,
                                uint32_t datarate, uint8_t coderate,
                                uint32_t bandwidthAfc, uint16_t preambleLen,
                                uint16_t symbTimeout, bool fixLen,
@@ -241,7 +237,7 @@
      *                          LoRa: [0: not inverted, 1: inverted]
      * @param [IN] timeout      Transmission timeout [us]
      */
-    virtual void SetTxConfig( ModemType modem, int8_t power, uint32_t fdev,
+    virtual void SetTxConfig( RadioModems_t modem, int8_t power, uint32_t fdev,
                               uint32_t bandwidth, uint32_t datarate,
                               uint8_t coderate, uint16_t preambleLen,
                               bool fixLen, bool crcOn, bool freqHopOn,
@@ -257,7 +253,7 @@
      *
      * @retval airTime        Computed airTime for the given packet payload length
      */
-    virtual double TimeOnAir ( ModemType modem, uint8_t pktLen );
+    virtual double TimeOnAir ( RadioModems_t modem, uint8_t pktLen );
     
     /*!
      * @brief Sends the buffer of size. Prepares the packet to be sent and sets
@@ -302,7 +298,7 @@
      *
      * @retval rssiValue Current RSSI value in [dBm]
      */
-    virtual int16_t GetRssi ( ModemType modem );
+    virtual int16_t GetRssi ( RadioModems_t modem );
     
     /*!
      * @brief Writes the radio register at the specified address
@@ -364,7 +360,7 @@
      * @param [IN] modem      Radio modem to be used [0: FSK, 1: LoRa]
      * @param [IN] max        Maximum payload length in bytes
      */
-    virtual void SetMaxPayloadLength( ModemType modem, uint8_t max );
+    virtual void SetMaxPayloadLength( RadioModems_t modem, uint8_t max );
     
     //-------------------------------------------------------------------------
     //                        Board relative functions
@@ -500,4 +496,4 @@
     static uint8_t GetFskBandwidthRegValue( uint32_t bandwidth );
 };
 
-#endif //__SX1276_H__
+#endif // __SX1276_H__
--- a/typedefs/typedefs.h	Thu Nov 26 10:39:03 2015 +0000
+++ b/typedefs/typedefs.h	Thu Nov 26 16:55:15 2015 +0000
@@ -4,7 +4,7 @@
  \____ \| ___ |    (_   _) ___ |/ ___)  _ \
  _____) ) ____| | | || |_| ____( (___| | | |
 (______/|_____)_|_|_| \__)_____)\____)_| |_|
-    ( C )2014 Semtech
+    (C) 2014 Semtech
 
 Description: -
 
@@ -51,4 +51,3 @@
 }RadioRegisters_t;
 
 #endif //__TYPEDEFS_H__
-