feat(llcc68): add configurable RF switch modes
Add an explicit rf-switch-mode devicetree property for LLCC68 instances, covering no switch handling, TXEN/RXEN complementary GPIO control, and DIO2 single-pin control for PE4259-style RF switches. Preserve the existing default behavior with an auto Kconfig default that only enables complementary GPIO handling when both TXEN and RXEN GPIOs are present. Resolve the RF switch mode into llcc68_config at build time and validate incompatible devicetree combinations with BUILD_ASSERT checks. Configure optional RXEN GPIO handling for DIO2 single-pin mode and keep DIO2 RF switch control disabled unless that mode is selected. Replace the old fire-and-forget TX/RX GPIO helper with a result-returning mode-aware RF switch state helper, and apply it across standby, sleep, CAD, TX, RX, continuous wave, infinite preamble, and modem init paths. Add SetRxDutyCycle support with explicit raw 24-bit LLCC68 period units, plus helpers and a millisecond wrapper for callers that work in time units. Select the RX RF path before issuing the duty-cycle command so RXEN stays valid for duty-cycle listen windows.
This commit is contained in:
@@ -1,10 +1,30 @@
|
||||
#include "llcc68_raw.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <zephyr/devicetree.h>
|
||||
#include <zephyr/sys/util.h>
|
||||
|
||||
#define DT_DRV_COMPAT semtech_llcc68_weihua
|
||||
|
||||
#define LLCC68_AUTO_RF_SWITCH_MODE(inst) \
|
||||
COND_CODE_1(DT_INST_NODE_HAS_PROP(inst, tx_enable_gpios), \
|
||||
(COND_CODE_1(DT_INST_NODE_HAS_PROP(inst, rx_enable_gpios), \
|
||||
(LLCC68_RF_SWITCH_GPIO_COMPLEMENTARY), (LLCC68_RF_SWITCH_NONE))), \
|
||||
(LLCC68_RF_SWITCH_NONE))
|
||||
|
||||
#if defined(CONFIG_LLCC68_RF_SWITCH_DEFAULT_GPIO_COMPLEMENTARY)
|
||||
#define LLCC68_DEFAULT_RF_SWITCH_MODE(inst) LLCC68_RF_SWITCH_GPIO_COMPLEMENTARY
|
||||
#elif defined(CONFIG_LLCC68_RF_SWITCH_DEFAULT_DIO2_SINGLE)
|
||||
#define LLCC68_DEFAULT_RF_SWITCH_MODE(inst) LLCC68_RF_SWITCH_DIO2_SINGLE
|
||||
#elif defined(CONFIG_LLCC68_RF_SWITCH_DEFAULT_NONE)
|
||||
#define LLCC68_DEFAULT_RF_SWITCH_MODE(inst) LLCC68_RF_SWITCH_NONE
|
||||
#else
|
||||
#define LLCC68_DEFAULT_RF_SWITCH_MODE(inst) LLCC68_AUTO_RF_SWITCH_MODE(inst)
|
||||
#endif
|
||||
|
||||
#define LLCC68_RF_SWITCH_MODE(inst) \
|
||||
DT_ENUM_IDX_OR(DT_DRV_INST(inst), rf_switch_mode, LLCC68_DEFAULT_RF_SWITCH_MODE(inst))
|
||||
|
||||
static void dio1_irq_trampoline(const struct device *port, struct gpio_callback *cb, uint32_t pins) {
|
||||
ARG_UNUSED(port);
|
||||
|
||||
@@ -20,14 +40,21 @@ int llcc68_init(const struct device *dev) {
|
||||
const struct llcc68_config *config = dev->config;
|
||||
struct llcc68_data *data = dev->data;
|
||||
|
||||
if (config->tx_enable_gpio.port != NULL) {
|
||||
if (config->rf_switch_mode == LLCC68_RF_SWITCH_GPIO_COMPLEMENTARY &&
|
||||
config->tx_enable_gpio.port != NULL) {
|
||||
gpio_pin_configure_dt(&config->tx_enable_gpio, GPIO_OUTPUT_INACTIVE);
|
||||
}
|
||||
|
||||
if (config->rx_enable_gpio.port != NULL) {
|
||||
if (config->rf_switch_mode == LLCC68_RF_SWITCH_GPIO_COMPLEMENTARY &&
|
||||
config->rx_enable_gpio.port != NULL) {
|
||||
gpio_pin_configure_dt(&config->rx_enable_gpio, GPIO_OUTPUT_INACTIVE);
|
||||
}
|
||||
|
||||
if (config->rf_switch_mode == LLCC68_RF_SWITCH_DIO2_SINGLE &&
|
||||
config->rx_enable_gpio.port != NULL) {
|
||||
gpio_pin_configure_dt(&config->rx_enable_gpio, GPIO_OUTPUT_ACTIVE);
|
||||
}
|
||||
|
||||
gpio_pin_configure_dt(&config->reset_gpio, GPIO_OUTPUT_INACTIVE);
|
||||
gpio_pin_configure_dt(&config->busy_gpio, GPIO_INPUT);
|
||||
gpio_pin_configure_dt(&config->dio1_gpio, GPIO_INPUT);
|
||||
@@ -43,6 +70,15 @@ int llcc68_init(const struct device *dev) {
|
||||
}
|
||||
|
||||
#define LLCC68_DEFINE(inst) \
|
||||
BUILD_ASSERT(LLCC68_RF_SWITCH_MODE(inst) != LLCC68_RF_SWITCH_GPIO_COMPLEMENTARY || \
|
||||
(DT_INST_NODE_HAS_PROP(inst, tx_enable_gpios) && \
|
||||
DT_INST_NODE_HAS_PROP(inst, rx_enable_gpios)), \
|
||||
"LLCC68 gpio-complementary RF switch mode requires tx-enable-gpios " \
|
||||
"and rx-enable-gpios"); \
|
||||
BUILD_ASSERT(LLCC68_RF_SWITCH_MODE(inst) != LLCC68_RF_SWITCH_DIO2_SINGLE || \
|
||||
!DT_INST_NODE_HAS_PROP(inst, tx_enable_gpios), \
|
||||
"LLCC68 dio2-single RF switch mode uses DIO2 for TXEN and must not " \
|
||||
"define tx-enable-gpios"); \
|
||||
static struct llcc68_data llcc68_data_##inst; \
|
||||
static const struct llcc68_config llcc68_config_##inst = \
|
||||
{ \
|
||||
@@ -52,6 +88,7 @@ int llcc68_init(const struct device *dev) {
|
||||
.dio1_gpio = GPIO_DT_SPEC_INST_GET(inst, dio1_gpios), \
|
||||
.tx_enable_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, tx_enable_gpios, {.port = NULL}), \
|
||||
.rx_enable_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, rx_enable_gpios, {.port = NULL}), \
|
||||
.rf_switch_mode = LLCC68_RF_SWITCH_MODE(inst), \
|
||||
}; \
|
||||
DEVICE_DT_INST_DEFINE(inst, \
|
||||
llcc68_init, \
|
||||
|
||||
Reference in New Issue
Block a user