SX1261 and sx1262 common library

Dependents:   SX126xDevKit SX1262PingPong SX126X_TXonly SX126X_PingPong_Demo ... more

Fork of SX126xLib by Gregory Cristian

Revision:
4:c6ef863d0b07
Parent:
3:7e3595a9ebe0
Child:
5:e488e6f185f3
--- a/sx126x-hal.cpp	Wed Oct 12 08:49:58 2016 +0000
+++ b/sx126x-hal.cpp	Mon Sep 04 15:16:44 2017 +0000
@@ -14,63 +14,85 @@
 */
 #include "sx126x-hal.h"
 
-#define V1A_WORKAROUNDS
+/*!
+ * \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
+ */
+#define DioAssignCallback( dio, pinMode, callback )                    \
+            if( dio != NULL )                                          \
+            {                                                          \
+                dio->mode( pinMode );                                  \
+                dio->rise( this, static_cast <Trigger>( callback ) );  \
+            }
 
 /*!
  * \brief Used to block execution waiting for low state on radio busy pin.
- *        Essentially used in SPI communications
  */
-#define WaitBusy( )          while( BUSY == 1 ){ }
-
-
+#define WaitOnBusy( )             while( BUSY == 1 ){ }
 
 /*!
- * \brief Blocking routine for waiting the UART to be writeable
- *
+ * \brief Used to block execution to give enough time to Busy to go up
  */
-#define WaitUartWritable( )  while( RadioUart->writeable( ) == false ){ }
+#define WaitOnCounter( )          for( uint8_t counter = 0; counter < 15; counter++ ) \
+                                  {  __nop( ); }
 
