initial commit for sx1280 util_tx_tag app

Dependencies:   mbed

Files at this revision

API Documentation at this revision

Comitter:
mick_ccc
Date:
Tue Aug 28 11:51:39 2018 +0000
Commit message:
export sx1280 util_tx_tag test application, to be used with sx1280 dev kit

Changed in this revision

main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
sx1280-driver/radio.h Show annotated file Show diff for this revision Revisions of this file
sx1280-driver/sx1280-hal.cpp Show annotated file Show diff for this revision Revisions of this file
sx1280-driver/sx1280-hal.h Show annotated file Show diff for this revision Revisions of this file
sx1280-driver/sx1280.cpp Show annotated file Show diff for this revision Revisions of this file
sx1280-driver/sx1280.h Show annotated file Show diff for this revision Revisions of this file
diff -r 000000000000 -r 1036ecbe7c51 main.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Tue Aug 28 11:51:39 2018 +0000
@@ -0,0 +1,269 @@
+/*
+  ______                              _
+ / _____)             _              | |
+( (____  _____ ____ _| |_ _____  ____| |__
+ \____ \| ___ |    (_   _) ___ |/ ___)  _ \
+ _____) ) ____| | | || |_| ____( (___| | | |
+(______/|_____)_|_|_| \__)_____)\____)_| |_|
+    (C)2017 Semtech
+ 
+Description: Main program
+ 
+*/
+ 
+#include "mbed.h"
+#include "radio.h"
+#include "sx1280-hal.h"
+ 
+ 
+/*!
+ * \brief Defines the nominal frequency
+ */
+#define RF_FREQUENCY                                2400000000UL // Hz
+ 
+/*!
+ * \brief Defines the output power in dBm
+ *
+ * \remark The range of the output power is [-18..+13] dBm
+ */
+#define TX_OUTPUT_POWER                             13
+ 
+/*!
+ * \brief Defines the buffer size, i.e. the payload size
+ */
+#define BUFFER_SIZE                                 255
+ 
+/*!
+ * \brief The size of the buffer
+ */
+//uint8_t BufferSize = 253;
+uint8_t BufferSize = 12;
+ 
+/*!
+ * \brief The buffer
+ */
+uint8_t Buffer[BUFFER_SIZE];
+ 
+int8_t RssiValue = 0;
+int8_t SnrValue = 0;
+ 
+/*!
+ * \brief Function to be executed on Radio Tx Done event
+ */
+void OnTxDone( void );
+ 
+/*!
+ * \brief Function to be executed on Radio Rx Done event
+ */
+void OnRxDone( void );
+ 
+/*!
+ * \brief Function executed on Radio Tx Timeout event
+ */
+void OnTxTimeout( void );
+ 
+/*!
+ * \brief Function executed on Radio Rx Timeout event
+ */
+void OnRxTimeout( void );
+ 
+/*!
+ * \brief Function executed on Radio Rx Error event
+ */
+void OnRxError( IrqErrorCode_t );
+ 
+/*!
+ * \brief All the callbacks are stored in a structure
+ */
+RadioCallbacks_t callbacks =
+{
+    &OnTxDone,        // txDone
+    &OnRxDone,        // rxDone
+    NULL,             // syncWordDone
+    NULL,             // headerDone
+    &OnTxTimeout,     // txTimeout
+    &OnRxTimeout,     // rxTimeout
+    &OnRxError,       // rxError
+    NULL,             // rangingDone
+    NULL,             // cadDone
+};
+ 
+// mosi, miso, sclk, nss, busy, dio1, dio2, dio3, rst, callbacks...
+SX1280Hal Radio( D11, D12, D13, D7, D3, D5, NC, NC, A0, &callbacks );
+ 
+DigitalOut ANT_SW( A3 );
+DigitalOut TxLed( A4 );
+DigitalOut RxLed( A5 );
+ 
+/*!
+ * \brief Define IO for Unused Pin
+ */
+DigitalOut F_CS( D6 );      // MBED description of pin
+DigitalOut SD_CS( D8 );     // MBED description of pin
+ 
+/*!
+ * \brief Number of tick size steps for tx timeout
+ */
+#define TX_TIMEOUT_VALUE                            100 // ms
+ 
+/*!
+ * \brief Number of tick size steps for rx timeout
+ */
+#define RX_TIMEOUT_VALUE                            100 // ms
+ 
+/*!
+ * \brief Size of ticks (used for Tx and Rx timeout)
+ */
+#define RX_TIMEOUT_TICK_SIZE                        RADIO_TICK_SIZE_1000_US
+ 
+/*!
+ * \brief Mask of IRQs to listen to in rx mode
+ */
+uint16_t RxIrqMask = IRQ_RX_DONE | IRQ_RX_TX_TIMEOUT;
+ 
+/*!
+ * \brief Mask of IRQs to listen to in tx mode
+ */
+uint16_t TxIrqMask = IRQ_TX_DONE | IRQ_RX_TX_TIMEOUT;
+ 
+/*!
+ * \brief Locals parameters and status for radio API
+ * NEED TO BE OPTIMIZED, COPY OF STUCTURE ALREADY EXISTING
+ */
+PacketParams_t PacketParams;
+PacketStatus_t PacketStatus;
+
+#if 1
+    const uint8_t nb_freq = 4;
+    uint32_t tx_freq[nb_freq] = {
+        2400000000U,
+        2406000000U,
+        2412000000U,
+        2418000000U
+    };
+#endif
+#if 0
+    const uint8_t nb_freq = 1;
+    uint32_t tx_freq[nb_freq] = {
+        2400000000U
+    };
+#endif
+#if 0
+    const uint8_t nb_freq = 2;
+    uint32_t tx_freq[nb_freq] = {
+        2400000000U,
+        2412000000U
+    };
+#endif
+
+/*!
+ * \brief Specify serial datarate for UART debug output
+ */
+void baud( int baudrate )
+{
+    Serial s( USBTX, USBRX );
+ 
+    s.baud( baudrate );
+}
+ 
+int main( )
+{
+    uint32_t cnt;
+    ModulationParams_t modulationParams;
+ 
+    baud( 115200 );
+ 
+    F_CS   = 1;
+    SD_CS  = 1;
+    RxLed  = 1;
+    TxLed  = 1;
+    ANT_SW = 1;
+ 
+    wait_ms( 500 ); // wait for on board DC/DC start-up time
+ 
+    Radio.Init( );
+    Radio.SetRegulatorMode( USE_DCDC ); // Can also be set in LDO mode but consume more power
+ 
+    memset( &Buffer, 0x00, BufferSize );
+ 
+    printf( "\nsx1280 TX test (fw:0x%x)\n\r", Radio.GetFirmwareVersion( ) );
+    modulationParams.PacketType                  = PACKET_TYPE_LORA;
+    modulationParams.Params.LoRa.SpreadingFactor = LORA_SF10;
+    modulationParams.Params.LoRa.Bandwidth       = LORA_BW_1600;
+    modulationParams.Params.LoRa.CodingRate      = LORA_CR_4_5;
+ 
+    PacketParams.PacketType                 = PACKET_TYPE_LORA;
+    PacketParams.Params.LoRa.PreambleLength = 0x08;
+    PacketParams.Params.LoRa.HeaderType     = LORA_PACKET_VARIABLE_LENGTH;
+    PacketParams.Params.LoRa.PayloadLength  = BufferSize;
+    PacketParams.Params.LoRa.Crc            = LORA_CRC_ON;
+    PacketParams.Params.LoRa.InvertIQ       = LORA_IQ_NORMAL;
+ 
+    Radio.SetStandby( STDBY_RC );
+    Radio.SetPacketType( modulationParams.PacketType );
+    Radio.SetModulationParams( &modulationParams );
+    Radio.SetPacketParams( &PacketParams );
+ 
+    Radio.SetRfFrequency( RF_FREQUENCY );
+    Radio.SetBufferBaseAddresses( 0x00, 0x00 );
+    Radio.SetTxParams( TX_OUTPUT_POWER, RADIO_RAMP_20_US );
+ 
+    RxLed = 0;
+    TxLed = 0;
+ 
+    cnt = 0;
+    //while( cnt < 1000 )
+    //while( cnt < 10 )
+    while( 1 )
+    {
+        Buffer[0] = 0; /* ID */
+        Buffer[1] = (uint8_t)(cnt >> 24);
+        Buffer[2] = (uint8_t)(cnt >> 16);
+        Buffer[3] = (uint8_t)(cnt >> 8);
+        Buffer[4] = (uint8_t)(cnt >> 0);
+        Radio.SetRfFrequency( tx_freq[cnt % nb_freq] );
+        Radio.SetDioIrqParams( TxIrqMask, TxIrqMask, IRQ_RADIO_NONE, IRQ_RADIO_NONE );
+        TxLed = 1;
+        Radio.SendPayload( Buffer, BufferSize, ( TickTime_t ){ RX_TIMEOUT_TICK_SIZE, TX_TIMEOUT_VALUE } );
+#if 0
+        wait_us( 2500 );
+#else
+        wait_ms( 1000 );
+#endif
+        TxLed = 0;
+        cnt += 1;
+    }
+}
+ 
+void OnTxDone( void )
+{
+}
+ 
+void OnRxDone( void )
+{
+    RssiValue = PacketStatus.LoRa.RssiPkt;
+    SnrValue = PacketStatus.LoRa.SnrPkt;
+    printf("rssi: %d; snr: %d\n\r", RssiValue, SnrValue );
+}
+ 
+void OnTxTimeout( void )
+{
+    printf( "<>>>>>>>>TXE\r\n" );
+}
+ 
+void OnRxTimeout( void )
+{
+}
+ 
+void OnRxError( IrqErrorCode_t errorCode )
+{
+    printf( "RXE<>>>>>>>>\r\n" );
+}
+ 
+void OnRangingDone( IrqRangingCode_t val )
+{
+}
+ 
+void OnCadDone( bool channelActivityDetected )
+{
+}
diff -r 000000000000 -r 1036ecbe7c51 mbed.bld
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Tue Aug 28 11:51:39 2018 +0000
@@ -0,0 +1,1 @@
+https://os.mbed.com/users/mbed_official/code/mbed/builds/a7c7b631e539
\ No newline at end of file
diff -r 000000000000 -r 1036ecbe7c51 sx1280-driver/radio.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sx1280-driver/radio.h	Tue Aug 28 11:51:39 2018 +0000
@@ -0,0 +1,310 @@
+/*
+  ______                              _
+ / _____)             _              | |
+( (____  _____ ____ _| |_ _____  ____| |__
+ \____ \| ___ |    (_   _) ___ |/ ___)  _ \
+ _____) ) ____| | | || |_| ____( (___| | | |
+(______/|_____)_|_|_| \__)_____)\____)_| |_|
+    (C)2016 Semtech
+
+Description: Handling of the node configuration protocol
+
+License: Revised BSD License, see LICENSE.TXT file include in the project
+
+Maintainer: Miguel Luis, Gregory Cristian and Matthieu Verdy
+*/
+#ifndef __RADIO_H__
+#define __RADIO_H__
+
+#include "mbed.h"
+
+/*!
+ * \brief Structure describing the radio status
+ */
+typedef union
+{
+    /*!
+     * \brief Structure of the radio status
+     */
+    struct
+    {
+        uint8_t CpuBusy   : 1;  //!< Flag for CPU radio busy
+        uint8_t DmaBusy   : 1;  //!< Flag for DMA busy
+        uint8_t CmdStatus : 3;  //!< Command status
+        uint8_t ChipMode  : 3;  //!< Chip mode
+    }Fields;
+
+    /*!
+     * \brief Serialized radio status
+     */
+    uint8_t Value;
+}RadioStatus_t;
+
+/*!
+ * \brief Structure describing the ranging codes for callback functions
+ */
+typedef enum
+{
+    IRQ_RANGING_SLAVE_ERROR_CODE            = 0x00,
+    IRQ_RANGING_SLAVE_VALID_CODE,
+    IRQ_RANGING_MASTER_ERROR_CODE,
+    IRQ_RANGING_MASTER_VALID_CODE,
+}IrqRangingCode_t;
+
+/*!
+ * \brief Structure describing the error codes for callback functions
+ */
+typedef enum
+{
+    IRQ_HEADER_ERROR_CODE                   = 0x00,
+    IRQ_SYNCWORD_ERROR_CODE,
+    IRQ_CRC_ERROR_CODE,
+    IRQ_RANGING_ON_LORA_ERROR_CODE,
+}IrqErrorCode_t;
+
+/*!
+ * \brief Structure describing the validity codes for callback function rxValid
+ */
+typedef enum
+{
+    IRQ_HEADER_VALID_CODE                   = 0x00,
+    IRQ_SYNCWORD_VALID_CODE,
+}IrqValidCode_t;
+
+/*!
+ * \brief Represents all possible opcode understood by the radio
+ */
+typedef enum RadioCommands_u
+{
+    RADIO_GET_STATUS                        = 0xC0,
+    RADIO_WRITE_REGISTER                    = 0x18,
+    RADIO_READ_REGISTER                     = 0x19,
+    RADIO_WRITE_BUFFER                      = 0x1A,
+    RADIO_READ_BUFFER                       = 0x1B,
+    RADIO_SET_SLEEP                         = 0x84,
+    RADIO_SET_STANDBY                       = 0x80,
+    RADIO_SET_FS                            = 0xC1,
+    RADIO_SET_TX                            = 0x83,
+    RADIO_SET_RX                            = 0x82,
+    RADIO_SET_RXDUTYCYCLE                   = 0x94,
+    RADIO_SET_CAD                           = 0xC5,
+    RADIO_SET_TXCONTINUOUSWAVE              = 0xD1,
+    RADIO_SET_TXCONTINUOUSPREAMBLE          = 0xD2,
+    RADIO_SET_PACKETTYPE                    = 0x8A,
+    RADIO_GET_PACKETTYPE                    = 0x03,
+    RADIO_SET_RFFREQUENCY                   = 0x86,
+    RADIO_SET_TXPARAMS                      = 0x8E,
+    RADIO_SET_CADPARAMS                     = 0x88,
+    RADIO_SET_BUFFERBASEADDRESS             = 0x8F,
+    RADIO_SET_MODULATIONPARAMS              = 0x8B,
+    RADIO_SET_PACKETPARAMS                  = 0x8C,
+    RADIO_GET_RXBUFFERSTATUS                = 0x17,
+    RADIO_GET_PACKETSTATUS                  = 0x1D,
+    RADIO_GET_RSSIINST                      = 0x1F,
+    RADIO_SET_DIOIRQPARAMS                  = 0x8D,
+    RADIO_GET_IRQSTATUS                     = 0x15,
+    RADIO_CLR_IRQSTATUS                     = 0x97,
+    RADIO_CALIBRATE                         = 0x89,
+    RADIO_SET_REGULATORMODE                 = 0x96,
+    RADIO_SET_SAVECONTEXT                   = 0xD5,
+    RADIO_SET_AUTOTX                        = 0x98,
+    RADIO_SET_AUTOFS                        = 0x9E,
+    RADIO_SET_LONGPREAMBLE                  = 0x9B,
+    RADIO_SET_UARTSPEED                     = 0x9D,
+    RADIO_SET_RANGING_ROLE                  = 0xA3,
+}RadioCommands_t;
+
+/*!
+ * \brief The radio callbacks structure
+ * Holds function pointers to be called on radio interrupts
+ */
+typedef struct
+{
+    void ( *txDone )( void );                       //!< Pointer to a function run on successful transmission
+    void ( *rxDone )( void );                       //!< Pointer to a function run on successful reception
+    void ( *rxSyncWordDone )( void );               //!< Pointer to a function run on successful SyncWord reception
+    void ( *rxHeaderDone )( void );                 //!< Pointer to a function run on successful Header reception
+    void ( *txTimeout )( void );                    //!< Pointer to a function run on transmission timeout
+    void ( *rxTimeout )( void );                    //!< Pointer to a function run on reception timeout
+    void ( *rxError )( IrqErrorCode_t errCode );    //!< Pointer to a function run on reception error
+    void ( *rangingDone )( IrqRangingCode_t val );  //!< Pointer to a function run on ranging terminated
+    void ( *cadDone )( bool cadFlag );              //!< Pointer to a function run on channel activity detected
+}RadioCallbacks_t;
+
+/*!
+ * \brief Class holding the basic communications with a radio
+ *
+ * It sets the functions to read/write registers, send commands and read/write
+ * payload.
+ * It also provides functions to run callback functions depending on the
+ * interrupts generated from the radio.
+ */
+class Radio
+{
+protected:
+    /*!
+     * \brief Callback on Tx done interrupt
+     */
+    void ( *txDone )( void );
+
+    /*!
+     * \brief Callback on Rx done interrupt
+     */
+    void ( *rxDone )( void );
+
+    /*!
+     * \brief Callback on Rx SyncWord interrupt
+     */
+    void ( *rxSyncWordDone )( void );
+
+    /*!
+     * \brief Callback on Rx header received interrupt
+     */
+    void ( *rxHeaderDone )( void );
+
+    /*!
+     * \brief Callback on Tx timeout interrupt
+     */
+    void ( *txTimeout )( void );
+
+    /*!
+     * \brief Callback on Rx timeout interrupt
+     */
+    void ( *rxTimeout )( void );
+
+    /*!
+     * \brief Callback on Rx error interrupt
+     *
+     * \param [out] errCode       A code indicating the type of interrupt (SyncWord error or CRC error)
+     */
+    void ( *rxError )( IrqErrorCode_t errCode );
+
+    /*!
+     * \brief Callback on ranging done interrupt
+     *
+     * \param [out] val           A flag indicating the type of interrupt (Master/Slave and Valid/Error)
+     */
+    void ( *rangingDone )( IrqRangingCode_t val );
+
+    /*!
+     * \brief Callback on Channel Activity Detection done interrupt
+     *
+     * \param [out] cadFlag       Flag for channel activity detected or not
+     */
+    void ( *cadDone )( bool cadFlag );
+
+public:
+    /*!
+     * \brief Constructor for radio class
+     * Sets the callbacks functions pointers
+     *
+     * \param [in]  callbacks     The structure of callbacks function pointers
+     *                            to be called on radio interrupts
+     *
+     */
+    Radio( RadioCallbacks_t *callbacks )
+    {
+        this->txDone = callbacks->txDone;
+        this->rxDone = callbacks->rxDone;
+        this->rxSyncWordDone = callbacks->rxSyncWordDone;
+        this->rxHeaderDone = callbacks->rxHeaderDone;
+        this->txTimeout = callbacks->txTimeout;
+        this->rxTimeout = callbacks->rxTimeout;
+        this->rxError = callbacks->rxError;
+        this->rangingDone = callbacks->rangingDone;
+        this->cadDone = callbacks->cadDone;
+    }
+    virtual ~Radio( void ){ };
+
+    /*!
+     * \brief Resets the radio
+     */
+    virtual void Reset( void ) = 0;
+
+    /*!
+     * \brief Gets the current radio status
+     *
+     * \retval      status        Radio status
+     */
+    virtual RadioStatus_t GetStatus( void ) = 0;
+
+    /*!
+     * \brief Writes the given command to the radio
+     *
+     * \param [in]  opcode        Command opcode
+     * \param [in]  buffer        Command parameters byte array
+     * \param [in]  size          Command parameters byte array size
+     */
+    virtual void WriteCommand( RadioCommands_t opcode, uint8_t *buffer, uint16_t size ) = 0;
+
+    /*!
+     * \brief Reads the given command from the radio
+     *
+     * \param [in]  opcode        Command opcode
+     * \param [in]  buffer        Command parameters byte array
+     * \param [in]  size          Command parameters byte array size
+     */
+    virtual void ReadCommand( RadioCommands_t opcode, uint8_t *buffer, uint16_t size ) = 0;
+
+    /*!
+     * \brief Writes multiple radio registers starting at address
+     *
+     * \param [in]  address       First Radio register address
+     * \param [in]  buffer        Buffer containing the new register's values
+     * \param [in]  size          Number of registers to be written
+     */
+    virtual void WriteRegister( uint16_t address, uint8_t *buffer, uint16_t size ) = 0;
+
+    /*!
+     * \brief Writes the radio register at the specified address
+     *
+     * \param [in]  address       Register address
+     * \param [in]  value         New register value
+     */
+    virtual void WriteRegister( uint16_t address, uint8_t value ) = 0;
+
+    /*!
+     * \brief Reads multiple radio registers starting at address
+     *
+     * \param [in]  address       First Radio register address
+     * \param [out] buffer        Buffer where to copy the registers data
+     * \param [in]  size          Number of registers to be read
+     */
+    virtual void ReadRegister( uint16_t address, uint8_t *buffer, uint16_t size ) = 0;
+
+    /*!
+     * \brief Reads the radio register at the specified address
+     *
+     * \param [in]  address       Register address
+     *
+     * \retval      value         The register value
+     */
+    virtual uint8_t ReadRegister( uint16_t address ) = 0;
+
+    /*!
+     * \brief Writes Radio Data Buffer with buffer of size starting at offset.
+     *
+     * \param [in]  offset        Offset where to start writing
+     * \param [in]  buffer        Buffer pointer
+     * \param [in]  size          Buffer size
+     */
+    virtual void WriteBuffer( uint8_t offset, uint8_t *buffer, uint8_t size ) = 0;
+
+    /*!
+     * \brief Reads Radio Data Buffer at offset to buffer of size
+     *
+     * \param [in]  offset        Offset where to start reading
+     * \param [out] buffer        Buffer pointer
+     * \param [in]  size          Buffer size
+     */
+    virtual void ReadBuffer( uint8_t offset, uint8_t *buffer, uint8_t size ) = 0;
+
+    /*!
+     * \brief Return firmware version
+     *
+     * \retval      firmware      The firmware version
+     */
+    virtual uint16_t GetFirmwareVersion( void ) = 0;
+};
+
+#endif // __RADIO_H__
diff -r 000000000000 -r 1036ecbe7c51 sx1280-driver/sx1280-hal.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sx1280-driver/sx1280-hal.cpp	Tue Aug 28 11:51:39 2018 +0000
@@ -0,0 +1,471 @@
+/*
+  ______                              _
+ / _____)             _              | |
+( (____  _____ ____ _| |_ _____  ____| |__
+ \____ \| ___ |    (_   _) ___ |/ ___)  _ \
+ _____) ) ____| | | || |_| ____( (___| | | |
+(______/|_____)_|_|_| \__)_____)\____)_| |_|
+    (C)2016 Semtech
+
+Description: Handling of the node configuration protocol
+
+License: Revised BSD License, see LICENSE.TXT file include in the project
+
+Maintainer: Miguel Luis, Gregory Cristian and Matthieu Verdy
+*/
+#include "sx1280-hal.h"
+
+/*!
+ * \brief Helper macro to create Interrupt objects only if the pin name is
+ *        different from NC
+ */
+#define CreateDioPin( pinName, dio )                 \
+            if( pinName == NC )                      \
+            {                                        \
+                dio = NULL;                          \
+            }                                        \
+            else                                     \
+            {                                        \
+                dio = new InterruptIn( pinName );    \
+            }
+
+/*!
+ * \brief Helper macro to avoid duplicating code for setting dio pins parameters
+ */
+#if defined( TARGET_NUCLEO_L476RG )
+#define DioAssignCallback( dio, pinMode, callback )                    \
+            if( dio != NULL )                                          \
+            {                                                          \
+                dio->mode( pinMode );                                  \
+                dio->rise( this, static_cast <Trigger>( callback ) );  \
+            }
+#else
+#define DioAssignCallback( dio, pinMode, callback )                    \
+            if( dio != NULL )                                          \
+            {                                                          \
+                dio->rise( this, static_cast <Trigger>( callback ) );  \
+            }
+#endif
+/*!
+ * \brief Used to block execution waiting for low state on radio busy pin.
+ *        Essentially used in SPI communications
+ */
+#define WaitOnBusy( )          while( BUSY == 1 ){ }
+
+/*!
+ * \brief Blocking routine for waiting the UART to be writeable
+ *
+ */
+#define WaitUartWritable( )  while( RadioUart->writeable( ) == false ){ }
+
+/*!
+ * \brief Blocking routine for waiting the UART to be readable
+ *
+ */
+#define WaitUartReadable( )  while( RadioUart->readable( ) == false ){ }
+
+// This code handles cases where assert_param is undefined
+#ifndef assert_param
+#define assert_param( ... )
+#endif
+
+SX1280Hal::SX1280Hal( PinName mosi, PinName miso, PinName sclk, PinName nss,
+                      PinName busy, PinName dio1, PinName dio2, PinName dio3, PinName rst,
+                      RadioCallbacks_t *callbacks )
+        :   SX1280( callbacks ),
+            RadioNss( nss ),
+            RadioReset( rst ),
+            RadioCtsn( NC ),
+            BUSY( busy )
+{
+    CreateDioPin( dio1, DIO1 );
+    CreateDioPin( dio2, DIO2 );
+    CreateDioPin( dio3, DIO3 );
+    RadioSpi = new SPI( mosi, miso, sclk );
+    RadioUart = NULL;
+
+    RadioNss = 1;
+    RadioReset = 1;
+}
+
+SX1280Hal::SX1280Hal( PinName tx, PinName rx, PinName ctsn,
+                      PinName busy, PinName dio1, PinName dio2, PinName dio3, PinName rst,
+                      RadioCallbacks_t *callbacks )
+        :   SX1280( callbacks ),
+            RadioNss( NC ),
+            RadioReset( rst ),
+            RadioCtsn( ctsn ),
+            BUSY( busy )
+{
+    CreateDioPin( dio1, DIO1 );
+    CreateDioPin( dio2, DIO2 );
+    CreateDioPin( dio3, DIO3 );
+    RadioSpi = NULL;
+    RadioUart = new Serial( tx, rx );
+    RadioCtsn = 0;
+    RadioReset = 1;
+}
+
+SX1280Hal::~SX1280Hal( void )
+{
+    if( this->RadioSpi != NULL )
+    {
+        delete RadioSpi;
+    }
+    if( this->RadioUart != NULL )
+    {
+        delete RadioUart;
+    }
+    if( DIO1 != NULL )
+    {
+        delete DIO1;
+    }
+    if( DIO2 != NULL )
+    {
+        delete DIO2;
+    }
+    if( DIO3 != NULL )
+    {
+        delete DIO3;
+    }
+};
+
+void SX1280Hal::SpiInit( void )
+{
+    RadioNss = 1;
+    RadioSpi->format( 8, 0 );
+#if defined( TARGET_KL25Z )
+    this->SetSpiSpeed( 4000000 );
+#elif defined( TARGET_NUCLEO_L476RG )
+    this->SetSpiSpeed( 8000000 );
+#else
+    this->SetSpiSpeed( 8000000 );
+#endif
+    wait( 0.1 );
+}
+
+void SX1280Hal::SetSpiSpeed( uint32_t spiSpeed )
+{
+    RadioSpi->frequency( spiSpeed );
+}
+
+void SX1280Hal::UartInit( void )
+{
+    RadioUart->format( 9, SerialBase::Even, 1 ); // 8 data bits + 1 even parity bit + 1 stop bit
+    RadioUart->baud( 115200 );
+    // After this point, the UART is running standard mode: 8 data bit, 1 even
+    // parity bit, 1 stop bit, 115200 baud, LSB first
+    wait_us( 10 );
+}
+
+void SX1280Hal::IoIrqInit( DioIrqHandler irqHandler )
+{
+    assert_param( RadioSpi != NULL || RadioUart != NULL );
+    if( RadioSpi != NULL )
+    {
+        SpiInit( );
+    }
+    if( RadioUart != NULL )
+    {
+        UartInit( );
+    }
+
+    BUSY.mode( PullNone );
+
+    DioAssignCallback( DIO1, PullNone, irqHandler );
+    DioAssignCallback( DIO2, PullNone, irqHandler );
+    DioAssignCallback( DIO3, PullNone, irqHandler );
+}
+
+void SX1280Hal::Reset( void )
+{
+    __disable_irq( );
+    wait_ms( 20 );
+    RadioReset.output( );
+    RadioReset = 0;
+    wait_ms( 50 );
+    RadioReset = 1;
+    RadioReset.input( ); // Using the internal pull-up
+    wait_ms( 20 );
+    __enable_irq( );
+}
+
+void SX1280Hal::Wakeup( void )
+{
+    __disable_irq( );
+
+    //Don't wait for BUSY here
+
+    if( RadioSpi != NULL )
+    {
+        RadioNss = 0;
+        RadioSpi->write( RADIO_GET_STATUS );
+        RadioSpi->write( 0 );
+        RadioNss = 1;
+    }
+    if( RadioUart != NULL )
+    {
+        RadioUart->putc( RADIO_GET_STATUS );
+        WaitUartReadable( );
+        RadioUart->getc( );
+    }
+
+    // Wait for chip to be ready.
+    WaitOnBusy( );
+
+    __enable_irq( );
+}
+
+void SX1280Hal::WriteCommand( RadioCommands_t command, uint8_t *buffer, uint16_t size )
+{
+    WaitOnBusy( );
+
+    if( RadioSpi != NULL )
+    {
+        RadioNss = 0;
+        RadioSpi->write( ( uint8_t )command );
+        for( uint16_t i = 0; i < size; i++ )
+        {
+            RadioSpi->write( buffer[i] );
+        }
+        RadioNss = 1;
+    }
+    if( RadioUart != NULL )
+    {
+        RadioUart->putc( command );
+        if( size > 0 )
+        {
+            RadioUart->putc( size );
+            for( uint16_t i = 0; i < size; i++ )
+            {
+                RadioUart->putc( buffer[i] );
+            }
+        }
+    }
+
+    if( command != RADIO_SET_SLEEP )
+    {
+        WaitOnBusy( );
+    }
+}
+
+void SX1280Hal::ReadCommand( RadioCommands_t command, uint8_t *buffer, uint16_t size )
+{
+    WaitOnBusy( );
+
+    if( RadioSpi != NULL )
+    {
+        RadioNss = 0;
+        if( command == RADIO_GET_STATUS )
+        {
+            buffer[0] = RadioSpi->write( ( uint8_t )command );
+            RadioSpi->write( 0 );
+            RadioSpi->write( 0 );
+        }
+        else
+        {
+            RadioSpi->write( ( uint8_t )command );
+            RadioSpi->write( 0 );
+            for( uint16_t i = 0; i < size; i++ )
+            {
+                 buffer[i] = RadioSpi->write( 0 );
+            }
+        }
+        RadioNss = 1;
+    }
+    if( RadioUart != NULL )
+    {
+        RadioUart->putc( command );
+
+        // Behavior on the UART is different depending of the opcode command
+        if( ( command == RADIO_GET_PACKETTYPE ) ||
+            ( command == RADIO_GET_RXBUFFERSTATUS ) ||
+            ( command == RADIO_GET_RSSIINST ) ||
+            ( command == RADIO_GET_PACKETSTATUS ) ||
+            ( command == RADIO_GET_IRQSTATUS ) )
+        {
+            /*
+             * TODO : Check size size in UART (uint8_t in putc)
+             */
+            RadioUart->putc( size );
+        }
+
+        WaitUartReadable( );
+        for( uint16_t i = 0; i < size; i++ )
+        {
+             buffer[i] = RadioUart->getc( );
+        }
+    }
+
+    WaitOnBusy( );
+}
+
+void SX1280Hal::WriteRegister( uint16_t address, uint8_t *buffer, uint16_t size )
+{
+    WaitOnBusy( );
+
+    if( RadioSpi != NULL )
+    {
+        RadioNss = 0;
+        RadioSpi->write( RADIO_WRITE_REGISTER );
+        RadioSpi->write( ( address & 0xFF00 ) >> 8 );
+        RadioSpi->write( address & 0x00FF );
+        for( uint16_t i = 0; i < size; i++ )
+        {
+            RadioSpi->write( buffer[i] );
+        }
+        RadioNss = 1;
+    }
+    if( RadioUart != NULL )
+    {
+        uint16_t addr = address;
+        uint16_t i = 0;
+        for( addr = address; ( addr + 255 ) < ( address + size ); )
+        {
+            RadioUart->putc( RADIO_WRITE_REGISTER );
+            RadioUart->putc( ( addr & 0xFF00 ) >> 8 );
+            RadioUart->putc( addr & 0x00FF );
+            RadioUart->putc( 255 );
+            for( uint16_t lastAddr = addr + 255 ; addr < lastAddr; i++, addr++ )
+            {
+                RadioUart->putc( buffer[i] );
+            }
+        }
+        RadioUart->putc( RADIO_WRITE_REGISTER );
+        RadioUart->putc( ( addr & 0xFF00 ) >> 8 );
+        RadioUart->putc( addr & 0x00FF );
+        RadioUart->putc( address + size - addr );
+
+        for( ; addr < ( address + size ); addr++, i++ )
+        {
+            RadioUart->putc( buffer[i] );
+        }
+    }
+
+    WaitOnBusy( );
+}
+
+void SX1280Hal::WriteRegister( uint16_t address, uint8_t value )
+{
+    WriteRegister( address, &value, 1 );
+}
+
+void SX1280Hal::ReadRegister( uint16_t address, uint8_t *buffer, uint16_t size )
+{
+    WaitOnBusy( );
+
+    if( RadioSpi != NULL )
+    {
+        RadioNss = 0;
+        RadioSpi->write( RADIO_READ_REGISTER );
+        RadioSpi->write( ( address & 0xFF00 ) >> 8 );
+        RadioSpi->write( address & 0x00FF );
+        RadioSpi->write( 0 );
+        for( uint16_t i = 0; i < size; i++ )
+        {
+            buffer[i] = RadioSpi->write( 0 );
+        }
+        RadioNss = 1;
+    }
+    if( RadioUart != NULL )
+    {
+        uint16_t addr = address;
+        uint16_t i = 0;
+        for( addr = address; ( addr + 255 ) < ( address + size ); )
+        {
+            RadioUart->putc( RADIO_READ_REGISTER );
+            RadioUart->putc( ( addr & 0xFF00 ) >> 8 );
+            RadioUart->putc( addr & 0x00FF );
+            RadioUart->putc( 255 );
+            WaitUartReadable( );
+            for( uint16_t lastAddr = addr + 255 ; addr < lastAddr; i++, addr++ )
+            {
+                buffer[i] = RadioUart->getc( );
+            }
+        }
+        RadioUart->putc( RADIO_READ_REGISTER );
+        RadioUart->putc( ( addr & 0xFF00 ) >> 8 );
+        RadioUart->putc( addr & 0x00FF );
+        RadioUart->putc( address + size - addr );
+        WaitUartReadable( );
+        for( ; addr < ( address + size ); addr++, i++ )
+        {
+            buffer[i] = RadioUart->getc( );
+        }
+    }
+
+    WaitOnBusy( );
+}
+
+uint8_t SX1280Hal::ReadRegister( uint16_t address )
+{
+    uint8_t data;
+
+    ReadRegister( address, &data, 1 );
+    return data;
+}
+
+void SX1280Hal::WriteBuffer( uint8_t offset, uint8_t *buffer, uint8_t size )
+{
+    WaitOnBusy( );
+
+    if( RadioSpi != NULL )
+    {
+        RadioNss = 0;
+        RadioSpi->write( RADIO_WRITE_BUFFER );
+        RadioSpi->write( offset );
+        for( uint16_t i = 0; i < size; i++ )
+        {
+            RadioSpi->write( buffer[i] );
+        }
+        RadioNss = 1;
+    }
+    if( RadioUart != NULL )
+    {
+        RadioUart->putc( RADIO_WRITE_BUFFER );
+        RadioUart->putc( offset );
+        RadioUart->putc( size );
+        for( uint16_t i = 0; i < size; i++ )
+        {
+            RadioUart->putc( buffer[i] );
+        }
+    }
+
+    WaitOnBusy( );
+}
+
+void SX1280Hal::ReadBuffer( uint8_t offset, uint8_t *buffer, uint8_t size )
+{
+    WaitOnBusy( );
+
+    if( RadioSpi != NULL )
+    {
+        RadioNss = 0;
+        RadioSpi->write( RADIO_READ_BUFFER );
+        RadioSpi->write( offset );
+        RadioSpi->write( 0 );
+        for( uint16_t i = 0; i < size; i++ )
+        {
+            buffer[i] = RadioSpi->write( 0 );
+        }
+        RadioNss = 1;
+    }
+    if( RadioUart != NULL )
+    {
+        RadioUart->putc( RADIO_READ_BUFFER );
+        RadioUart->putc( offset );
+        RadioUart->putc( size );
+        WaitUartReadable( );
+        for( uint16_t i = 0; i < size; i++ )
+        {
+            buffer[i] = RadioUart->getc( );
+        }
+    }
+
+    WaitOnBusy( );
+}
+
+uint8_t SX1280Hal::GetDioStatus( void )
+{
+    return ( *DIO3 << 3 ) | ( *DIO2 << 2 ) | ( *DIO1 << 1 ) | ( BUSY << 0 );
+}
diff -r 000000000000 -r 1036ecbe7c51 sx1280-driver/sx1280-hal.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sx1280-driver/sx1280-hal.h	Tue Aug 28 11:51:39 2018 +0000
@@ -0,0 +1,181 @@
+/*
+  ______                              _
+ / _____)             _              | |
+( (____  _____ ____ _| |_ _____  ____| |__
+ \____ \| ___ |    (_   _) ___ |/ ___)  _ \
+ _____) ) ____| | | || |_| ____( (___| | | |
+(______/|_____)_|_|_| \__)_____)\____)_| |_|
+    (C)2015 Semtech
+
+Description: Handling of the node configuration protocol
+
+License: Revised BSD License, see LICENSE.TXT file include in the project
+
+Maintainer: Miguel Luis and Gregory Cristian
+*/
+#ifndef __SX1280_HAL_H__
+#define __SX1280_HAL_H__
+
+#include "sx1280.h"
+
+/*!
+ * \brief Actual implementation of a SX1280 radio
+ */
+class SX1280Hal : public SX1280
+{
+public:
+    /*!
+     * \brief Constructor for SX1280Hal with SPI support
+     *
+     * Represents the physical connectivity with the radio and set callback functions on radio interrupts
+     */
+    SX1280Hal( PinName mosi, PinName miso, PinName sclk, PinName nss,
+               PinName busy, PinName dio1, PinName dio2, PinName dio3, PinName rst,
+               RadioCallbacks_t *callbacks );
+
+    /*!
+     * \brief Constructor for SX1280Hal with UART support
+     *
+     * Represents the physical connectivity with the radio and set callback functions on radio interrupts
+     */
+    SX1280Hal( PinName tx, PinName rx, PinName ctsn,
+               PinName busy, PinName dio1, PinName dio2, PinName dio3, PinName rst,
+               RadioCallbacks_t *callbacks );
+
+    /*!
+     * \brief Destructor for SX1280Hal with UART support
+     *
+     * Take care of the correct destruction of the communication objects
+     */
+    virtual ~SX1280Hal( void );
+
+    /*!
+     * \brief Soft resets the radio
+     */
+    virtual void Reset( void );
+
+    /*!
+     * \brief Wakes up the radio
+     */
+    virtual void Wakeup( void );
+
+    /*!
+     * \brief Set the SPI Speed
+     *
+     * \param [in]  spiSpeed      Speed of the SPI in Hz
+     */
+    void SetSpiSpeed( uint32_t spiSpeed );
+
+    /*!
+     * \brief Send a command that write data to the radio
+     *
+     * \param [in]  opcode        Opcode of the command
+     * \param [in]  buffer        Buffer to be send to the radio
+     * \param [in]  size          Size of the buffer to send
+     */
+    virtual void WriteCommand( RadioCommands_t opcode, uint8_t *buffer, uint16_t size );
+
+    /*!
+     * \brief Send a command that read data from the radio
+     *
+     * \param [in]  opcode        Opcode of the command
+     * \param [out] buffer        Buffer holding data from the radio
+     * \param [in]  size          Size of the buffer
+     */
+    virtual void ReadCommand( RadioCommands_t opcode, uint8_t *buffer, uint16_t size );
+
+    /*!
+     * \brief Write data to the radio memory
+     *
+     * \param [in]  address       The address of the first byte to write in the radio
+     * \param [in]  buffer        The data to be written in radio's memory
+     * \param [in]  size          The number of bytes to write in radio's memory
+     */
+    virtual void WriteRegister( uint16_t address, uint8_t *buffer, uint16_t size );
+
+    /*!
+     * \brief Write a single byte of data to the radio memory
+     *
+     * \param [in]  address       The address of the first byte to write in the radio
+     * \param [in]  value         The data to be written in radio's memory
+     */
+    virtual void WriteRegister( uint16_t address, uint8_t value );
+
+    /*!
+     * \brief Read data from the radio memory
+     *
+     * \param [in]  address       The address of the first byte to read from the radio
+     * \param [out] buffer        The buffer that holds data read from radio
+     * \param [in]  size          The number of bytes to read from radio's memory
+     */
+    virtual void ReadRegister( uint16_t address, uint8_t *buffer, uint16_t size );
+
+    /*!
+     * \brief Read a single byte of data from the radio memory
+     *
+     * \param [in]  address       The address of the first byte to write in the
+     *                            radio
+     *
+     * \retval      value         The value of the byte at the given address in
+     *                            radio's memory
+     */
+    virtual uint8_t ReadRegister( uint16_t address );
+
+    /*!
+     * \brief Write data to the buffer holding the payload in the radio
+     *
+     * \param [in]  offset        The offset to start writing the payload
+     * \param [in]  buffer        The data to be written (the payload)
+     * \param [in]  size          The number of byte to be written
+     */
+    virtual void WriteBuffer( uint8_t offset, uint8_t *buffer, uint8_t size );
+
+    /*!
+     * \brief Read data from the buffer holding the payload in the radio
+     *
+     * \param [in]  offset        The offset to start reading the payload
+     * \param [out] buffer        A pointer to a buffer holding the data from the radio
+     * \param [in]  size          The number of byte to be read
+     */
+    virtual void ReadBuffer( uint8_t offset, uint8_t *buffer, uint8_t size );
+
+    /*!
+     * \brief Returns the status of DIOs pins
+     *
+     * \retval      dioStatus     A byte where each bit represents a DIO state:
+     *                            [ DIO3 | DIO2 | DIO1 | BUSY ]
+     */
+    virtual uint8_t GetDioStatus( void );
+
+protected:
+
+    SPI *RadioSpi;                                  //!< The SPI object used to communicate with the radio
+    Serial *RadioUart;                              //!< The UART object used to communicate with the radio
+    DigitalOut RadioNss;                            //!< The pin connected to Radio chip select (active low)
+    DigitalInOut RadioReset;                        //!< The reset pin connected to the radio
+    DigitalOut RadioCtsn;                           //!< The Clear To Send radio pin (active low)
+
+    DigitalIn    BUSY;                              //!< The pin connected to BUSY
+    InterruptIn *DIO1;                              //!< The pin connected to DIO1
+    InterruptIn *DIO2;                              //!< The pin connected to DIO2
+    InterruptIn *DIO3;                              //!< The pin connected to DIO3
+
+    /*!
+     * \brief Initializes SPI object used to communicate with the radio
+     */
+    virtual void SpiInit( void );
+
+    /*!
+     * \brief Initializes UART object used to communicate with the radio
+     */
+    virtual void UartInit( void );
+
+    /*!
+     * \brief Sets the callback functions to be run on DIO1..3 interrupt
+     *
+     * \param [in]  irqHandler    A function pointer of the function to be run on every DIO interrupt
+     */
+    virtual void IoIrqInit( DioIrqHandler irqHandler );
+};
+
+#endif // __SX1280_HAL_H__
diff -r 000000000000 -r 1036ecbe7c51 sx1280-driver/sx1280.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sx1280-driver/sx1280.cpp	Tue Aug 28 11:51:39 2018 +0000
@@ -0,0 +1,1226 @@
+/*
+  ______                              _
+ / _____)             _              | |
+( (____  _____ ____ _| |_ _____  ____| |__
+ \____ \| ___ |    (_   _) ___ |/ ___)  _ \
+ _____) ) ____| | | || |_| ____( (___| | | |
+(______/|_____)_|_|_| \__)_____)\____)_| |_|
+    (C)2016 Semtech
+
+Description: Driver for SX1280 devices
+
+License: Revised BSD License, see LICENSE.TXT file include in the project
+
+Maintainer: Miguel Luis, Gregory Cristian and Matthieu Verdy
+*/
+#include "mbed.h"
+#include "sx1280.h"
+#include "sx1280-hal.h"
+
+/*!
+ * \brief Radio registers definition
+ *
+ */
+typedef struct
+{
+    uint16_t      Addr;                             //!< The address of the register
+    uint8_t       Value;                            //!< The value of the register
+}RadioRegisters_t;
+
+/*!
+ * \brief Radio hardware registers initialization definition
+ */
+#define RADIO_INIT_REGISTERS_VALUE  { }
+
+/*!
+ * \brief Radio hardware registers initialization
+ */
+const RadioRegisters_t RadioRegsInit[] = RADIO_INIT_REGISTERS_VALUE;
+
+void SX1280::Init( void )
+{
+    Reset( );
+    IoIrqInit( dioIrq );
+    Wakeup( );
+    SetRegistersDefault( );
+}
+
+void SX1280::SetRegistersDefault( void )
+{
+    for( int16_t i = 0; i < sizeof( RadioRegsInit ) / sizeof( RadioRegisters_t ); i++ )
+    {
+        WriteRegister( RadioRegsInit[i].Addr, RadioRegsInit[i].Value );
+    }
+}
+
+uint16_t SX1280::GetFirmwareVersion( void )
+{
+    return( ( ( ReadRegister( REG_LR_FIRMWARE_VERSION_MSB ) ) << 8 ) | ( ReadRegister( REG_LR_FIRMWARE_VERSION_MSB + 1 ) ) );
+}
+
+RadioStatus_t SX1280::GetStatus( void )
+{
+    uint8_t stat = 0;
+    RadioStatus_t status;
+
+    ReadCommand( RADIO_GET_STATUS, ( uint8_t * )&stat, 1 );
+    status.Value = stat;
+    return( status );
+}
+
+RadioOperatingModes_t SX1280::GetOpMode( void )
+{
+    return( OperatingMode );
+}
+
+void SX1280::SetSleep( SleepParams_t sleepConfig )
+{
+    uint8_t sleep = ( sleepConfig.WakeUpRTC << 3 ) |
+                    ( sleepConfig.InstructionRamRetention << 2 ) |
+                    ( sleepConfig.DataBufferRetention << 1 ) |
+                    ( sleepConfig.DataRamRetention );
+
+    OperatingMode = MODE_SLEEP;
+    WriteCommand( RADIO_SET_SLEEP, &sleep, 1 );
+}
+
+void SX1280::SetStandby( RadioStandbyModes_t standbyConfig )
+{
+    WriteCommand( RADIO_SET_STANDBY, ( uint8_t* )&standbyConfig, 1 );
+    if( standbyConfig == STDBY_RC )
+    {
+        OperatingMode = MODE_STDBY_RC;
+    }
+    else
+    {
+        OperatingMode = MODE_STDBY_XOSC;
+    }
+}
+
+void SX1280::SetFs( void )
+{
+    WriteCommand( RADIO_SET_FS, 0, 0 );
+    OperatingMode = MODE_FS;
+}
+
+void SX1280::SetTx( TickTime_t timeout )
+{
+    uint8_t buf[3];
+    buf[0] = timeout.PeriodBase;
+    buf[1] = ( uint8_t )( ( timeout.PeriodBaseCount >> 8 ) & 0x00FF );
+    buf[2] = ( uint8_t )( timeout.PeriodBaseCount & 0x00FF );
+
+    ClearIrqStatus( IRQ_RADIO_ALL );
+
+    // If the radio is doing ranging operations, then apply the specific calls
+    // prior to SetTx
+    if( GetPacketType( true ) == PACKET_TYPE_RANGING )
+    {
+        SetRangingRole( RADIO_RANGING_ROLE_MASTER );
+    }
+    WriteCommand( RADIO_SET_TX, buf, 3 );
+    OperatingMode = MODE_TX;
+}
+
+void SX1280::SetRx( TickTime_t timeout )
+{
+    uint8_t buf[3];
+    buf[0] = timeout.PeriodBase;
+    buf[1] = ( uint8_t )( ( timeout.PeriodBaseCount >> 8 ) & 0x00FF );
+    buf[2] = ( uint8_t )( timeout.PeriodBaseCount & 0x00FF );
+
+    ClearIrqStatus( IRQ_RADIO_ALL );
+
+    // If the radio is doing ranging operations, then apply the specific calls
+    // prior to SetRx
+    if( GetPacketType( true ) == PACKET_TYPE_RANGING )
+    {
+        SetRangingRole( RADIO_RANGING_ROLE_SLAVE );
+    }
+    WriteCommand( RADIO_SET_RX, buf, 3 );
+    OperatingMode = MODE_RX;
+}
+
+void SX1280::SetRxDutyCycle( RadioTickSizes_t periodBase, uint16_t periodBaseCountRx, uint16_t periodBaseCountSleep )
+{
+    uint8_t buf[5];
+
+    buf[0] = periodBase;
+    buf[1] = ( uint8_t )( ( periodBaseCountRx >> 8 ) & 0x00FF );
+    buf[2] = ( uint8_t )( periodBaseCountRx & 0x00FF );
+    buf[3] = ( uint8_t )( ( periodBaseCountSleep >> 8 ) & 0x00FF );
+    buf[4] = ( uint8_t )( periodBaseCountSleep & 0x00FF );
+    WriteCommand( RADIO_SET_RXDUTYCYCLE, buf, 5 );
+    OperatingMode = MODE_RX;
+}
+
+void SX1280::SetCad( void )
+{
+    WriteCommand( RADIO_SET_CAD, 0, 0 );
+    OperatingMode = MODE_CAD;
+}
+
+void SX1280::SetTxContinuousWave( void )
+{
+    WriteCommand( RADIO_SET_TXCONTINUOUSWAVE, 0, 0 );
+}
+
+void SX1280::SetTxContinuousPreamble( void )
+{
+    WriteCommand( RADIO_SET_TXCONTINUOUSPREAMBLE, 0, 0 );
+}
+
+void SX1280::SetPacketType( RadioPacketTypes_t packetType )
+{
+    // Save packet type internally to avoid questioning the radio
+    this->PacketType = packetType;
+
+    WriteCommand( RADIO_SET_PACKETTYPE, ( uint8_t* )&packetType, 1 );
+}
+
+RadioPacketTypes_t SX1280::GetPacketType( bool returnLocalCopy )
+{
+    RadioPacketTypes_t packetType = PACKET_TYPE_NONE;
+    if( returnLocalCopy == false )
+    {
+        ReadCommand( RADIO_GET_PACKETTYPE, ( uint8_t* )&packetType, 1 );
+        if( this->PacketType != packetType )
+        {
+            this->PacketType = packetType;
+        }
+    }
+    else
+    {
+        packetType = this->PacketType;
+    }
+    return packetType;
+}
+
+void SX1280::SetRfFrequency( uint32_t rfFrequency )
+{
+    uint8_t buf[3];
+    uint32_t freq = 0;
+
+    freq = ( uint32_t )( ( double )rfFrequency / ( double )FREQ_STEP );
+    buf[0] = ( uint8_t )( ( freq >> 16 ) & 0xFF );
+    buf[1] = ( uint8_t )( ( freq >> 8 ) & 0xFF );
+    buf[2] = ( uint8_t )( freq & 0xFF );
+    WriteCommand( RADIO_SET_RFFREQUENCY, buf, 3 );
+}
+
+void SX1280::SetTxParams( int8_t power, RadioRampTimes_t rampTime )
+{
+    uint8_t buf[2];
+
+    // The power value to send on SPI/UART is in the range [0..31] and the
+    // physical output power is in the range [-18..13]dBm
+    buf[0] = power + 18;
+    buf[1] = ( uint8_t )rampTime;
+    WriteCommand( RADIO_SET_TXPARAMS, buf, 2 );
+}
+
+void SX1280::SetCadParams( RadioLoRaCadSymbols_t cadSymbolNum )
+{
+    WriteCommand( RADIO_SET_CADPARAMS, ( uint8_t* )&cadSymbolNum, 1 );
+    OperatingMode = MODE_CAD;
+}
+
+void SX1280::SetBufferBaseAddresses( uint8_t txBaseAddress, uint8_t rxBaseAddress )
+{
+    uint8_t buf[2];
+
+    buf[0] = txBaseAddress;
+    buf[1] = rxBaseAddress;
+    WriteCommand( RADIO_SET_BUFFERBASEADDRESS, buf, 2 );
+}
+
+void SX1280::SetModulationParams( ModulationParams_t *modParams )
+{
+    uint8_t buf[3];
+
+    // Check if required configuration corresponds to the stored packet type
+    // If not, silently update radio packet type
+    if( this->PacketType != modParams->PacketType )
+    {
+        this->SetPacketType( modParams->PacketType );
+    }
+
+    switch( modParams->PacketType )
+    {
+        case PACKET_TYPE_GFSK:
+            buf[0] = modParams->Params.Gfsk.BitrateBandwidth;
+            buf[1] = modParams->Params.Gfsk.ModulationIndex;
+            buf[2] = modParams->Params.Gfsk.ModulationShaping;
+            break;
+        case PACKET_TYPE_LORA:
+        case PACKET_TYPE_RANGING:
+            buf[0] = modParams->Params.LoRa.SpreadingFactor;
+            buf[1] = modParams->Params.LoRa.Bandwidth;
+            buf[2] = modParams->Params.LoRa.CodingRate;
+            this->LoRaBandwidth = modParams->Params.LoRa.Bandwidth;
+            break;
+        case PACKET_TYPE_FLRC:
+            buf[0] = modParams->Params.Flrc.BitrateBandwidth;
+            buf[1] = modParams->Params.Flrc.CodingRate;
+            buf[2] = modParams->Params.Flrc.ModulationShaping;
+            break;
+        case PACKET_TYPE_BLE:
+            buf[0] = modParams->Params.Ble.BitrateBandwidth;
+            buf[1] = modParams->Params.Ble.ModulationIndex;
+            buf[2] = modParams->Params.Ble.ModulationShaping;
+            break;
+        case PACKET_TYPE_NONE:
+            buf[0] = NULL;
+            buf[1] = NULL;
+            buf[2] = NULL;
+            break;
+    }
+    WriteCommand( RADIO_SET_MODULATIONPARAMS, buf, 3 );
+}
+
+void SX1280::SetPacketParams( PacketParams_t *packetParams )
+{
+    uint8_t buf[7];
+    // Check if required configuration corresponds to the stored packet type
+    // If not, silently update radio packet type
+    if( this->PacketType != packetParams->PacketType )
+    {
+        this->SetPacketType( packetParams->PacketType );
+    }
+
+    switch( packetParams->PacketType )
+    {
+        case PACKET_TYPE_GFSK:
+            buf[0] = packetParams->Params.Gfsk.PreambleLength;
+            buf[1] = packetParams->Params.Gfsk.SyncWordLength;
+            buf[2] = packetParams->Params.Gfsk.SyncWordMatch;
+            buf[3] = packetParams->Params.Gfsk.HeaderType;
+            buf[4] = packetParams->Params.Gfsk.PayloadLength;
+            buf[5] = packetParams->Params.Gfsk.CrcLength;
+            buf[6] = packetParams->Params.Gfsk.Whitening;
+            break;
+        case PACKET_TYPE_LORA:
+        case PACKET_TYPE_RANGING:
+            buf[0] = packetParams->Params.LoRa.PreambleLength;
+            buf[1] = packetParams->Params.LoRa.HeaderType;
+            buf[2] = packetParams->Params.LoRa.PayloadLength;
+            buf[3] = packetParams->Params.LoRa.Crc;
+            buf[4] = packetParams->Params.LoRa.InvertIQ;
+            buf[5] = NULL;
+            buf[6] = NULL;
+            break;
+        case PACKET_TYPE_FLRC:
+            buf[0] = packetParams->Params.Flrc.PreambleLength;
+            buf[1] = packetParams->Params.Flrc.SyncWordLength;
+            buf[2] = packetParams->Params.Flrc.SyncWordMatch;
+            buf[3] = packetParams->Params.Flrc.HeaderType;
+            buf[4] = packetParams->Params.Flrc.PayloadLength;
+            buf[5] = packetParams->Params.Flrc.CrcLength;
+            buf[6] = packetParams->Params.Flrc.Whitening;
+            break;
+        case PACKET_TYPE_BLE:
+            buf[0] = packetParams->Params.Ble.ConnectionState;
+            buf[1] = packetParams->Params.Ble.CrcLength;
+            buf[2] = packetParams->Params.Ble.BleTestPayload;
+            buf[3] = packetParams->Params.Ble.Whitening;
+            buf[4] = NULL;
+            buf[5] = NULL;
+            buf[6] = NULL;
+            break;
+        case PACKET_TYPE_NONE:
+            buf[0] = NULL;
+            buf[1] = NULL;
+            buf[2] = NULL;
+            buf[3] = NULL;
+            buf[4] = NULL;
+            buf[5] = NULL;
+            buf[6] = NULL;
+            break;
+    }
+    WriteCommand( RADIO_SET_PACKETPARAMS, buf, 7 );
+}
+
+void SX1280::ForcePreambleLength( RadioPreambleLengths_t preambleLength )
+{
+    this->WriteRegister( REG_LR_PREAMBLELENGTH, ( this->ReadRegister( REG_LR_PREAMBLELENGTH ) & MASK_FORCE_PREAMBLELENGTH ) | preambleLength );
+}
+
+void SX1280::GetRxBufferStatus( uint8_t *rxPayloadLength, uint8_t *rxStartBufferPointer )
+{
+    uint8_t status[2];
+
+    ReadCommand( RADIO_GET_RXBUFFERSTATUS, status, 2 );
+
+    // In case of LORA fixed header, the rxPayloadLength is obtained by reading
+    // the register REG_LR_PAYLOADLENGTH
+    if( ( this -> GetPacketType( true ) == PACKET_TYPE_LORA ) && ( ReadRegister( REG_LR_PACKETPARAMS ) >> 7 == 1 ) )
+    {
+        *rxPayloadLength = ReadRegister( REG_LR_PAYLOADLENGTH );
+    }
+    else if( this -> GetPacketType( true ) == PACKET_TYPE_BLE )
+    {
+        // In the case of BLE, the size returned in status[0] do not include the 2-byte length PDU header
+        // so it is added there
+        *rxPayloadLength = status[0] + 2;
+    }
+    else
+    {
+        *rxPayloadLength = status[0];
+    }
+
+    *rxStartBufferPointer = status[1];
+}
+
+void SX1280::GetPacketStatus( PacketStatus_t *packetStatus )
+{
+    uint8_t status[5];
+
+    ReadCommand( RADIO_GET_PACKETSTATUS, status, 5 );
+
+    packetStatus->packetType = this -> GetPacketType( true );
+    switch( packetStatus->packetType )
+    {
+        case PACKET_TYPE_GFSK:
+            packetStatus->Gfsk.RssiSync = -( status[1] / 2 );
+
+            packetStatus->Gfsk.ErrorStatus.SyncError = ( status[2] >> 6 ) & 0x01;
+            packetStatus->Gfsk.ErrorStatus.LengthError = ( status[2] >> 5 ) & 0x01;
+            packetStatus->Gfsk.ErrorStatus.CrcError = ( status[2] >> 4 ) & 0x01;
+            packetStatus->Gfsk.ErrorStatus.AbortError = ( status[2] >> 3 ) & 0x01;
+            packetStatus->Gfsk.ErrorStatus.HeaderReceived = ( status[2] >> 2 ) & 0x01;
+            packetStatus->Gfsk.ErrorStatus.PacketReceived = ( status[2] >> 1 ) & 0x01;
+            packetStatus->Gfsk.ErrorStatus.PacketControlerBusy = status[2] & 0x01;
+
+            packetStatus->Gfsk.TxRxStatus.RxNoAck = ( status[3] >> 5 ) & 0x01;
+            packetStatus->Gfsk.TxRxStatus.PacketSent = status[3] & 0x01;
+
+            packetStatus->Gfsk.SyncAddrStatus = status[4] & 0x07;
+            break;
+
+        case PACKET_TYPE_LORA:
+        case PACKET_TYPE_RANGING:
+            packetStatus->LoRa.RssiPkt = -( status[0] / 2 );
+            ( status[1] < 128 ) ? ( packetStatus->LoRa.SnrPkt = status[1] / 4 ) : ( packetStatus->LoRa.SnrPkt = ( ( status[1] - 256 ) /4 ) );
+            break;
+
+        case PACKET_TYPE_FLRC:
+            packetStatus->Flrc.RssiSync = -( status[1] / 2 );
+
+            packetStatus->Flrc.ErrorStatus.SyncError = ( status[2] >> 6 ) & 0x01;
+            packetStatus->Flrc.ErrorStatus.LengthError = ( status[2] >> 5 ) & 0x01;
+            packetStatus->Flrc.ErrorStatus.CrcError = ( status[2] >> 4 ) & 0x01;
+            packetStatus->Flrc.ErrorStatus.AbortError = ( status[2] >> 3 ) & 0x01;
+            packetStatus->Flrc.ErrorStatus.HeaderReceived = ( status[2] >> 2 ) & 0x01;
+            packetStatus->Flrc.ErrorStatus.PacketReceived = ( status[2] >> 1 ) & 0x01;
+            packetStatus->Flrc.ErrorStatus.PacketControlerBusy = status[2] & 0x01;
+
+            packetStatus->Flrc.TxRxStatus.RxPid = ( status[3] >> 6 ) & 0x03;
+            packetStatus->Flrc.TxRxStatus.RxNoAck = ( status[3] >> 5 ) & 0x01;
+            packetStatus->Flrc.TxRxStatus.RxPidErr = ( status[3] >> 4 ) & 0x01;
+            packetStatus->Flrc.TxRxStatus.PacketSent = status[3] & 0x01;
+
+            packetStatus->Flrc.SyncAddrStatus = status[4] & 0x07;
+            break;
+
+        case PACKET_TYPE_BLE:
+            packetStatus->Ble.RssiSync =  -( status[1] / 2 );
+
+            packetStatus->Ble.ErrorStatus.SyncError = ( status[2] >> 6 ) & 0x01;
+            packetStatus->Ble.ErrorStatus.LengthError = ( status[2] >> 5 ) & 0x01;
+            packetStatus->Ble.ErrorStatus.CrcError = ( status[2] >> 4 ) & 0x01;
+            packetStatus->Ble.ErrorStatus.AbortError = ( status[2] >> 3 ) & 0x01;
+            packetStatus->Ble.ErrorStatus.HeaderReceived = ( status[2] >> 2 ) & 0x01;
+            packetStatus->Ble.ErrorStatus.PacketReceived = ( status[2] >> 1 ) & 0x01;
+            packetStatus->Ble.ErrorStatus.PacketControlerBusy = status[2] & 0x01;
+
+            packetStatus->Ble.TxRxStatus.PacketSent = status[3] & 0x01;
+
+            packetStatus->Ble.SyncAddrStatus = status[4] & 0x07;
+            break;
+
+        case PACKET_TYPE_NONE:
+            // In that specific case, we set everything in the packetStatus to zeros
+            // and reset the packet type accordingly
+            memset( packetStatus, 0, sizeof( PacketStatus_t ) );
+            packetStatus->packetType = PACKET_TYPE_NONE;
+            break;
+    }
+}
+
+int8_t SX1280::GetRssiInst( void )
+{
+    uint8_t raw = 0;
+
+    ReadCommand( RADIO_GET_RSSIINST, &raw, 1 );
+
+    return ( int8_t ) ( -raw / 2 );
+}
+
+void SX1280::SetDioIrqParams( uint16_t irqMask, uint16_t dio1Mask, uint16_t dio2Mask, uint16_t dio3Mask )
+{
+    uint8_t buf[8];
+
+    buf[0] = ( uint8_t )( ( irqMask >> 8 ) & 0x00FF );
+    buf[1] = ( uint8_t )( irqMask & 0x00FF );
+    buf[2] = ( uint8_t )( ( dio1Mask >> 8 ) & 0x00FF );
+    buf[3] = ( uint8_t )( dio1Mask & 0x00FF );
+    buf[4] = ( uint8_t )( ( dio2Mask >> 8 ) & 0x00FF );
+    buf[5] = ( uint8_t )( dio2Mask & 0x00FF );
+    buf[6] = ( uint8_t )( ( dio3Mask >> 8 ) & 0x00FF );
+    buf[7] = ( uint8_t )( dio3Mask & 0x00FF );
+    WriteCommand( RADIO_SET_DIOIRQPARAMS, buf, 8 );
+}
+
+uint16_t SX1280::GetIrqStatus( void )
+{
+    uint8_t irqStatus[2];
+    ReadCommand( RADIO_GET_IRQSTATUS, irqStatus, 2 );
+    return ( irqStatus[0] << 8 ) | irqStatus[1];
+}
+
+void SX1280::ClearIrqStatus( uint16_t irqMask )
+{
+    uint8_t buf[2];
+
+    buf[0] = ( uint8_t )( ( ( uint16_t )irqMask >> 8 ) & 0x00FF );
+    buf[1] = ( uint8_t )( ( uint16_t )irqMask & 0x00FF );
+    WriteCommand( RADIO_CLR_IRQSTATUS, buf, 2 );
+}
+
+void SX1280::Calibrate( CalibrationParams_t calibParam )
+{
+    uint8_t cal = ( calibParam.ADCBulkPEnable << 5 ) |
+                  ( calibParam.ADCBulkNEnable << 4 ) |
+                  ( calibParam.ADCPulseEnable << 3 ) |
+                  ( calibParam.PLLEnable << 2 ) |
+                  ( calibParam.RC13MEnable << 1 ) |
+                  ( calibParam.RC64KEnable );
+    WriteCommand( RADIO_CALIBRATE, &cal, 1 );
+}
+
+void SX1280::SetRegulatorMode( RadioRegulatorModes_t mode )
+{
+    WriteCommand( RADIO_SET_REGULATORMODE, ( uint8_t* )&mode, 1 );
+}
+
+void SX1280::SetSaveContext( void )
+{
+    WriteCommand( RADIO_SET_SAVECONTEXT, 0, 0 );
+}
+
+void SX1280::SetAutoTx( uint16_t time )
+{
+    uint16_t compensatedTime = time - ( uint16_t )AUTO_TX_OFFSET;
+    uint8_t buf[2];
+
+    buf[0] = ( uint8_t )( ( compensatedTime >> 8 ) & 0x00FF );
+    buf[1] = ( uint8_t )( compensatedTime & 0x00FF );
+    WriteCommand( RADIO_SET_AUTOTX, buf, 2 );
+}
+
+void SX1280::StopAutoTx( void )
+{
+    uint8_t buf[2] = {0x00, 0x00};
+    WriteCommand( RADIO_SET_AUTOTX, buf, 2 );
+}
+
+void SX1280::SetAutoFs( bool enableAutoFs )
+{
+    WriteCommand( RADIO_SET_AUTOFS, ( uint8_t * )&enableAutoFs, 1 );
+}
+
+void SX1280::SetLongPreamble( bool enable )
+{
+    WriteCommand( RADIO_SET_LONGPREAMBLE, ( uint8_t * )&enable, 1 );
+}
+
+void SX1280::SetPayload( uint8_t *buffer, uint8_t size, uint8_t offset )
+{
+    WriteBuffer( offset, buffer, size );
+}
+
+uint8_t SX1280::GetPayload( uint8_t *buffer, uint8_t *size , uint8_t maxSize )
+{
+    uint8_t offset;
+
+    GetRxBufferStatus( size, &offset );
+    if( *size > maxSize )
+    {
+        return 1;
+    }
+    ReadBuffer( offset, buffer, *size );
+    return 0;
+}
+
+void SX1280::SendPayload( uint8_t *payload, uint8_t size, TickTime_t timeout, uint8_t offset )
+{
+    SetPayload( payload, size, offset );
+    SetTx( timeout );
+}
+
+uint8_t SX1280::SetSyncWord( uint8_t syncWordIdx, uint8_t *syncWord )
+{
+    uint16_t addr;
+    uint8_t syncwordSize = 0;
+
+    switch( GetPacketType( true ) )
+    {
+        case PACKET_TYPE_GFSK:
+            syncwordSize = 5;
+            switch( syncWordIdx )
+            {
+                case 1:
+                    addr = REG_LR_SYNCWORDBASEADDRESS1;
+                    break;
+                case 2:
+                    addr = REG_LR_SYNCWORDBASEADDRESS2;
+                    break;
+                case 3:
+                    addr = REG_LR_SYNCWORDBASEADDRESS3;
+                    break;
+                default:
+                    return 1;
+            }
+            break;
+        case PACKET_TYPE_FLRC:
+            // For FLRC packet type, the SyncWord is one byte shorter and
+            // the base address is shifted by one byte
+            syncwordSize = 4;
+            switch( syncWordIdx )
+            {
+                case 1:
+                    addr = REG_LR_SYNCWORDBASEADDRESS1 + 1;
+                    break;
+                case 2:
+                    addr = REG_LR_SYNCWORDBASEADDRESS2 + 1;
+                    break;
+                case 3:
+                    addr = REG_LR_SYNCWORDBASEADDRESS3 + 1;
+                    break;
+                default:
+                    return 1;
+            }
+            break;
+        case PACKET_TYPE_BLE:
+            // For Ble packet type, only the first SyncWord is used and its
+            // address is shifted by one byte
+            syncwordSize = 4;
+            switch( syncWordIdx )
+            {
+                case 1:
+                    addr = REG_LR_SYNCWORDBASEADDRESS1 + 1;
+                    break;
+                default:
+                    return 1;
+            }
+            break;
+        default:
+            return 1;
+    }
+    WriteRegister( addr, syncWord, syncwordSize );
+    return 0;
+}
+
+void SX1280::SetSyncWordErrorTolerance( uint8_t ErrorBits )
+{
+    ErrorBits = ( ReadRegister( REG_LR_SYNCWORDTOLERANCE ) & 0xF0 ) | ( ErrorBits & 0x0F );
+    WriteRegister( REG_LR_SYNCWORDTOLERANCE, ErrorBits );
+}
+
+uint8_t SX1280::SetCrcSeed( uint8_t *seed )
+{
+    uint8_t updated = 0;
+    switch( GetPacketType( true ) )
+    {
+        case PACKET_TYPE_GFSK:
+        case PACKET_TYPE_FLRC:
+            WriteRegister( REG_LR_CRCSEEDBASEADDR, seed, 2 );
+            updated = 1;
+            break;
+        case PACKET_TYPE_BLE:
+            this->WriteRegister(0x9c7, seed[2] );
+            this->WriteRegister(0x9c8, seed[1] );
+            this->WriteRegister(0x9c9, seed[0] );
+            updated = 1;
+            break;
+        default:
+            break;
+    }
+    return updated;
+}
+
+void SX1280::SetBleAccessAddress( uint32_t accessAddress )
+{
+    this->WriteRegister( REG_LR_BLE_ACCESS_ADDRESS, ( accessAddress >> 24 ) & 0x000000FF );
+    this->WriteRegister( REG_LR_BLE_ACCESS_ADDRESS + 1, ( accessAddress >> 16 ) & 0x000000FF );
+    this->WriteRegister( REG_LR_BLE_ACCESS_ADDRESS + 2, ( accessAddress >> 8 ) & 0x000000FF );
+    this->WriteRegister( REG_LR_BLE_ACCESS_ADDRESS + 3, accessAddress & 0x000000FF );
+}
+
+void SX1280::SetBleAdvertizerAccessAddress( void )
+{
+    this->SetBleAccessAddress( BLE_ADVERTIZER_ACCESS_ADDRESS );
+}
+
+void SX1280::SetCrcPolynomial( uint16_t polynomial )
+{
+    uint8_t val[2];
+
+    val[0] = ( uint8_t )( polynomial >> 8 ) & 0xFF;
+    val[1] = ( uint8_t )( polynomial  & 0xFF );
+
+    switch( GetPacketType( true ) )
+    {
+        case PACKET_TYPE_GFSK:
+        case PACKET_TYPE_FLRC:
+            WriteRegister( REG_LR_CRCPOLYBASEADDR, val, 2 );
+            break;
+        default:
+            break;
+    }
+}
+
+void SX1280::SetWhiteningSeed( uint8_t seed )
+{
+    switch( GetPacketType( true ) )
+    {
+        case PACKET_TYPE_GFSK:
+        case PACKET_TYPE_FLRC:
+        case PACKET_TYPE_BLE:
+            WriteRegister( REG_LR_WHITSEEDBASEADDR, seed );
+            break;
+        default:
+            break;
+    }
+}
+
+void SX1280::EnableManualGain( void )
+{
+    this->WriteRegister( REG_ENABLE_MANUAL_GAIN_CONTROL, this->ReadRegister( REG_ENABLE_MANUAL_GAIN_CONTROL ) | MASK_MANUAL_GAIN_CONTROL );
+    this->WriteRegister( REG_DEMOD_DETECTION, this->ReadRegister( REG_DEMOD_DETECTION ) & MASK_DEMOD_DETECTION );
+}
+
+void SX1280::DisableManualGain( void )
+{
+    this->WriteRegister( REG_ENABLE_MANUAL_GAIN_CONTROL, this->ReadRegister( REG_ENABLE_MANUAL_GAIN_CONTROL ) & (~MASK_MANUAL_GAIN_CONTROL) );
+    this->WriteRegister( REG_DEMOD_DETECTION, this->ReadRegister( REG_DEMOD_DETECTION ) | (~MASK_DEMOD_DETECTION) );
+}
+
+void SX1280::SetManualGainValue( uint8_t gain )
+{
+    this->WriteRegister( REG_MANUAL_GAIN_VALUE, ( this->ReadRegister( REG_MANUAL_GAIN_VALUE ) & MASK_MANUAL_GAIN_VALUE ) | gain );
+}
+
+void SX1280::SetLNAGainSetting( const RadioLnaSettings_t lnaSetting )
+{
+    switch(lnaSetting)
+    {
+        case LNA_HIGH_SENSITIVITY_MODE:
+        {
+            this->WriteRegister( REG_LNA_REGIME, this->ReadRegister( REG_LNA_REGIME ) | MASK_LNA_REGIME );
+            break;
+        }
+        case LNA_LOW_POWER_MODE:
+        {
+            this->WriteRegister( REG_LNA_REGIME, this->ReadRegister( REG_LNA_REGIME ) & ~MASK_LNA_REGIME );
+            break;
+        }
+    }
+}
+
+void SX1280::SetRangingIdLength( RadioRangingIdCheckLengths_t length )
+{
+    switch( GetPacketType( true ) )
+    {
+        case PACKET_TYPE_RANGING:
+            WriteRegister( REG_LR_RANGINGIDCHECKLENGTH, ( ( ( ( uint8_t )length ) & 0x03 ) << 6 ) | ( ReadRegister( REG_LR_RANGINGIDCHECKLENGTH ) & 0x3F ) );
+            break;
+        default:
+            break;
+    }
+}
+
+void SX1280::SetDeviceRangingAddress( uint32_t address )
+{
+    uint8_t addrArray[] = { address >> 24, address >> 16, address >> 8, address };
+
+    switch( GetPacketType( true ) )
+    {
+        case PACKET_TYPE_RANGING:
+            WriteRegister( REG_LR_DEVICERANGINGADDR, addrArray, 4 );
+            break;
+        default:
+            break;
+    }
+}
+
+void SX1280::SetRangingRequestAddress( uint32_t address )
+{
+    uint8_t addrArray[] = { address >> 24, address >> 16, address >> 8, address };
+
+    switch( GetPacketType( true ) )
+    {
+        case PACKET_TYPE_RANGING:
+            WriteRegister( REG_LR_REQUESTRANGINGADDR, addrArray, 4 );
+            break;
+        default:
+            break;
+    }
+}
+
+double SX1280::GetRangingResult( RadioRangingResultTypes_t resultType )
+{
+    uint32_t valLsb = 0;
+    double val = 0.0;
+
+    switch( GetPacketType( true ) )
+    {
+        case PACKET_TYPE_RANGING:
+            this->SetStandby( STDBY_XOSC );
+            this->WriteRegister( 0x97F, this->ReadRegister( 0x97F ) | ( 1 << 1 ) ); // enable LORA modem clock
+            WriteRegister( REG_LR_RANGINGRESULTCONFIG, ( ReadRegister( REG_LR_RANGINGRESULTCONFIG ) & MASK_RANGINGMUXSEL ) | ( ( ( ( uint8_t )resultType ) & 0x03 ) << 4 ) );
+            valLsb = ( ( ReadRegister( REG_LR_RANGINGRESULTBASEADDR ) << 16 ) | ( ReadRegister( REG_LR_RANGINGRESULTBASEADDR + 1 ) << 8 ) | ( ReadRegister( REG_LR_RANGINGRESULTBASEADDR + 2 ) ) );
+            this->SetStandby( STDBY_RC );
+
+            // Convertion from LSB to distance. For explanation on the formula, refer to Datasheet of SX1280
+            switch( resultType )
+            {
+                case RANGING_RESULT_RAW:
+                    // Convert the ranging LSB to distance in meter
+                    // The theoretical conversion from register value to distance [m] is given by:
+                    // distance [m] = ( complement2( register ) * 150 ) / ( 2^12 * bandwidth[MHz] ) )
+                    // The API provide BW in [Hz] so the implemented formula is complement2( register ) / bandwidth[Hz] * A,
+                    // where A = 150 / (2^12 / 1e6) = 36621.09
+                    val = ( double )complement2( valLsb, 24 ) / ( double )this->GetLoRaBandwidth( ) * 36621.09375;
+                    break;
+
+                case RANGING_RESULT_AVERAGED:
+                case RANGING_RESULT_DEBIASED:
+                case RANGING_RESULT_FILTERED:
+                    val = ( double )valLsb * 20.0 / 100.0;
+                    break;
+                default:
+                    val = 0.0;
+            }
+            break;
+        default:
+            break;
+    }
+    return val;
+}
+
+void SX1280::SetRangingCalibration( uint16_t cal )
+{
+    switch( GetPacketType( true ) )
+    {
+        case PACKET_TYPE_RANGING:
+            WriteRegister( REG_LR_RANGINGRERXTXDELAYCAL, ( uint8_t )( ( cal >> 8 ) & 0xFF ) );
+            WriteRegister( REG_LR_RANGINGRERXTXDELAYCAL + 1, ( uint8_t )( ( cal ) & 0xFF ) );
+            break;
+        default:
+            break;
+    }
+}
+
+void SX1280::RangingClearFilterResult( void )
+{
+    uint8_t regVal = ReadRegister( REG_LR_RANGINGRESULTCLEARREG );
+
+    // To clear result, set bit 5 to 1 then to 0
+    WriteRegister( REG_LR_RANGINGRESULTCLEARREG, regVal | ( 1 << 5 ) );
+    WriteRegister( REG_LR_RANGINGRESULTCLEARREG, regVal & ( ~( 1 << 5 ) ) );
+}
+
+void SX1280::RangingSetFilterNumSamples( uint8_t num )
+{
+    // Silently set 8 as minimum value
+    WriteRegister( REG_LR_RANGINGFILTERWINDOWSIZE, ( num < DEFAULT_RANGING_FILTER_SIZE ) ? DEFAULT_RANGING_FILTER_SIZE : num );
+}
+
+void SX1280::SetRangingRole( RadioRangingRoles_t role )
+{
+    uint8_t buf[1];
+
+    buf[0] = role;
+    WriteCommand( RADIO_SET_RANGING_ROLE, &buf[0], 1 );
+}
+
+double SX1280::GetFrequencyError( )
+{
+    uint8_t efeRaw[3] = {0};
+    uint32_t efe = 0;
+    double efeHz = 0.0;
+
+    switch( this->GetPacketType( true ) )
+    {
+        case PACKET_TYPE_LORA:
+        case PACKET_TYPE_RANGING:
+            efeRaw[0] = this->ReadRegister( REG_LR_ESTIMATED_FREQUENCY_ERROR_MSB );
+            efeRaw[1] = this->ReadRegister( REG_LR_ESTIMATED_FREQUENCY_ERROR_MSB + 1 );
+            efeRaw[2] = this->ReadRegister( REG_LR_ESTIMATED_FREQUENCY_ERROR_MSB + 2 );
+            efe = ( efeRaw[0]<<16 ) | ( efeRaw[1]<<8 ) | efeRaw[2];
+            efe &= REG_LR_ESTIMATED_FREQUENCY_ERROR_MASK;
+
+            efeHz = 1.55 * ( double )complement2( efe, 20 ) / ( 1600.0 / ( double )this->GetLoRaBandwidth( ) * 1000.0 );
+            break;
+
+        case PACKET_TYPE_NONE:
+        case PACKET_TYPE_BLE:
+        case PACKET_TYPE_FLRC:
+        case PACKET_TYPE_GFSK:
+            break;
+    }
+
+    return efeHz;
+}
+
+void SX1280::SetPollingMode( void )
+{
+    this->PollingMode = true;
+}
+
+int32_t SX1280::complement2( const uint32_t num, const uint8_t bitCnt )
+{
+    int32_t retVal = ( int32_t )num;
+    if( num >= 2<<( bitCnt - 2 ) )
+    {
+        retVal -= 2<<( bitCnt - 1 );
+    }
+    return retVal;
+}
+
+int32_t SX1280::GetLoRaBandwidth( )
+{
+    int32_t bwValue = 0;
+
+    switch( this->LoRaBandwidth )
+    {
+        case LORA_BW_0200:
+            bwValue = 203125;
+            break;
+        case LORA_BW_0400:
+            bwValue = 406250;
+            break;
+        case LORA_BW_0800:
+            bwValue = 812500;
+            break;
+        case LORA_BW_1600:
+            bwValue = 1625000;
+            break;
+        default:
+            bwValue = 0;
+    }
+    return bwValue;
+}
+
+void SX1280::SetInterruptMode( void )
+{
+    this->PollingMode = false;
+}
+
+void SX1280::OnDioIrq( void )
+{
+    /*
+     * When polling mode is activated, it is up to the application to call
+     * ProcessIrqs( ). Otherwise, the driver automatically calls ProcessIrqs( )
+     * on radio interrupt.
+     */
+    if( this->PollingMode == true )
+    {
+        this->IrqState = true;
+    }
+    else
+    {
+        this->ProcessIrqs( );
+    }
+}
+
+void SX1280::ProcessIrqs( void )
+{
+    RadioPacketTypes_t packetType = PACKET_TYPE_NONE;
+
+    if( this->PollingMode == true )
+    {
+        if( this->IrqState == true )
+        {
+            __disable_irq( );
+            this->IrqState = false;
+            __enable_irq( );
+        }
+        else
+        {
+            return;
+        }
+    }
+
+    packetType = GetPacketType( true );
+    uint16_t irqRegs = GetIrqStatus( );
+    ClearIrqStatus( IRQ_RADIO_ALL );
+
+#if( SX1280_DEBUG == 1 )
+    DigitalOut TEST_PIN_1( D14 );
+    DigitalOut TEST_PIN_2( D15 );
+    for( int i = 0x8000; i != 0; i >>= 1 )
+    {
+        TEST_PIN_2 = 0;
+        TEST_PIN_1 = ( ( irqRegs & i ) != 0 ) ? 1 : 0;
+        TEST_PIN_2 = 1;
+    }
+    TEST_PIN_1 = 0;
+    TEST_PIN_2 = 0;
+#endif
+
+    switch( packetType )
+    {
+        case PACKET_TYPE_GFSK:
+        case PACKET_TYPE_FLRC:
+        case PACKET_TYPE_BLE:
+            switch( OperatingMode )
+            {
+                case MODE_RX:
+                    if( ( irqRegs & IRQ_RX_DONE ) == IRQ_RX_DONE )
+                    {
+                        if( ( irqRegs & IRQ_CRC_ERROR ) == IRQ_CRC_ERROR )
+                        {
+                            if( rxError != NULL )
+                            {
+                                rxError( IRQ_CRC_ERROR_CODE );
+                            }
+                        }
+                        else if( ( irqRegs & IRQ_SYNCWORD_ERROR ) == IRQ_SYNCWORD_ERROR )
+                        {
+                            if( rxError != NULL )
+                            {
+                                rxError( IRQ_SYNCWORD_ERROR_CODE );
+                            }
+                        }
+                        else
+                        {
+                            if( rxDone != NULL )
+                            {
+                                rxDone( );
+                            }
+                        }
+                    }
+                    if( ( irqRegs & IRQ_SYNCWORD_VALID ) == IRQ_SYNCWORD_VALID )
+                    {
+                        if( rxSyncWordDone != NULL )
+                        {
+                            rxSyncWordDone( );
+                        }
+                    }
+                    if( ( irqRegs & IRQ_SYNCWORD_ERROR ) == IRQ_SYNCWORD_ERROR )
+                    {
+                        if( rxError != NULL )
+                        {
+                            rxError( IRQ_SYNCWORD_ERROR_CODE );
+                        }
+                    }
+                    if( ( irqRegs & IRQ_RX_TX_TIMEOUT ) == IRQ_RX_TX_TIMEOUT )
+                    {
+                        if( rxTimeout != NULL )
+                        {
+                            rxTimeout( );
+                        }
+                    }
+                    if( ( irqRegs & IRQ_TX_DONE ) == IRQ_TX_DONE )
+                    {
+                        if( txDone != NULL )
+                        {
+                            txDone( );
+                        }
+                    }
+                    break;
+                case MODE_TX:
+                    if( ( irqRegs & IRQ_TX_DONE ) == IRQ_TX_DONE )
+                    {
+                        if( txDone != NULL )
+                        {
+                            txDone( );
+                        }
+                    }
+                    if( ( irqRegs & IRQ_RX_TX_TIMEOUT ) == IRQ_RX_TX_TIMEOUT )
+                    {
+                        if( txTimeout != NULL )
+                        {
+                            txTimeout( );
+                        }
+                    }
+                    break;
+                default:
+                    // Unexpected IRQ: silently returns
+                    break;
+            }
+            break;
+        case PACKET_TYPE_LORA:
+            switch( OperatingMode )
+            {
+                case MODE_RX:
+                    if( ( irqRegs & IRQ_RX_DONE ) == IRQ_RX_DONE )
+                    {
+                        if( ( irqRegs & IRQ_CRC_ERROR ) == IRQ_CRC_ERROR )
+                        {
+                            if( rxError != NULL )
+                            {
+                                rxError( IRQ_CRC_ERROR_CODE );
+                            }
+                        }
+                        else
+                        {
+                            if( rxDone != NULL )
+                            {
+                                rxDone( );
+                            }
+                        }
+                    }
+                    if( ( irqRegs & IRQ_HEADER_VALID ) == IRQ_HEADER_VALID )
+                    {
+                        if( rxHeaderDone != NULL )
+                        {
+                            rxHeaderDone( );
+                        }
+                    }
+                    if( ( irqRegs & IRQ_HEADER_ERROR ) == IRQ_HEADER_ERROR )
+                    {
+                        if( rxError != NULL )
+                        {
+                            rxError( IRQ_HEADER_ERROR_CODE );
+                        }
+                    }
+                    if( ( irqRegs & IRQ_RX_TX_TIMEOUT ) == IRQ_RX_TX_TIMEOUT )
+                    {
+                        if( rxTimeout != NULL )
+                        {
+                            rxTimeout( );
+                        }
+                    }
+                    if( ( irqRegs & IRQ_RANGING_SLAVE_REQUEST_DISCARDED ) == IRQ_RANGING_SLAVE_REQUEST_DISCARDED )
+                    {
+                        if( rxError != NULL )
+                        {
+                            rxError( IRQ_RANGING_ON_LORA_ERROR_CODE );
+                        }
+                    }
+                    break;
+                case MODE_TX:
+                    if( ( irqRegs & IRQ_TX_DONE ) == IRQ_TX_DONE )
+                    {
+                        if( txDone != NULL )
+                        {
+                            txDone( );
+                        }
+                    }
+                    if( ( irqRegs & IRQ_RX_TX_TIMEOUT ) == IRQ_RX_TX_TIMEOUT )
+                    {
+                        if( txTimeout != NULL )
+                        {
+                            txTimeout( );
+                        }
+                    }
+                    break;
+                case MODE_CAD:
+                    if( ( irqRegs & IRQ_CAD_DONE ) == IRQ_CAD_DONE )
+                    {
+                        if( ( irqRegs & IRQ_CAD_DETECTED ) == IRQ_CAD_DETECTED )
+                        {
+                            if( cadDone != NULL )
+                            {
+                                cadDone( true );
+                            }
+                        }
+                        else
+                        {
+                            if( cadDone != NULL )
+                            {
+                                cadDone( false );
+                            }
+                        }
+                    }
+                    else if( ( irqRegs & IRQ_RX_TX_TIMEOUT ) == IRQ_RX_TX_TIMEOUT )
+                    {
+                        if( rxTimeout != NULL )
+                        {
+                            rxTimeout( );
+                        }
+                    }
+                    break;
+                default:
+                    // Unexpected IRQ: silently returns
+                    break;
+            }
+            break;
+        case PACKET_TYPE_RANGING:
+            switch( OperatingMode )
+            {
+                // MODE_RX indicates an IRQ on the Slave side
+                case MODE_RX:
+                    if( ( irqRegs & IRQ_RANGING_SLAVE_REQUEST_DISCARDED ) == IRQ_RANGING_SLAVE_REQUEST_DISCARDED )
+                    {
+                        if( rangingDone != NULL )
+                        {
+                            rangingDone( IRQ_RANGING_SLAVE_ERROR_CODE );
+                        }
+                    }
+                    if( ( irqRegs & IRQ_RANGING_SLAVE_REQUEST_VALID ) == IRQ_RANGING_SLAVE_REQUEST_VALID )
+                    {
+                        if( rangingDone != NULL )
+                        {
+                            rangingDone( IRQ_RANGING_SLAVE_VALID_CODE );
+                        }
+                    }
+                    if( ( irqRegs & IRQ_RANGING_SLAVE_RESPONSE_DONE ) == IRQ_RANGING_SLAVE_RESPONSE_DONE )
+                    {
+                        if( rangingDone != NULL )
+                        {
+                            rangingDone( IRQ_RANGING_SLAVE_VALID_CODE );
+                        }
+                    }
+                    if( ( irqRegs & IRQ_RX_TX_TIMEOUT ) == IRQ_RX_TX_TIMEOUT )
+                    {
+                        if( rangingDone != NULL )
+                        {
+                            rangingDone( IRQ_RANGING_SLAVE_ERROR_CODE );
+                        }
+                    }
+                    if( ( irqRegs & IRQ_HEADER_VALID ) == IRQ_HEADER_VALID )
+                    {
+                        if( rxHeaderDone != NULL )
+                        {
+                            rxHeaderDone( );
+                        }
+                    }
+                    if( ( irqRegs & IRQ_HEADER_ERROR ) == IRQ_HEADER_ERROR )
+                    {
+                        if( rxError != NULL )
+                        {
+                            rxError( IRQ_HEADER_ERROR_CODE );
+                        }
+                    }
+                    break;
+                // MODE_TX indicates an IRQ on the Master side
+                case MODE_TX:
+                    if( ( irqRegs & IRQ_RANGING_MASTER_TIMEOUT ) == IRQ_RANGING_MASTER_TIMEOUT )
+                    {
+                        if( rangingDone != NULL )
+                        {
+                            rangingDone( IRQ_RANGING_MASTER_ERROR_CODE );
+                        }
+                    }
+                    if( ( irqRegs & IRQ_RANGING_MASTER_RESULT_VALID ) == IRQ_RANGING_MASTER_RESULT_VALID )
+                    {
+                        if( rangingDone != NULL )
+                        {
+                            rangingDone( IRQ_RANGING_MASTER_VALID_CODE );
+                        }
+                    }
+                    break;
+                default:
+                    // Unexpected IRQ: silently returns
+                    break;
+            }
+            break;
+        default:
+            // Unexpected IRQ: silently returns
+            break;
+    }
+}
diff -r 000000000000 -r 1036ecbe7c51 sx1280-driver/sx1280.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sx1280-driver/sx1280.h	Tue Aug 28 11:51:39 2018 +0000
@@ -0,0 +1,1666 @@
+/*
+  ______                              _
+ / _____)             _              | |
+( (____  _____ ____ _| |_ _____  ____| |__
+ \____ \| ___ |    (_   _) ___ |/ ___)  _ \
+ _____) ) ____| | | || |_| ____( (___| | | |
+(______/|_____)_|_|_| \__)_____)\____)_| |_|
+    (C)2016 Semtech
+
+Description: Driver for SX1280 devices
+
+License: Revised BSD License, see LICENSE.TXT file include in the project
+
+Maintainer: Miguel Luis, Gregory Cristian and Matthieu Verdy
+*/
+#ifndef __SX1280_H__
+#define __SX1280_H__
+
+#include "radio.h"
+
+/*!
+ * \brief Enables/disables driver debug features
+ */
+#define SX1280_DEBUG                                0
+
+/*!
+ * \brief Hardware IO IRQ callback function definition
+ */
+class SX1280;
+typedef void ( SX1280::*DioIrqHandler )( void );
+
+/*!
+ * \brief IRQ triggers callback function definition
+ */
+class SX1280Hal;
+typedef void ( SX1280Hal::*Trigger )( void );
+
+/*!
+ * \brief Provides the frequency of the chip running on the radio and the frequency step
+ *
+ * \remark These defines are used for computing the frequency divider to set the RF frequency
+ */
+#define XTAL_FREQ                                   52000000
+#define FREQ_STEP                                   ( ( double )( XTAL_FREQ / pow( 2.0, 18.0 ) ) )
+
+/*!
+ * \brief Compensation delay for SetAutoTx method in microseconds
+ */
+#define AUTO_TX_OFFSET                              33
+
+/*!
+ * \brief The address of the register holding the firmware version MSB
+ */
+#define REG_LR_FIRMWARE_VERSION_MSB                 0x0153
+
+/*!
+ * \brief The address of the register holding the first byte defining the CRC seed
+ *
+ * \remark Only used for packet types GFSK and Flrc
+ */
+#define REG_LR_CRCSEEDBASEADDR                      0x09C8
+
+/*!
+ * \brief The address of the register holding the first byte defining the CRC polynomial
+ *
+ * \remark Only used for packet types GFSK and Flrc
+ */
+#define REG_LR_CRCPOLYBASEADDR                      0x09C6
+
+/*!
+ * \brief The address of the register holding the first byte defining the whitening seed
+ *
+ * \remark Only used for packet types GFSK, FLRC and BLE
+ */
+#define REG_LR_WHITSEEDBASEADDR                     0x09C5
+
+/*!
+ * \brief The address of the register holding the ranging id check length
+ *
+ * \remark Only used for packet type Ranging
+ */
+#define REG_LR_RANGINGIDCHECKLENGTH                 0x0931
+
+/*!
+ * \brief The address of the register holding the device ranging id
+ *
+ * \remark Only used for packet type Ranging
+ */
+#define REG_LR_DEVICERANGINGADDR                    0x0916
+
+/*!
+ * \brief The address of the register holding the device ranging id
+ *
+ * \remark Only used for packet type Ranging
+ */
+#define REG_LR_REQUESTRANGINGADDR                   0x0912
+
+/*!
+ * \brief The address of the register holding ranging results configuration
+ * and the corresponding mask
+ *
+ * \remark Only used for packet type Ranging
+ */
+#define REG_LR_RANGINGRESULTCONFIG                  0x0924
+#define MASK_RANGINGMUXSEL                          0xCF
+
+/*!
+ * \brief The address of the register holding the first byte of ranging results
+ * Only used for packet type Ranging
+ */
+#define REG_LR_RANGINGRESULTBASEADDR                0x0961
+
+/*!
+ * \brief The address of the register allowing to read ranging results
+ *
+ * \remark Only used for packet type Ranging
+ */
+#define REG_LR_RANGINGRESULTSFREEZE                 0x097F
+
+/*!
+ * \brief The address of the register holding the first byte of ranging calibration
+ *
+ * \remark Only used for packet type Ranging
+ */
+#define REG_LR_RANGINGRERXTXDELAYCAL                0x092C
+
+/*!
+ *\brief The address of the register holding the ranging filter window size
+ *
+ * \remark Only used for packet type Ranging
+ */
+#define REG_LR_RANGINGFILTERWINDOWSIZE              0x091E
+
+/*!
+ *\brief The address of the register to reset for clearing ranging filter
+ *
+ * \remark Only used for packet type Ranging
+ */
+#define REG_LR_RANGINGRESULTCLEARREG                0x0923
+
+/*!
+ * \brief The default number of samples considered in built-in ranging filter
+ */
+#define DEFAULT_RANGING_FILTER_SIZE                 127
+
+/*!
+ * \brief The address of the register holding LORA packet parameters
+ */
+#define REG_LR_PACKETPARAMS                         0x903
+
+/*!
+ * \brief The address of the register holding payload length
+ *
+ * \remark Do NOT try to read it directly. Use GetRxBuffer( ) instead.
+ */
+#define REG_LR_PAYLOADLENGTH                        0x901
+
+/*!
+ * \brief The addresses of the registers holding SyncWords values
+ *
+ * \remark The addresses depends on the Packet Type in use, and not all
+ *         SyncWords are available for every Packet Type
+ */
+#define REG_LR_SYNCWORDBASEADDRESS1                 0x09CE
+#define REG_LR_SYNCWORDBASEADDRESS2                 0x09D3
+#define REG_LR_SYNCWORDBASEADDRESS3                 0x09D8
+
+/*!
+ * \brief The MSB address and mask used to read the estimated frequency
+ * error
+ */
+#define REG_LR_ESTIMATED_FREQUENCY_ERROR_MSB        0x0954
+#define REG_LR_ESTIMATED_FREQUENCY_ERROR_MASK       0x0FFFFF
+
+/*!
+ * \brief Defines how many bit errors are tolerated in sync word detection
+ */
+#define REG_LR_SYNCWORDTOLERANCE                    0x09CD
+
+/*!
+ * \brief Register and mask for GFSK and BLE preamble length forcing
+ */
+#define REG_LR_PREAMBLELENGTH                       0x09C1
+#define MASK_FORCE_PREAMBLELENGTH                   0x8F
+
+/*!
+ * \brief Register for MSB Access Address (BLE)
+ */
+#define REG_LR_BLE_ACCESS_ADDRESS                   0x09CF
+#define BLE_ADVERTIZER_ACCESS_ADDRESS               0x8E89BED6
+
+/*!
+ * \brief Select high sensitivity versus power consumption
+ */
+#define REG_LNA_REGIME                              0x0891
+#define MASK_LNA_REGIME                             0xC0
+
+/*
+ * \brief Register and mask controling the enabling of manual gain control
+ */
+#define REG_ENABLE_MANUAL_GAIN_CONTROL     0x089F
+#define MASK_MANUAL_GAIN_CONTROL           0x80
+
+/*!
+ * \brief Register and mask controling the demodulation detection
+ */
+#define REG_DEMOD_DETECTION                0x0895
+#define MASK_DEMOD_DETECTION               0xFE
+
+/*!
+ * Register and mask to set the manual gain parameter
+ */
+#define REG_MANUAL_GAIN_VALUE              0x089E
+#define MASK_MANUAL_GAIN_VALUE             0xF0
+
+/*!
+ * \brief Represents the states of the radio
+ */
+typedef enum
+{
+    RF_IDLE                                 = 0x00,         //!< The radio is idle
+    RF_RX_RUNNING,                                          //!< The radio is in reception state
+    RF_TX_RUNNING,                                          //!< The radio is in transmission state
+    RF_CAD,                                                 //!< The radio is doing channel activity detection
+}RadioStates_t;
+
+/*!
+ * \brief Represents the operating mode the radio is actually running
+ */
+typedef enum
+{
+    MODE_SLEEP                              = 0x00,         //! The radio is in sleep mode
+    MODE_CALIBRATION,                                       //! The radio is in calibration mode
+    MODE_STDBY_RC,                                          //! The radio is in standby mode with RC oscillator
+    MODE_STDBY_XOSC,                                        //! The radio is in standby mode with XOSC oscillator
+    MODE_FS,                                                //! The radio is in frequency synthesis mode
+    MODE_RX,                                                //! The radio is in receive mode
+    MODE_TX,                                                //! The radio is in transmit mode
+    MODE_CAD                                                //! The radio is in channel activity detection mode
+}RadioOperatingModes_t;
+
+/*!
+ * \brief Declares the oscillator in use while in standby mode
+ *
+ * Using the STDBY_RC standby mode allow to reduce the energy consumption
+ * STDBY_XOSC should be used for time critical applications
+ */
+typedef enum
+{
+    STDBY_RC                                = 0x00,
+    STDBY_XOSC                              = 0x01,
+}RadioStandbyModes_t;
+
+/*!
+ * \brief Declares the power regulation used to power the device
+ *
+ * This command allows the user to specify if DC-DC or LDO is used for power regulation.
+ * Using only LDO implies that the Rx or Tx current is doubled
+ */
+typedef enum
+{
+    USE_LDO                                 = 0x00,         //! Use LDO (default value)
+    USE_DCDC                                = 0x01,         //! Use DCDC
+}RadioRegulatorModes_t;
+
+/*!
+ * \brief Represents the possible packet type (i.e. modem) used
+ */
+typedef enum
+{
+    PACKET_TYPE_GFSK                        = 0x00,
+    PACKET_TYPE_LORA,
+    PACKET_TYPE_RANGING,
+    PACKET_TYPE_FLRC,
+    PACKET_TYPE_BLE,
+    PACKET_TYPE_NONE                        = 0x0F,
+}RadioPacketTypes_t;
+
+/*!
+ * \brief Represents the ramping time for power amplifier
+ */
+typedef enum
+{
+    RADIO_RAMP_02_US                        = 0x00,
+    RADIO_RAMP_04_US                        = 0x20,
+    RADIO_RAMP_06_US                        = 0x40,
+    RADIO_RAMP_08_US                        = 0x60,
+    RADIO_RAMP_10_US                        = 0x80,
+    RADIO_RAMP_12_US                        = 0xA0,
+    RADIO_RAMP_16_US                        = 0xC0,
+    RADIO_RAMP_20_US                        = 0xE0,
+}RadioRampTimes_t;
+
+/*!
+ * \brief Represents the number of symbols to be used for channel activity detection operation
+ */
+typedef enum
+{
+    LORA_CAD_01_SYMBOL                      = 0x00,
+    LORA_CAD_02_SYMBOLS                     = 0x20,
+    LORA_CAD_04_SYMBOLS                     = 0x40,
+    LORA_CAD_08_SYMBOLS                     = 0x60,
+    LORA_CAD_16_SYMBOLS                     = 0x80,
+}RadioLoRaCadSymbols_t;
+
+/*!
+ * \brief Represents the possible combinations of bitrate and bandwidth for
+ *        GFSK and BLE packet types
+ *
+ * The bitrate is expressed in Mb/s and the bandwidth in MHz
+ */
+typedef enum
+{
+    GFSK_BLE_BR_2_000_BW_2_4                = 0x04,
+    GFSK_BLE_BR_1_600_BW_2_4                = 0x28,
+    GFSK_BLE_BR_1_000_BW_2_4                = 0x4C,
+    GFSK_BLE_BR_1_000_BW_1_2                = 0x45,
+    GFSK_BLE_BR_0_800_BW_2_4                = 0x70,
+    GFSK_BLE_BR_0_800_BW_1_2                = 0x69,
+    GFSK_BLE_BR_0_500_BW_1_2                = 0x8D,
+    GFSK_BLE_BR_0_500_BW_0_6                = 0x86,
+    GFSK_BLE_BR_0_400_BW_1_2                = 0xB1,
+    GFSK_BLE_BR_0_400_BW_0_6                = 0xAA,
+    GFSK_BLE_BR_0_250_BW_0_6                = 0xCE,
+    GFSK_BLE_BR_0_250_BW_0_3                = 0xC7,
+    GFSK_BLE_BR_0_125_BW_0_3                = 0xEF,
+}RadioGfskBleBitrates_t;
+
+/*!
+ * \brief Represents the modulation index used in GFSK and BLE packet
+ *        types
+ */
+typedef enum
+{
+    GFSK_BLE_MOD_IND_0_35                   =  0,
+    GFSK_BLE_MOD_IND_0_50                   =  1,
+    GFSK_BLE_MOD_IND_0_75                   =  2,
+    GFSK_BLE_MOD_IND_1_00                   =  3,
+    GFSK_BLE_MOD_IND_1_25                   =  4,
+    GFSK_BLE_MOD_IND_1_50                   =  5,
+    GFSK_BLE_MOD_IND_1_75                   =  6,
+    GFSK_BLE_MOD_IND_2_00                   =  7,
+    GFSK_BLE_MOD_IND_2_25                   =  8,
+    GFSK_BLE_MOD_IND_2_50                   =  9,
+    GFSK_BLE_MOD_IND_2_75                   = 10,
+    GFSK_BLE_MOD_IND_3_00                   = 11,
+    GFSK_BLE_MOD_IND_3_25                   = 12,
+    GFSK_BLE_MOD_IND_3_50                   = 13,
+    GFSK_BLE_MOD_IND_3_75                   = 14,
+    GFSK_BLE_MOD_IND_4_00                   = 15,
+}RadioGfskBleModIndexes_t;
+
+/*!
+ * \brief Represents the possible combination of bitrate and bandwidth for FLRC
+ *        packet type
+ *
+ * The bitrate is in Mb/s and the bitrate in MHz
+ */
+typedef enum
+{
+    FLRC_BR_1_300_BW_1_2                    = 0x45,
+    FLRC_BR_1_040_BW_1_2                    = 0x69,
+    FLRC_BR_0_650_BW_0_6                    = 0x86,
+    FLRC_BR_0_520_BW_0_6                    = 0xAA,
+    FLRC_BR_0_325_BW_0_3                    = 0xC7,
+    FLRC_BR_0_260_BW_0_3                    = 0xEB,
+}RadioFlrcBitrates_t;
+
+/*!
+ * \brief Represents the possible values for coding rate parameter in FLRC
+ *        packet type
+ */
+typedef enum
+{
+    FLRC_CR_1_2                             = 0x00,
+    FLRC_CR_3_4                             = 0x02,
+    FLRC_CR_1_0                             = 0x04,
+}RadioFlrcCodingRates_t;
+
+/*!
+ * \brief Represents the modulation shaping parameter for GFSK, FLRC and BLE
+ *        packet types
+ */
+typedef enum
+{
+    RADIO_MOD_SHAPING_BT_OFF                = 0x00,         //! No filtering
+    RADIO_MOD_SHAPING_BT_1_0                = 0x10,
+    RADIO_MOD_SHAPING_BT_0_5                = 0x20,
+}RadioModShapings_t;
+
+/*!
+ * \brief Represents the possible spreading factor values in LORA packet types
+ */
+typedef enum
+{
+    LORA_SF5                                = 0x50,
+    LORA_SF6                                = 0x60,
+    LORA_SF7                                = 0x70,
+    LORA_SF8                                = 0x80,
+    LORA_SF9                                = 0x90,
+    LORA_SF10                               = 0xA0,
+    LORA_SF11                               = 0xB0,
+    LORA_SF12                               = 0xC0,
+}RadioLoRaSpreadingFactors_t;
+
+/*!
+ * \brief Represents the bandwidth values for LORA packet type
+ */
+typedef enum
+{
+    LORA_BW_0200                            = 0x34,
+    LORA_BW_0400                            = 0x26,
+    LORA_BW_0800                            = 0x18,
+    LORA_BW_1600                            = 0x0A,
+}RadioLoRaBandwidths_t;
+
+/*!
+ * \brief Represents the coding rate values for LORA packet type
+ */
+typedef enum
+{
+    LORA_CR_4_5                             = 0x01,
+    LORA_CR_4_6                             = 0x02,
+    LORA_CR_4_7                             = 0x03,
+    LORA_CR_4_8                             = 0x04,
+    LORA_CR_LI_4_5                          = 0x05,
+    LORA_CR_LI_4_6                          = 0x06,
+    LORA_CR_LI_4_7                          = 0x07,
+}RadioLoRaCodingRates_t;
+
+/*!
+ * \brief Represents the preamble length values for GFSK and FLRC packet
+ *        types
+ */
+typedef enum
+{
+    PREAMBLE_LENGTH_04_BITS                 = 0x00,         //!< Preamble length: 04 bits
+    PREAMBLE_LENGTH_08_BITS                 = 0x10,         //!< Preamble length: 08 bits
+    PREAMBLE_LENGTH_12_BITS                 = 0x20,         //!< Preamble length: 12 bits
+    PREAMBLE_LENGTH_16_BITS                 = 0x30,         //!< Preamble length: 16 bits
+    PREAMBLE_LENGTH_20_BITS                 = 0x40,         //!< Preamble length: 20 bits
+    PREAMBLE_LENGTH_24_BITS                 = 0x50,         //!< Preamble length: 24 bits
+    PREAMBLE_LENGTH_28_BITS                 = 0x60,         //!< Preamble length: 28 bits
+    PREAMBLE_LENGTH_32_BITS                 = 0x70,         //!< Preamble length: 32 bits
+}RadioPreambleLengths_t;
+
+/*!
+ * \brief Represents the SyncWord length for FLRC packet type
+ */
+typedef enum
+{
+    FLRC_NO_SYNCWORD                        = 0x00,
+    FLRC_SYNCWORD_LENGTH_4_BYTE             = 0x04,
+}RadioFlrcSyncWordLengths_t;
+
+/*!
+ * \brief The length of sync words for GFSK packet type
+ */
+typedef enum
+{
+    GFSK_SYNCWORD_LENGTH_1_BYTE             = 0x00,         //!< Sync word length: 1 byte
+    GFSK_SYNCWORD_LENGTH_2_BYTE             = 0x02,         //!< Sync word length: 2 bytes
+    GFSK_SYNCWORD_LENGTH_3_BYTE             = 0x04,         //!< Sync word length: 3 bytes
+    GFSK_SYNCWORD_LENGTH_4_BYTE             = 0x06,         //!< Sync word length: 4 bytes
+    GFSK_SYNCWORD_LENGTH_5_BYTE             = 0x08,         //!< Sync word length: 5 bytes
+}RadioSyncWordLengths_t;
+
+/*!
+ * \brief Represents the possible combinations of SyncWord correlators
+ *        activated for GFSK and FLRC packet types
+ */
+typedef enum
+{
+    RADIO_RX_MATCH_SYNCWORD_OFF             = 0x00,         //!< No correlator turned on, i.e. do not search for SyncWord
+    RADIO_RX_MATCH_SYNCWORD_1               = 0x10,
+    RADIO_RX_MATCH_SYNCWORD_2               = 0x20,
+    RADIO_RX_MATCH_SYNCWORD_1_2             = 0x30,
+    RADIO_RX_MATCH_SYNCWORD_3               = 0x40,
+    RADIO_RX_MATCH_SYNCWORD_1_3             = 0x50,
+    RADIO_RX_MATCH_SYNCWORD_2_3             = 0x60,
+    RADIO_RX_MATCH_SYNCWORD_1_2_3           = 0x70,
+}RadioSyncWordRxMatchs_t;
+
+/*!
+ *  \brief Radio packet length mode for GFSK and FLRC packet types
+ */
+typedef enum
+{
+    RADIO_PACKET_FIXED_LENGTH               = 0x00,         //!< The packet is known on both sides, no header included in the packet
+    RADIO_PACKET_VARIABLE_LENGTH            = 0x20,         //!< The packet is on variable size, header included
+}RadioPacketLengthModes_t;
+
+/*!
+ * \brief Represents the CRC length for GFSK and FLRC packet types
+ *
+ * \warning Not all configurations are available for both GFSK and FLRC
+ *          packet type. Refer to the datasheet for possible configuration.
+ */
+typedef enum
+{
+    RADIO_CRC_OFF                           = 0x00,         //!< No CRC in use
+    RADIO_CRC_1_BYTES                       = 0x10,
+    RADIO_CRC_2_BYTES                       = 0x20,
+    RADIO_CRC_3_BYTES                       = 0x30,
+}RadioCrcTypes_t;
+
+/*!
+ * \brief Radio whitening mode activated or deactivated for GFSK, FLRC and
+ *        BLE packet types
+ */
+typedef enum
+{
+    RADIO_WHITENING_ON                      = 0x00,
+    RADIO_WHITENING_OFF                     = 0x08,
+}RadioWhiteningModes_t;
+
+/*!
+ * \brief Holds the packet length mode of a LORA packet type
+ */
+typedef enum
+{
+    LORA_PACKET_VARIABLE_LENGTH             = 0x00,         //!< The packet is on variable size, header included
+    LORA_PACKET_FIXED_LENGTH                = 0x80,         //!< The packet is known on both sides, no header included in the packet
+    LORA_PACKET_EXPLICIT                    = LORA_PACKET_VARIABLE_LENGTH,
+    LORA_PACKET_IMPLICIT                    = LORA_PACKET_FIXED_LENGTH,
+}RadioLoRaPacketLengthsModes_t;
+
+/*!
+ * \brief Represents the CRC mode for LORA packet type
+ */
+typedef enum
+{
+    LORA_CRC_ON                             = 0x20,         //!< CRC activated
+    LORA_CRC_OFF                            = 0x00,         //!< CRC not used
+}RadioLoRaCrcModes_t;
+
+/*!
+ * \brief Represents the IQ mode for LORA packet type
+ */
+typedef enum
+{
+    LORA_IQ_NORMAL                          = 0x40,
+    LORA_IQ_INVERTED                        = 0x00,
+}RadioLoRaIQModes_t;
+
+/*!
+ * \brief Represents the length of the ID to check in ranging operation
+ */
+typedef enum
+{
+    RANGING_IDCHECK_LENGTH_08_BITS          = 0x00,
+    RANGING_IDCHECK_LENGTH_16_BITS,
+    RANGING_IDCHECK_LENGTH_24_BITS,
+    RANGING_IDCHECK_LENGTH_32_BITS,
+}RadioRangingIdCheckLengths_t;
+
+/*!
+ * \brief Represents the result type to be used in ranging operation
+ */
+typedef enum
+{
+    RANGING_RESULT_RAW                      = 0x00,
+    RANGING_RESULT_AVERAGED                 = 0x01,
+    RANGING_RESULT_DEBIASED                 = 0x02,
+    RANGING_RESULT_FILTERED                 = 0x03,
+}RadioRangingResultTypes_t;
+
+/*!
+ * \brief Represents the connection state for BLE packet type
+ */
+typedef enum
+{
+    BLE_PAYLOAD_LENGTH_MAX_31_BYTES         = 0x00,
+    BLE_PAYLOAD_LENGTH_MAX_37_BYTES         = 0x20,
+    BLE_TX_TEST_MODE                        = 0x40,
+    BLE_PAYLOAD_LENGTH_MAX_255_BYTES        = 0x80,
+}RadioBleConnectionStates_t;
+
+/*!
+ * \brief Represents the CRC field length for BLE packet type
+ */
+typedef enum
+{
+    BLE_CRC_OFF                             = 0x00,
+    BLE_CRC_3B                              = 0x10,
+}RadioBleCrcTypes_t;
+
+/*!
+ * \brief Represents the specific packets to use in BLE packet type
+ */
+typedef enum
+{
+    BLE_PRBS_9                              = 0x00,         //!< Pseudo Random Binary Sequence based on 9th degree polynomial
+    BLE_PRBS_15                             = 0x0C,         //!< Pseudo Random Binary Sequence based on 15th degree polynomial
+    BLE_EYELONG_1_0                         = 0x04,         //!< Repeated '11110000' sequence
+    BLE_EYELONG_0_1                         = 0x18,         //!< Repeated '00001111' sequence
+    BLE_EYESHORT_1_0                        = 0x08,         //!< Repeated '10101010' sequence
+    BLE_EYESHORT_0_1                        = 0x1C,         //!< Repeated '01010101' sequence
+    BLE_ALL_1                               = 0x10,         //!< Repeated '11111111' sequence
+    BLE_ALL_0                               = 0x14,         //!< Repeated '00000000' sequence
+}RadioBleTestPayloads_t;
+
+/*!
+ * \brief Represents the interruption masks available for the radio
+ *
+ * \remark Note that not all these interruptions are available for all packet types
+ */
+typedef enum
+{
+    IRQ_RADIO_NONE                          = 0x0000,
+    IRQ_TX_DONE                             = 0x0001,
+    IRQ_RX_DONE                             = 0x0002,
+    IRQ_SYNCWORD_VALID                      = 0x0004,
+    IRQ_SYNCWORD_ERROR                      = 0x0008,
+    IRQ_HEADER_VALID                        = 0x0010,
+    IRQ_HEADER_ERROR                        = 0x0020,
+    IRQ_CRC_ERROR                           = 0x0040,
+    IRQ_RANGING_SLAVE_RESPONSE_DONE         = 0x0080,
+    IRQ_RANGING_SLAVE_REQUEST_DISCARDED     = 0x0100,
+    IRQ_RANGING_MASTER_RESULT_VALID         = 0x0200,
+    IRQ_RANGING_MASTER_TIMEOUT              = 0x0400,
+    IRQ_RANGING_SLAVE_REQUEST_VALID         = 0x0800,
+    IRQ_CAD_DONE                            = 0x1000,
+    IRQ_CAD_DETECTED                        = 0x2000,
+    IRQ_RX_TX_TIMEOUT                       = 0x4000,
+    IRQ_PREAMBLE_DETECTED                   = 0x8000,
+    IRQ_RADIO_ALL                           = 0xFFFF,
+}RadioIrqMasks_t;
+
+/*!
+ * \brief Represents the digital input/output of the radio
+ */
+typedef enum
+{
+    RADIO_DIO1                              = 0x02,
+    RADIO_DIO2                              = 0x04,
+    RADIO_DIO3                              = 0x08,
+}RadioDios_t;
+
+/*!
+ * \brief Represents the tick size available for Rx/Tx timeout operations
+ */
+typedef enum
+{
+    RADIO_TICK_SIZE_0015_US                 = 0x00,
+    RADIO_TICK_SIZE_0062_US                 = 0x01,
+    RADIO_TICK_SIZE_1000_US                 = 0x02,
+    RADIO_TICK_SIZE_4000_US                 = 0x03,
+}RadioTickSizes_t;
+
+/*!
+ * \brief Represents the role of the radio during ranging operations
+ */
+typedef enum
+{
+    RADIO_RANGING_ROLE_SLAVE                = 0x00,
+    RADIO_RANGING_ROLE_MASTER               = 0x01,
+}RadioRangingRoles_t;
+
+/*!
+ * \brief Represents the possible Mask settings for sensitivity selection
+ */
+typedef enum
+{
+    LNA_LOW_POWER_MODE,
+    LNA_HIGH_SENSITIVITY_MODE,
+}RadioLnaSettings_t;
+
+/*!
+ * \brief Represents an amount of time measurable by the radio clock
+ *
+ * @code
+ * Time = PeriodBase * PeriodBaseCount
+ * Example:
+ * PeriodBase = RADIO_TICK_SIZE_4000_US( 4 ms )
+ * PeriodBaseCount = 1000
+ * Time = 4e-3 * 1000 = 4 seconds
+ * @endcode
+ */
+typedef struct TickTime_s
+{
+    RadioTickSizes_t PeriodBase;                            //!< The base time of ticktime
+    /*!
+     * \brief The number of periodBase for ticktime
+     * Special values are:
+     *     - 0x0000 for single mode
+     *     - 0xFFFF for continuous mode
+     */
+    uint16_t PeriodBaseCount;
+}TickTime_t;
+
+/*!
+* \brief RX_TX_CONTINUOUS and RX_TX_SINGLE are two particular values for TickTime.
+* The former keep the radio in Rx or Tx mode, even after successfull reception
+* or transmission. It should never generate Timeout interrupt.
+* The later let the radio enought time to make one reception or transmission.
+* No Timeout interrupt is generated, and the radio fall in StandBy mode after
+* reception or transmission.
+*/
+#define RX_TX_CONTINUOUS ( TickTime_t ){ RADIO_TICK_SIZE_0015_US, 0xFFFF }
+#define RX_TX_SINGLE     ( TickTime_t ){ RADIO_TICK_SIZE_0015_US, 0 }
+
+/*!
+ * \brief The type describing the modulation parameters for every packet types
+ */
+typedef struct
+{
+    RadioPacketTypes_t                    PacketType;       //!< Packet to which the modulation parameters are referring to.
+    struct
+    {
+        /*!
+         * \brief Holds the GFSK modulation parameters
+         *
+         * In GFSK modulation, the bit-rate and bandwidth are linked together. In this structure, its values are set using the same token.
+         */
+        struct
+        {
+            RadioGfskBleBitrates_t    BitrateBandwidth;     //!< The bandwidth and bit-rate values for BLE and GFSK modulations
+            RadioGfskBleModIndexes_t  ModulationIndex;      //!< The coding rate for BLE and GFSK modulations
+            RadioModShapings_t        ModulationShaping;    //!< The modulation shaping for BLE and GFSK modulations
+        }Gfsk;
+        /*!
+         * \brief Holds the LORA modulation parameters
+         *
+         * LORA modulation is defined by Spreading Factor (SF), Bandwidth and Coding Rate
+         */
+        struct
+        {
+            RadioLoRaSpreadingFactors_t  SpreadingFactor;   //!< Spreading Factor for the LORA modulation
+            RadioLoRaBandwidths_t        Bandwidth;         //!< Bandwidth for the LORA modulation
+            RadioLoRaCodingRates_t       CodingRate;        //!< Coding rate for the LORA modulation
+        }LoRa;
+        /*!
+         * \brief Holds the FLRC modulation parameters
+         *
+         * In FLRC modulation, the bit-rate and bandwidth are linked together. In this structure, its values are set using the same token.
+         */
+        struct
+        {
+            RadioFlrcBitrates_t          BitrateBandwidth;  //!< The bandwidth and bit-rate values for FLRC modulation
+            RadioFlrcCodingRates_t       CodingRate;        //!< The coding rate for FLRC modulation
+            RadioModShapings_t           ModulationShaping; //!< The modulation shaping for FLRC modulation
+        }Flrc;
+        /*!
+         * \brief Holds the BLE modulation parameters
+         *
+         * In BLE modulation, the bit-rate and bandwidth are linked together. In this structure, its values are set using the same token.
+         */
+        struct
+        {
+            RadioGfskBleBitrates_t       BitrateBandwidth;  //!< The bandwidth and bit-rate values for BLE and GFSK modulations
+            RadioGfskBleModIndexes_t     ModulationIndex;   //!< The coding rate for BLE and GFSK modulations
+            RadioModShapings_t           ModulationShaping; //!< The modulation shaping for BLE and GFSK modulations
+        }Ble;
+    }Params;                                                //!< Holds the modulation parameters structure
+}ModulationParams_t;
+
+/*!
+ * \brief The type describing the packet parameters for every packet types
+ */
+typedef struct
+{
+    RadioPacketTypes_t                    PacketType;       //!< Packet to which the packet parameters are referring to.
+    struct
+    {
+        /*!
+         * \brief Holds the GFSK packet parameters
+         */
+        struct
+        {
+            RadioPreambleLengths_t       PreambleLength;    //!< The preamble length for GFSK packet type
+            RadioSyncWordLengths_t       SyncWordLength;    //!< The synchronization word length for GFSK packet type
+            RadioSyncWordRxMatchs_t      SyncWordMatch;     //!< The synchronization correlator to use to check synchronization word
+            RadioPacketLengthModes_t     HeaderType;        //!< If the header is explicit, it will be transmitted in the GFSK packet. If the header is implicit, it will not be transmitted
+            uint8_t                      PayloadLength;     //!< Size of the payload in the GFSK packet
+            RadioCrcTypes_t              CrcLength;         //!< Size of the CRC block in the GFSK packet
+            RadioWhiteningModes_t        Whitening;         //!< Usage of whitening on payload and CRC blocks plus header block if header type is variable
+        }Gfsk;
+        /*!
+         * \brief Holds the LORA packet parameters
+         */
+        struct
+        {
+            uint8_t                       PreambleLength;   //!< The preamble length is the number of LORA symbols in the preamble. To set it, use the following formula @code Number of symbols = PreambleLength[3:0] * ( 2^PreambleLength[7:4] ) @endcode
+            RadioLoRaPacketLengthsModes_t HeaderType;       //!< If the header is explicit, it will be transmitted in the LORA packet. If the header is implicit, it will not be transmitted
+            uint8_t                       PayloadLength;    //!< Size of the payload in the LORA packet
+            RadioLoRaCrcModes_t           Crc;              //!< Size of CRC block in LORA packet
+            RadioLoRaIQModes_t            InvertIQ;         //!< Allows to swap IQ for LORA packet
+        }LoRa;
+        /*!
+         * \brief Holds the FLRC packet parameters
+         */
+        struct
+        {
+            RadioPreambleLengths_t       PreambleLength;    //!< The preamble length for FLRC packet type
+            RadioFlrcSyncWordLengths_t   SyncWordLength;    //!< The synchronization word length for FLRC packet type
+            RadioSyncWordRxMatchs_t      SyncWordMatch;     //!< The synchronization correlator to use to check synchronization word
+            RadioPacketLengthModes_t     HeaderType;        //!< If the header is explicit, it will be transmitted in the FLRC packet. If the header is implicit, it will not be transmitted.
+            uint8_t                      PayloadLength;     //!< Size of the payload in the FLRC packet
+            RadioCrcTypes_t              CrcLength;         //!< Size of the CRC block in the FLRC packet
+            RadioWhiteningModes_t        Whitening;         //!< Usage of whitening on payload and CRC blocks plus header block if header type is variable
+        }Flrc;
+        /*!
+         * \brief Holds the BLE packet parameters
+         */
+        struct
+        {
+            RadioBleConnectionStates_t    ConnectionState;   //!< The BLE state
+            RadioBleCrcTypes_t            CrcLength;         //!< Size of the CRC block in the BLE packet
+            RadioBleTestPayloads_t        BleTestPayload;    //!< Special BLE payload for test purpose
+            RadioWhiteningModes_t         Whitening;         //!< Usage of whitening on PDU and CRC blocks of BLE packet
+        }Ble;
+    }Params;                                                 //!< Holds the packet parameters structure
+}PacketParams_t;
+
+/*!
+ * \brief Represents the packet status for every packet type
+ */
+typedef struct
+{
+    RadioPacketTypes_t                    packetType;        //!< Packet to which the packet status are referring to.
+    union
+    {
+        struct
+        {
+            int8_t RssiSync;                                //!< The RSSI measured on last packet
+            struct
+            {
+                bool SyncError :1;                          //!< SyncWord error on last packet
+                bool LengthError :1;                        //!< Length error on last packet
+                bool CrcError :1;                           //!< CRC error on last packet
+                bool AbortError :1;                         //!< Abort error on last packet
+                bool HeaderReceived :1;                     //!< Header received on last packet
+                bool PacketReceived :1;                     //!< Packet received
+                bool PacketControlerBusy :1;                //!< Packet controller busy
+            }ErrorStatus;                                   //!< The error status Byte
+            struct
+            {
+                bool RxNoAck :1;                            //!< No acknowledgment received for Rx with variable length packets
+                bool PacketSent :1;                         //!< Packet sent, only relevant in Tx mode
+            }TxRxStatus;                                    //!< The Tx/Rx status Byte
+            uint8_t SyncAddrStatus :3;                      //!< The id of the correlator who found the packet
+        }Gfsk;
+        struct
+        {
+            int8_t RssiPkt;                                 //!< The RSSI of the last packet
+            int8_t SnrPkt;                                  //!< The SNR of the last packet
+        }LoRa;
+        struct
+        {
+            int8_t RssiSync;                                //!< The RSSI of the last packet
+            struct
+            {
+                bool SyncError :1;                          //!< SyncWord error on last packet
+                bool LengthError :1;                        //!< Length error on last packet
+                bool CrcError :1;                           //!< CRC error on last packet
+                bool AbortError :1;                         //!< Abort error on last packet
+                bool HeaderReceived :1;                     //!< Header received on last packet
+                bool PacketReceived :1;                     //!< Packet received
+                bool PacketControlerBusy :1;                //!< Packet controller busy
+            }ErrorStatus;                                   //!< The error status Byte
+            struct
+            {
+                uint8_t RxPid :2;                           //!< PID of the Rx
+                bool RxNoAck :1;                            //!< No acknowledgment received for Rx with variable length packets
+                bool RxPidErr :1;                           //!< Received PID error
+                bool PacketSent :1;                         //!< Packet sent, only relevant in Tx mode
+            }TxRxStatus;                                    //!< The Tx/Rx status Byte
+            uint8_t SyncAddrStatus :3;                      //!< The id of the correlator who found the packet
+        }Flrc;
+        struct
+        {
+            int8_t RssiSync;                                //!< The RSSI of the last packet
+            struct
+            {
+                bool SyncError :1;                          //!< SyncWord error on last packet
+                bool LengthError :1;                        //!< Length error on last packet
+                bool CrcError :1;                           //!< CRC error on last packet
+                bool AbortError :1;                         //!< Abort error on last packet
+                bool HeaderReceived :1;                     //!< Header received on last packet
+                bool PacketReceived :1;                     //!< Packet received
+                bool PacketControlerBusy :1;                //!< Packet controller busy
+            }ErrorStatus;                                   //!< The error status Byte
+            struct
+            {
+                bool PacketSent :1;                         //!< Packet sent, only relevant in Tx mode
+            }TxRxStatus;                                    //!< The Tx/Rx status Byte
+            uint8_t SyncAddrStatus :3;                      //!< The id of the correlator who found the packet
+        }Ble;
+    };
+}PacketStatus_t;
+
+/*!
+ * \brief Represents the Rx internal counters values when GFSK or LORA packet type is used
+ */
+typedef struct
+{
+    RadioPacketTypes_t                    packetType;       //!< Packet to which the packet status are referring to.
+    union
+    {
+        struct
+        {
+            uint16_t PacketReceived;                        //!< Number of received packets
+            uint16_t CrcError;                              //!< Number of CRC errors
+            uint16_t LengthError;                           //!< Number of length errors
+            uint16_t SyncwordError;                         //!< Number of sync-word errors
+        }Gfsk;
+        struct
+        {
+            uint16_t PacketReceived;                        //!< Number of received packets
+            uint16_t CrcError;                              //!< Number of CRC errors
+            uint16_t HeaderValid;                           //!< Number of valid headers
+        }LoRa;
+    };
+}RxCounter_t;
+
+/*!
+ * \brief Represents a calibration configuration
+ */
+typedef struct
+{
+    uint8_t RC64KEnable    : 1;                             //!< Calibrate RC64K clock
+    uint8_t RC13MEnable    : 1;                             //!< Calibrate RC13M clock
+    uint8_t PLLEnable      : 1;                             //!< Calibrate PLL
+    uint8_t ADCPulseEnable : 1;                             //!< Calibrate ADC Pulse
+    uint8_t ADCBulkNEnable : 1;                             //!< Calibrate ADC bulkN
+    uint8_t ADCBulkPEnable : 1;                             //!< Calibrate ADC bulkP
+}CalibrationParams_t;
+
+/*!
+ * \brief Represents a sleep mode configuration
+ */
+typedef struct
+{
+    uint8_t WakeUpRTC               : 1;                    //!< Get out of sleep mode if wakeup signal received from RTC
+    uint8_t InstructionRamRetention : 1;                    //!< InstructionRam is conserved during sleep
+    uint8_t DataBufferRetention     : 1;                    //!< Data buffer is conserved during sleep
+    uint8_t DataRamRetention        : 1;                    //!< Data ram is conserved during sleep
+}SleepParams_t;
+
+/*!
+ * \brief Represents the SX1280 and its features
+ *
+ * It implements the commands the SX1280 can understands
+ */
+class SX1280 : public Radio
+{
+public:
+    /*!
+     * \brief Instantiates a SX1280 object and provides API functions to communicates with the radio
+     *
+     * \param [in]  callbacks      Pointer to the callbacks structure defining
+     *                             all callbacks function pointers
+     */
+    SX1280( RadioCallbacks_t *callbacks ):
+        // The class members are value-initialiazed in member-initilaizer list
+        Radio( callbacks ), OperatingMode( MODE_STDBY_RC ), PacketType( PACKET_TYPE_NONE ),
+        LoRaBandwidth( LORA_BW_1600 ), IrqState( false ), PollingMode( false )
+    {
+        this->dioIrq        = &SX1280::OnDioIrq;
+
+        // Warning: this constructor set the LoRaBandwidth member to a valid
+        // value, but it is not related to the actual radio configuration!
+    }
+
+    virtual ~SX1280( )
+    {
+    }
+
+private:
+    /*!
+     * \brief Holds the internal operating mode of the radio
+     */
+    RadioOperatingModes_t OperatingMode;
+
+    /*!
+     * \brief Stores the current packet type set in the radio
+     */
+    RadioPacketTypes_t PacketType;
+
+    /*!
+     * \brief Stores the current LORA bandwidth set in the radio
+     */
+    RadioLoRaBandwidths_t LoRaBandwidth;
+
+    /*!
+     * \brief Holds a flag raised on radio interrupt
+     */
+    bool IrqState;
+
+    /*!
+     * \brief Hardware DIO IRQ functions
+     */
+    DioIrqHandler dioIrq;
+
+    /*!
+     * \brief Holds the polling state of the driver
+     */
+    bool PollingMode;
+
+    /*! 
+     * \brief Compute the two's complement for a register of size lower than
+     *        32bits
+     *
+     * \param [in]  num           The register to be two's complemented
+     * \param [in]  bitCnt        The position of the sign bit
+     */
+    static int32_t complement2( const uint32_t num, const uint8_t bitCnt );
+
+    /*!
+     * \brief Returns the value of LoRa bandwidth from driver's value
+     *
+     * The value is returned in Hz so that it can be represented as an integer
+     * type. Most computation should be done as integer to reduce floating
+     * point related errors.
+     *
+     * \retval loRaBw             The value of the current bandwidth in Hz
+     */
+    int32_t GetLoRaBandwidth( void );
+
+protected:
+    /*!
+     * \brief Sets a function to be triggered on radio interrupt
+     *
+     * \param [in]  irqHandler    A pointer to a function to be run on interrupt
+     *                            from the radio
+     */
+    virtual void IoIrqInit( DioIrqHandler irqHandler ) = 0;
+
+    /*!
+     * \brief DIOs interrupt callback
+     *
+     * \remark Called to handle all 3 DIOs pins
+     */
+    void OnDioIrq( void );
+
+    /*!
+     * \brief Set the role of the radio during ranging operations
+     *
+     * \param [in]  role          Role of the radio
+     */
+    void SetRangingRole( RadioRangingRoles_t role );
+
+public:
+    /*!
+     * \brief Initializes the radio driver
+     */
+    void Init( void );
+
+    /*!
+     * \brief Set the driver in polling mode.
+     *
+     * In polling mode the application is responsible to call ProcessIrqs( ) to
+     * execute callbacks functions.
+     * The default mode is Interrupt Mode.
+     * @code
+     * // Initializations and callbacks declaration/definition
+     * radio = SX1280( mosi, miso, sclk, nss, busy, int1, int2, int3, rst, &callbacks );
+     * radio.Init( );
+     * radio.SetPollingMode( );
+     *
+     * while( true )
+     * {
+     *                            //     IRQ processing is automatically done
+     *     radio.ProcessIrqs( );  // <-- here, as well as callback functions
+     *                            //     calls
+     *     // Do some applicative work
+     * }
+     * @endcode
+     *
+     * \see SX1280::SetInterruptMode
+     */
+    void SetPollingMode( void );
+
+    /*!
+     * \brief Set the driver in interrupt mode.
+     *
+     * In interrupt mode, the driver communicate with the radio during the
+     * interruption by direct calls to ProcessIrqs( ). The main advantage is
+     * the possibility to have low power application architecture.
+     * This is the default mode.
+     * @code
+     * // Initializations and callbacks declaration/definition
+     * radio = SX1280( mosi, miso, sclk, nss, busy, int1, int2, int3, rst, &callbacks );
+     * radio.Init( );
+     * radio.SetInterruptMode( );   // Optionnal. Driver default behavior
+     *
+     * while( true )
+     * {
+     *     // Do some applicative work
+     * }
+     * @endcode
+     *
+     * \see SX1280::SetPollingMode
+     */
+    void SetInterruptMode( void );
+
+    /*!
+     * \brief Initializes the radio registers to the recommended default values
+     */
+    void SetRegistersDefault( void );
+
+    /*!
+     * \brief Returns the current device firmware version
+     *
+     * \retval      version       Firmware version
+     */
+    virtual uint16_t GetFirmwareVersion( void );
+
+    /*!
+     * \brief Resets the radio
+     */
+    virtual void Reset( void ) = 0;
+
+    /*!
+     * \brief Wake-ups the radio from Sleep mode
+     */
+    virtual void Wakeup( void ) = 0;
+
+    /*!
+     * \brief Writes the given command to the radio
+     *
+     * \param [in]  opcode        Command opcode
+     * \param [in]  buffer        Command parameters byte array
+     * \param [in]  size          Command parameters byte array size
+     */
+    virtual void WriteCommand( RadioCommands_t opcode, uint8_t *buffer, uint16_t size ) = 0;
+
+    /*!
+     * \brief Reads the given command from the radio
+     *
+     * \param [in]  opcode        Command opcode
+     * \param [in]  buffer        Command parameters byte array
+     * \param [in]  size          Command parameters byte array size
+     */
+    virtual void ReadCommand( RadioCommands_t opcode, uint8_t *buffer, uint16_t size ) = 0;
+
+    /*!
+     * \brief Writes multiple radio registers starting at address
+     *
+     * \param [in]  address       First Radio register address
+     * \param [in]  buffer        Buffer containing the new register's values
+     * \param [in]  size          Number of registers to be written
+     */
+    virtual void WriteRegister( uint16_t address, uint8_t *buffer, uint16_t size ) = 0;
+
+    /*!
+     * \brief Writes the radio register at the specified address
+     *
+     * \param [in]  address       Register address
+     * \param [in]  value         New register value
+     */
+    virtual void WriteRegister( uint16_t address, uint8_t value ) = 0;
+
+    /*!
+     * \brief Reads multiple radio registers starting at address
+     *
+     * \param [in]  address       First Radio register address
+     * \param [out] buffer        Buffer where to copy the registers data
+     * \param [in]  size          Number of registers to be read
+     */
+    virtual void ReadRegister( uint16_t address, uint8_t *buffer, uint16_t size ) = 0;
+
+    /*!
+     * \brief Reads the radio register at the specified address
+     *
+     * \param [in]  address       Register address
+     *
+     * \retval      data          Register value
+     */
+    virtual uint8_t ReadRegister( uint16_t address ) = 0;
+
+    /*!
+     * \brief Writes Radio Data Buffer with buffer of size starting at offset.
+     *
+     * \param [in]  offset        Offset where to start writing
+     * \param [in]  buffer        Buffer pointer
+     * \param [in]  size          Buffer size
+     */
+    virtual void WriteBuffer( uint8_t offset, uint8_t *buffer, uint8_t size ) = 0;
+
+    /*!
+     * \brief Reads Radio Data Buffer at offset to buffer of size
+     *
+     * \param [in]  offset        Offset where to start reading
+     * \param [out] buffer        Buffer pointer
+     * \param [in]  size          Buffer size
+     */
+    virtual void ReadBuffer( uint8_t offset, uint8_t *buffer, uint8_t size ) = 0;
+
+    /*!
+     * \brief Gets the current status of the radio DIOs
+     *
+     * \retval      status        [Bit #3: DIO3, Bit #2: DIO2,
+     *                             Bit #1: DIO1, Bit #0: BUSY]
+     */
+    virtual uint8_t GetDioStatus( void ) = 0;
+
+    /*!
+     * \brief Gets the current Operation Mode of the Radio
+     *
+     * \retval      opMode        Last operating mode
+     */
+    virtual RadioOperatingModes_t GetOpMode( void );
+
+    /*!
+     * \brief Gets the current radio status
+     *
+     * \retval      status        Radio status
+     */
+    virtual RadioStatus_t GetStatus( void );
+
+    /*!
+     * \brief Sets the radio in sleep mode
+     *
+     * \param [in]  sleepConfig   The sleep configuration describing data
+     *                            retention and RTC wake-up
+     */
+    void SetSleep( SleepParams_t sleepConfig );
+
+    /*!
+     * \brief Sets the radio in configuration mode
+     *
+     * \param [in]  mode          The standby mode to put the radio into
+     */
+    void SetStandby( RadioStandbyModes_t mode );
+
+    /*!
+     * \brief Sets the radio in FS mode
+     */
+    void SetFs( void );
+
+    /*!
+     * \brief Sets the radio in transmission mode
+     *
+     * \param [in]  timeout       Structure describing the transmission timeout value
+     */
+    void SetTx( TickTime_t timeout );
+
+    /*!
+     * \brief Sets the radio in reception mode
+     *
+     * \param [in]  timeout       Structure describing the reception timeout value
+     */
+    void SetRx( TickTime_t timeout );
+
+    /*!
+     * \brief Sets the Rx duty cycle management parameters
+     *
+     * \param [in]  periodBase             Base time for Rx and Sleep TickTime sequences
+     * \param [in]  periodBaseCountRx      Number of base time for Rx TickTime sequence
+     * \param [in]  periodBaseCountSleep   Number of base time for Sleep TickTime sequence
+     */
+    void SetRxDutyCycle( RadioTickSizes_t periodBase, uint16_t periodBaseCountRx, uint16_t periodBaseCountSleep );
+
+    /*!
+     * \brief Sets the radio in CAD mode
+     *
+     * \see SX1280::SetCadParams
+     */
+    void SetCad( void );
+
+    /*!
+     * \brief Sets the radio in continuous wave transmission mode
+     */
+    void SetTxContinuousWave( void );
+
+    /*!
+     * \brief Sets the radio in continuous preamble transmission mode
+     */
+    void SetTxContinuousPreamble( void );
+
+    /*!
+     * \brief Sets the radio for the given protocol
+     *
+     * \param [in]  packetType    [PACKET_TYPE_GFSK, PACKET_TYPE_LORA,
+     *                             PACKET_TYPE_RANGING, PACKET_TYPE_FLRC,
+     *                             PACKET_TYPE_BLE]
+     *
+     * \remark This method has to be called before SetRfFrequency,
+     *         SetModulationParams and SetPacketParams
+     */
+    void SetPacketType( RadioPacketTypes_t packetType );
+
+    /*!
+     * \brief Gets the current radio protocol
+     *
+     * Default behavior return the packet type returned by the radio. To
+     * reduce the SPI activity and return the packet type stored by the
+     * driver, a second optional argument must be provided evaluating as true
+     * boolean
+     *
+     * \param [in]  returnLocalCopy If true, the packet type returned is the last
+     *                              saved in the driver
+     *                              If false, the packet type is obtained from
+     *                              the chip
+     *                              Default: false
+     *
+     * \retval      packetType    [PACKET_TYPE_GENERIC, PACKET_TYPE_LORA,
+     *                             PACKET_TYPE_RANGING, PACKET_TYPE_FLRC,
+     *                             PACKET_TYPE_BLE, PACKET_TYPE_NONE]
+     */
+    RadioPacketTypes_t GetPacketType( bool returnLocalCopy = false );
+
+    /*!
+     * \brief Sets the RF frequency
+     *
+     * \param [in]  rfFrequency   RF frequency [Hz]
+     */
+    void SetRfFrequency( uint32_t rfFrequency );
+
+    /*!
+     * \brief Sets the transmission parameters
+     *
+     * \param [in]  power         RF output power [-18..13] dBm
+     * \param [in]  rampTime      Transmission ramp up time
+     */
+    void SetTxParams( int8_t power, RadioRampTimes_t rampTime );
+
+    /*!
+     * \brief Sets the number of symbols to be used for Channel Activity
+     *        Detection operation
+     *
+     * \param [in]  cadSymbolNum  The number of symbol to use for Channel Activity
+     *                            Detection operations [LORA_CAD_01_SYMBOL, LORA_CAD_02_SYMBOLS,
+     *                            LORA_CAD_04_SYMBOLS, LORA_CAD_08_SYMBOLS, LORA_CAD_16_SYMBOLS]
+     */
+    void SetCadParams( RadioLoRaCadSymbols_t cadSymbolNum );
+
+    /*!
+     * \brief Sets the data buffer base address for transmission and reception
+     *
+     * \param [in]  txBaseAddress Transmission base address
+     * \param [in]  rxBaseAddress Reception base address
+     */
+    void SetBufferBaseAddresses( uint8_t txBaseAddress, uint8_t rxBaseAddress );
+
+    /*!
+     * \brief Set the modulation parameters
+     *
+     * \param [in]  modParams     A structure describing the modulation parameters
+     */
+    void SetModulationParams( ModulationParams_t *modParams );
+
+    /*!
+     * \brief Sets the packet parameters
+     *
+     * \param [in]  packetParams  A structure describing the packet parameters
+     */
+    void SetPacketParams( PacketParams_t *packetParams );
+
+    /*!
+     * \brief Gets the last received packet buffer status
+     *
+     * \param [out] rxPayloadLength       Last received packet payload length
+     * \param [out] rxStartBufferPointer  Last received packet buffer address pointer
+     */
+    void GetRxBufferStatus( uint8_t *rxPayloadLength, uint8_t *rxStartBufferPointer );
+
+    /*!
+     * \brief Gets the last received packet status
+     *
+     * The packet status structure returned depends on the modem type selected
+     *
+     * \see PacketStatus_t for the description of availabled informations
+     *
+     * \param [out] packetStatus  A structure of packet status
+     */
+    void GetPacketStatus( PacketStatus_t *packetStatus );
+
+    /*!
+     * \brief Returns the instantaneous RSSI value for the last packet received
+     *
+     * \retval      rssiInst      Instantaneous RSSI
+     */
+    int8_t GetRssiInst( void );
+
+    /*!
+     * \brief   Sets the IRQ mask and DIO masks
+     *
+     * \param [in]  irqMask       General IRQ mask
+     * \param [in]  dio1Mask      DIO1 mask
+     * \param [in]  dio2Mask      DIO2 mask
+     * \param [in]  dio3Mask      DIO3 mask
+     */
+    void SetDioIrqParams( uint16_t irqMask, uint16_t dio1Mask, uint16_t dio2Mask, uint16_t dio3Mask );
+
+    /*!
+     * \brief Returns the current IRQ status
+     *
+     * \retval      irqStatus     IRQ status
+     */
+    uint16_t GetIrqStatus( void );
+
+    /*!
+     * \brief Clears the IRQs
+     *
+     * \param [in]  irqMask       IRQ(s) to be cleared
+     */
+    void ClearIrqStatus( uint16_t irqMask );
+
+    /*!
+     * \brief Calibrates the given radio block
+     *
+     * \param [in]  calibParam    The description of blocks to be calibrated
+     */
+    void Calibrate( CalibrationParams_t calibParam );
+
+    /*!
+     * \brief Sets the power regulators operating mode
+     *
+     * \param [in]  mode          [0: LDO, 1:DC_DC]
+     */
+    void SetRegulatorMode( RadioRegulatorModes_t mode );
+
+    /*!
+     * \brief Saves the current selected modem configuration into data RAM
+     */
+    void SetSaveContext( void );
+
+    /*!
+     * \brief Sets the chip to automatically send a packet after the end of a packet reception
+     *
+     * \remark The offset is automatically compensated inside the function
+     *
+     * \param [in]  time          The delay in us after which a Tx is done
+     */
+    void SetAutoTx( uint16_t time );
+
+    /*!
+     * \brief Stop the chip to automatically send a packet after the end of a packet reception
+     *        if previously activated with SX1280::SetAutoTx command
+     */
+    void StopAutoTx( void );
+
+    /*!
+     * \brief Sets the chip to stay in FS mode after sending a packet
+     *
+     * \param [in]  enableAutoFs  Turn on auto FS
+     */
+    void SetAutoFs( bool enableAutoFs );
+
+    /*!
+     * \brief Enables or disables long preamble detection mode
+     *
+     * \param [in]  enable        Turn on long preamble mode
+     */
+    void SetLongPreamble( bool enable );
+
+    /*!
+     * \brief Saves the payload to be send in the radio buffer
+     *
+     * \param [in]  payload       A pointer to the payload
+     * \param [in]  size          The size of the payload
+     * \param [in]  offset        The address in FIFO where writting first byte (default = 0x00)
+     */
+    void SetPayload( uint8_t *payload, uint8_t size, uint8_t offset = 0x00 );
+
+    /*!
+     * \brief Reads the payload received. If the received payload is longer
+     * than maxSize, then the method returns 1 and do not set size and payload.
+     *
+     * \param [out] payload       A pointer to a buffer into which the payload will be copied
+     * \param [out] size          A pointer to the size of the payload received
+     * \param [in]  maxSize       The maximal size allowed to copy into the buffer
+     */
+    uint8_t GetPayload( uint8_t *payload, uint8_t *size, uint8_t maxSize );
+
+    /*!
+     * \brief Sends a payload
+     *
+     * \param [in]  payload       A pointer to the payload to send
+     * \param [in]  size          The size of the payload to send
+     * \param [in]  timeout       The timeout for Tx operation
+     * \param [in]  offset        The address in FIFO where writting first byte (default = 0x00)
+     */
+    void SendPayload( uint8_t *payload, uint8_t size, TickTime_t timeout, uint8_t offset = 0x00 );
+
+    /*!
+     * \brief Sets the Sync Word given by index used in GFSK, FLRC and BLE protocols
+     *
+     * \remark 5th byte isn't used in FLRC and BLE protocols
+     *
+     * \param [in]  syncWordIdx   Index of SyncWord to be set [1..3]
+     * \param [in]  syncWord      SyncWord bytes ( 5 bytes )
+     *
+     * \retval      status        [0: OK, 1: NOK]
+     */
+    uint8_t SetSyncWord( uint8_t syncWordIdx, uint8_t *syncWord );
+
+    /*!
+     * \brief Defines how many error bits are tolerated in sync word detection
+     *
+     * \param [in]  errorBits     Number of error bits supported to validate the Sync word detection
+     *                            ( default is 4 bit, minimum is 1 bit )
+     */
+    void SetSyncWordErrorTolerance( uint8_t errorBits );
+
+    /*!
+     * \brief Sets the Initial value for the LFSR used for the CRC calculation
+     *
+     * \param [in]  seed          Initial LFSR value ( 4 bytes )
+     *
+     * \retval      updated       [0: failure, 1: success]
+     *
+     */
+    uint8_t SetCrcSeed( uint8_t *seed );
+
+    /*!
+     * \brief Set the Access Address field of BLE packet
+     *
+     * \param [in]  accessAddress The access address to be used for next BLE packet sent
+     *
+     * \see SX1280::SetBleAdvertizerAccessAddress
+     */
+    void SetBleAccessAddress( uint32_t accessAddress );
+
+    /*!
+     * \brief Set the Access Address for Advertizer BLE packets
+     *
+     * All advertizer BLE packets must use a particular value for Access
+     * Address field. This method sets it.
+     *
+     * \see SX1280::SetBleAccessAddress
+     */
+    void SetBleAdvertizerAccessAddress( void );
+
+    /*!
+     * \brief Sets the seed used for the CRC calculation
+     *
+     * \param [in]  polynomial    The seed value
+     *
+     */
+    void SetCrcPolynomial( uint16_t polynomial );
+
+    /*!
+     * \brief Sets the Initial value of the LFSR used for the whitening in GFSK, FLRC and BLE protocols
+     *
+     * \param [in]  seed          Initial LFSR value
+     */
+    void SetWhiteningSeed( uint8_t seed );
+    
+    /*!
+     * \brief Enable manual gain control and disable AGC
+     *
+     * \see SX1280::SetManualGainValue, SX1280::DisableManualGain
+     */
+    void EnableManualGain( void );
+    
+    /*!
+     * \brief Disable the manual gain control and enable AGC
+     *
+     * \see SX1280::EnableManualGain
+     */
+    void DisableManualGain( void );
+
+    /*!
+     * \brief Set the gain for the AGC
+     *
+     * SX1280::EnableManualGain must be called before using this method
+     *
+     * \param [in]  gain          The value of gain to set, refer to datasheet for value meaning
+     *
+     * \see SX1280::EnableManualGain, SX1280::DisableManualGain
+     */
+    void SetManualGainValue( uint8_t gain );
+
+    /*!
+     * \brief Configure the LNA regime of operation
+     *
+     * \param [in]  lnaSetting    The LNA setting. Possible values are
+     *                            LNA_LOW_POWER_MODE and
+     *                            LNA_HIGH_SENSITIVITY_MODE
+     */
+    void SetLNAGainSetting( const RadioLnaSettings_t lnaSetting );
+
+    /*!
+     * \brief Sets the number of bits used to check that ranging request match ranging ID
+     *
+     * \param [in]  length        [0: 8 bits, 1: 16 bits,
+     *                             2: 24 bits, 3: 32 bits]
+     */
+    void SetRangingIdLength( RadioRangingIdCheckLengths_t length );
+
+    /*!
+     * \brief Sets ranging device id
+     *
+     * \param [in]  address       Device address
+     */
+    void SetDeviceRangingAddress( uint32_t address );
+
+    /*!
+     * \brief Sets the device id to ping in a ranging request
+     *
+     * \param [in]  address       Address of the device to ping
+     */
+    void SetRangingRequestAddress( uint32_t address );
+
+    /*!
+     * \brief Return the ranging result value
+     *
+     * \param [in]  resultType    Specifies the type of result.
+     *                            [0: RAW, 1: Averaged,
+     *                             2: De-biased, 3:Filtered]
+     *
+     * \retval      ranging       The ranging measure filtered according to resultType [m]
+     */
+    double GetRangingResult( RadioRangingResultTypes_t resultType );
+
+    /*!
+     * \brief Sets the standard processing delay between Master and Slave
+     *
+     * \param [in]  cal           RxTx delay offset for correcting ranging bias.
+     *
+     * The calibration value reflects the group delay of the radio front end and
+     * must be re-performed for each new SX1280 PCB design. The value is obtained
+     * empirically by either conducted measurement in a known electrical length
+     * coaxial RF cable (where the design is connectorised) or by radiated
+     * measurement, at a known distance, where an antenna is present.
+     * The result of the calibration process is that the SX1280 ranging result
+     * accurately reflects the physical range, the calibration procedure therefore
+     * removes the average timing error from the time-of-flight measurement for a
+     * given design.
+     *
+     * The values are Spreading Factor dependents, and depend also of the board
+     * design.
+     */
+    void SetRangingCalibration( uint16_t cal );
+
+    /*!
+     * \brief Clears the ranging filter
+     */
+    void RangingClearFilterResult( void );
+
+    /*!
+     * \brief Set the number of samples considered in the built-in filter
+     *
+     * \param [in]  numSample     The number of samples to use built-in filter
+     *                            [8..255]
+     *
+     * \remark Value inferior to 8 will be silently set to 8
+     */
+    void RangingSetFilterNumSamples( uint8_t numSample );
+
+    /*!
+     * \brief Return the Estimated Frequency Error in LORA and RANGING operations
+     *
+     * \retval efe                The estimated frequency error [Hz]
+     */
+    double GetFrequencyError( );
+
+    /*!
+     * \brief Process the analysis of radio IRQs and calls callback functions
+     *        depending on radio state
+     */
+    void ProcessIrqs( void );
+
+    /*!
+     * \brief Force the preamble length in GFSK and BLE mode
+     *
+     * \param [in]  preambleLength  The desired preamble length
+     */
+    void ForcePreambleLength( RadioPreambleLengths_t preambleLength );
+};
+
+#endif // __SX1280_H__