321 lines
7.8 KiB
C
321 lines
7.8 KiB
C
/*
|
|
______ _
|
|
/ _____) _ | |
|
|
( (____ _____ ____ _| |_ _____ ____| |__
|
|
\____ \| ___ | (_ _) ___ |/ ___) _ \
|
|
_____) ) ____| | | || |_| ____( (___| | | |
|
|
(______/|_____)_|_|_| \__)_____)\____)_| |_|
|
|
(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 "hw.h"
|
|
#include "sx1281-hal.h"
|
|
#include "radio.h"
|
|
#include <string.h>
|
|
#include "bsp/gpio.h"
|
|
/*!
|
|
* \brief Define the size of tx and rx hal buffers
|
|
*
|
|
* The Tx and Rx hal buffers are used for SPI communication to
|
|
* store data to be sent/receive to/from the chip.
|
|
*
|
|
* \warning The application must ensure the maximal useful size to be much lower
|
|
* than the MAX_HAL_BUFFER_SIZE
|
|
*/
|
|
#define MAX_HAL_BUFFER_SIZE 0xFFF
|
|
|
|
#define IRQ_HIGH_PRIORITY 0
|
|
|
|
/*!
|
|
* Radio driver structure initialization
|
|
*/
|
|
const struct Radio_s Radio =
|
|
{
|
|
SX1281Init,
|
|
SX1281HalReset,
|
|
SX1281GetStatus,
|
|
SX1281HalWriteCommand,
|
|
SX1281HalReadCommand,
|
|
SX1281HalWriteRegisters,
|
|
SX1281HalWriteRegister,
|
|
SX1281HalReadRegisters,
|
|
SX1281HalReadRegister,
|
|
SX1281HalWriteBuffer,
|
|
SX1281HalReadBuffer,
|
|
SX1281HalGetDioStatus,
|
|
SX1281GetFirmwareVersion,
|
|
SX1281SetRegulatorMode,
|
|
SX1281SetStandby,
|
|
SX1281SetPacketType,
|
|
SX1281SetModulationParams,
|
|
SX1281SetPacketParams,
|
|
SX1281SetRfFrequency,
|
|
SX1281SetBufferBaseAddresses,
|
|
SX1281SetTxParams,
|
|
SX1281SetDioIrqParams,
|
|
SX1281SetSyncWord,
|
|
SX1281SetRx,
|
|
SX1281GetPayload,
|
|
SX1281SendPayload,
|
|
SX1281SetPollingMode,
|
|
SX1281SetInterruptMode,
|
|
SX1281SetRegistersDefault,
|
|
SX1281GetOpMode,
|
|
SX1281SetSleep,
|
|
SX1281SetFs,
|
|
SX1281SetTx,
|
|
SX1281SetRxDutyCycle,
|
|
SX1281SetCad,
|
|
SX1281SetTxContinuousWave,
|
|
SX1281SetTxContinuousPreamble,
|
|
SX1281GetPacketType,
|
|
SX1281SetCadParams,
|
|
SX1281GetRxBufferStatus,
|
|
SX1281GetPacketStatus,
|
|
SX1281GetRssiInst,
|
|
SX1281GetIrqStatus,
|
|
SX1281ClearIrqStatus,
|
|
SX1281Calibrate,
|
|
SX1281SetSaveContext,
|
|
SX1281SetAutoTx,
|
|
SX1281SetAutoFS,
|
|
SX1281SetLongPreamble,
|
|
SX1281SetPayload,
|
|
SX1281SetSyncWordErrorTolerance,
|
|
SX1281SetCrcSeed,
|
|
SX1281SetBleAccessAddress,
|
|
SX1281SetBleAdvertizerAccessAddress,
|
|
SX1281SetCrcPolynomial,
|
|
SX1281SetWhiteningSeed,
|
|
SX1281GetFrequencyError,
|
|
};
|
|
|
|
static uint8_t halTxBuffer[MAX_HAL_BUFFER_SIZE] = {0x00};
|
|
static uint8_t halRxBuffer[MAX_HAL_BUFFER_SIZE] = {0x00};
|
|
|
|
/*!
|
|
* \brief Used to block execution waiting for low state on radio busy pin.
|
|
* Essentially used in SPI communications
|
|
*/
|
|
void SX1281HalWaitOnBusy( void )
|
|
{
|
|
while( HAL_GPIO_ReadPin( RADIO_BUSY_PORT, RADIO_BUSY_PIN ) == 1 );
|
|
}
|
|
|
|
void SX1281HalInit( DioIrqHandler **irqHandlers )
|
|
{
|
|
SX1281HalReset( );
|
|
SX1281HalIoIrqInit( irqHandlers );
|
|
}
|
|
|
|
void SX1281HalIoIrqInit( DioIrqHandler **irqHandlers )
|
|
{
|
|
GpioSetIrq( RADIO_DIOx_PORT, RADIO_DIOx_PIN, IRQ_HIGH_PRIORITY, irqHandlers[0] );
|
|
// BSP_GPIO_RegisterCallback(BSP_GPIO_RADIO_DIO1, irqHandlers); 成功后改成bsp函数
|
|
}
|
|
|
|
void SX1281HalReset( void )
|
|
{
|
|
HAL_Delay( 20 );
|
|
GpioWrite( RADIO_nRESET_PORT, RADIO_nRESET_PIN, 0 );
|
|
HAL_Delay( 50 );
|
|
GpioWrite( RADIO_nRESET_PORT, RADIO_nRESET_PIN, 1 );
|
|
HAL_Delay( 20 );
|
|
}
|
|
|
|
void SX1281HalClearInstructionRam( void )
|
|
{
|
|
// Clearing the instruction RAM is writing 0x00s on every bytes of the
|
|
// instruction RAM
|
|
uint16_t halSize = 3 + IRAM_SIZE;
|
|
halTxBuffer[0] = RADIO_WRITE_REGISTER;
|
|
halTxBuffer[1] = ( IRAM_START_ADDRESS >> 8 ) & 0x00FF;
|
|
halTxBuffer[2] = IRAM_START_ADDRESS & 0x00FF;
|
|
for( uint16_t index = 0; index < IRAM_SIZE; index++ )
|
|
{
|
|
halTxBuffer[3+index] = 0x00;
|
|
}
|
|
|
|
SX1281HalWaitOnBusy( );
|
|
|
|
GpioWrite( RADIO_NSS_PORT, RADIO_NSS_PIN, 0 );
|
|
|
|
SpiIn( halTxBuffer, halSize );
|
|
|
|
GpioWrite( RADIO_NSS_PORT, RADIO_NSS_PIN, 1 );
|
|
|
|
SX1281HalWaitOnBusy( );
|
|
}
|
|
|
|
void SX120HalWakeup( void )
|
|
{
|
|
__disable_irq( );
|
|
|
|
GpioWrite( RADIO_NSS_PORT, RADIO_NSS_PIN, 0 );
|
|
|
|
uint16_t halSize = 2;
|
|
halTxBuffer[0] = RADIO_GET_STATUS;
|
|
halTxBuffer[1] = 0x00;
|
|
SpiIn( halTxBuffer, halSize );
|
|
|
|
GpioWrite( RADIO_NSS_PORT, RADIO_NSS_PIN, 1 );
|
|
|
|
// Wait for chip to be ready.
|
|
SX1281HalWaitOnBusy( );
|
|
|
|
__enable_irq( );
|
|
}
|
|
|
|
void SX1281HalWriteCommand( RadioCommands_t command, uint8_t *buffer, uint16_t size )
|
|
{
|
|
uint16_t halSize = size + 1;
|
|
SX1281HalWaitOnBusy( );
|
|
|
|
GpioWrite( RADIO_NSS_PORT, RADIO_NSS_PIN, 0 );
|
|
|
|
halTxBuffer[0] = command;
|
|
memcpy( halTxBuffer + 1, ( uint8_t * )buffer, size * sizeof( uint8_t ) );
|
|
|
|
SpiIn( halTxBuffer, halSize );
|
|
|
|
GpioWrite( RADIO_NSS_PORT, RADIO_NSS_PIN, 1 );
|
|
|
|
if( command != RADIO_SET_SLEEP )
|
|
{
|
|
SX1281HalWaitOnBusy( );
|
|
}
|
|
}
|
|
|
|
void SX1281HalReadCommand( RadioCommands_t command, uint8_t *buffer, uint16_t size )
|
|
{
|
|
uint16_t halSize = 2 + size;
|
|
halTxBuffer[0] = command;
|
|
halTxBuffer[1] = 0x00;
|
|
for( uint16_t index = 0; index < size; index++ )
|
|
{
|
|
halTxBuffer[2+index] = 0x00;
|
|
}
|
|
|
|
SX1281HalWaitOnBusy( );
|
|
|
|
GpioWrite( RADIO_NSS_PORT, RADIO_NSS_PIN, 0 );
|
|
|
|
SpiInOut( halTxBuffer, halRxBuffer, halSize );
|
|
|
|
memcpy( buffer, halRxBuffer + 2, size );
|
|
|
|
GpioWrite( RADIO_NSS_PORT, RADIO_NSS_PIN, 1 );
|
|
|
|
SX1281HalWaitOnBusy( );
|
|
}
|
|
|
|
void SX1281HalWriteRegisters( uint16_t address, uint8_t *buffer, uint16_t size )
|
|
{
|
|
uint16_t halSize = size + 3;
|
|
halTxBuffer[0] = RADIO_WRITE_REGISTER;
|
|
halTxBuffer[1] = ( address & 0xFF00 ) >> 8;
|
|
halTxBuffer[2] = address & 0x00FF;
|
|
memcpy( halTxBuffer + 3, buffer, size );
|
|
|
|
SX1281HalWaitOnBusy( );
|
|
|
|
GpioWrite( RADIO_NSS_PORT, RADIO_NSS_PIN, 0 );
|
|
|
|
SpiIn( halTxBuffer, halSize );
|
|
|
|
GpioWrite( RADIO_NSS_PORT, RADIO_NSS_PIN, 1 );
|
|
|
|
SX1281HalWaitOnBusy( );
|
|
}
|
|
|
|
void SX1281HalWriteRegister( uint16_t address, uint8_t value )
|
|
{
|
|
SX1281HalWriteRegisters( address, &value, 1 );
|
|
}
|
|
|
|
void SX1281HalReadRegisters( uint16_t address, uint8_t *buffer, uint16_t size )
|
|
{
|
|
uint16_t halSize = 4 + size;
|
|
halTxBuffer[0] = RADIO_READ_REGISTER;
|
|
halTxBuffer[1] = ( address & 0xFF00 ) >> 8;
|
|
halTxBuffer[2] = address & 0x00FF;
|
|
halTxBuffer[3] = 0x00;
|
|
for( uint16_t index = 0; index < size; index++ )
|
|
{
|
|
halTxBuffer[4+index] = 0x00;
|
|
}
|
|
|
|
SX1281HalWaitOnBusy( );
|
|
|
|
GpioWrite( RADIO_NSS_PORT, RADIO_NSS_PIN, 0 );
|
|
|
|
SpiInOut( halTxBuffer, halRxBuffer, halSize );
|
|
|
|
memcpy( buffer, halRxBuffer + 4, size );
|
|
|
|
GpioWrite( RADIO_NSS_PORT, RADIO_NSS_PIN, 1 );
|
|
|
|
SX1281HalWaitOnBusy( );
|
|
}
|
|
|
|
uint8_t SX1281HalReadRegister( uint16_t address )
|
|
{
|
|
uint8_t data;
|
|
|
|
SX1281HalReadRegisters( address, &data, 1 );
|
|
|
|
return data;
|
|
}
|
|
|
|
void SX1281HalWriteBuffer( uint8_t offset, uint8_t *buffer, uint8_t size )
|
|
{
|
|
uint16_t halSize = size + 2;
|
|
halTxBuffer[0] = RADIO_WRITE_BUFFER;
|
|
halTxBuffer[1] = ( offset ) >> 8;
|
|
memcpy( halTxBuffer + 2, buffer, size );
|
|
|
|
SX1281HalWaitOnBusy( );
|
|
|
|
GpioWrite( RADIO_NSS_PORT, RADIO_NSS_PIN, 0 );
|
|
|
|
SpiIn( halTxBuffer, halSize );
|
|
|
|
GpioWrite( RADIO_NSS_PORT, RADIO_NSS_PIN, 1 );
|
|
|
|
SX1281HalWaitOnBusy( );
|
|
}
|
|
|
|
void SX1281HalReadBuffer( uint8_t offset, uint8_t *buffer, uint8_t size )
|
|
{
|
|
uint16_t halSize = size + 3;
|
|
halTxBuffer[0] = RADIO_READ_BUFFER;
|
|
halTxBuffer[1] = offset;
|
|
halTxBuffer[2] = 0x00;
|
|
for( uint16_t index = 0; index < size; index++ )
|
|
{
|
|
halTxBuffer[3+index] = 0x00;
|
|
}
|
|
|
|
SX1281HalWaitOnBusy( );
|
|
|
|
GpioWrite( RADIO_NSS_PORT, RADIO_NSS_PIN, 0 );
|
|
|
|
SpiInOut( halTxBuffer, halRxBuffer, halSize );
|
|
|
|
memcpy( buffer, halRxBuffer + 3, size );
|
|
|
|
GpioWrite( RADIO_NSS_PORT, RADIO_NSS_PIN, 1 );
|
|
|
|
SX1281HalWaitOnBusy( );
|
|
}
|
|
|
|
uint8_t SX1281HalGetDioStatus( void )
|
|
{
|
|
return ( GpioRead( RADIO_DIOx_PORT, RADIO_DIOx_PIN ) << 1 ) | ( GpioRead( RADIO_BUSY_PORT, RADIO_BUSY_PIN ) << 0 );
|
|
}
|