-/*!
- * \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
 
-SX126xHal::SX126xHal( PinName mosi, PinName miso, PinName sclk, PinName nss, PinName busy, PinName dio1, PinName dio2, PinName dio3, PinName rst,
-                            void ( *txDone )( ), void ( *rxDone )( ), void ( *rxPblSyncWordHeader )( IrqPblSyncHeaderCode_t val ),
-                            void ( *rxTxTimeout )( IrqTimeoutCode_t timeoutCode ), void ( *rxError )( IrqErrorCode_t errorCode ), void ( *cadDone )( bool channelActivityDetected ),
-                            void ( *onDioIrq )( ) )
-        :   SX126x( txDone, rxDone, rxPblSyncWordHeader, rxTxTimeout,  rxError, cadDone, onDioIrq ),
+SX126xHal::SX126xHal( PinName mosi, PinName miso, PinName sclk, PinName nss,
+                      PinName busy, PinName dio1, PinName dio2, PinName dio3, PinName rst,
+                      PinName deviceSelect, PinName antSwPower, RadioCallbacks_t *callbacks )
+        :   SX126x( callbacks ),
             RadioNss( nss ),
             RadioReset( rst ),
             BUSY( busy ),
-            DIO1( dio1 ),
-            DIO2( dio2 ),
-            DIO3( dio3 )
+            DeviceSelect( deviceSelect ),
+            antSwitchPower( antSwPower )
 {
+    CreateDioPin( dio1, DIO1 );
+    CreateDioPin( dio2, DIO2 );
+    CreateDioPin( dio3, DIO3 );
     RadioSpi = new SPI( mosi, miso, sclk );
-    RadioUart = NULL;
 
     RadioNss = 1;
     RadioReset = 1;
 }
 
-SX126xHal::SX126xHal( PinName tx, PinName rx, PinName busy, PinName dio1, PinName dio2, PinName dio3, PinName rst,
-                            void ( *txDone )( ), void ( *rxDone )( ), void ( *rxPblSyncWordHeader )( IrqPblSyncHeaderCode_t val ),
-                            void ( *rxTxTimeout )( IrqTimeoutCode_t timeoutCode ), void ( *rxError )( IrqErrorCode_t errorCode ), void ( *cadDone )( bool channelActivityDetected ),
-                            void ( *onDioIrq )( ) )
-        :   SX126x( txDone, rxDone, rxPblSyncWordHeader, rxTxTimeout, rxError, cadDone, onDioIrq ),
-            RadioNss( NC ),
-            RadioReset( rst ),
-            BUSY( busy ),
-            DIO1( dio1 ),
-            DIO2( dio2 ),
-            DIO3( dio3 )
+SX126xHal::~SX126xHal( void )
 {
-    RadioSpi = NULL;
-    RadioUart = new Serial( tx, rx );
-    RadioReset = 1;
-}
+    if( this->RadioSpi != NULL )
+    {
+        delete RadioSpi;
+    }
+    if( DIO1 != NULL )
+    {
+        delete DIO1;
+    }
+    if( DIO2 != NULL )
+    {
+        delete DIO2;
+    }
+    if( DIO3 != NULL )
+    {
+        delete DIO3;
+    }
+};
 
 void SX126xHal::SpiInit( void )
 {
@@ -81,105 +103,40 @@
     wait( 0.1 );
 }
 
-void SX126xHal::UartInit( void )
-{
-    RadioUart->format( 9, SerialBase::Even, 1 ); // 8 data bits + 1 even parity bit + 1 stop bit
-    RadioUart->baud( 115200 );
-
-    // By default the SX126x UART is setup to handle bytes MSB first.
-    // In order to setup the radio to use the UART standard way we first send
-    // the equivalent of a WriteRegister with reversed bit order in order to
-    // change the endianness.
-    //@todo 
-    /*uint8_t regVal = 0;
-    RadioUart->putc( 0x98 );            // Reversed opcode for read register (0x19)
-    RadioUart->putc( 0x10 );            // Reversed MSB register address (0x08)
-    RadioUart->putc( 0x18 );            // Reversed LSB register address (0x18)
-    RadioUart->putc( 0x80 );            // Reversed value for reading only 1 byte (0x01)
-    regVal = RadioUart->getc( )& 0xF3;  // Read reversed value and mask it
-
-    RadioUart->putc( 0x18 );            // Reversed opcode for read register (0x18)
-    RadioUart->putc( 0x10 );            // Reversed MSB register address (0x08)
-    RadioUart->putc( 0x18 );            // Reversed LSB register address (0x18)
-    RadioUart->putc( 0x80 );            // Reversed value for writing only 1 byte (0x01)
-    RadioUart->putc( regVal );          // The new value of the register*/
-
-    // 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 SX126xHal::IoIrqInit( DioIrqHandler irqHandler )
 {
-    assert_param( RadioSpi != 0 || RadioUart != 0 );
+    assert_param( RadioSpi != NULL );
     if( RadioSpi != NULL )
     {
         SpiInit( );
     }
-    if( RadioUart != NULL )
-    {
-        UartInit( );
-    }
 
-    BUSY.mode( PullDown );
-    DIO1.mode( PullDown );
-    DIO2.mode( PullDown );
-    DIO3.mode( PullDown );
+    BUSY.mode( PullNone );
+    DioAssignCallback( DIO1, PullNone, irqHandler );
+//    DioAssignCallback( DIO2, PullNone, irqHandler );
+//    DioAssignCallback( DIO3, PullNone, irqHandler );
 
-    DIO1.rise( this, static_cast <Trigger>( irqHandler ) );
-    DIO2.rise( this, static_cast <Trigger>( irqHandler ) );
-    DIO3.rise( this, static_cast <Trigger>( irqHandler ) );
 }
 
 void SX126xHal::Reset( void )
 {
     __disable_irq( );
-    wait( 0.05 );
+    wait_ms( 20 );
+    RadioReset.output( );
     RadioReset = 0;
-    wait( 0.1 );
+    wait_ms( 50 );
     RadioReset = 1;
-    wait( 0.05 );
+    RadioReset.input( ); // Using the internal pull-up
+    wait_ms( 20 );
     __enable_irq( );
 }
 
