blob: 5e28d17a6ec8fe35df17f3b17c86f010ffbc2bdb [file] [log] [blame]
/*
/ _____) _ | |
( (____ _____ ____ _| |_ _____ ____| |__
\____ \| ___ | (_ _) ___ |/ ___) _ \
_____) ) ____| | | || |_| ____( (___| | | |
(______/|_____)_|_|_| \__)_____)\____)_| |_|
(C)2013 Semtech
Description: SX1276 driver specific target board functions implementation
License: Revised BSD License, see LICENSE.TXT file include in the project
Maintainer: Miguel Luis and Gregory Cristian
*/
#include <assert.h>
#include "hal/hal_spi.h"
#include "bsp/bsp.h"
#include "radio/radio.h"
#include "sx1276.h"
#include "sx1276-board.h"
extern DioIrqHandler *DioIrq[];
#if MYNEWT_VAL(SX1276_HAS_ANT_SW)
/*!
* Flag used to set the RF switch control pins in low power mode when the radio is not active.
*/
static bool RadioIsActive = false;
#endif
/*!
* Radio driver structure initialization
*/
const struct Radio_s Radio =
{
.Init = SX1276Init,
.GetStatus = SX1276GetStatus,
.SetModem = SX1276SetModem,
.SetChannel = SX1276SetChannel,
.IsChannelFree = SX1276IsChannelFree,
.Random = SX1276Random,
.SetRxConfig = SX1276SetRxConfig,
.SetTxConfig = SX1276SetTxConfig,
.CheckRfFrequency = SX1276CheckRfFrequency,
.TimeOnAir = SX1276GetTimeOnAir,
.Send = SX1276Send,
.Sleep = SX1276SetSleep,
.Standby = SX1276SetStby,
.Rx = SX1276SetRx,
.StartCad = SX1276StartCad,
.Rssi = SX1276ReadRssi,
.Write = SX1276Write,
.Read = SX1276Read,
.WriteBuffer = SX1276WriteBuffer,
.ReadBuffer = SX1276ReadBuffer,
.SetMaxPayloadLength = SX1276SetMaxPayloadLength,
.SetPublicNetwork = SX1276SetPublicNetwork,
.GetWakeupTime = SX1276GetWakeupTime,
.RxDisable = SX1276RxDisable
};
void
SX1276IoInit(void)
{
struct hal_spi_settings spi_settings;
int rc;
#if MYNEWT_VAL(SX1276_HAS_ANT_SW)
rc = hal_gpio_init_out(SX1276_RXTX, 0);
assert(rc == 0);
#endif
rc = hal_gpio_init_out(RADIO_NSS, 1);
assert(rc == 0);
hal_spi_disable(RADIO_SPI_IDX);
spi_settings.data_order = HAL_SPI_MSB_FIRST;
spi_settings.data_mode = HAL_SPI_MODE0;
spi_settings.baudrate = MYNEWT_VAL(SX1276_SPI_BAUDRATE);
spi_settings.word_size = HAL_SPI_WORD_SIZE_8BIT;
rc = hal_spi_config(RADIO_SPI_IDX, &spi_settings);
assert(rc == 0);
rc = hal_spi_enable(RADIO_SPI_IDX);
assert(rc == 0);
}
void
SX1276IoIrqInit(DioIrqHandler **irqHandlers)
{
int rc;
if (irqHandlers[0] != NULL) {
rc = hal_gpio_irq_init(SX1276_DIO0, irqHandlers[0], NULL,
HAL_GPIO_TRIG_RISING, HAL_GPIO_PULL_NONE);
assert(rc == 0);
hal_gpio_irq_enable(SX1276_DIO0);
}
if (irqHandlers[1] != NULL) {
rc = hal_gpio_irq_init(SX1276_DIO1, irqHandlers[1], NULL,
HAL_GPIO_TRIG_RISING, HAL_GPIO_PULL_NONE);
assert(rc == 0);
hal_gpio_irq_enable(SX1276_DIO1);
}
if (irqHandlers[2] != NULL) {
rc = hal_gpio_irq_init(SX1276_DIO2, irqHandlers[2], NULL,
HAL_GPIO_TRIG_RISING, HAL_GPIO_PULL_NONE);
assert(rc == 0);
hal_gpio_irq_enable(SX1276_DIO2);
}
if (irqHandlers[3] != NULL) {
rc = hal_gpio_irq_init(SX1276_DIO3, irqHandlers[3], NULL,
HAL_GPIO_TRIG_RISING, HAL_GPIO_PULL_NONE);
assert(rc == 0);
hal_gpio_irq_enable(SX1276_DIO3);
}
if (irqHandlers[4] != NULL) {
rc = hal_gpio_irq_init(SX1276_DIO4, irqHandlers[4], NULL,
HAL_GPIO_TRIG_RISING, HAL_GPIO_PULL_NONE);
assert(rc == 0);
hal_gpio_irq_enable(SX1276_DIO4);
}
if (irqHandlers[5] != NULL) {
rc = hal_gpio_irq_init(SX1276_DIO5, irqHandlers[5], NULL,
HAL_GPIO_TRIG_RISING, HAL_GPIO_PULL_NONE);
assert(rc == 0);
hal_gpio_irq_enable(SX1276_DIO5);
}
}
void
SX1276IoDeInit( void )
{
if (DioIrq[0] != NULL) {
hal_gpio_irq_release(SX1276_DIO0);
}
if (DioIrq[1] != NULL) {
hal_gpio_irq_release(SX1276_DIO1);
}
if (DioIrq[2] != NULL) {
hal_gpio_irq_release(SX1276_DIO2);
}
if (DioIrq[3] != NULL) {
hal_gpio_irq_release(SX1276_DIO3);
}
if (DioIrq[4] != NULL) {
hal_gpio_irq_release(SX1276_DIO4);
}
if (DioIrq[5] != NULL) {
hal_gpio_irq_release(SX1276_DIO5);
}
}
uint8_t
SX1276GetPaSelect(uint32_t channel)
{
uint8_t pacfg;
if (channel < RF_MID_BAND_THRESH) {
#if (MYNEWT_VAL(SX1276_LF_USE_PA_BOOST) == 1)
pacfg = RF_PACONFIG_PASELECT_PABOOST;
#else
pacfg = RF_PACONFIG_PASELECT_RFO;
#endif
} else {
#if (MYNEWT_VAL(SX1276_HF_USE_PA_BOOST) == 1)
pacfg = RF_PACONFIG_PASELECT_PABOOST;
#else
pacfg = RF_PACONFIG_PASELECT_RFO;
#endif
}
return pacfg;
}
#if MYNEWT_VAL(SX1276_HAS_ANT_SW)
void SX1276SetAntSwLowPower( bool status )
{
if (RadioIsActive != status) {
RadioIsActive = status;
if (status == false) {
SX1276AntSwInit( );
} else {
SX1276AntSwDeInit( );
}
}
}
void
SX1276AntSwInit(void)
{
// Consider turning off GPIO pins for low power. They are always on right
// now. GPIOTE library uses 0.5uA max when on, typical 0.1uA.
}
void
SX1276AntSwDeInit(void)
{
// Consider this for low power - ie turning off GPIO pins
}
void
SX1276SetAntSw(uint8_t rxTx)
{
// 1: TX, 0: RX
if (rxTx != 0) {
hal_gpio_write(SX1276_RXTX, 1);
} else {
hal_gpio_write(SX1276_RXTX, 0);
}
}
#endif
bool
SX1276CheckRfFrequency(uint32_t frequency)
{
// Implement check. Currently all frequencies are supported
return true;
}
uint32_t
SX1276GetBoardTcxoWakeupTime(void)
{
return 0;
}
void
SX1276RxIoIrqDisable(void)
{
hal_gpio_irq_disable(SX1276_DIO0);
hal_gpio_irq_disable(SX1276_DIO1);
hal_gpio_irq_disable(SX1276_DIO2);
hal_gpio_irq_disable(SX1276_DIO3);
}
void
SX1276RxIoIrqEnable(void)
{
hal_gpio_irq_enable(SX1276_DIO0);
hal_gpio_irq_enable(SX1276_DIO1);
hal_gpio_irq_enable(SX1276_DIO2);
hal_gpio_irq_enable(SX1276_DIO3);
}