SX1261 and sx1262 common library
Dependents: SX126xDevKit SX1262PingPong SX126X_TXonly SX126X_PingPong_Demo ... more
Fork of SX126xLib by
Diff: sx126x-hal.cpp
- 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; +}