267 lines
6.4 KiB
C++
267 lines
6.4 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 "sx1280-hal.h"
|
|
#include <functional>
|
|
#include <FreeRTOS.h>
|
|
#include <task.h>
|
|
#include <cstring>
|
|
|
|
/*!
|
|
* \brief Used to block execution waiting for low state on radio busy pin.
|
|
* Essentially used in SPI communications
|
|
*/
|
|
#define WaitOnBusy( ) for(uint8_t val=0; val != 1; BUSY->read(&val));
|
|
|
|
/*!
|
|
* \brief Macro used to enable and disable callback without disabling IRQ
|
|
*/
|
|
|
|
#define setDioIrqEnabled( enabled ) EXTIHandler::getInstance()->setCallbackEnabled(DIO1, enabled)
|
|
|
|
// This code handles cases where assert_param is undefined
|
|
#ifndef assert_param
|
|
#define assert_param( ... )
|
|
#endif
|
|
|
|
SX1280Hal::SX1280Hal( SPI_Peripheral* pSpiPeripheral, GPIO_Pin* pNssPin,
|
|
GPIO_Pin* pBusyPin, GPIO_Pin* pIrqPin, GPIO_Pin* pRstPin,
|
|
RadioCallbacks_t *callbacks ) :
|
|
SX1280( callbacks ),
|
|
RadioSpi(pSpiPeripheral),
|
|
RadioNss( pNssPin ),
|
|
RadioReset( pRstPin ),
|
|
BUSY( pBusyPin ),
|
|
DIO1( pIrqPin )
|
|
{
|
|
|
|
}
|
|
|
|
SX1280Hal::~SX1280Hal( void )
|
|
{
|
|
|
|
};
|
|
|
|
void SX1280Hal::SpiInit( void )
|
|
{
|
|
RadioNss->set();
|
|
}
|
|
|
|
void SX1280Hal::IoIrqInit( DioIrqHandler irqHandler )
|
|
{
|
|
assert_param( RadioSpi != NULL );
|
|
SpiInit( );
|
|
|
|
std::function<void(void*)> callbackFunction = [this, irqHandler](void* ptr){(this->*irqHandler)();};
|
|
EXTIHandler::getInstance()->registerCallback(callbackFunction, nullptr, DIO1);
|
|
EXTIHandler::getInstance()->setCallbackEnabled(DIO1, true);
|
|
}
|
|
|
|
void SX1280Hal::Reset( void )
|
|
{
|
|
setDioIrqEnabled( false );
|
|
vTaskDelay( 20 );
|
|
RadioReset->reset();
|
|
vTaskDelay( 50 );
|
|
RadioReset->set();
|
|
vTaskDelay( 20 );
|
|
setDioIrqEnabled( true );
|
|
}
|
|
|
|
void SX1280Hal::Wakeup( void )
|
|
{
|
|
setDioIrqEnabled( false );
|
|
|
|
//Don't wait for BUSY here
|
|
|
|
if( RadioSpi != NULL )
|
|
{
|
|
RadioSpi->take(100);
|
|
RadioNss->reset();
|
|
uint8_t txBuffer[2] = {RADIO_GET_STATUS, 0};
|
|
RadioSpi->transmit(txBuffer, 2);
|
|
RadioNss->set();
|
|
RadioSpi->give();
|
|
}
|
|
|
|
// Wait for chip to be ready.
|
|
WaitOnBusy( );
|
|
|
|
setDioIrqEnabled( true );
|
|
}
|
|
|
|
void SX1280Hal::WriteCommand( RadioCommands_t command, uint8_t *buffer, uint16_t size )
|
|
{
|
|
WaitOnBusy( );
|
|
|
|
if( RadioSpi != NULL )
|
|
{
|
|
RadioSpi->take(100);
|
|
RadioNss->reset();
|
|
uint8_t txBuffer[size+1];
|
|
txBuffer[0] = command;
|
|
memcpy(txBuffer+1, buffer, size);
|
|
RadioSpi->transmit(txBuffer, size+1);
|
|
RadioNss->set();
|
|
RadioSpi->give();
|
|
}
|
|
|
|
if( command != RADIO_SET_SLEEP )
|
|
{
|
|
WaitOnBusy( );
|
|
}
|
|
}
|
|
|
|
void SX1280Hal::ReadCommand( RadioCommands_t command, uint8_t *buffer, uint16_t size )
|
|
{
|
|
WaitOnBusy( );
|
|
|
|
if( RadioSpi != NULL )
|
|
{
|
|
RadioSpi->take(100);
|
|
RadioNss->reset();
|
|
if( command == RADIO_GET_STATUS )
|
|
{
|
|
uint8_t txBuffer[3] = {RADIO_GET_STATUS, 0, 0};
|
|
uint8_t rxBuffer[3];
|
|
RadioSpi->trx(txBuffer, rxBuffer, 3);
|
|
buffer[0] = rxBuffer[0];
|
|
}
|
|
else
|
|
{
|
|
uint8_t txBuffer[size+2];
|
|
uint8_t rxBuffer[size+2];
|
|
memset(txBuffer, 0, size+2);
|
|
txBuffer[0] = command;
|
|
RadioSpi->trx(txBuffer, rxBuffer, size+2);
|
|
memcpy(buffer, rxBuffer+2, size);
|
|
}
|
|
RadioNss->set();
|
|
RadioSpi->give();
|
|
}
|
|
|
|
WaitOnBusy( );
|
|
}
|
|
|
|
void SX1280Hal::WriteRegister( uint16_t address, uint8_t *buffer, uint16_t size )
|
|
{
|
|
WaitOnBusy( );
|
|
|
|
if( RadioSpi != NULL )
|
|
{
|
|
RadioSpi->take(100);
|
|
RadioNss->reset();
|
|
uint8_t txBuffer[size+3];
|
|
txBuffer[0] = RADIO_WRITE_REGISTER;
|
|
txBuffer[1] = ( address & 0xFF00 ) >> 8;
|
|
txBuffer[2] = address & 0x00FF;
|
|
memcpy(txBuffer+3, buffer, size);
|
|
RadioSpi->transmit(txBuffer, size+3);
|
|
RadioNss->set();
|
|
RadioSpi->give();
|
|
}
|
|
|
|
WaitOnBusy( );
|
|
}
|
|
|
|
void SX1280Hal::WriteRegister( uint16_t address, uint8_t value )
|
|
{
|
|
WriteRegister( address, &value, 1 );
|
|
}
|
|
|
|
void SX1280Hal::ReadRegister( uint16_t address, uint8_t *buffer, uint16_t size )
|
|
{
|
|
WaitOnBusy( );
|
|
|
|
if( RadioSpi != NULL )
|
|
{
|
|
RadioSpi->take(100);
|
|
RadioNss->reset();
|
|
uint8_t txBuffer[size+4];
|
|
uint8_t rxBuffer[size+4];
|
|
txBuffer[0] = RADIO_READ_REGISTER;
|
|
txBuffer[1] = ( address & 0xFF00 ) >> 8;
|
|
txBuffer[2] = address & 0x00FF;
|
|
memset(txBuffer+3, 0, size+1);
|
|
RadioSpi->trx(txBuffer, rxBuffer, size+4);
|
|
memcpy(buffer, rxBuffer+4, size);
|
|
RadioNss->set();
|
|
RadioSpi->give();
|
|
}
|
|
|
|
WaitOnBusy( );
|
|
}
|
|
|
|
uint8_t SX1280Hal::ReadRegister( uint16_t address )
|
|
{
|
|
uint8_t data;
|
|
|
|
ReadRegister( address, &data, 1 );
|
|
return data;
|
|
}
|
|
|
|
void SX1280Hal::WriteBuffer( uint8_t offset, uint8_t *buffer, uint8_t size )
|
|
{
|
|
WaitOnBusy( );
|
|
|
|
if( RadioSpi != NULL )
|
|
{
|
|
RadioSpi->take(100);
|
|
RadioNss->reset();
|
|
uint8_t txBuffer[size+2];
|
|
txBuffer[0] = RADIO_WRITE_BUFFER;
|
|
txBuffer[1] = offset;
|
|
memcpy(txBuffer+2, buffer, size);
|
|
RadioSpi->transmit(txBuffer, size+2);
|
|
RadioNss->set();
|
|
RadioSpi->give();
|
|
}
|
|
|
|
WaitOnBusy( );
|
|
}
|
|
|
|
void SX1280Hal::ReadBuffer( uint8_t offset, uint8_t *buffer, uint8_t size )
|
|
{
|
|
WaitOnBusy( );
|
|
|
|
if( RadioSpi != NULL )
|
|
{
|
|
RadioSpi->take(100);
|
|
RadioNss->reset();
|
|
uint8_t txBuffer[size+3];
|
|
uint8_t rxBuffer[size+3];
|
|
txBuffer[0] = RADIO_READ_BUFFER;
|
|
txBuffer[1] = offset;
|
|
memset(txBuffer+2, 0, size+1);
|
|
RadioSpi->trx(txBuffer, rxBuffer, size+3);
|
|
memcpy(buffer, rxBuffer+3, size);
|
|
RadioNss->set();
|
|
RadioSpi->give();
|
|
}
|
|
|
|
WaitOnBusy( );
|
|
}
|
|
|
|
uint8_t SX1280Hal::GetDioStatus( void )
|
|
{
|
|
uint8_t inter =0;
|
|
uint8_t retval = 0;
|
|
DIO1->read(&retval);
|
|
retval = retval<<1;
|
|
BUSY->read(&inter);
|
|
retval += inter;
|
|
return retval;
|
|
}
|