-void SX126xHal::ClearInstructionRam( void )
-{
-    // Clearing the instruction RAM is writing 0x00s on every bytes of the
-    // instruction RAM
-    WaitBusy( );
-
-    if( RadioSpi != NULL )
-    {
-        RadioNss = 0;
-        RadioSpi->write( RADIO_WRITE_REGISTER );                 // Send write register opcode
-        RadioSpi->write( ( IRAM_START_ADDRESS >> 8 ) & 0x00FF ); // Send MSB of the first byte address
-        RadioSpi->write( IRAM_START_ADDRESS & 0x00FF );          // Send LSB of the first byte address
-
-        for( uint16_t address = IRAM_START_ADDRESS; address < ( IRAM_START_ADDRESS + IRAM_SIZE ); address++ )
-        {
-            RadioSpi->write( 0x00 );
-        }
-        RadioNss = 1;
-    }
-    if( RadioUart != NULL )
-    {
-        // We can't erase the whole instruction RAM in one shot with UART
-        // because we need to send the length of register to erase
-        // and this length is coded on 1 byte.
-        for( uint16_t address = IRAM_START_ADDRESS; address < ( IRAM_START_ADDRESS + IRAM_SIZE ); address++ )
-        {
-            WriteRegister( address, 0 );
-        }
-    }
-
-    WaitBusy( );
-}
-
 void SX126xHal::Wakeup( void )
 {
     __disable_irq( );
 
-    //Don't wait for DIO0 here
+    //Don't wait for BUSY here
 
     if( RadioSpi != NULL )
     {
@@ -188,33 +145,27 @@
         RadioSpi->write( 0 );
         RadioNss = 1;
     }
-    if( RadioUart != NULL )
-    {
-        RadioUart->putc( RADIO_GET_STATUS );
-        WaitUartReadable( );
-        RadioUart->getc( );
-    }
 
     // Wait for chip to be ready.
-    WaitBusy( );
-    
-    #ifdef V1A_WORKAROUNDS
-    //V1a workaround: rc64k not enabled after warm_start, rtc_wake_up=0
-    WriteRegister(0x91e, ReadRegister(0x91e) | 0x40);
-    //rc13m enable bug
-    uint8_t txFallbackFunc[2];
-    //set to  ModeTx2Rc addr = 0fce, so rc is not enabled before ramp down
-    txFallbackFunc[0] = 0x0f;
-    txFallbackFunc[1] = 0xce;
-    WriteRegister(0x00CC, txFallbackFunc, 2);
-    #endif
+    WaitOnBusy( );
 
     __enable_irq( );
+    
+    AntSwOn( );
 }
 
 void SX126xHal::WriteCommand( RadioCommands_t command, uint8_t *buffer, uint16_t size )
 {
-    WaitBusy( );
+#ifdef ADV_DEBUG
+    printf("cmd: 0x%02x", command );
+    for( uint8_t i = 0; i < size; i++ )
+    {
+        printf("-%02x", buffer[i] );
+    }
+    printf("\n\r");
+#endif
+    
+    WaitOnBusy( );
 
     if( RadioSpi != NULL )
     {
@@ -226,28 +177,12 @@
         }
         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 )
-    {
-        WaitBusy( );
-    }
+    WaitOnCounter( );
 }
 
 void SX126xHal::ReadCommand( RadioCommands_t command, uint8_t *buffer, uint16_t size )
 {
-    WaitBusy( );
+    WaitOnBusy( );
 
     if( RadioSpi != NULL )
     {
@@ -260,37 +195,11 @@
         }
         RadioNss = 1;
     }
-    else 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 ) )
-        {
-            RadioUart->putc( size );
-        }
-
-        WaitUartReadable( );
-        for( uint16_t i = 0; i < size; i++ )
-        {
-             buffer[i] = RadioUart->getc( );
-        }
-    }
-    else
-    {
-        buffer[0] = 0xFF;
-    }
-
-    WaitBusy( );
 }
 
 void SX126xHal::WriteRegister( uint16_t address, uint8_t *buffer, uint16_t size )
 {
-    WaitBusy( );
+    WaitOnBusy( );
 
     if( RadioSpi != NULL )
     {
@@ -304,61 +213,16 @@
         }
         RadioNss = 1;
     }
-    if( RadioUart != NULL )
-    {
-        RadioUart->putc( RADIO_WRITE_REGISTER );
-        RadioUart->putc( ( address & 0xFF00 ) >> 8 );
-        RadioUart->putc( address & 0x00FF );
-        RadioUart->putc( size );
-        for( uint16_t i = 0; i < size; i++ )
-        {
-            RadioUart->putc( buffer[i] );
-        }
-    }
-
-    WaitBusy( );
 }
 
