/*! * \file sx1262mbxcas-board.c * * \brief Target board SX1262MBXCAS shield driver implementation * * \copyright Revised BSD License, see section \ref LICENSE. * * \code * ______ _ * / _____) _ | | * ( (____ _____ ____ _| |_ _____ ____| |__ * \____ \| ___ | (_ _) ___ |/ ___) _ \ * _____) ) ____| | | || |_| ____( (___| | | | * (______/|_____)_|_|_| \__)_____)\____)_| |_| * (C)2013-2017 Semtech * * \endcode * * \author Miguel Luis ( Semtech ) * * \author Gregory Cristian ( Semtech ) */ #include #include "utilities.h" #include "board-config.h" #include "board.h" #include "delay.h" #include "radio.h" #include "sx126x-board.h" /*! * Antenna switch GPIO pins objects */ Gpio_t AntPow; Gpio_t DeviceSel; /*! * Debug GPIO pins objects */ #if defined( USE_RADIO_DEBUG ) Gpio_t DbgPinTx; Gpio_t DbgPinRx; #endif void SX126xIoInit( void ) { GpioInit( &SX126x.Spi.Nss, RADIO_NSS, PIN_OUTPUT, PIN_PUSH_PULL, PIN_NO_PULL, 1 ); GpioInit( &SX126x.BUSY, RADIO_BUSY, PIN_INPUT, PIN_PUSH_PULL, PIN_NO_PULL, 0 ); //GpioInit( &SX126x.BUSY, RADIO_BUSY, PIN_INPUT, PIN_PUSH_PULL, PIN_PULL_DOWN, 0 ); GpioInit( &SX126x.DIO1, RADIO_DIO_1, PIN_INPUT, PIN_PUSH_PULL, PIN_NO_PULL, 0 ); GpioInit( &SX126x.Reset, RADIO_RESET, PIN_OUTPUT, PIN_PUSH_PULL, PIN_NO_PULL, 1 ); // It's active low GpioInit( &AntPow, RADIO_ANT_SWITCH_POWER, PIN_OUTPUT, PIN_PUSH_PULL, PIN_NO_PULL, 0 ); GpioInit( &DeviceSel, RADIO_DEVICE_SEL, PIN_INPUT, PIN_PUSH_PULL, PIN_NO_PULL, 0 ); } void SX126xIoIrqInit( DioIrqHandler dioIrq ) { GpioSetInterrupt( &SX126x.DIO1, IRQ_RISING_EDGE, IRQ_HIGH_PRIORITY, dioIrq ); } void SX126xIoDeInit( void ) { GpioInit( &SX126x.Spi.Nss, RADIO_NSS, PIN_OUTPUT, PIN_PUSH_PULL, PIN_NO_PULL, 1 ); GpioInit( &SX126x.BUSY, RADIO_BUSY, PIN_INPUT, PIN_PUSH_PULL, PIN_NO_PULL, 0 ); GpioInit( &SX126x.DIO1, RADIO_DIO_1, PIN_INPUT, PIN_PUSH_PULL, PIN_NO_PULL, 0 ); } void SX126xIoDbgInit( void ) { #if defined( USE_RADIO_DEBUG ) GpioInit( &DbgPinTx, RADIO_DBG_PIN_TX, PIN_OUTPUT, PIN_PUSH_PULL, PIN_NO_PULL, 0 ); GpioInit( &DbgPinRx, RADIO_DBG_PIN_RX, PIN_OUTPUT, PIN_PUSH_PULL, PIN_NO_PULL, 0 ); #endif } void SX126xIoTcxoInit( void ) { // No TCXO component available on this board design. } uint32_t SX126xGetBoardTcxoWakeupTime( void ) { return BOARD_TCXO_WAKEUP_TIME; } void SX126xReset( void ) { DelayMs( 10 ); //GpioInit( &SX126x.Reset, RADIO_RESET, PIN_OUTPUT, PIN_PUSH_PULL, PIN_NO_PULL, 0 ); GpioWrite(&SX126x.Reset, 0); DelayMs( 20 ); //GpioInit( &SX126x.Reset, RADIO_RESET, PIN_ANALOGIC, PIN_PUSH_PULL, PIN_NO_PULL, 0 ); // internal pull-up GpioWrite(&SX126x.Reset, 1); DelayMs( 10 ); } void SX126xWaitOnBusy( void ) { while( GpioRead( &SX126x.BUSY ) == 1 ); } void SX126xWakeup( void ) { //CRITICAL_SECTION_BEGIN( ); GpioWrite( &SX126x.Spi.Nss, 0 ); SpiInOut( &SX126x.Spi, RADIO_GET_STATUS ); SpiInOut( &SX126x.Spi, 0x00 ); GpioWrite( &SX126x.Spi.Nss, 1 ); // Wait for chip to be ready. SX126xWaitOnBusy( ); //CRITICAL_SECTION_END( ); } void SX126xWriteCommand( RadioCommands_t command, uint8_t *buffer, uint16_t size ) { SX126xCheckDeviceReady( ); GpioWrite( &SX126x.Spi.Nss, 0 ); SpiInOut( &SX126x.Spi, ( uint8_t )command ); for( uint16_t i = 0; i < size; i++ ) { SpiInOut( &SX126x.Spi, buffer[i] ); } GpioWrite( &SX126x.Spi.Nss, 1 ); if( command != RADIO_SET_SLEEP ) { SX126xWaitOnBusy( ); } //#define SHOW_RADIO_COMMANDS #ifdef SHOW_RADIO_COMMANDS size_t msg_len = size + 1; uint8_t msg[msg_len + 1]; msg[0] = command; memcpy(&msg[1], buffer, size); msg[msg_len + 1] = '\0'; printf("Sending: %x\n", msg); printf("\nDEBUG: Chip Status: %x\n", SX126xGetStatus()); printf("DEBUG: Chip Errors: %x\n", SX126xGetDeviceErrors()); #endif } uint8_t SX126xReadCommand( RadioCommands_t command, uint8_t *buffer, uint16_t size ) { uint8_t status = 0; SX126xCheckDeviceReady( ); GpioWrite( &SX126x.Spi.Nss, 0 ); SpiInOut( &SX126x.Spi, ( uint8_t )command ); status = SpiInOut( &SX126x.Spi, 0x00 ); for( uint16_t i = 0; i < size; i++ ) { buffer[i] = SpiInOut( &SX126x.Spi, 0 ); } GpioWrite( &SX126x.Spi.Nss, 1 ); SX126xWaitOnBusy( ); return status; } void SX126xWriteRegisters( uint16_t address, uint8_t *buffer, uint16_t size ) { SX126xCheckDeviceReady( ); GpioWrite( &SX126x.Spi.Nss, 0 ); SpiInOut( &SX126x.Spi, RADIO_WRITE_REGISTER ); SpiInOut( &SX126x.Spi, ( address & 0xFF00 ) >> 8 ); SpiInOut( &SX126x.Spi, address & 0x00FF ); for( uint16_t i = 0; i < size; i++ ) { SpiInOut( &SX126x.Spi, buffer[i] ); } GpioWrite( &SX126x.Spi.Nss, 1 ); SX126xWaitOnBusy( ); } void SX126xWriteRegister( uint16_t address, uint8_t value ) { SX126xWriteRegisters( address, &value, 1 ); } void SX126xReadRegisters( uint16_t address, uint8_t *buffer, uint16_t size ) { SX126xCheckDeviceReady( ); GpioWrite( &SX126x.Spi.Nss, 0 ); SpiInOut( &SX126x.Spi, RADIO_READ_REGISTER ); SpiInOut( &SX126x.Spi, ( address & 0xFF00 ) >> 8 ); SpiInOut( &SX126x.Spi, address & 0x00FF ); SpiInOut( &SX126x.Spi, 0 ); for( uint16_t i = 0; i < size; i++ ) { buffer[i] = SpiInOut( &SX126x.Spi, 0 ); } GpioWrite( &SX126x.Spi.Nss, 1 ); SX126xWaitOnBusy( ); } uint8_t SX126xReadRegister( uint16_t address ) { uint8_t data; SX126xReadRegisters( address, &data, 1 ); return data; } void SX126xWriteBuffer( uint8_t offset, uint8_t *buffer, uint8_t size ) { SX126xCheckDeviceReady( ); GpioWrite( &SX126x.Spi.Nss, 0 ); SpiInOut( &SX126x.Spi, RADIO_WRITE_BUFFER ); SpiInOut( &SX126x.Spi, offset ); for( uint16_t i = 0; i < size; i++ ) { SpiInOut( &SX126x.Spi, buffer[i] ); } GpioWrite( &SX126x.Spi.Nss, 1 ); SX126xWaitOnBusy( ); } void SX126xReadBuffer( uint8_t offset, uint8_t *buffer, uint8_t size ) { SX126xCheckDeviceReady( ); GpioWrite( &SX126x.Spi.Nss, 0 ); SpiInOut( &SX126x.Spi, RADIO_READ_BUFFER ); SpiInOut( &SX126x.Spi, offset ); SpiInOut( &SX126x.Spi, 0 ); for( uint16_t i = 0; i < size; i++ ) { buffer[i] = SpiInOut( &SX126x.Spi, 0 ); } GpioWrite( &SX126x.Spi.Nss, 1 ); SX126xWaitOnBusy( ); } void SX126xSetRfTxPower( int8_t power ) { SX126xSetTxParams( power, RADIO_RAMP_40_US ); } uint8_t SX126xGetDeviceId( void ) { if( GpioRead( &DeviceSel ) == 1 ) { return SX1261; } else { return SX1262; } } void SX126xAntSwOn( void ) { GpioWrite( &AntPow, 1); } void SX126xAntSwOff( void ) { GpioWrite( &AntPow, 0); } bool SX126xCheckRfFrequency( uint32_t frequency ) { // Implement check. Currently all frequencies are supported return true; } #if defined( USE_RADIO_DEBUG ) void SX126xDbgPinTxWrite( uint8_t state ) { GpioWrite( &DbgPinTx, state ); } void SX126xDbgPinRxWrite( uint8_t state ) { GpioWrite( &DbgPinRx, state ); } #endif