r g / SX1276GenericLib-us915

Dependents:   DISCO-L072CZ-LRWAN1_LoRa_PingPong

Fork of SX1276GenericLib by Helmut Tschemernjak

Files at this revision

API Documentation at this revision

Comitter:
Helmut Tschemernjak
Date:
Thu May 11 10:11:13 2017 +0200
Parent:
45:9788b98821a5
Child:
47:ec1183094b71
Commit message:
Updated LoRa_TODO.txt
Added template code to the Arduino HAL files
Change DigitalInOut to DigitalOut for the antenna switch
Added README.md file

Changed in this revision

LoRa_TODO.txt Show annotated file Show diff for this revision Revisions of this file
README.md Show annotated file Show diff for this revision Revisions of this file
sx1276/sx1276-arduino-hal.cpp Show annotated file Show diff for this revision Revisions of this file
sx1276/sx1276-arduino-hal.h Show annotated file Show diff for this revision Revisions of this file
sx1276/sx1276-mbed-hal.cpp Show annotated file Show diff for this revision Revisions of this file
sx1276/sx1276-mbed-hal.h Show annotated file Show diff for this revision Revisions of this file
--- a/LoRa_TODO.txt	Tue May 09 14:46:15 2017 +0000
+++ b/LoRa_TODO.txt	Thu May 11 10:11:13 2017 +0200
@@ -1,22 +1,22 @@
 
-Tasks we needs to be done.
 Move finished tasks to Done section:
-
-- Make the timers more generic and move the OS code into the HAL layer.
+
+TODOs:
 - add support for Arduino - add sx1276-Arduino-hal.h/cpp
 - add support for Linux - add sx1276-Linux-hal.h/cpp
 - Add support for Cad detection before sending a packet
 - Add support to provide the send/receive packet buffer,
   no need to allocate packet data in the sx1276 driver. Can be provided
-  Rx/Tx parameters.
+  Rx/Tx parameters, this avoids double memory usage
 - Add support for larger Lora packets (can be up to 2048 bytes)
   this feature is not so important, however the current implementation
   is very basic.
 - It is a little bit strange that RX/TX/Cad Timeout Timer calling the
   some handler OnTimeoutIrq. Maybe we just need a single timer, or 
