From 9c11985998bc7e3fb3c71fc973c6c309c92e8918 Mon Sep 17 00:00:00 2001 From: Nicolas ALBAREL Date: Thu, 11 Sep 2025 15:31:49 +0200 Subject: [PATCH 1/9] fix warnings in sx1280_raw_driver --- modules/sx1280_raw_driver/ral_sx1280.c | 8 ++++++-- modules/sx1280_raw_driver/ral_sx1280.h | 1 - modules/sx1280_raw_driver/sx1280_hal.c | 9 ++++++++- tests/driver_sx1280/Makefile | 1 + 4 files changed, 15 insertions(+), 4 deletions(-) diff --git a/modules/sx1280_raw_driver/ral_sx1280.c b/modules/sx1280_raw_driver/ral_sx1280.c index 6d85dca..65cc10b 100644 --- a/modules/sx1280_raw_driver/ral_sx1280.c +++ b/modules/sx1280_raw_driver/ral_sx1280.c @@ -478,12 +478,16 @@ ral_status_t ral_sx1280_setup_tx_flrc( const ral_t* ral, const ral_params_flrc_t ral_status_t ral_sx1280_setup_tx_lora_e( const ral_t* ral, const ral_params_lora_e_t* params ) { - return RAL_STATUS_UNSUPPORTED_FEATURE; + (void)ral; + (void)params; + return RAL_STATUS_UNSUPPORTED_FEATURE; } ral_status_t ral_sx1280_tx_bpsk( const ral_t* ral, const ral_params_bpsk_t* params ) { - return RAL_STATUS_UNSUPPORTED_FEATURE; + (void)ral; + (void)params; + return RAL_STATUS_UNSUPPORTED_FEATURE; } ral_status_t ral_sx1280_setup_cad( const ral_t* ral, const ral_lora_cad_params_t* params ) diff --git a/modules/sx1280_raw_driver/ral_sx1280.h b/modules/sx1280_raw_driver/ral_sx1280.h index 4bdf334..857235a 100644 --- a/modules/sx1280_raw_driver/ral_sx1280.h +++ b/modules/sx1280_raw_driver/ral_sx1280.h @@ -516,7 +516,6 @@ static inline ral_status_t ral_sx1280_init_all(const ral_t* ral, gpio_cb_t evt_h res = ral_sx1280_init(ral); if (res == RAL_STATUS_OK) { uint16_t fwid = ral_sx1280_get_firmware_version(ral); - printf("SX1280 firmware version = %x\n", fwid); if (fwid == 0x5853) { sx1280_hal_setup_irq(evt_handler); sx1280_set_lna_settings(ral->context, SX1280_LNA_HIGH_SENSITIVITY_MODE); diff --git a/modules/sx1280_raw_driver/sx1280_hal.c b/modules/sx1280_raw_driver/sx1280_hal.c index 2c56adc..aba51eb 100644 --- a/modules/sx1280_raw_driver/sx1280_hal.c +++ b/modules/sx1280_raw_driver/sx1280_hal.c @@ -12,6 +12,7 @@ #include // C99 types #include // bool type +#include #include "xtimer.h" #include "irq.h" @@ -128,6 +129,8 @@ sx1280_hal_status_t sx1280_hal_read( const void *context, const uint8_t *command void sx1280_hal_reset( const void *context ) { + (void)context; + gpio_clear(SX1280_PARAM_RESET); _delay_ms(5); gpio_set(SX1280_PARAM_RESET); @@ -136,7 +139,9 @@ void sx1280_hal_reset( const void *context ) sx1280_hal_status_t sx1280_hal_wakeup( const void *context ) { - if (!spi_initialized) { + (void)context; + + if (!spi_initialized) { spi_initialized = true; spi_acquire(spiconf.dev, spiconf.cs, spiconf.mode, spiconf.clk); @@ -179,11 +184,13 @@ sx1280_hal_status_t sx1280_hal_wakeup( const void *context ) sx1280_hal_operating_mode_t sx1280_hal_get_operating_mode( const void *context ) { + (void)context; return radio_opmode; } void sx1280_hal_set_operating_mode( const void *context, const sx1280_hal_operating_mode_t op_mode ) { + (void)context; radio_opmode = op_mode; if ((op_mode == SX1280_HAL_OP_MODE_SLEEP) && (spi_initialized)) { diff --git a/tests/driver_sx1280/Makefile b/tests/driver_sx1280/Makefile index f0004fb..213830c 100644 --- a/tests/driver_sx1280/Makefile +++ b/tests/driver_sx1280/Makefile @@ -4,6 +4,7 @@ APPLICATION=driver_sx1280_shell +EXTERNAL_BOARD_DIRS ?= ../../boards BOARD_WHITELIST := thingsat-l0 nucleo-l053r8 nucleo-l073rz nucleo-l432kc nucleo-f411re nucleo-f401re nucleo-f446re nucleo-f446ze nucleo-f103rb olimexino-stm32 # BOARD_WHITELIST += esp32-wroom-32 lora-e5-dev bluepill bluepill-128kib From efb983a490995ca65113197773e9b612f43350f7 Mon Sep 17 00:00:00 2001 From: Nicolas ALBAREL Date: Fri, 12 Sep 2025 15:12:09 +0200 Subject: [PATCH 2/9] change inisat board definition for sx1280 --- boards/nucleo-l432kc-inisat/include/board.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/boards/nucleo-l432kc-inisat/include/board.h b/boards/nucleo-l432kc-inisat/include/board.h index 5fdb04a..787063f 100644 --- a/boards/nucleo-l432kc-inisat/include/board.h +++ b/boards/nucleo-l432kc-inisat/include/board.h @@ -76,15 +76,15 @@ extern "C" { #endif #ifndef SX1280_PARAM_RESET -#define SX1280_PARAM_RESET GPIO_UNDEF /**< Reset pin */ +#define SX1280_PARAM_RESET PWM2_PIN /**< Reset pin /!\ on PWM2 for test - Mikrobus slot does not work /!\ */ #endif #ifndef SX1280_PARAM_DIO0 -#define SX1280_PARAM_DIO0 GPIO_UNDEF /**< DIO0 */ +#define SX1280_PARAM_DIO0 SENS1_PIN /**< DIO0 / BUSY /!\ on SENS1_PIN for test - Mikrobus slot does not work /!\*/ #endif #ifndef SX1280_PARAM_DIO1 -#define SX1280_PARAM_DIO1 GPIO_PIN(PORT_B,8) /**< DIO1 */ +#define SX1280_PARAM_DIO1 SENS2_PIN /**< DIO1 /!\ on SENS2_PIN for test - Mikrobus slot does not work /!\*/ #endif #ifndef MCP9808_I2C_ADDRESS From 4d80a38ee19af979db50726562e406227877e34a Mon Sep 17 00:00:00 2001 From: Nicolas ALBAREL Date: Fri, 12 Sep 2025 15:12:32 +0200 Subject: [PATCH 3/9] add busy signal check after reset --- modules/sx1280_raw_driver/sx1280_hal.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/modules/sx1280_raw_driver/sx1280_hal.c b/modules/sx1280_raw_driver/sx1280_hal.c index aba51eb..192aca5 100644 --- a/modules/sx1280_raw_driver/sx1280_hal.c +++ b/modules/sx1280_raw_driver/sx1280_hal.c @@ -134,7 +134,14 @@ void sx1280_hal_reset( const void *context ) gpio_clear(SX1280_PARAM_RESET); _delay_ms(5); gpio_set(SX1280_PARAM_RESET); - _delay_ms(5); + + printf("BUSY check ON\n"); + while (!gpio_read(SX1280_PARAM_DIO0)) {}; // wait ON + printf("BUSY check OFF\n"); + sx1280_hal_wait_on_busy(); // wait OFF + printf("BUSY check OK\n"); + + _delay_ms(1); } sx1280_hal_status_t sx1280_hal_wakeup( const void *context ) From 0fc809649520fab85b52771206342120acbcfbe3 Mon Sep 17 00:00:00 2001 From: Nicolas ALBAREL Date: Fri, 12 Sep 2025 15:13:46 +0200 Subject: [PATCH 4/9] disable default parameters in sx1280 module --- modules/sx1280_raw_driver/sx1280_hal.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/sx1280_raw_driver/sx1280_hal.h b/modules/sx1280_raw_driver/sx1280_hal.h index 1d470dc..5e60ad2 100644 --- a/modules/sx1280_raw_driver/sx1280_hal.h +++ b/modules/sx1280_raw_driver/sx1280_hal.h @@ -49,6 +49,7 @@ extern "C" { * --- PUBLIC MACROS ----------------------------------------------------------- */ +#if 0 // DEFAULT PARAMETERS ARE DISABLED - DOES NOT MAKE SENSE IN A MODULE #ifndef SX1280_PARAM_SPI #define SX1280_PARAM_SPI (SPI_DEV(0)) #endif @@ -81,6 +82,7 @@ extern "C" { #ifndef SX1280_PARAM_DIO3 #define SX1280_PARAM_DIO3 GPIO_UNDEF #endif +#endif /* From fcc767b5e3c6f5fde7fdd1aa0d4295a1a3762743 Mon Sep 17 00:00:00 2001 From: Nicolas ALBAREL Date: Fri, 12 Sep 2025 16:12:40 +0200 Subject: [PATCH 5/9] sx1280_raw: acquire spi device only during transaction --- modules/sx1280_raw_driver/sx1280_hal.c | 75 ++++++++++++++------------ 1 file changed, 40 insertions(+), 35 deletions(-) diff --git a/modules/sx1280_raw_driver/sx1280_hal.c b/modules/sx1280_raw_driver/sx1280_hal.c index 192aca5..dc259d3 100644 --- a/modules/sx1280_raw_driver/sx1280_hal.c +++ b/modules/sx1280_raw_driver/sx1280_hal.c @@ -39,9 +39,8 @@ static struct { spi_cs_t cs; } spiconf; -static bool spi_initialized; - -//TODO autoclose SPI +static bool spi_acquired; +static bool hal_initialized; /* * ----------------------------------------------------------------------------- @@ -65,6 +64,23 @@ static void _delay_ms(uint32_t period) xtimer_usleep(period * 1000); } + +static inline bool _prepare_spi(void) { + if (hal_initialized && !spi_acquired) { + spi_acquire(spiconf.dev, spiconf.cs, spiconf.mode, spiconf.clk); + spi_acquired = true; + } + + return spi_acquired; +} + +static inline void _release_spi(void) { + if (spi_acquired) { + spi_acquired = false; + spi_release(spiconf.dev); + } +} + /* * ----------------------------------------------------------------------------- * --- PUBLIC FUNCTIONS --------------------------------------------- @@ -75,9 +91,11 @@ sx1280_hal_status_t sx1280_hal_write( const void *context, const uint8_t *comman const uint8_t *data, const uint16_t data_length ) { sx1280_hal_wakeup( context ); + if (!_prepare_spi()) { + return SX1280_HAL_STATUS_ERROR; + } //printf("sx1280_hal_write: command_length=%d data_length=%d\n", command_length, data_length); - if (command_length) { spi_transfer_bytes(spiconf.dev, spiconf.cs, data_length, command, NULL, command_length); } @@ -85,10 +103,13 @@ sx1280_hal_status_t sx1280_hal_write( const void *context, const uint8_t *comman spi_transfer_bytes(spiconf.dev, spiconf.cs, false, data, NULL, data_length); } + _release_spi(); + // 0x84 - SX1280_SET_SLEEP opcode. In sleep mode the radio dio is struck to 1 => do not test it if (command[0] != 0x84) { sx1280_hal_wait_on_busy( ); } + return SX1280_HAL_STATUS_OK; } @@ -96,9 +117,10 @@ sx1280_hal_status_t sx1280_hal_read( const void *context, const uint8_t *command const uint16_t command_length, uint8_t *data, const uint16_t data_length ) { - - sx1280_hal_wakeup( context ); - + sx1280_hal_wakeup( context ); + if (!_prepare_spi()) { + return SX1280_HAL_STATUS_ERROR; + } #if ENABLE_ONE_SPI_TRANSFER_BYTES == 1 @@ -124,6 +146,7 @@ sx1280_hal_status_t sx1280_hal_read( const void *context, const uint8_t *command #endif + _release_spi(); return SX1280_HAL_STATUS_OK; } @@ -147,29 +170,9 @@ void sx1280_hal_reset( const void *context ) sx1280_hal_status_t sx1280_hal_wakeup( const void *context ) { (void)context; - - if (!spi_initialized) { - spi_initialized = true; - - spi_acquire(spiconf.dev, spiconf.cs, spiconf.mode, spiconf.clk); - -/* int tmp = spi_acquire(spiconf.dev, spiconf.cs, spiconf.mode, spiconf.clk); - if (tmp == SPI_NOMODE) { - puts("error: given SPI mode is not supported"); - return SX1280_HAL_STATUS_ERROR; - } - else if (tmp == SPI_NOCLK) { - puts("error: targeted clock speed is not supported"); - return SX1280_HAL_STATUS_ERROR; - } - else if (tmp != SPI_OK) { - puts("error: unable to acquire bus with given parameters"); - return SX1280_HAL_STATUS_ERROR; - }*/ - - printf("SX1280 SPI initialized\n"); - } - + if (!hal_initialized) { + return SX1280_HAL_STATUS_ERROR; + } if (radio_opmode == SX1280_HAL_OP_MODE_SLEEP) { // Busy is HIGH in sleep mode, wake-up the device @@ -199,11 +202,6 @@ void sx1280_hal_set_operating_mode( const void *context, const sx1280_hal_operat { (void)context; radio_opmode = op_mode; - - if ((op_mode == SX1280_HAL_OP_MODE_SLEEP) && (spi_initialized)) { - spi_initialized = false; - spi_release(spiconf.dev); - } } /* @@ -260,6 +258,10 @@ void sx1280_hal_setup_io( const radio_callbacks_t *cb ) return; } + spi_acquire(spiconf.dev, spiconf.cs, spiconf.mode, spiconf.clk); // should assert if parameters are wrong + spi_release(spiconf.dev); + + if (gpio_init(SX1280_PARAM_RESET, GPIO_OUT) < 0) { printf("Error to initialize SX1280_PARAM_RESET\n"); return; @@ -271,6 +273,9 @@ void sx1280_hal_setup_io( const radio_callbacks_t *cb ) } _delay_ms(2); + + printf("SX1280 HAL initialized\n"); + hal_initialized = true; } From 61caa60ee750c43ac4f436fda339739db63d4cc7 Mon Sep 17 00:00:00 2001 From: Nicolas ALBAREL Date: Tue, 16 Sep 2025 12:36:17 +0200 Subject: [PATCH 6/9] add a thread && mutex to avoid processing in interrupt mode --- tests/driver_sx1280/Makefile | 17 +- tests/driver_sx1280/sx1280_cmd.c | 188 +++++++++++++++------ tests/driver_sx1280/sx1280_cmd.h | 30 +++- tests/driver_sx1280/sx1280_rangetest_cmd.c | 35 ++-- 4 files changed, 202 insertions(+), 68 deletions(-) diff --git a/tests/driver_sx1280/Makefile b/tests/driver_sx1280/Makefile index 213830c..3022047 100644 --- a/tests/driver_sx1280/Makefile +++ b/tests/driver_sx1280/Makefile @@ -18,13 +18,28 @@ USEMODULE += hashes USEMODULE += crypto USEMODULE += shell - USEMODULE += fmt USEMODULE += printf_float USEMODULE += xtimer USEMODULE += random +# ----------------------------- +# Debug +# ----------------------------- + +USEMODULE += shell_cmds_default +USEMODULE += ps +USEMODULE += git + +# Set this to 1 to enable code in RIOT that does safety checking +# which is not needed in a production environment but helps in the +# development process: +DEVELHELP ?= 1 + +#CFLAGS += -DENABLE_DEBUG=1 +CFLAGS += -DDEBUG_ASSERT_VERBOSE=1 + # ----------------------------- # sx1280_utils diff --git a/tests/driver_sx1280/sx1280_cmd.c b/tests/driver_sx1280/sx1280_cmd.c index dc665cb..4669228 100644 --- a/tests/driver_sx1280/sx1280_cmd.c +++ b/tests/driver_sx1280/sx1280_cmd.c @@ -21,19 +21,34 @@ #include "xtimer.h" #include "random.h" +#include "thread.h" #include "periph/pm.h" #include "ral_sx1280.h" - #include "sx1280_cmd.h" -static ral_status_t sx1280_init_status; +/* ******************************************** */ + +// Thread +static char _thread_stack[THREAD_STACKSIZE_DEFAULT]; +static kernel_pid_t _thread_pid; + +// Mutex for sx1280 access +static mutex_t sx1280_mutex = MUTEX_INIT; + +static ral_status_t _sx1280_init_status = RAL_STATUS_UNKNOWN_VALUE; + +#define MSG_QUEUE_SIZE (8) +#define MSG_TYPE_IRQ (0x00) -#ifdef MULTITECH_ISM2400_PARAMS -ral_params_lora_t params = { +/* ******************************************** */ + + +static ral_params_lora_t params = { +#ifdef MULTITECH_ISM2400_PARAMS .freq_in_hz = MULTITECH_ISM2400_CHANNEL_1, .sf = MULTITECH_ISM2400_SF, .bw = MULTITECH_ISM2400_BANDWITH, @@ -45,27 +60,35 @@ ral_params_lora_t params = { .invert_iq_is_on = false, .symb_nb_timeout = 0, //! Rx only parameters - useless anyway .pwr_in_dbm = SX1280_MAX_TXPOWER, //! Tx only parameters -}; + #else + .freq_in_hz = 2483500000, + .sf = RAL_LORA_SF9, + .bw = RAL_LORA_BW_200_KHZ, + .cr = RAL_LORA_CR_LI_4_5, + .pbl_len_in_symb = 12, + //.sync_word = 0x12, + .sync_word = 0x21, + .pld_is_fix = false, + .crc_is_on = true, + .invert_iq_is_on = false, + .symb_nb_timeout = 0, //! Rx only parameters - useless anyway + .pwr_in_dbm = 4, //! Tx only parameters -ral_params_lora_t params = { .freq_in_hz = 2483500000, - .sf = RAL_LORA_SF9, .bw = RAL_LORA_BW_200_KHZ, - .cr = RAL_LORA_CR_LI_4_5, - .pbl_len_in_symb = 12, - //.sync_word = 0x12, - .sync_word = 0x21, .pld_is_fix = false, .crc_is_on = true, - .invert_iq_is_on = false, .symb_nb_timeout = 0, //! Rx only parameters - useless anyway - .pwr_in_dbm = 4, //! Tx only parameters +#endif }; -#endif +ral_params_lora_t * sx1280_get_params(void) { + return ¶ms; +} + /* * @brief Get the frequency in Hz from the driver lora definition */ -uint32_t getBW(ral_lora_bw_t lora_bw) +uint32_t sx1280_getBW(ral_lora_bw_t lora_bw) { switch (lora_bw) { case RAL_LORA_BW_007_KHZ: @@ -123,12 +146,12 @@ int sx1280_channel_cmd(int argc, char **argv) return -1; } uint32_t freq_in_hz = strtoull(argv[2], NULL, 10); - if ((ISM2400_LOWER_FREQUENCY + (getBW(params.bw) / 2) >= freq_in_hz) + if ((ISM2400_LOWER_FREQUENCY + (sx1280_getBW(params.bw) / 2) >= freq_in_hz) && (freq_in_hz - <= ISM2400_HIGHER_FREQUENCY - (getBW(params.bw) / 2))) { + <= ISM2400_HIGHER_FREQUENCY - (sx1280_getBW(params.bw) / 2))) { printf( "[Error] setup: out-of-range frequency value given for bw=%ld\n", - getBW(params.bw)); + sx1280_getBW(params.bw)); return -1; } params.freq_in_hz = freq_in_hz; @@ -380,7 +403,7 @@ int sx1280_crc_cmd(int argc, char **argv) int sx1280_setup_cmd(int argc, char **argv) { if (argc == 1) { - printf("Setup: sf=%d bw=%ldHz cr=%d/8\n", params.sf, getBW(params.bw), + printf("Setup: sf=%d bw=%ldHz cr=%d/8\n", params.sf, sx1280_getBW(params.bw), params.cr); return 0; } @@ -516,19 +539,24 @@ int sx1280_send_cmd(int argc, char **argv) printf("sending \"%s\" payload (%u bytes) (%d/%d)\n", to_send, (unsigned)strlen(to_send) + 1, i, count); - params.pld_len_in_bytes = (unsigned)strlen(to_send) + 1; - ral_status_t res = ral_sx1280_setup_tx_lora(&ral_default_cfg, ¶ms); - if (res != RAL_STATUS_OK) { - printf("ral_sx1280_setup_tx_lora ERROR %d\n", res); - } - else { - ral_sx1280_set_pkt_payload(&ral_default_cfg, (uint8_t *)to_send, - (unsigned)strlen(to_send) + 1); - res = ral_sx1280_set_tx(&ral_default_cfg); - if (res != RAL_STATUS_OK) { - printf("ral_sx1280_set_tx ERROR %d\n", res); - } - } + mutex_lock(&sx1280_mutex); + { + params.pld_len_in_bytes = (unsigned)strlen(to_send) + 1; + ral_status_t res = ral_sx1280_setup_tx_lora(&ral_default_cfg, ¶ms); + if (res != RAL_STATUS_OK) { + printf("ral_sx1280_setup_tx_lora ERROR %d\n", res); + } + else { + ral_sx1280_set_pkt_payload(&ral_default_cfg, (uint8_t *)to_send, + (unsigned)strlen(to_send) + 1); + res = ral_sx1280_set_tx(&ral_default_cfg); + if (res != RAL_STATUS_OK) { + printf("ral_sx1280_set_tx ERROR %d\n", res); + } + } + } + mutex_unlock(&sx1280_mutex); + if (i < count) { xtimer_usleep(DELAY_BETWEEN_TX); } @@ -569,23 +597,29 @@ int sx1280_listen_cmd(int argc, char **argv) for (uint32_t c = 0; c < count; c++) { printf("c=%ld\n", c); - params.pld_len_in_bytes = 255; - ral_status_t res = ral_sx1280_setup_rx_lora(&ral_default_cfg, ¶ms); - if (res != RAL_STATUS_OK) { - printf("ral_sx1280_setup_rx_lora ERROR %d\n", res); - } - else { - res = ral_sx1280_set_rx(&ral_default_cfg, timeout * 1000); - if (res != RAL_STATUS_OK) { - printf("ral_sx1280_set_rx ERROR %d\n", res); - } - } + mutex_lock(&sx1280_mutex); + { + params.pld_len_in_bytes = 255; + ral_status_t res = ral_sx1280_setup_rx_lora(&ral_default_cfg, ¶ms); + if (res != RAL_STATUS_OK) { + printf("ral_sx1280_setup_rx_lora ERROR %d\n", res); + } + else { + res = ral_sx1280_set_rx(&ral_default_cfg, timeout * 1000); + if (res != RAL_STATUS_OK) { + printf("ral_sx1280_set_rx ERROR %d\n", res); + } + } + } + mutex_unlock(&sx1280_mutex); } return 0; } +/* ******************************************** */ + /* * @brief handler when Tx is down */ @@ -642,12 +676,46 @@ static void _SX1280_OnRxError(void) printf("SX1280 OnRxError\n"); } +/* ******************************************** */ + static void sx1280_handler_cb(void *arg) { (void)arg; // unused param - ral_sx1280_proces_lora_irqs(&ral_default_cfg); + static msg_t irq_msg = { + .type = MSG_TYPE_IRQ, + .content = { + .value = 0, + } + }; + + msg_send_int(&irq_msg, _thread_pid); +} + +static void * _sx1280_thread(void *arg) { + (void)arg; + + static msg_t msg_queue[MSG_QUEUE_SIZE]; + static msg_t msg; + + msg_init_queue(msg_queue, MSG_QUEUE_SIZE); + + printf("sx1280 Thread running\n"); + while (1) { + msg_receive(&msg); + + mutex_lock(&sx1280_mutex); + { + // only one message type for now + ral_sx1280_proces_lora_irqs(&ral_default_cfg); + } + mutex_unlock(&sx1280_mutex); + + } + return NULL; } +/* ******************************************** */ + /* * @brief Initialize the SX1280 driver */ @@ -657,16 +725,32 @@ int sx1280_init(void) _SX1280_OnRxDone, .rxHeaderDone = NULL, .rxTimeout = _SX1280_OnRxTimeout, .rxError = _SX1280_OnRxError, }; - sx1280_init_status = ral_sx1280_init_all(&ral_default_cfg, + _sx1280_init_status = ral_sx1280_init_all(&ral_default_cfg, sx1280_handler_cb, &rcb); - if (sx1280_init_status != RAL_STATUS_OK) { - printf("sx1280_init_status ERROR %d\n", sx1280_init_status); + if (_sx1280_init_status != RAL_STATUS_OK) { + printf("sx1280_init_status ERROR %d\n", _sx1280_init_status); return -1; } + + /* init local thread */ + _thread_pid = thread_create(_thread_stack, + sizeof(_thread_stack), + THREAD_PRIORITY_MAIN - 1, + THREAD_CREATE_STACKTEST, + _sx1280_thread, + NULL, + "sx1280_thread"); + + if (_thread_pid <= KERNEL_PID_UNDEF) { + printf("sx1280 ERROR: impossible to create a thread\n"); + return -1; + } + return 0; } + /* * @brief Initialize the SX1280 driver and reboot if the init failed */ @@ -680,3 +764,13 @@ void sx1280_init_and_reboot_on_failure(void) pm_reboot(); } } + + +void sx1280_lock(void) { + mutex_lock(&sx1280_mutex); +} + + +void sx1280_unlock(void) { + mutex_unlock(&sx1280_mutex); +} diff --git a/tests/driver_sx1280/sx1280_cmd.h b/tests/driver_sx1280/sx1280_cmd.h index 393d48a..d1b96a5 100644 --- a/tests/driver_sx1280/sx1280_cmd.h +++ b/tests/driver_sx1280/sx1280_cmd.h @@ -30,25 +30,39 @@ #define SECONDS_IF_INIT_FAILED (5U) #endif + /* - * @brief The LoRa modulation parameters for Rx and Tx + * @brief Initialize the SX1280 driver */ -extern ral_params_lora_t params; +int sx1280_init(void); /* - * @brief Get the frequency in Hz from the driver lora definition + * @brief Initialize the SX1280 driver and reboot on initialization failure */ -uint32_t getBW(ral_lora_bw_t lora_bw); +void sx1280_init_and_reboot_on_failure(void); + /* - * @brief Initialize the SX1280 driver + * @brief Lock the mutex that protect low level access to sx1280 (useful when calling the driver directly) */ -int sx1280_init(void); +void sx1280_lock(void); /* - * @brief Initialize the SX1280 driver and reboot on initialization failure + * @brief Unlock the mutex that protect low level access to sx1280 (useful when calling the driver directly) */ -void sx1280_init_and_reboot_on_failure(void); +void sx1280_unlock(void); + + +/* + * @brief The LoRa modulation parameters for Rx and Tx + */ +ral_params_lora_t * sx1280_get_params(void); + +/* + * @brief Get the frequency in Hz from the driver lora definition + */ +uint32_t sx1280_getBW(ral_lora_bw_t lora_bw); + /* * @brief Get/Set the central frequencies of the LoRa channel diff --git a/tests/driver_sx1280/sx1280_rangetest_cmd.c b/tests/driver_sx1280/sx1280_rangetest_cmd.c index 793b08d..03041e2 100644 --- a/tests/driver_sx1280/sx1280_rangetest_cmd.c +++ b/tests/driver_sx1280/sx1280_rangetest_cmd.c @@ -103,15 +103,16 @@ static void reboot_after_delay(uint32_t delay) */ int sx1280_channel_set(uint32_t freq_in_hz) { + ral_params_lora_t * const params = sx1280_get_params(); - if ((ISM2400_LOWER_FREQUENCY + (getBW(params.bw) / 2) >= freq_in_hz) - && (freq_in_hz <= ISM2400_HIGHER_FREQUENCY - (getBW(params.bw) / 2))) { + if ((ISM2400_LOWER_FREQUENCY + (sx1280_getBW(params->bw) / 2) >= freq_in_hz) + && (freq_in_hz <= ISM2400_HIGHER_FREQUENCY - (sx1280_getBW(params->bw) / 2))) { printf("[Error] setup: out-of-range frequency value given for bw=%ld\n", - getBW(params.bw)); + sx1280_getBW(params->bw)); return -1; } - params.freq_in_hz = freq_in_hz; - printf("New channel set to %lu Hz\n", params.freq_in_hz); + params->freq_in_hz = freq_in_hz; + printf("New channel set to %lu Hz\n", params->freq_in_hz); return 0; } @@ -122,7 +123,8 @@ int sx1280_channel_set(uint32_t freq_in_hz) */ void sx1280_invertiq_set(bool invert_iq_is_on) { - params.invert_iq_is_on = invert_iq_is_on; + ral_params_lora_t * const params = sx1280_get_params(); + params->invert_iq_is_on = invert_iq_is_on; } @@ -174,6 +176,8 @@ int sx1280_rangetest_cmd(int argc, char **argv) return -1; } + ral_params_lora_t * const params = sx1280_get_params(); + uint32_t count = atoi(argv[1]); uint32_t payload_len = atoi(argv[2]); uint32_t delay = atoi(argv[3]); @@ -197,6 +201,8 @@ int sx1280_rangetest_cmd(int argc, char **argv) for (uint32_t i = 0; i < count; i++) { + sx1280_lock(); // lock for tx setup + // set a new channel uint32_t channel = ((uint32_t)atoi(argv[4 + i % 3])) * 1000U; sx1280_channel_set(channel); @@ -220,13 +226,13 @@ int sx1280_rangetest_cmd(int argc, char **argv) sx1280_invertiq_set(false); // prepare the LoRaWAN frame - printf("sending : channel=%lu iq=%d fcnt=%lu frame=", channel, params.invert_iq_is_on, + printf("sending : channel=%lu iq=%d fcnt=%lu frame=", channel, params->invert_iq_is_on, fcnt); printf_ba(frame, payload_len); printf("\n"); - params.pld_len_in_bytes = payload_len; - ral_status_t res = ral_sx1280_setup_tx_lora(&ral_default_cfg, ¶ms); + params->pld_len_in_bytes = payload_len; + ral_status_t res = ral_sx1280_setup_tx_lora(&ral_default_cfg, params); if (res != RAL_STATUS_OK) { printf("ral_sx1280_setup_tx_lora ERROR %d\n", res); reboot_after_delay(10); @@ -242,17 +248,21 @@ int sx1280_rangetest_cmd(int argc, char **argv) return -1; } + sx1280_unlock(); // tx setup done + xtimer_sleep(RECEIVE_WINDOWS_IN_SECONDS); + sx1280_lock(); // lock for rx setup + // Set the IQ to inverted for downlink sx1280_invertiq_set(true); // listen downlink on receive windows printf("listen : channel=%lu iq=%d duration=%d seconds ...\n", channel, - params.invert_iq_is_on, RECEIVE_WINDOWS_TIMEOUT_IN_SECONDS); + params->invert_iq_is_on, RECEIVE_WINDOWS_TIMEOUT_IN_SECONDS); - params.pld_len_in_bytes = 255; - ral_status_t res = ral_sx1280_setup_rx_lora(&ral_default_cfg, ¶ms); + params->pld_len_in_bytes = 255; + ral_status_t res = ral_sx1280_setup_rx_lora(&ral_default_cfg, params); if (res != RAL_STATUS_OK) { printf("ral_sx1280_setup_rx_lora ERROR %d\n", res); } @@ -263,6 +273,7 @@ int sx1280_rangetest_cmd(int argc, char **argv) printf("ral_sx1280_set_rx ERROR %d\n", res); } } + sx1280_unlock(); // rx setup done xtimer_sleep(RECEIVE_WINDOWS_TIMEOUT_IN_SECONDS); From 5b33e515ea776001267db2a5c0fa182c853f1a1d Mon Sep 17 00:00:00 2001 From: Nicolas ALBAREL Date: Tue, 16 Sep 2025 16:54:15 +0200 Subject: [PATCH 7/9] factorize sx1280 shell command && move it into the module (for reuse) --- .../sx1280_raw_driver}/ism2400.h | 0 .../sx1280_raw_driver}/sx1280_cmd.c | 190 ++++++++++-------- .../sx1280_raw_driver}/sx1280_cmd.h | 54 +---- tests/driver_sx1280/main.c | 17 +- 4 files changed, 114 insertions(+), 147 deletions(-) rename {tests/driver_sx1280 => modules/sx1280_raw_driver}/ism2400.h (100%) rename {tests/driver_sx1280 => modules/sx1280_raw_driver}/sx1280_cmd.c (88%) rename {tests/driver_sx1280 => modules/sx1280_raw_driver}/sx1280_cmd.h (50%) diff --git a/tests/driver_sx1280/ism2400.h b/modules/sx1280_raw_driver/ism2400.h similarity index 100% rename from tests/driver_sx1280/ism2400.h rename to modules/sx1280_raw_driver/ism2400.h diff --git a/tests/driver_sx1280/sx1280_cmd.c b/modules/sx1280_raw_driver/sx1280_cmd.c similarity index 88% rename from tests/driver_sx1280/sx1280_cmd.c rename to modules/sx1280_raw_driver/sx1280_cmd.c index 4669228..7f7fbd7 100644 --- a/tests/driver_sx1280/sx1280_cmd.c +++ b/modules/sx1280_raw_driver/sx1280_cmd.c @@ -22,11 +22,13 @@ #include "xtimer.h" #include "random.h" #include "thread.h" +#include "shell.h" #include "periph/pm.h" #include "ral_sx1280.h" #include "sx1280_cmd.h" +#include "ism2400.h" /* ******************************************** */ @@ -80,55 +82,10 @@ static ral_params_lora_t params = { }; - -ral_params_lora_t * sx1280_get_params(void) { - return ¶ms; -} - -/* - * @brief Get the frequency in Hz from the driver lora definition - */ -uint32_t sx1280_getBW(ral_lora_bw_t lora_bw) -{ - switch (lora_bw) { - case RAL_LORA_BW_007_KHZ: - return 7000; - case RAL_LORA_BW_010_KHZ: - return 10000; - case RAL_LORA_BW_015_KHZ: - return 15000; - case RAL_LORA_BW_020_KHZ: - return 20000; - case RAL_LORA_BW_031_KHZ: - return 31000; - case RAL_LORA_BW_041_KHZ: - return 41000; - case RAL_LORA_BW_062_KHZ: - return 62000; - case RAL_LORA_BW_125_KHZ: - return 125000; - case RAL_LORA_BW_200_KHZ: - return 200000; - case RAL_LORA_BW_250_KHZ: - return 250000; - case RAL_LORA_BW_400_KHZ: - return 400000; - case RAL_LORA_BW_500_KHZ: - return 500000; - case RAL_LORA_BW_800_KHZ: - return 800000; - case RAL_LORA_BW_1600_KHZ: - return 1600000; - default: - return 0; - } -} - - /* * @brief Get/Set the central frequencies of the LoRa channel */ -int sx1280_channel_cmd(int argc, char **argv) +static int sx1280_channel_cmd(int argc, char **argv) { if (argc < 2) { puts("usage: channel "); @@ -168,7 +125,7 @@ int sx1280_channel_cmd(int argc, char **argv) /* * @brief Get/Set the TX power of the next TX LoRa communications */ -int sx1280_txpower_cmd(int argc, char **argv) +static int sx1280_txpower_cmd(int argc, char **argv) { if (argc < 2) { @@ -200,7 +157,7 @@ int sx1280_txpower_cmd(int argc, char **argv) /* * @brief Get/Set the sync word of the next LoRa communications */ -int sx1280_syncword_cmd(int argc, char **argv) +static int sx1280_syncword_cmd(int argc, char **argv) { if (argc < 2) { @@ -232,7 +189,7 @@ int sx1280_syncword_cmd(int argc, char **argv) /* * @brief Get/Set the preamble length of the next LoRa communications */ -int sx1280_preamble_cmd(int argc, char **argv) +static int sx1280_preamble_cmd(int argc, char **argv) { if (argc < 2) { @@ -269,7 +226,7 @@ int sx1280_preamble_cmd(int argc, char **argv) /* * @brief Get/Set the payload size of the next LoRa communications */ -int sx1280_payload_cmd(int argc, char **argv) +static int sx1280_payload_cmd(int argc, char **argv) { if (argc < 2) { @@ -311,7 +268,7 @@ int sx1280_payload_cmd(int argc, char **argv) /* * @brief Get/Set the IQ of the next LoRa communications */ -int sx1280_invertiq_cmd(int argc, char **argv) +static int sx1280_invertiq_cmd(int argc, char **argv) { if (argc < 2) { @@ -355,7 +312,7 @@ int sx1280_invertiq_cmd(int argc, char **argv) /* * @brief Get/Set the CRC of the next LoRa communications */ -int sx1280_crc_cmd(int argc, char **argv) +static int sx1280_crc_cmd(int argc, char **argv) { (void)argc; @@ -400,7 +357,7 @@ int sx1280_crc_cmd(int argc, char **argv) /* * @brief Setup the bandwidth, the spreading factor and the code rate of the next LoRa communications */ -int sx1280_setup_cmd(int argc, char **argv) +static int sx1280_setup_cmd(int argc, char **argv) { if (argc == 1) { printf("Setup: sf=%d bw=%ldHz cr=%d/8\n", params.sf, sx1280_getBW(params.bw), @@ -480,34 +437,10 @@ int sx1280_setup_cmd(int argc, char **argv) return 0; } -//static int sx1280_tx_cmd(int argc, char **argv) -//{ -// if (argc != 2) { -// puts("usage: tx "); -// return -1; -// } -// -// char* msg = argv[1]; -// -// params.pld_len_in_bytes = strlen(msg)+1; -// ral_status_t res = ral_sx1280_setup_tx_lora(&ral_default_cfg, ¶ms ); -// if (res != RAL_STATUS_OK) { -// printf("ral_sx1280_setup_tx_lora ERROR %d\n", res); -// } else { -// ral_sx1280_set_pkt_payload(&ral_default_cfg, (uint8_t *)&msg, strlen(msg)+1 ); -// res = ral_sx1280_set_tx(&ral_default_cfg); -// if (res != RAL_STATUS_OK) { -// printf("ral_sx1280_set_tx ERROR %d\n", res); -// } -// } -// -// return 0; -//} - /* * @brief Send packets to the SX1280 radio */ -int sx1280_send_cmd(int argc, char **argv) +static int sx1280_send_cmd(int argc, char **argv) { if (argc < 2) { puts("usage: send "); @@ -574,7 +507,7 @@ int sx1280_send_cmd(int argc, char **argv) * @param timeout_in_sec * @param count */ -int sx1280_listen_cmd(int argc, char **argv) +static int sx1280_listen_cmd(int argc, char **argv) { uint32_t timeout; uint32_t count = 1; @@ -716,6 +649,50 @@ static void * _sx1280_thread(void *arg) { /* ******************************************** */ +ral_params_lora_t * sx1280_get_params(void) { + return ¶ms; +} + +/* + * @brief Get the frequency in Hz from the driver lora definition + */ +uint32_t sx1280_getBW(ral_lora_bw_t lora_bw) +{ + switch (lora_bw) { + case RAL_LORA_BW_007_KHZ: + return 7000; + case RAL_LORA_BW_010_KHZ: + return 10000; + case RAL_LORA_BW_015_KHZ: + return 15000; + case RAL_LORA_BW_020_KHZ: + return 20000; + case RAL_LORA_BW_031_KHZ: + return 31000; + case RAL_LORA_BW_041_KHZ: + return 41000; + case RAL_LORA_BW_062_KHZ: + return 62000; + case RAL_LORA_BW_125_KHZ: + return 125000; + case RAL_LORA_BW_200_KHZ: + return 200000; + case RAL_LORA_BW_250_KHZ: + return 250000; + case RAL_LORA_BW_400_KHZ: + return 400000; + case RAL_LORA_BW_500_KHZ: + return 500000; + case RAL_LORA_BW_800_KHZ: + return 800000; + case RAL_LORA_BW_1600_KHZ: + return 1600000; + default: + return 0; + } +} + + /* * @brief Initialize the SX1280 driver */ @@ -774,3 +751,58 @@ void sx1280_lock(void) { void sx1280_unlock(void) { mutex_unlock(&sx1280_mutex); } + + +/* ******************************************** */ + +static const shell_command_t internal_shell_commands[] = { + { "setup", "Setup the sx1280 parameters for rx/tx", sx1280_setup_cmd }, + { "channel", "Get/Set channel frequency (in Hz)", sx1280_channel_cmd }, + { "preamble", "Get/Set the preamble length", sx1280_preamble_cmd }, + { "syncword", "Get/Set the sync word", sx1280_syncword_cmd }, + { "invert_iq", "Get/Set IQ swapping", sx1280_invertiq_cmd }, + { "crc", "Get/Set CRC on/off", sx1280_crc_cmd }, + { "payload", "Get/Set Payload fix/var", sx1280_payload_cmd }, + { "txpower", "Get/Set the TX power", sx1280_txpower_cmd }, + { "invert_iq", "Get/Set IQ swapping", sx1280_invertiq_cmd }, + { "send", "Sends a message with sx1280", sx1280_send_cmd }, + { "listen", "Waits for a message with sx1280", sx1280_listen_cmd }, + { NULL, NULL, NULL } +}; + + +static void _cmd_usage(char **argv) { + int idx = 0; + while (internal_shell_commands[idx].name) { + printf("%s %-10s : %s\n", argv[0], internal_shell_commands[idx].name, internal_shell_commands[idx].desc); + idx++; + } +} + +static shell_command_handler_t _find_handler(char * name) { + int idx = 0; + while (internal_shell_commands[idx].name) { + if (strcmp(name, internal_shell_commands[idx].name) == 0) { + return internal_shell_commands[idx].handler; + } + idx++; + } + return NULL; +} + +int sx1280_cmd(int argc, char **argv) { + if (argc < 2) { + _cmd_usage(argv); + return EXIT_FAILURE; + + } else { + const shell_command_handler_t handler = _find_handler(argv[1]); + if (handler) { + return handler(argc - 1, argv + 1); + + } else { + _cmd_usage(argv); + return EXIT_FAILURE; + } + } +} \ No newline at end of file diff --git a/tests/driver_sx1280/sx1280_cmd.h b/modules/sx1280_raw_driver/sx1280_cmd.h similarity index 50% rename from tests/driver_sx1280/sx1280_cmd.h rename to modules/sx1280_raw_driver/sx1280_cmd.h index d1b96a5..701b11e 100644 --- a/tests/driver_sx1280/sx1280_cmd.h +++ b/modules/sx1280_raw_driver/sx1280_cmd.h @@ -20,8 +20,6 @@ #include "ral_defs.h" -#include "ism2400.h" - #ifndef DELAY_BETWEEN_TX #define DELAY_BETWEEN_TX (2000000U) #endif @@ -65,57 +63,9 @@ uint32_t sx1280_getBW(ral_lora_bw_t lora_bw); /* - * @brief Get/Set the central frequencies of the LoRa channel - */ -int sx1280_channel_cmd(int argc, char **argv); - -/* - * @brief Get/Set the TX power of the next TX LoRa communications - */ -int sx1280_txpower_cmd(int argc, char **argv); - -/* - * @brief Get/Set the sync word of the next LoRa communications - */ -int sx1280_syncword_cmd(int argc, char **argv); - -/* - * @brief Get/Set the preamble length of the next LoRa communications - */ -int sx1280_preamble_cmd(int argc, char **argv); - -/* - * @brief Get/Set the payload size of the next LoRa communications - */ -int sx1280_payload_cmd(int argc, char **argv); - -/* - * @brief Get/Set the IQ of the next LoRa communications - */ -int sx1280_invertiq_cmd(int argc, char **argv); - -/* - * @brief Get/Set the CRC of the next LoRa communications - */ -int sx1280_crc_cmd(int argc, char **argv); - -/* - * @brief Setup the bandwidth, the spreading factor and the code rate of the next LoRa communications - */ -int sx1280_setup_cmd(int argc, char **argv); - -/* - * @brief Send packets to the SX1280 radio - */ -int sx1280_send_cmd(int argc, char **argv); - -/* - * @brief Listen the SX1280 radio for count packets during timeout_in_sec seconds for each packet - * - * @param timeout_in_sec - * @param count + * The `sx1280` shell command */ -int sx1280_listen_cmd(int argc, char **argv); +int sx1280_cmd(int argc, char **argv); #endif diff --git a/tests/driver_sx1280/main.c b/tests/driver_sx1280/main.c index df4d38a..96525d7 100644 --- a/tests/driver_sx1280/main.c +++ b/tests/driver_sx1280/main.c @@ -28,22 +28,7 @@ #if RANGETEST != 1 static const shell_command_t shell_commands[] = { - { "setup", "Setup the sx1280 parameters for rx/tx", sx1280_setup_cmd }, - { "channel", "Get/Set channel frequency (in Hz)", sx1280_channel_cmd }, - // {"reset", "Reset the sx1280 device", sx1280_reset_cmd}, - // {"status", "Get the sx1280 status", sx1280_status_cmd}, - { "preamble", "Get/Set the preamble length", sx1280_preamble_cmd }, - { "syncword", "Get/Set the sync word", sx1280_syncword_cmd }, - { "invert_iq", "Get/Set IQ swapping", sx1280_invertiq_cmd }, - { "crc", "Get/Set CRC on/off", sx1280_crc_cmd }, - { "payload", "Get/Set Payload fix/var", sx1280_payload_cmd }, - { "txpower", "Get/Set the TX power", sx1280_txpower_cmd }, - { "invert_iq", "Get/Set IQ swapping", sx1280_invertiq_cmd }, - // { "ping", "Ping", sx1280_ping_cmd}, - // { "pong", "Pong", sx1280_pong_cmd}, - // { "tx", "Sends a message with sx1280", sx1280_tx_cmd }, - { "send", "Sends a message with sx1280", sx1280_send_cmd }, - { "listen", "Waits for a message with sx1280", sx1280_listen_cmd }, + { "sx1280", "LoRa sx1280 basic commands", sx1280_cmd }, { "rangetest", "Range Test", sx1280_rangetest_cmd }, { NULL, NULL, NULL } }; From 2bfd2835d7e46f6acfeae0b2da66d166dfdeaa88 Mon Sep 17 00:00:00 2001 From: Nicolas ALBAREL Date: Tue, 16 Sep 2025 17:14:02 +0200 Subject: [PATCH 8/9] add support for sx1280 module in tests/driver_sx1302 use SX1280=1 in the build command --- tests/driver_sx1302/Makefile | 8 ++++++++ tests/driver_sx1302/main.c | 10 ++++++++++ 2 files changed, 18 insertions(+) diff --git a/tests/driver_sx1302/Makefile b/tests/driver_sx1302/Makefile index 296d931..316bad3 100644 --- a/tests/driver_sx1302/Makefile +++ b/tests/driver_sx1302/Makefile @@ -19,6 +19,14 @@ CFLAGS += -DMESHTASTIC=$(MESHTASTIC) USEMODULE += meshtastic_utils endif +# SX1280 +SX1280 ?= 0 +ifeq ($(SX1280),1) +CFLAGS += -DSX1280=$(SX1280) +USEMODULE += sx1280_raw_driver +USEMODULE += random +endif + # LoRa Chirpstack Messages USEMODULE += lora_mesh diff --git a/tests/driver_sx1302/main.c b/tests/driver_sx1302/main.c index dc30cfe..8f66268 100644 --- a/tests/driver_sx1302/main.c +++ b/tests/driver_sx1302/main.c @@ -26,6 +26,10 @@ #include "gps_uart.h" #endif +#if SX1280 == 1 +#include "sx1280_cmd.h" +#endif + #if defined(MODULE_STTS751) || defined(STTS751_CORECELL_I2C_ADDR) #include "stts751.h" @@ -121,6 +125,9 @@ static const shell_command_t shell_commands[] = { #endif #if ENABLE_GPS == 1 { "gps", "GPS commands", gps_cmd }, +#endif +#if SX1280 == 1 + { "sx1280", "LoRa sx1280 basic commands", sx1280_cmd }, #endif { NULL, NULL, NULL } }; @@ -191,6 +198,9 @@ int main(void) { (void) mission_i2c_scan_and_check(idx); } +#if SX1280 == 1 + sx1280_init_and_reboot_on_failure(); +#endif #if defined(MODULE_STTS751) || defined(STTS751_CORECELL_I2C_ADDR) sensors_init_all(); From 5d51655078e655f1521bd8740088edf94462692a Mon Sep 17 00:00:00 2001 From: Nicolas ALBAREL Date: Wed, 17 Sep 2025 11:53:53 +0200 Subject: [PATCH 9/9] define SX1302_PARAM_POWER_EN_PIN as GPIO_UNDEF to avoid default value --- boards/nucleo-l432kc-inisat/include/board.h | 1 + 1 file changed, 1 insertion(+) diff --git a/boards/nucleo-l432kc-inisat/include/board.h b/boards/nucleo-l432kc-inisat/include/board.h index 787063f..bce7a06 100644 --- a/boards/nucleo-l432kc-inisat/include/board.h +++ b/boards/nucleo-l432kc-inisat/include/board.h @@ -53,6 +53,7 @@ extern "C" { #define SX1302_PARAM_SPI_CLK_SPEED SPI_CLK_5MHZ #define SX1302_PARAM_RESET_PIN GPIO_PIN(PORT_B,0) // Nano D3 +#define SX1302_PARAM_POWER_EN_PIN GPIO_UNDEF #define SX1302_GPIO6_PIN GPIO_PIN(PORT_A,4) // Nano A3