-void SX126xHal::WriteRegisterNoBusy( uint16_t address, uint8_t *buffer, uint16_t size )
-{
-    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 )
-    {
-        RadioUart->putc( RADIO_WRITE_REGISTER );
-        RadioUart->putc( ( address & 0xFF00 ) >> 8 );
-        RadioUart->putc( address & 0x00FF );
-        RadioUart->putc( size );
-        for( uint16_t i = 0; i < size; i++ )
-        {
-            RadioUart->putc( buffer[i] );
-        }
-    }
-}
-
-void SX126xHal::WriteRegister( uint16_t address, uint8_t value )
+void SX126xHal::WriteReg( uint16_t address, uint8_t value )
 {
     WriteRegister( address, &value, 1 );
 }
 
-void SX126xHal::WriteRegisterNoBusy( uint16_t address, uint8_t value )
-{
-    WriteRegisterNoBusy( address, &value, 1 );
-}
-
 void SX126xHal::ReadRegister( uint16_t address, uint8_t *buffer, uint16_t size )
 {
-    WaitBusy( );
+    WaitOnBusy( );
 
     if( RadioSpi != NULL )
     {
@@ -373,54 +237,9 @@
         }
         RadioNss = 1;
     }
-    if( RadioUart != NULL )
-    {
-        RadioUart->putc( RADIO_READ_REGISTER );
-        RadioUart->putc( ( address & 0xFF00 ) >> 8 );
-        RadioUart->putc( address & 0x00FF );
-        RadioUart->putc( size );
-        WaitUartReadable( );
-        for( uint16_t i = 0; i < size; i++ )
-        {
-            buffer[i] = RadioUart->getc( );
-        }
-    }
-
-    WaitBusy( );
 }
 
-void SX126xHal::ReadRegisterNoBusy( uint16_t address, uint8_t *buffer, uint16_t size )
-{
-
-    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 )
-    {
-        RadioUart->putc( RADIO_READ_REGISTER );
-        RadioUart->putc( ( address & 0xFF00 ) >> 8 );
-        RadioUart->putc( address & 0x00FF );
-        RadioUart->putc( size );
-        WaitUartReadable( );
-        for( uint16_t i = 0; i < size; i++ )
-        {
-            buffer[i] = RadioUart->getc( );
-        }
-    }
-
-}
-
-uint8_t SX126xHal::ReadRegister( uint16_t address )
+uint8_t SX126xHal::ReadReg( uint16_t address )
 {
     uint8_t data;
 
@@ -428,17 +247,9 @@
     return data;
 }
 
-uint8_t SX126xHal::ReadRegisterNoBusy( uint16_t address )
-{
-    uint8_t data;
-
-    ReadRegisterNoBusy( address, &data, 1 );
-    return data;
-}
-
 void SX126xHal::WriteBuffer( uint8_t offset, uint8_t *buffer, uint8_t size )
 {
-    WaitBusy( );
+    WaitOnBusy( );
 
     if( RadioSpi != NULL )
     {
@@ -451,23 +262,11 @@
         }
         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] );
-        }
-    }
-
-    WaitBusy( );
 }
 
 void SX126xHal::ReadBuffer( uint8_t offset, uint8_t *buffer, uint8_t size )
 {
-    WaitBusy( );
+    WaitOnBusy( );
 
     if( RadioSpi != NULL )
     {
@@ -481,24 +280,24 @@
         }
         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( );
-        }
-    }
-
-    WaitBusy( );
 }
 
 uint8_t SX126xHal::GetDioStatus( void )
 {
-    return ( DIO3 << 3 ) | ( DIO2 << 2 ) | ( DIO1 << 1 ) | ( BUSY << 0 );
+    return ( *DIO3 << 3 ) | ( *DIO2 << 2 ) | ( *DIO1 << 1 ) | ( BUSY << 0 );
+}
+
+uint8_t SX126xHal::GetDeviceType( void )
+{
+    return( DeviceSelect.read( ) );
 }
 
+void SX126xHal::AntSwOn( void )
+{
+    antSwitchPower = 1;
+}
 
+void SX126xHal::AntSwOff( void )
+{
+    antSwitchPower = 0;
+}