-  it is a good idea to split the OnTimeoutIrq function
-- Test if the SX1276 timeouts (rx(tx/sync really uses three timers or
-  just one at a time.
+  it is a good idea to split the OnTimeoutIrq function into separate
+  callbacks for RX/TX/Cad timeouts
+- Test if the SX1276 timeouts. Does rx/tx/sync really uses three different
+  timers or just one at a time.
 
 
 Done:
@@ -25,4 +25,6 @@
 - Migrated enum code into sx1276.h/radio.h (7-May-2017 Helmut)
 - Verify the Murata ANT Switch code
 - MURATA PA_BOOST case,is _antSwitchTXBoost right? (Same as STM sample code)
-- Check of the MURATA TCXO config is correct (implemented, check JP9 on STM L0 board)
+- Check of the MURATA TCXO config is correct (implemented, check JP9 on STM L0 board)
+- Make the timers more generic and move the OS code into the HAL layer. (May Helmut)
+- Removed pull down on dio=-dio5 for L151 &LPC11U6X which make no sense to me. May 2017 Helmut
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/README.md	Thu May 11 10:11:13 2017 +0200
@@ -0,0 +1,32 @@
+# SX1276Generic Driver
+/*
+ * (c) 2017 Helmut Tschemernjak (Helmut64 on mbed).
+ * 30826 Garbsen (Hannover) Germany
+ */
+
+This library represents a common SX1276 module driver supporting SX1276 based modules. The approach is to support multiple OS versions including mbed, Arduino and Linux using the same driver code and little adjustments for the different OS version. The SX1276 driver is based on the Semtech 1276 code which can be seen in the revisions of this library repository.
+
+## Supported LoRa Modules
+
+The following Lora modules are supported:
+- HopeRF RFM95
+- Murata MURATA_SX1276 (CMWX1ZZABZ-078, used the STM B_L072Z_LRWAN1 board)
+- SX1276MB1MAS (433, 868 MHz version)
+- SX1276MB1LAS (433, 915 MHz version)
+
+## Getting Started for Developers
+Import the mbed sample project:
+http://developer.mbed.org/users/Helmut64/code/STM32L0_LoRa
+- It includes a PingPong sample code
+- It includes a PinMap.h which allows to define the LoRa SPI,
+  DIO interrupt, reset and antenna pins.
+The STM32L0_LoRa is a turnkey sample application for the STM B_L072Z_LRWAN1, however it will work with all other mbed based boards by adjusting the PinMap.h
+
+## Developers help needed
+A list of tasks is documented in the file: LoRa_TODO.txt
+I (Helmut Tschemernjak) spend a very significant time to complete the initial version of the SX1276Generic packet driver. Enhancements, further module support and tuning is more than welcome. Please send me your patches via mbed. Also questions can be submitted in the mbed “Questions” area or a personal message via mbed.
+
+## Future developments
+I work in a advanced private protocol using basic LoRa modules to communicate between simple nodes (battery powered) and stations (permanent power). The station should support thousands of nodes running on an Linux based OS using this 1276Generic driver or the LoRa concentrator module. The station should also work on mbed or Arduino assuming sufficient memory is provided. I believe there is an opportunity to do a better protocol compared to the official LoRa protocol which requires an Concentrator, a LoRa server and an application server. The idea is to over only efficient, reliable and secure communication between the nodes and the stations. Further forwarding to MQTT and other network services can be handled separately on the station.
+
+
--- a/sx1276/sx1276-arduino-hal.cpp	Tue May 09 14:46:15 2017 +0000
+++ b/sx1276/sx1276-arduino-hal.cpp	Thu May 11 10:11:13 2017 +0200
@@ -0,0 +1,431 @@
+
+/*
+ * This file contains a copy of the master content sx1276-mbed-hal.h
+ * with adaption for the Arduino environment
+ * (c) 2017 Helmut Tschemernjak
+ * 30826 Garbsen (Hannover) Germany
+ */
+#ifdef ARDUINO
+
+/*
+ (C) 2014 Semtech
+ Description: -
+ License: Revised BSD License, see LICENSE.TXT file include in the project
+ Maintainers: Miguel Luis, Gregory Cristian and Nicolas Huguenin
+ */
+
+/*
+ * additional development to make it more generic across multiple OS versions
+ * (c) 2017 Helmut Tschemernjak
+ * 30826 Garbsen (Hannover) Germany
+ */
+
+#include "sx1276-arduino-hal.h"
+
+
+
+SX1276Generic::SX1276Generic( RadioEvents_t *events, BoardType_t board,
+                             PinName mosi, PinName miso, PinName sclk, PinName nss, PinName reset,
+                             PinName dio0, PinName dio1, PinName dio2, PinName dio3, PinName dio4, PinName dio5,
+                             PinName antSwitch, PinName antSwitchTX, PinName antSwitchTXBoost, PinName tcxo)
+: SX1276( events)
+{
+    this->RadioEvents = events;
+    boardConnected = board;
+    
+    _antSwitch = NULL;
+    _antSwitchTX = NULL;
+    _antSwitchTXBoost = NULL;
+    
+    _tcxo = NULL;
+    if (tcxo != NC)
+        _tcxo = new DigitalOut(tcxo);
+    
+    switch(boardConnected) {
+        case SX1276MB1MAS:
+        case SX1276MB1LAS:
+            _antSwitch = new DigitalOut(antSwitch);
+            break;
+        case RFM95_SX1276:
+            break;
+        case MURATA_SX1276:
+            _antSwitch = new DigitalOut(antSwitch);
+            _antSwitchTX = new DigitalOut(antSwitchTX);
+            _antSwitchTXBoost = new DigitalOut(antSwitchTXBoost);
+            break;
+        default:
+            break;
+    }
+    _spi = new SPI(mosi, miso, sclk );
+    _nss = new DigitalOut(nss);
+    
+    _reset = new DigitalInOut(reset);
+    
+    _dio0 = NULL;
+    _dio1 = NULL;
+    _dio2 = NULL;
+    _dio3 = NULL;
+    _dio4 = NULL;
+    _dio5 = NULL;
+    if (dio0 != NC)
+        _dio0 = new InterruptIn(dio0);
+    if (dio1 != NC)
+        _dio1 = new InterruptIn(dio1);
+    if (dio2 != NC)
+        _dio2 = new InterruptIn(dio2);
+    if (dio3 != NC)
+        _dio3 = new InterruptIn(dio3);
+    if (dio4 != NC)
+        _dio4 = new InterruptIn(dio4);
+    if (dio5 != NC)
+        _dio5 = new DigitalIn(dio5);
+    
+    Reset( );
+    
+    IoInit( );
+    
+    RxChainCalibration( );
+    
+    SetOpMode( RF_OPMODE_SLEEP );
+    
+    IoIrqInit( dioIrq );
+    
+    RadioRegistersInit( );
+    
+    SetModem( MODEM_FSK );
+    
+    this->settings.State = RF_IDLE ;
+}
+
+SX1276Generic::~SX1276Generic()
+{
+    if (_antSwitch)
+        delete _antSwitch;
+    if (_antSwitchTX)
+        delete _antSwitchTX;
+    if (_antSwitchTXBoost)
+        delete _antSwitchTXBoost;
+    
+    if (_tcxo) {
+        *_tcxo = 0;
+        delete (_tcxo);
+    }
+    delete _reset;
+    delete _spi;
+    delete _nss;
+    
+    if (_dio0)
+        delete _dio0;
+    if (_dio1)
+        delete _dio1;
+    if (_dio2)
+        delete _dio2;
+    if (_dio3)
+        delete _dio3;
+    if (_dio4)
+        delete _dio4;
+    if (_dio5)
+        delete _dio5;
+}
+
+
+//-------------------------------------------------------------------------
+//                      Board relative functions
+//-------------------------------------------------------------------------
+uint8_t SX1276Generic::DetectBoardType( void )
+{
+    return boardConnected;
+}
+
+void SX1276Generic::IoInit( void )
+{
+    if (_tcxo)
+        *_tcxo = 1;
+    AntSwInit( );
+    SpiInit( );
+}
+
+
+void SX1276Generic::SpiInit( void )
+{
+    *_nss = 1;
+    _spi->format( 8,0 );
+    uint32_t frequencyToSet = 8000000;
+    _spi->frequency( frequencyToSet );
+    wait_ms(100);
+}
+
+void SX1276Generic::IoIrqInit( DioIrqHandler *irqHandlers )
+{
+    if (_dio0)
+        _dio0->rise(callback(this, static_cast< Trigger > ( irqHandlers[0] )));
+    if (_dio1)
+        _dio1->rise(callback(this, static_cast< Trigger > ( irqHandlers[1] )));
+    if (_dio2)
+        _dio2->rise(callback(this, static_cast< Trigger > ( irqHandlers[2] )));
+    if (_dio3)
+        _dio3->rise(callback(this, static_cast< Trigger > ( irqHandlers[3] )));
+    if (_dio4)
+        _dio4->rise(callback(this, static_cast< Trigger > ( irqHandlers[4] )));
+}
+
+void SX1276Generic::IoDeInit( void )
+{
+    //nothing
+}
+
+void SX1276Generic::SetRfTxPower( int8_t power )
+{
+    uint8_t paConfig = 0;
+    uint8_t paDac = 0;
+    
+    paConfig = Read( REG_PACONFIG );
+    paDac = Read( REG_PADAC );
+    
+    paConfig = ( paConfig & RF_PACONFIG_PASELECT_MASK ) | GetPaSelect( this->settings.Channel );
+    paConfig = ( paConfig & RF_PACONFIG_MAX_POWER_MASK ) | 0x70;
+    
+    if( ( paConfig & RF_PACONFIG_PASELECT_PABOOST ) == RF_PACONFIG_PASELECT_PABOOST )
+    {
+        if( power > 17 )
+        {
+            paDac = ( paDac & RF_PADAC_20DBM_MASK ) | RF_PADAC_20DBM_ON;
+        }
+        else
+        {
+            paDac = ( paDac & RF_PADAC_20DBM_MASK ) | RF_PADAC_20DBM_OFF;
+        }
+        if( ( paDac & RF_PADAC_20DBM_ON ) == RF_PADAC_20DBM_ON )
+        {
+            if( power < 5 )
+            {
+                power = 5;
+            }
+            if( power > 20 )
+            {
+                power = 20;
+            }
+            paConfig = ( paConfig & RF_PACONFIG_OUTPUTPOWER_MASK ) | ( uint8_t )( ( uint16_t )( power - 5 ) & 0x0F );
+        }
+        else
+        {
+            if( power < 2 )
+            {
+                power = 2;
+            }
+            if( power > 17 )
+            {
+                power = 17;
+            }
+            paConfig = ( paConfig & RF_PACONFIG_OUTPUTPOWER_MASK ) | ( uint8_t )( ( uint16_t )( power - 2 ) & 0x0F );
+        }
+    }
+    else
+    {
+        if( power < -1 )
+        {
+            power = -1;
+        }
+        if( power > 14 )
+        {
+            power = 14;
+        }
+        paConfig = ( paConfig & RF_PACONFIG_OUTPUTPOWER_MASK ) | ( uint8_t )( ( uint16_t )( power + 1 ) & 0x0F );
+    }
+    Write( REG_PACONFIG, paConfig );
+    Write( REG_PADAC, paDac );
+}
+
+
+uint8_t SX1276Generic::GetPaSelect( uint32_t channel )
+{
+    if( channel > RF_MID_BAND_THRESH )
+    {
+        if( boardConnected == SX1276MB1LAS || boardConnected == RFM95_SX1276)
+        {
+            return RF_PACONFIG_PASELECT_PABOOST;
+        }
+        else
+        {
+            return RF_PACONFIG_PASELECT_RFO;
+        }
+    }
+    else
+    {
+        return RF_PACONFIG_PASELECT_RFO;
+    }
+}
+
+void SX1276Generic::SetAntSwLowPower( bool status )
+{
+    if( isRadioActive != status )
+    {
+        isRadioActive = status;
+        
+        if( status == false )
+        {
+            AntSwInit( );
+        }
+        else
+        {
+            AntSwDeInit( );
+        }
+    }
+}
+
+void SX1276Generic::AntSwInit( void )
+{
+    if (_antSwitch)
+        *_antSwitch = 0;
+    if (boardConnected == MURATA_SX1276) {
+        *_antSwitchTX = 0;
+        *_antSwitchTXBoost = 0;
+    }
+}
+
+void SX1276Generic::AntSwDeInit( void )
+{
+    if (_antSwitch)
+        *_antSwitch = 0;
+    if (boardConnected == MURATA_SX1276) {
+        *_antSwitchTX = 0;
+        *_antSwitchTXBoost = 0;
+    }
+}
+
+
+void SX1276Generic::SetAntSw( uint8_t opMode )
+{
+    switch( opMode )
+    {
+        case RFLR_OPMODE_TRANSMITTER:
+            if (boardConnected == MURATA_SX1276) {
+                *_antSwitch = 0;// Murata-RX
+                if (Read( REG_PACONFIG) & RF_PACONFIG_PASELECT_PABOOST)
+                    *_antSwitchTXBoost = 1;
+                else
+                    *_antSwitchTX = 1; 	// alternate: antSwitchTXBoost = 1
+            } else {
+                if (_antSwitch)
+                    *_antSwitch = 1;
+            }
+            break;
+        case RFLR_OPMODE_RECEIVER:
+        case RFLR_OPMODE_RECEIVER_SINGLE:
+        case RFLR_OPMODE_CAD:
+            if (boardConnected == MURATA_SX1276) {
+                *_antSwitch = 1;  // Murata-RX
+                *_antSwitchTX = 0;
+                *_antSwitchTXBoost = 0;
+            } else {
+                if (_antSwitch)
+                    _antSwitch = 0;
+            }
+            break;
+        case RFLR_OPMODE_SLEEP:
+        case RFLR_OPMODE_STANDBY:
+        default:
+            if (boardConnected == MURATA_SX1276) {
+                *_antSwitch = 0;  //Murata-RX
+                *_antSwitchTX = 0;
+                *_antSwitchTXBoost = 0;
+            } else {
+                if (_antSwitch)
+                    *_antSwitch = 0;
+            }
+            break;
+    }
+}
+
+void SX1276Generic::SetTimeout(TimeoutTimer_t timer, timeoutFuncPtr func, int timeout_ms)
+{
+    switch(timer) {
+        case RXTimeoutTimer:
+            if (func)
+                rxTimeoutTimer.attach_us(callback(this, func), timeout_ms);
+            else
+                rxTimeoutTimer.detach();
+            break;
+        case TXTimeoutTimer:
+            if (func)
+                txTimeoutTimer.attach_us(callback(this, func), timeout_ms);
+            else
+                txTimeoutTimer.detach();
+            break;
+        case RXTimeoutSyncWorldTimer:
+            if (func)
+                rxTimeoutSyncWord.attach_us(callback(this, func), timeout_ms);
+            else
+                rxTimeoutSyncWord.detach();
+            break;
+    }
+}
+
+bool SX1276Generic::CheckRfFrequency( uint32_t frequency )
+{
+    // Implement check. Currently all frequencies are supported
+    return true;
+}
+
+void SX1276Generic::Reset( void )
+{
+    _reset->output();
+    *_reset = 0;
+    wait_ms( 1 );
+    *_reset = 1;
+    _reset->input();	// I don't know my input again, maybe to save power (Helmut T)
+    wait_ms( 6 );
+}
+
+void SX1276Generic::Write( uint8_t addr, uint8_t data )
+{
+    Write( addr, &data, 1 );
+}
+
+uint8_t SX1276Generic::Read( uint8_t addr )
+{
+    uint8_t data;
+    Read( addr, &data, 1 );
+    return data;
+}
+
+void SX1276Generic::Write( uint8_t addr, uint8_t *buffer, uint8_t size )
+{
+    uint8_t i;
+    
+    *_nss = 0; // what about SPI hold/release timing on fast MCUs? Helmut
+    _spi->write( addr | 0x80 );
+    for( i = 0; i < size; i++ )
+    {
+        _spi->write( buffer[i] );
+    }
+    *_nss = 1;
+}
+
+void SX1276Generic::Read( uint8_t addr, uint8_t *buffer, uint8_t size )
+{
+    uint8_t i;
+    
+    *_nss = 0; // what about SPI hold/release timing on fast MCUs? Helmut
+    _spi->write( addr & 0x7F );
+    for( i = 0; i < size; i++ )
+    {
+        buffer[i] = _spi->write( 0 );
+    }
+    *_nss = 1;
+}
+
+void SX1276Generic::WriteFifo( uint8_t *buffer, uint8_t size )
+{
+    Write( 0, buffer, size );
+}
+
+void SX1276Generic::ReadFifo( uint8_t *buffer, uint8_t size )
+{
+    Read( 0, buffer, size );
+}
+
+
+
+
+#endif // ARDUINO
--- a/sx1276/sx1276-arduino-hal.h	Tue May 09 14:46:15 2017 +0000
+++ b/sx1276/sx1276-arduino-hal.h	Thu May 11 10:11:13 2017 +0200
@@ -7,12 +7,233 @@
  */
 #ifdef ARDUINO
 
+/*
+ (C) 2014 Semtech
+ Description: -
+ License: Revised BSD License, see LICENSE.TXT file include in the project
+ Maintainers: Miguel Luis, Gregory Cristian and Nicolas Huguenin
+ */
 
+/*
+ * additional development to make it more generic across multiple OS versions
+ * (c) 2017 Helmut Tschemernjak
+ * 30826 Garbsen (Hannover) Germany
+ */
 
+#ifndef __SX1276_ARDUINO_HAL_H__
+#define __SX1276_ARDUINO_HAL_H__
+#include "sx1276.h"
 
 
 
-
+/*!
+ * Actual implementation of a SX1276 radio, includes some modifications to make it compatible with the MB1 LAS board
+ */
+class SX1276Generic : public SX1276
+{
+protected:
+    /*!
+     * Antenna switch GPIO pins objects
+     */
+    DigitalOut *_antSwitch;
+    DigitalOut *_antSwitchTX;
+    DigitalOut *_antSwitchTXBoost;
+    
+    /*!
+     * SX1276 Reset pin
+     */
+    DigitalInOut *_reset;
+    
+    /*!
+     * TCXO being used with the Murata Module
+     */
+    DigitalOut *_tcxo;
+    
+    /*!
+     * SPI Interface
+     */
+    SPI *_spi; // mosi, miso, sclk
+    DigitalOut *_nss;
+    
+    /*!
+     * SX1276 DIO pins
+     */
+    InterruptIn *_dio0;
+    InterruptIn *_dio1;
+    InterruptIn *_dio2;
+    InterruptIn *_dio3;
+    InterruptIn *_dio4;
+    DigitalIn *_dio5;
+    
+    /*!
+     * Tx and Rx timers
+     */
+    Timeout txTimeoutTimer;
+    Timeout rxTimeoutTimer;
+    Timeout rxTimeoutSyncWord;
+    
+    
+private:
+    /*!
+     * triggers definition
+     */
+    typedef void (SX1276Generic::*Trigger)(void);
+    
+    
+public:
+    SX1276Generic( RadioEvents_t *events, BoardType_t board,
+                  PinName mosi, PinName miso, PinName sclk, PinName nss, PinName reset,
+                  PinName dio0, PinName dio1, PinName dio2, PinName dio3, PinName dio4, PinName dio5,
+                  PinName antSwitch = NC, PinName antSwitchTX= NC, PinName antSwitchTXBoost = NC, PinName tcxo = NC);
+    
+    
+    SX1276Generic( RadioEvents_t *events );
+    
+    virtual ~SX1276Generic();
+    
+protected:
+    /*!
+     * @brief Initializes the radio I/Os pins interface
+     */
+    virtual void IoInit( void );
+    
+    /*!
+     * @brief Initializes the radio SPI
+     */
+    virtual void SpiInit( void );
+    
+    /*!
+     * @brief Initializes DIO IRQ handlers
+     *
+     * @param [IN] irqHandlers Array containing the IRQ callback functions
+     */
+    virtual void IoIrqInit( DioIrqHandler *irqHandlers );
+    
+    /*!
+     * @brief De-initializes the radio I/Os pins interface.
+     *
+     * \remark Useful when going in MCU lowpower modes
+     */
+    virtual void IoDeInit( void );
+    
+    /*!
+     * \brief Sets the radio output power.
+     *
+     * @param [IN] power Sets the RF output power
+     */
+    virtual void SetRfTxPower( int8_t power );
+    
+    /*!
+     * @brief Gets the board PA selection configuration
+     *
+     * @param [IN] channel Channel frequency in Hz
+     * @retval PaSelect RegPaConfig PaSelect value
+     */
+    virtual uint8_t GetPaSelect( uint32_t channel );
+    
+    /*!
+     * @brief Set the RF Switch I/Os pins in Low Power mode
+     *
+     * @param [IN] status enable or disable
+     */
+    virtual void SetAntSwLowPower( bool status );
+    
+    /*!
+     * @brief Initializes the RF Switch I/Os pins interface
+     */
+    virtual void AntSwInit( void );
+    
+    /*!
+     * @brief De-initializes the RF Switch I/Os pins interface
+     *
+     * @remark Needed to decrease the power consumption in MCU lowpower modes
+     */
+    virtual void AntSwDeInit( void );
+    
+    /*!
+     * @brief Controls the antena switch if necessary.
+     *
+     * @remark see errata note
+     *
+     * @param [IN] opMode Current radio operating mode
+     */
+    virtual void SetAntSw( uint8_t opMode );
+    
+    /*
+     * The the Timeout for a given Timer.
+     */
+    virtual void SetTimeout(TimeoutTimer_t timer, timeoutFuncPtr, int timeout_ms = 0);
+    
+public:
+    
+    /*!
+     * @brief Detect the board connected by reading the value of the antenna switch pin
+     */
+    virtual uint8_t DetectBoardType( void );
+    
+    /*!
+     * @brief Checks if the given RF frequency is supported by the hardware
+     *
+     * @param [IN] frequency RF frequency to be checked
+     * @retval isSupported [true: supported, false: unsupported]
+     */
+    virtual bool CheckRfFrequency( uint32_t frequency );
+    
+    /*!
+     * @brief Writes the radio register at the specified address
+     *
+     * @param [IN]: addr Register address
+     * @param [IN]: data New register value
+     */
+    virtual void Write ( uint8_t addr, uint8_t data ) ;
+    
+    /*!
+     * @brief Reads the radio register at the specified address
+     *
+     * @param [IN]: addr Register address
+     * @retval data Register value
+     */
+    virtual uint8_t Read ( uint8_t addr ) ;
+    
+    /*!
+     * @brief Writes multiple radio registers starting at address
+     *
+     * @param [IN] addr   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 Write( uint8_t addr, uint8_t *buffer, uint8_t size ) ;
+    
+    /*!
+     * @brief Reads multiple radio registers starting at address
+     *
+     * @param [IN] addr 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 Read ( uint8_t addr, uint8_t *buffer, uint8_t size ) ;
+    
+    /*!
+     * @brief Writes the buffer contents to the SX1276 FIFO
+     *
+     * @param [IN] buffer Buffer containing data to be put on the FIFO.
+     * @param [IN] size Number of bytes to be written to the FIFO
+     */
+    virtual void WriteFifo( uint8_t *buffer, uint8_t size ) ;
+    
+    /*!
+     * @brief Reads the contents of the SX1276 FIFO
+     *
+     * @param [OUT] buffer Buffer where to copy the FIFO read data.
+     * @param [IN] size Number of bytes to be read from the FIFO
+     */
+    virtual void ReadFifo( uint8_t *buffer, uint8_t size ) ;
+    
+    /*!
+     * @brief Reset the SX1276
+     */
+    virtual void Reset( void );
+};
 
-
+#endif // __SX1276_ARDUINO_HAL_H__
 #endif // ARDUINO
--- a/sx1276/sx1276-mbed-hal.cpp	Tue May 09 14:46:15 2017 +0000
+++ b/sx1276/sx1276-mbed-hal.cpp	Thu May 11 10:11:13 2017 +0200
@@ -43,14 +43,14 @@
     switch(boardConnected) {
         case SX1276MB1MAS:
         case SX1276MB1LAS:
-            _antSwitch = new DigitalInOut(antSwitch);
+            _antSwitch = new DigitalOut(antSwitch);
             break;
         case RFM95_SX1276:
             break;
         case MURATA_SX1276:
-            _antSwitch = new DigitalInOut(antSwitch);
-            _antSwitchTX = new DigitalInOut(antSwitchTX);
-            _antSwitchTXBoost = new DigitalInOut(antSwitchTXBoost);
+            _antSwitch = new DigitalOut(antSwitch);
+            _antSwitchTX = new DigitalOut(antSwitchTX);
+            _antSwitchTXBoost = new DigitalOut(antSwitchTXBoost);
             break;
         default:
             break;
@@ -160,13 +160,6 @@
 
 void SX1276Generic::IoIrqInit( DioIrqHandler *irqHandlers )
 {
-#if( defined ( TARGET_NUCLEO_L152RE ) || defined ( TARGET_LPC11U6X ) )
-    dio0.mode( PullDown );
-    dio1.mode( PullDown );
-    dio2.mode( PullDown );
-    dio3.mode( PullDown );
-    dio4.mode( PullDown );
-#endif
     if (_dio0)
     	_dio0->rise(callback(this, static_cast< Trigger > ( irqHandlers[0] )));
     if (_dio1)
--- a/sx1276/sx1276-mbed-hal.h	Tue May 09 14:46:15 2017 +0000
+++ b/sx1276/sx1276-mbed-hal.h	Thu May 11 10:11:13 2017 +0200
@@ -34,9 +34,9 @@
     /*!
      * Antenna switch GPIO pins objects
      */
-    DigitalInOut *_antSwitch;
-    DigitalInOut *_antSwitchTX;
-    DigitalInOut *_antSwitchTXBoost;
+    DigitalOut *_antSwitch;
+    DigitalOut *_antSwitchTX;
+    DigitalOut *_antSwitchTXBoost;
 
     /*!
      * SX1276 Reset pin