diff --git a/drivers/include/sx126x.h b/drivers/include/sx126x.h index 2a61318af3..df153bffae 100644 --- a/drivers/include/sx126x.h +++ b/drivers/include/sx126x.h @@ -32,6 +32,27 @@ extern "C" { #endif +/** + * @brief Whether there's only one variant of this driver at compile time or + * not. + */ +#define SX126X_SINGLE (( \ + IS_USED(MODULE_SX1261) \ + + IS_USED(MODULE_SX1262) \ + + IS_USED(MODULE_SX1268) \ + + IS_USED(MODULE_LLCC68) \ + ) == 1) + +/** + * @brief Variant of the SX126x driver. + */ +typedef enum { + SX126X_TYPE_SX1261, + SX126X_TYPE_SX1262, + SX126X_TYPE_SX1268, + SX126X_TYPE_LLCC68, +} sx126x_type_t; + /** * @brief Device initialization parameters */ @@ -42,6 +63,7 @@ typedef struct { gpio_t busy_pin; /**< Busy pin */ gpio_t dio1_pin; /**< Dio1 pin */ sx126x_reg_mod_t regulator; /**< Power regulator mode */ + sx126x_type_t type; /**< Variant of sx126x */ } sx126x_params_t; /** diff --git a/drivers/sx126x/Kconfig b/drivers/sx126x/Kconfig index f682c31920..913da7bc06 100644 --- a/drivers/sx126x/Kconfig +++ b/drivers/sx126x/Kconfig @@ -1,14 +1,44 @@ # Copyright (c) 2021 Inria +# Copyright (c) 2021 HAW Hamburg # # This file is subject to the terms and conditions of the GNU Lesser # General Public License v2.1. See the file LICENSE in the top level # directory for more details. -# + +menu "Driver sx126x" + depends on TEST_KCONFIG config MODULE_SX126X - bool "SX126X LoRa Sub-GHz radio" - depends on HAS_PERIPH_GPIO_IRQ - depends on PACKAGE_DRIVER_SX126X - depends on TEST_KCONFIG - select MODULE_PERIPH_GPIO_IRQ + bool + select PACKAGE_DRIVER_SX126X select MODULE_IOLIST + +if HAS_PERIPH_SPI && HAS_PERIPH_GPIO_IRQ + +config MODULE_SX1261 + bool "SX1261" + select MODULE_SX126X + select MODULE_PERIPH_GPIO + select MODULE_PERIPH_GPIO_IRQ + +config MODULE_SX1262 + bool "SX1262" + select MODULE_SX126X + select MODULE_PERIPH_GPIO + select MODULE_PERIPH_GPIO_IRQ + +config MODULE_SX1268 + bool "SX1268" + select MODULE_SX126X + select MODULE_PERIPH_GPIO + select MODULE_PERIPH_GPIO_IRQ + +config MODULE_LLCC68 + bool "LLCC68" + select MODULE_SX126X + select MODULE_PERIPH_GPIO + select MODULE_PERIPH_GPIO_IRQ + +endif + +endmenu diff --git a/drivers/sx126x/include/sx126x_internal.h b/drivers/sx126x/include/sx126x_internal.h new file mode 100644 index 0000000000..0be5d4f784 --- /dev/null +++ b/drivers/sx126x/include/sx126x_internal.h @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2021 HAW Hamburg + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @defgroup drivers_sx126x_internal SX1261/2/8 and LLCC68 internal functions + * @ingroup drivers_sx126x + * @brief Internal functions for the SX1261/2/8 and LLCC68 + * + * @{ + * + * @file + * + * @author José I. Alamos + */ +#ifndef SX126X_INTERNAL_H +#define SX126X_INTERNAL_H + +#include +#include "sx126x.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Check whether the device model is sx1261 + * + * @param[in] dev Device descriptor of the driver + * + * @retval true if the device is sx1261 + * @retval false otherwise + */ +static inline bool sx126x_is_sx1261(sx126x_t *dev) +{ + assert(dev); + if (SX126X_SINGLE) { + return IS_USED(MODULE_SX1261); + } + else { + return dev->params->type == SX126X_TYPE_SX1261; + } +} + +/** + * @brief Check whether the device model is sx1262 + * + * @param[in] dev Device descriptor of the driver + * + * @retval true if the device is sx1262 + * @retval false otherwise + */ +static inline bool sx126x_is_sx1262(sx126x_t *dev) +{ + assert(dev); + if (SX126X_SINGLE) { + return IS_USED(MODULE_SX1262); + } + else { + return dev->params->type == SX126X_TYPE_SX1262; + } +} + +/** + * @brief Check whether the device model is llcc68 + * + * @param[in] dev Device descriptor of the driver + * + * @retval true if the device is llcc68 + * @retval false otherwise + */ +static inline bool sx126x_is_llcc68(sx126x_t *dev) +{ + assert(dev); + if (SX126X_SINGLE) { + return IS_USED(MODULE_LLCC68); + } + else { + return dev->params->type == SX126X_TYPE_LLCC68; + } +} + +/** + * @brief Check whether the device model is sx1268 + * + * @param[in] dev Device descriptor of the driver + * + * @retval true if the device is sx1268 + * @retval false otherwise + */ +static inline bool sx126x_is_sx1268(sx126x_t *dev) +{ + assert(dev); + if (SX126X_SINGLE) { + return IS_USED(MODULE_SX1268); + } + else { + return dev->params->type == SX126X_TYPE_SX1268; + } +} + +#ifdef __cplusplus +} +#endif + +#endif /* SX126X_INTERNAL_H */ +/** @} */ diff --git a/drivers/sx126x/include/sx126x_params.h b/drivers/sx126x/include/sx126x_params.h index 6c4b95b6b2..29984f5b85 100644 --- a/drivers/sx126x/include/sx126x_params.h +++ b/drivers/sx126x/include/sx126x_params.h @@ -57,11 +57,26 @@ extern "C" { #define SX126X_PARAM_REGULATOR SX126X_REG_MODE_DCDC #endif -#define SX126X_PARAMS { .spi = SX126X_PARAM_SPI, \ - .nss_pin = SX126X_PARAM_SPI_NSS, \ +#ifndef SX126X_PARAM_TYPE +# if IS_USED(MODULE_SX1261) +# define SX126X_PARAM_TYPE SX126X_TYPE_SX1261 +# elif IS_USED(MODULE_SX1262) +# define SX126X_PARAM_TYPE SX126X_TYPE_SX1262 +# elif IS_USED(MODULE_SX1268) +# define SX126X_PARAM_TYPE SX126X_TYPE_SX1268 +# elif IS_USED(MODULE_LLCC68) +# define SX126X_PARAM_TYPE SX126X_TYPE_LLCC68 +# else +# error "You should select at least one of the SX126x variants." +# endif +#endif + +#define SX126X_PARAMS { .spi = SX126X_PARAM_SPI, \ + .nss_pin = SX126X_PARAM_SPI_NSS, \ .reset_pin = SX126X_PARAM_RESET, \ .busy_pin = SX126X_PARAM_BUSY, \ .dio1_pin = SX126X_PARAM_DIO1, \ + .type = SX126X_PARAM_TYPE, \ .regulator = SX126X_PARAM_REGULATOR } /**@}*/ diff --git a/drivers/sx126x/sx126x.c b/drivers/sx126x/sx126x.c index f7a4322ce9..abc8e60e05 100644 --- a/drivers/sx126x/sx126x.c +++ b/drivers/sx126x/sx126x.c @@ -28,6 +28,7 @@ #include "sx126x_driver.h" #include "sx126x.h" #include "sx126x_params.h" +#include "sx126x_internal.h" #define ENABLE_DEBUG 0 #include "debug.h" @@ -104,13 +105,13 @@ static void sx126x_init_default_config(sx126x_t *dev) * Values used here comes from the datasheet, section 13.1.14 SetPaConfig * and are optimal for a TX output power of 14dBm. */ - if (IS_USED(MODULE_LLCC68) || IS_USED(MODULE_SX1262)) { + if (sx126x_is_llcc68(dev) || sx126x_is_sx1262(dev)) { sx126x_set_pa_cfg(dev, &sx1262_pa_cfg); } - else if (IS_USED(MODULE_SX1268)) { + else if (sx126x_is_sx1268(dev)) { sx126x_set_pa_cfg(dev, &sx1268_pa_cfg); } - else { /* IS_USED(MODULE_SX1261) */ + else { /* sx126x_is_sx1261(dev) */ sx126x_set_pa_cfg(dev, &sx1261_pa_cfg); } sx126x_set_tx_params(dev, CONFIG_SX126X_TX_POWER_DEFAULT, CONFIG_SX126X_RAMP_TIME_DEFAULT); diff --git a/drivers/sx126x/sx126x_netdev.c b/drivers/sx126x/sx126x_netdev.c index 0e93e75ef3..85b72a8ce6 100644 --- a/drivers/sx126x/sx126x_netdev.c +++ b/drivers/sx126x/sx126x_netdev.c @@ -29,15 +29,13 @@ #include "sx126x.h" #include "sx126x_netdev.h" +#include "sx126x_internal.h" #define ENABLE_DEBUG 0 #include "debug.h" -#if IS_USED(MODULE_LLCC68) -#define SX126X_MAX_SF LORA_SF11 -#else -#define SX126X_MAX_SF LORA_SF12 -#endif +const uint8_t llcc68_max_sf = LORA_SF11; +const uint8_t sx126x_max_sf = LORA_SF12; static int _send(netdev_t *netdev, const iolist_t *iolist) { @@ -357,7 +355,10 @@ static int _set(netdev_t *netdev, netopt_t opt, const void *val, size_t len) case NETOPT_SPREADING_FACTOR: assert(len <= sizeof(uint8_t)); uint8_t sf = *((const uint8_t *)val); - if ((sf < LORA_SF6) || (sf > SX126X_MAX_SF)) { + const uint8_t max_sf = sx126x_is_llcc68(dev) + ? llcc68_max_sf + : sx126x_max_sf; + if ((sf < LORA_SF6) || (sf > max_sf)) { res = -EINVAL; break; } diff --git a/tests/driver_sx126x/app.config.test b/tests/driver_sx126x/app.config.test index f6daeadf2b..d37668e7e4 100644 --- a/tests/driver_sx126x/app.config.test +++ b/tests/driver_sx126x/app.config.test @@ -1,7 +1,6 @@ # this file enables modules defined in Kconfig. Do not use this file for # application configuration. This is only needed during migration. -CONFIG_MODULE_SX126X=y -CONFIG_PACKAGE_DRIVER_SX126X=y +CONFIG_MODULE_SX1261=y CONFIG_MODULE_SHELL=y CONFIG_MODULE_SHELL_COMMANDS=y