drivers: sx126x: refactor few functions for stm32wl support
Move few functions around in preparation of adding the STM32WL variant of the driver. Signed-off-by: Fabio Baltieri <fabio.baltieri@gmail.com>
This commit is contained in:
parent
624886156a
commit
74efaa920a
4 changed files with 167 additions and 74 deletions
|
|
@ -14,3 +14,4 @@ zephyr_library_sources_ifdef(CONFIG_HAS_SEMTECH_RADIO_DRIVERS hal_common.c)
|
||||||
zephyr_library_sources_ifdef(CONFIG_HAS_SEMTECH_RADIO_DRIVERS sx12xx_common.c)
|
zephyr_library_sources_ifdef(CONFIG_HAS_SEMTECH_RADIO_DRIVERS sx12xx_common.c)
|
||||||
zephyr_library_sources_ifdef(CONFIG_LORA_SX127X sx127x.c)
|
zephyr_library_sources_ifdef(CONFIG_LORA_SX127X sx127x.c)
|
||||||
zephyr_library_sources_ifdef(CONFIG_LORA_SX126X sx126x.c)
|
zephyr_library_sources_ifdef(CONFIG_LORA_SX126X sx126x.c)
|
||||||
|
zephyr_library_sources_ifdef(CONFIG_LORA_SX126X sx126x_standalone.c)
|
||||||
|
|
|
||||||
|
|
@ -13,41 +13,15 @@
|
||||||
#include <sx126x/sx126x.h>
|
#include <sx126x/sx126x.h>
|
||||||
|
|
||||||
#include "sx12xx_common.h"
|
#include "sx12xx_common.h"
|
||||||
|
#include "sx126x_common.h"
|
||||||
|
|
||||||
#include <logging/log.h>
|
#include <logging/log.h>
|
||||||
LOG_MODULE_REGISTER(sx126x, CONFIG_LORA_LOG_LEVEL);
|
LOG_MODULE_REGISTER(sx126x, CONFIG_LORA_LOG_LEVEL);
|
||||||
|
|
||||||
#if DT_HAS_COMPAT_STATUS_OKAY(semtech_sx1261)
|
|
||||||
#define DT_DRV_COMPAT semtech_sx1261
|
|
||||||
#define SX126X_DEVICE_ID SX1261
|
|
||||||
#elif DT_HAS_COMPAT_STATUS_OKAY(semtech_sx1262)
|
|
||||||
#define DT_DRV_COMPAT semtech_sx1262
|
|
||||||
#define SX126X_DEVICE_ID SX1262
|
|
||||||
#else
|
|
||||||
#error No SX126x instance in device tree.
|
|
||||||
#endif
|
|
||||||
|
|
||||||
BUILD_ASSERT(DT_NUM_INST_STATUS_OKAY(semtech_sx1261) +
|
BUILD_ASSERT(DT_NUM_INST_STATUS_OKAY(semtech_sx1261) +
|
||||||
DT_NUM_INST_STATUS_OKAY(semtech_sx1262) <= 1,
|
DT_NUM_INST_STATUS_OKAY(semtech_sx1262) <= 1,
|
||||||
"Multiple SX126x instances in DT");
|
"Multiple SX126x instances in DT");
|
||||||
|
|
||||||
#define HAVE_GPIO_CS DT_INST_SPI_DEV_HAS_CS_GPIOS(0)
|
|
||||||
#define HAVE_GPIO_ANTENNA_ENABLE \
|
|
||||||
DT_INST_NODE_HAS_PROP(0, antenna_enable_gpios)
|
|
||||||
#define HAVE_GPIO_TX_ENABLE DT_INST_NODE_HAS_PROP(0, tx_enable_gpios)
|
|
||||||
#define HAVE_GPIO_RX_ENABLE DT_INST_NODE_HAS_PROP(0, rx_enable_gpios)
|
|
||||||
|
|
||||||
#define GPIO_CS_LABEL DT_INST_SPI_DEV_CS_GPIOS_LABEL(0)
|
|
||||||
#define GPIO_CS_PIN DT_INST_SPI_DEV_CS_GPIOS_PIN(0)
|
|
||||||
#define GPIO_CS_FLAGS DT_INST_SPI_DEV_CS_GPIOS_FLAGS(0)
|
|
||||||
|
|
||||||
#define GPIO_RESET_PIN DT_INST_GPIO_PIN(0, reset_gpios)
|
|
||||||
#define GPIO_BUSY_PIN DT_INST_GPIO_PIN(0, busy_gpios)
|
|
||||||
#define GPIO_DIO1_PIN DT_INST_GPIO_PIN(0, dio1_gpios)
|
|
||||||
#define GPIO_ANTENNA_ENABLE_PIN DT_INST_GPIO_PIN(0, antenna_enable_gpios)
|
|
||||||
#define GPIO_TX_ENABLE_PIN DT_INST_GPIO_PIN(0, tx_enable_gpios)
|
|
||||||
#define GPIO_RX_ENABLE_PIN DT_INST_GPIO_PIN(0, rx_enable_gpios)
|
|
||||||
|
|
||||||
#define DIO2_TX_ENABLE DT_INST_PROP(0, dio2_tx_enable)
|
#define DIO2_TX_ENABLE DT_INST_PROP(0, dio2_tx_enable)
|
||||||
|
|
||||||
#define HAVE_DIO3_TCXO DT_INST_NODE_HAS_PROP(0, dio3_tcxo_voltage)
|
#define HAVE_DIO3_TCXO DT_INST_NODE_HAS_PROP(0, dio3_tcxo_voltage)
|
||||||
|
|
@ -64,30 +38,7 @@ BUILD_ASSERT(DT_NUM_INST_STATUS_OKAY(semtech_sx1261) +
|
||||||
|
|
||||||
#define SX126X_CALIBRATION_ALL 0x7f
|
#define SX126X_CALIBRATION_ALL 0x7f
|
||||||
|
|
||||||
struct sx126x_data {
|
static struct sx126x_data dev_data;
|
||||||
const struct device *reset;
|
|
||||||
const struct device *busy;
|
|
||||||
const struct device *dio1;
|
|
||||||
struct gpio_callback dio1_irq_callback;
|
|
||||||
struct k_work dio1_irq_work;
|
|
||||||
DioIrqHandler *radio_dio_irq;
|
|
||||||
#if HAVE_GPIO_ANTENNA_ENABLE
|
|
||||||
const struct device *antenna_enable;
|
|
||||||
#endif
|
|
||||||
#if HAVE_GPIO_TX_ENABLE
|
|
||||||
const struct device *tx_enable;
|
|
||||||
#endif
|
|
||||||
#if HAVE_GPIO_RX_ENABLE
|
|
||||||
const struct device *rx_enable;
|
|
||||||
#endif
|
|
||||||
const struct device *spi;
|
|
||||||
struct spi_config spi_cfg;
|
|
||||||
#if HAVE_GPIO_CS
|
|
||||||
struct spi_cs_control spi_cs;
|
|
||||||
#endif
|
|
||||||
RadioOperatingModes_t mode;
|
|
||||||
} dev_data;
|
|
||||||
|
|
||||||
|
|
||||||
void SX126xWaitOnBusy(void);
|
void SX126xWaitOnBusy(void);
|
||||||
|
|
||||||
|
|
@ -333,8 +284,7 @@ void SX126xSetOperatingMode(RadioOperatingModes_t mode)
|
||||||
|
|
||||||
case MODE_SLEEP:
|
case MODE_SLEEP:
|
||||||
/* Additionally disable the DIO1 interrupt to save power */
|
/* Additionally disable the DIO1 interrupt to save power */
|
||||||
gpio_pin_interrupt_configure(dev_data.dio1, GPIO_DIO1_PIN,
|
sx126x_dio1_irq_disable(&dev_data);
|
||||||
GPIO_INT_DISABLE);
|
|
||||||
__fallthrough;
|
__fallthrough;
|
||||||
default:
|
default:
|
||||||
sx126x_set_rx_enable(0);
|
sx126x_set_rx_enable(0);
|
||||||
|
|
@ -386,10 +336,9 @@ void SX126xIoRfSwitchInit(void)
|
||||||
void SX126xReset(void)
|
void SX126xReset(void)
|
||||||
{
|
{
|
||||||
LOG_DBG("Resetting radio");
|
LOG_DBG("Resetting radio");
|
||||||
gpio_pin_set(dev_data.reset, GPIO_RESET_PIN, 1);
|
|
||||||
k_sleep(K_MSEC(20));
|
sx126x_reset(&dev_data);
|
||||||
gpio_pin_set(dev_data.reset, GPIO_RESET_PIN, 0);
|
|
||||||
k_sleep(K_MSEC(10));
|
|
||||||
/* Device transitions to standby on reset */
|
/* Device transitions to standby on reset */
|
||||||
dev_data.mode = MODE_STDBY_RC;
|
dev_data.mode = MODE_STDBY_RC;
|
||||||
}
|
}
|
||||||
|
|
@ -402,7 +351,7 @@ void SX126xSetRfTxPower(int8_t power)
|
||||||
|
|
||||||
void SX126xWaitOnBusy(void)
|
void SX126xWaitOnBusy(void)
|
||||||
{
|
{
|
||||||
while (gpio_pin_get(dev_data.busy, GPIO_BUSY_PIN)) {
|
while (sx126x_is_busy(&dev_data)) {
|
||||||
k_sleep(K_MSEC(1));
|
k_sleep(K_MSEC(1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -412,8 +361,7 @@ void SX126xWakeup(void)
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/* Reenable DIO1 when waking up */
|
/* Reenable DIO1 when waking up */
|
||||||
gpio_pin_interrupt_configure(dev_data.dio1, GPIO_DIO1_PIN,
|
sx126x_dio1_irq_enable(&dev_data);
|
||||||
GPIO_INT_EDGE_TO_ACTIVE);
|
|
||||||
|
|
||||||
uint8_t req[] = { RADIO_GET_STATUS, 0 };
|
uint8_t req[] = { RADIO_GET_STATUS, 0 };
|
||||||
const struct spi_buf tx_buf = {
|
const struct spi_buf tx_buf = {
|
||||||
|
|
@ -445,7 +393,7 @@ void SX126xWakeup(void)
|
||||||
|
|
||||||
uint32_t SX126xGetDio1PinState(void)
|
uint32_t SX126xGetDio1PinState(void)
|
||||||
{
|
{
|
||||||
return gpio_pin_get(dev_data.dio1, GPIO_DIO1_PIN) > 0 ? 1U : 0U;
|
return sx126x_get_dio1_pin_state(&dev_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sx126x_dio1_irq_work_handler(struct k_work *work)
|
static void sx126x_dio1_irq_work_handler(struct k_work *work)
|
||||||
|
|
@ -460,14 +408,8 @@ static void sx126x_dio1_irq_work_handler(struct k_work *work)
|
||||||
if (Radio.IrqProcess) {
|
if (Radio.IrqProcess) {
|
||||||
Radio.IrqProcess();
|
Radio.IrqProcess();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
static void sx126x_dio1_irq_callback(const struct device *dev,
|
sx126x_dio1_irq_enable(&dev_data);
|
||||||
struct gpio_callback *cb, uint32_t pins)
|
|
||||||
{
|
|
||||||
if (pins & BIT(GPIO_DIO1_PIN)) {
|
|
||||||
k_work_submit(&dev_data.dio1_irq_work);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sx126x_lora_init(const struct device *dev)
|
static int sx126x_lora_init(const struct device *dev)
|
||||||
|
|
@ -487,11 +429,10 @@ static int sx126x_lora_init(const struct device *dev)
|
||||||
|
|
||||||
k_work_init(&dev_data.dio1_irq_work, sx126x_dio1_irq_work_handler);
|
k_work_init(&dev_data.dio1_irq_work, sx126x_dio1_irq_work_handler);
|
||||||
|
|
||||||
gpio_init_callback(&dev_data.dio1_irq_callback,
|
ret = sx126x_variant_init(dev);
|
||||||
sx126x_dio1_irq_callback, BIT(GPIO_DIO1_PIN));
|
if (ret) {
|
||||||
if (gpio_add_callback(dev_data.dio1, &dev_data.dio1_irq_callback) < 0) {
|
LOG_ERR("Variant initialization failed");
|
||||||
LOG_ERR("Could not set GPIO callback for DIO1 interrupt.");
|
return ret;
|
||||||
return -EIO;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dev_data.spi = device_get_binding(DT_INST_BUS_LABEL(0));
|
dev_data.spi = device_get_binding(DT_INST_BUS_LABEL(0));
|
||||||
|
|
@ -535,6 +476,6 @@ static const struct lora_driver_api sx126x_lora_api = {
|
||||||
.test_cw = sx12xx_lora_test_cw,
|
.test_cw = sx12xx_lora_test_cw,
|
||||||
};
|
};
|
||||||
|
|
||||||
DEVICE_DT_INST_DEFINE(0, &sx126x_lora_init, NULL, NULL,
|
DEVICE_DT_INST_DEFINE(0, &sx126x_lora_init, NULL, &dev_data,
|
||||||
NULL, POST_KERNEL, CONFIG_LORA_INIT_PRIORITY,
|
NULL, POST_KERNEL, CONFIG_LORA_INIT_PRIORITY,
|
||||||
&sx126x_lora_api);
|
&sx126x_lora_api);
|
||||||
|
|
|
||||||
79
drivers/lora/sx126x_common.h
Normal file
79
drivers/lora/sx126x_common.h
Normal file
|
|
@ -0,0 +1,79 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2019 Manivannan Sadhasivam
|
||||||
|
* Copyright (c) 2020 Andreas Sandberg
|
||||||
|
* Copyright (c) 2021 Fabio Baltieri
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ZEPHYR_DRIVERS_SX126X_COMMON_H_
|
||||||
|
#define ZEPHYR_DRIVERS_SX126X_COMMON_H_
|
||||||
|
|
||||||
|
#include <zephyr/types.h>
|
||||||
|
#include <drivers/gpio.h>
|
||||||
|
#include <drivers/lora.h>
|
||||||
|
#include <drivers/spi.h>
|
||||||
|
|
||||||
|
#include <sx126x/sx126x.h>
|
||||||
|
|
||||||
|
#if DT_HAS_COMPAT_STATUS_OKAY(semtech_sx1261)
|
||||||
|
#define DT_DRV_COMPAT semtech_sx1261
|
||||||
|
#define SX126X_DEVICE_ID SX1261
|
||||||
|
#elif DT_HAS_COMPAT_STATUS_OKAY(semtech_sx1262)
|
||||||
|
#define DT_DRV_COMPAT semtech_sx1262
|
||||||
|
#define SX126X_DEVICE_ID SX1262
|
||||||
|
#else
|
||||||
|
#error No SX126x instance in device tree.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define HAVE_GPIO_CS DT_INST_SPI_DEV_HAS_CS_GPIOS(0)
|
||||||
|
#define HAVE_GPIO_ANTENNA_ENABLE \
|
||||||
|
DT_INST_NODE_HAS_PROP(0, antenna_enable_gpios)
|
||||||
|
#define HAVE_GPIO_TX_ENABLE DT_INST_NODE_HAS_PROP(0, tx_enable_gpios)
|
||||||
|
#define HAVE_GPIO_RX_ENABLE DT_INST_NODE_HAS_PROP(0, rx_enable_gpios)
|
||||||
|
|
||||||
|
#define GPIO_CS_LABEL DT_INST_SPI_DEV_CS_GPIOS_LABEL(0)
|
||||||
|
#define GPIO_CS_PIN DT_INST_SPI_DEV_CS_GPIOS_PIN(0)
|
||||||
|
#define GPIO_CS_FLAGS DT_INST_SPI_DEV_CS_GPIOS_FLAGS(0)
|
||||||
|
|
||||||
|
#define GPIO_ANTENNA_ENABLE_PIN DT_INST_GPIO_PIN(0, antenna_enable_gpios)
|
||||||
|
#define GPIO_TX_ENABLE_PIN DT_INST_GPIO_PIN(0, tx_enable_gpios)
|
||||||
|
#define GPIO_RX_ENABLE_PIN DT_INST_GPIO_PIN(0, rx_enable_gpios)
|
||||||
|
|
||||||
|
struct sx126x_data {
|
||||||
|
const struct device *reset;
|
||||||
|
const struct device *busy;
|
||||||
|
const struct device *dio1;
|
||||||
|
struct gpio_callback dio1_irq_callback;
|
||||||
|
struct k_work dio1_irq_work;
|
||||||
|
DioIrqHandler *radio_dio_irq;
|
||||||
|
#if HAVE_GPIO_ANTENNA_ENABLE
|
||||||
|
const struct device *antenna_enable;
|
||||||
|
#endif
|
||||||
|
#if HAVE_GPIO_TX_ENABLE
|
||||||
|
const struct device *tx_enable;
|
||||||
|
#endif
|
||||||
|
#if HAVE_GPIO_RX_ENABLE
|
||||||
|
const struct device *rx_enable;
|
||||||
|
#endif
|
||||||
|
const struct device *spi;
|
||||||
|
struct spi_config spi_cfg;
|
||||||
|
#if HAVE_GPIO_CS
|
||||||
|
struct spi_cs_control spi_cs;
|
||||||
|
#endif
|
||||||
|
RadioOperatingModes_t mode;
|
||||||
|
};
|
||||||
|
|
||||||
|
void sx126x_reset(struct sx126x_data *dev_data);
|
||||||
|
|
||||||
|
bool sx126x_is_busy(struct sx126x_data *dev_data);
|
||||||
|
|
||||||
|
uint32_t sx126x_get_dio1_pin_state(struct sx126x_data *dev_data);
|
||||||
|
|
||||||
|
void sx126x_dio1_irq_enable(struct sx126x_data *dev_data);
|
||||||
|
|
||||||
|
void sx126x_dio1_irq_disable(struct sx126x_data *dev_data);
|
||||||
|
|
||||||
|
int sx126x_variant_init(const struct device *dev);
|
||||||
|
|
||||||
|
#endif /* ZEPHYR_DRIVERS_SX126X_COMMON_H_ */
|
||||||
72
drivers/lora/sx126x_standalone.c
Normal file
72
drivers/lora/sx126x_standalone.c
Normal file
|
|
@ -0,0 +1,72 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2019 Manivannan Sadhasivam
|
||||||
|
* Copyright (c) 2020 Andreas Sandberg
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <drivers/gpio.h>
|
||||||
|
#include <zephyr.h>
|
||||||
|
|
||||||
|
#include "sx126x_common.h"
|
||||||
|
|
||||||
|
#include <logging/log.h>
|
||||||
|
LOG_MODULE_DECLARE(sx126x, CONFIG_LORA_LOG_LEVEL);
|
||||||
|
|
||||||
|
#define GPIO_RESET_PIN DT_INST_GPIO_PIN(0, reset_gpios)
|
||||||
|
#define GPIO_BUSY_PIN DT_INST_GPIO_PIN(0, busy_gpios)
|
||||||
|
#define GPIO_DIO1_PIN DT_INST_GPIO_PIN(0, dio1_gpios)
|
||||||
|
|
||||||
|
void sx126x_reset(struct sx126x_data *dev_data)
|
||||||
|
{
|
||||||
|
gpio_pin_set(dev_data->reset, GPIO_RESET_PIN, 1);
|
||||||
|
k_sleep(K_MSEC(20));
|
||||||
|
gpio_pin_set(dev_data->reset, GPIO_RESET_PIN, 0);
|
||||||
|
k_sleep(K_MSEC(10));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool sx126x_is_busy(struct sx126x_data *dev_data)
|
||||||
|
{
|
||||||
|
return gpio_pin_get(dev_data->busy, GPIO_BUSY_PIN);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t sx126x_get_dio1_pin_state(struct sx126x_data *dev_data)
|
||||||
|
{
|
||||||
|
return gpio_pin_get(dev_data->dio1, GPIO_DIO1_PIN) > 0 ? 1U : 0U;
|
||||||
|
}
|
||||||
|
|
||||||
|
void sx126x_dio1_irq_enable(struct sx126x_data *dev_data)
|
||||||
|
{
|
||||||
|
gpio_pin_interrupt_configure(dev_data->dio1, GPIO_DIO1_PIN,
|
||||||
|
GPIO_INT_EDGE_TO_ACTIVE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sx126x_dio1_irq_disable(struct sx126x_data *dev_data)
|
||||||
|
{
|
||||||
|
gpio_pin_interrupt_configure(dev_data->dio1, GPIO_DIO1_PIN,
|
||||||
|
GPIO_INT_DISABLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void sx126x_dio1_irq_callback(const struct device *dev,
|
||||||
|
struct gpio_callback *cb, uint32_t pins)
|
||||||
|
{
|
||||||
|
struct sx126x_data *dev_data = dev->data;
|
||||||
|
|
||||||
|
if (pins & BIT(GPIO_DIO1_PIN)) {
|
||||||
|
k_work_submit(&dev_data->dio1_irq_work);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int sx126x_variant_init(const struct device *dev)
|
||||||
|
{
|
||||||
|
struct sx126x_data *dev_data = dev->data;
|
||||||
|
|
||||||
|
gpio_init_callback(&dev_data->dio1_irq_callback,
|
||||||
|
sx126x_dio1_irq_callback, BIT(GPIO_DIO1_PIN));
|
||||||
|
if (gpio_add_callback(dev_data->dio1, &dev_data->dio1_irq_callback) < 0) {
|
||||||
|
LOG_ERR("Could not set GPIO callback for DIO1 interrupt.");
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue