From 36debb200a520732786b751e32b526b64687997d Mon Sep 17 00:00:00 2001 From: Brandon Dester Date: Mon, 11 Dec 2023 17:59:21 -0500 Subject: [PATCH 1/9] Replace deprecated register_component() call with idf_component_register() --- CMakeLists.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3da2380..72cdebc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -54,7 +54,10 @@ set(COMPONENT_ADD_INCLUDEDIRS "src/LoRaMac-node/src/peripherals/soft-se" ) -register_component() +idf_component_register(SRCS ${COMPONENT_SRCS} + INCLUDE_DIRS ${COMPONENT_ADD_INCLUDEDIRS} + REQUIRES ${COMPONENT_REQUIRES} +) add_definitions(-DREGION_EU868=1) add_definitions(-DSOFT_SE) From 879966dd763fe3cbeb14464d1bc112345c9e9c93 Mon Sep 17 00:00:00 2001 From: Brandon Dester Date: Mon, 11 Dec 2023 22:24:52 -0500 Subject: [PATCH 2/9] Add configuration files to allow for user configurable SPI parameters --- Kconfig | 47 +++++++++++++++++++++++++++++++++++++++++++++++ idf_component.yml | 4 ++++ 2 files changed, 51 insertions(+) create mode 100644 Kconfig create mode 100644 idf_component.yml diff --git a/Kconfig b/Kconfig new file mode 100644 index 0000000..c170da5 --- /dev/null +++ b/Kconfig @@ -0,0 +1,47 @@ +menu "SX126x Configuration" + + config SX126X_SPI_MISO_GPIO + int "SX126x SPI MISO GPIO" + help + Set the GPIO number used for SPI MISO. + + config SX126X_SPI_MOSI_GPIO + int "SX126x SPI MOSI GPIO" + help + Set the GPIO number used for SPI MOSI. + + config SX126X_SPI_SCLK_GPIO + int "SX126x SPI SCLK GPIO" + help + Set the GPIO number used for SPI SCLK. + + config SX126X_SPI_CS_GPIO + int "SX126x SPI CS GPIO" + help + Set the GPIO number used for SPI CS. + + config SX126X_RESET_GPIO + int "SX126x RESET GPIO" + help + Set the GPIO number used for RESET. + + config SX126X_IRQ_DIO1_GPIO + int "SX126x IRQ (DIO1) GPIO" + help + Set the GPIO number used for IRQ (DIO1). + + config SX126X_BUSY_GPIO + int "SX126x BUSY GPIO" + help + Set the GPIO number used for BUSY. + + config SX126X_SPI_HOST + int "SX126x SPI HOST" + default 1 + help + The SPI peripheral used to communicate with the SX1262. + 0 = SPI1_HOST + 1 = SPI2_HOST + 2 = SPI3_HOST + +endmenu \ No newline at end of file diff --git a/idf_component.yml b/idf_component.yml new file mode 100644 index 0000000..d9e375f --- /dev/null +++ b/idf_component.yml @@ -0,0 +1,4 @@ +description: Creates an ESP32 component to allow ESP32 board compatibility with the LoRaMac-node stack. +dependencies: + idf: + version: ">=5.0" From bb0757a91f98b52e800295817caf79635e055810 Mon Sep 17 00:00:00 2001 From: Brandon Dester Date: Mon, 11 Dec 2023 22:37:27 -0500 Subject: [PATCH 3/9] Initialize SPI, and Busy and Reset GPIOs in BoardInitPeriph --- CMakeLists.txt | 5 ++ src/LoRaMac-node | 2 +- src/board/generic_esp32/generic-esp32-board.c | 81 ++++++++++++++++++- 3 files changed, 86 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 72cdebc..c00e313 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -59,5 +59,10 @@ idf_component_register(SRCS ${COMPONENT_SRCS} REQUIRES ${COMPONENT_REQUIRES} ) +include_directories( + $ENV{IDF_PATH}/components/driver/gpio/include + $ENV{IDF_PATH}/components/driver/spi/include +) + add_definitions(-DREGION_EU868=1) add_definitions(-DSOFT_SE) diff --git a/src/LoRaMac-node b/src/LoRaMac-node index 2bf36bd..dc2e680 160000 --- a/src/LoRaMac-node +++ b/src/LoRaMac-node @@ -1 +1 @@ -Subproject commit 2bf36bde72f68257eb96b5c00900619546bedca8 +Subproject commit dc2e680ad9fd6e8177c62dbc89b3d5046de9c1b1 diff --git a/src/board/generic_esp32/generic-esp32-board.c b/src/board/generic_esp32/generic-esp32-board.c index 478ba6a..564d597 100644 --- a/src/board/generic_esp32/generic-esp32-board.c +++ b/src/board/generic_esp32/generic-esp32-board.c @@ -5,6 +5,10 @@ #include "esp_err.h" #include "esp_log.h" +#include "driver/gpio.h" +#include "driver/spi_common.h" +#include "driver/spi_master.h" + #include "freertos/task.h" // from LoRaMac @@ -13,6 +17,28 @@ // ANSI #include +#define HZ_PER_KHZ 1000 +#define KHZ_PER_MHZ 1000 +#define HZ_PER_MHZ (HZ_PER_KHZ * KHZ_PER_MHZ) + +#define SX126X_MAX_SPI_CLOCK_SPEED_MHZ 16 +#define SX126X_NUM_COMMAND_BITS 8 +#define SX126X_NUM_REGISTER_ADDRESS_BITS 16 + +typedef struct spi_s { + spi_device_handle_t handle; + gpio_num_t miso; + gpio_num_t mosi; + gpio_num_t sclk; + gpio_num_t cs; + gpio_num_t reset; + gpio_num_t irq_dio1; +#if defined(SX1261MBXBAS) || defined(SX1262MBXCAS) || defined(SX1262MBXDAS) + gpio_num_t busy; +#endif +} spi_c; + +static spi_c lora_spi; static const char *TAG = "ESP32Board"; @@ -24,7 +50,60 @@ void BoardInitMcu( void ) void BoardInitPeriph(void) { - + esp_err_t ret; + + lora_spi.miso = CONFIG_SX126X_SPI_MISO_GPIO; + lora_spi.mosi = CONFIG_SX126X_SPI_MOSI_GPIO; + lora_spi.sclk = CONFIG_SX126X_SPI_SCLK_GPIO; + lora_spi.cs = CONFIG_SX126X_SPI_CS_GPIO; + lora_spi.reset = CONFIG_SX126X_RESET_GPIO; + lora_spi.irq_dio1 = CONFIG_SX126X_IRQ_DIO1_GPIO; +#if defined(SX1261MBXBAS) || defined(SX1262MBXCAS) || defined(SX1262MBXDAS) + lora_spi.busy = CONFIG_SX126X_BUSY_GPIO; + + gpio_config_t busy_conf = { + (1ULL< Date: Mon, 11 Dec 2023 23:45:48 -0500 Subject: [PATCH 4/9] Implement SX126x functions for LoRaMac stack --- src/board/generic_esp32/generic-esp32-board.c | 191 +++++++++++++++++- 1 file changed, 181 insertions(+), 10 deletions(-) diff --git a/src/board/generic_esp32/generic-esp32-board.c b/src/board/generic_esp32/generic-esp32-board.c index 564d597..6cc8d2e 100644 --- a/src/board/generic_esp32/generic-esp32-board.c +++ b/src/board/generic_esp32/generic-esp32-board.c @@ -17,6 +17,8 @@ // ANSI #include +#define ESP_INTR_FLAG_DEFAULT 0 + #define HZ_PER_KHZ 1000 #define KHZ_PER_MHZ 1000 #define HZ_PER_MHZ (HZ_PER_KHZ * KHZ_PER_MHZ) @@ -24,6 +26,8 @@ #define SX126X_MAX_SPI_CLOCK_SPEED_MHZ 16 #define SX126X_NUM_COMMAND_BITS 8 #define SX126X_NUM_REGISTER_ADDRESS_BITS 16 +#define SX126X_NUM_COMMAND_ADDRESS_BITS 0 +#define SX126X_NUM_BUFFER_OFFSET_BITS 8 typedef struct spi_s { spi_device_handle_t handle; @@ -357,12 +361,34 @@ void RtcStopAlarm( void ) static RadioOperatingModes_t OperatingMode; +#if defined(SX1261MBXBAS) || defined(SX1262MBXCAS) || defined(SX1262MBXDAS) +void SX126xWaitOnBusy( void ) +{ + while(gpio_get_level(lora_spi.busy) == 1) { + vTaskDelay(pdTICKS_TO_MS(1)); + }; +} +#endif + /*! * \brief HW Reset of the radio */ void SX126xReset( void ) { + ESP_ERROR_CHECK(gpio_set_level(lora_spi.reset, 0)); + + // Hold low for at least 100us. + // SX1261/2 Datasheet, Rev 1.1 Section 8.1 Reset + DelayMs(1); + + ESP_ERROR_CHECK(gpio_set_level(lora_spi.reset, 1)); +#if defined(SX1261MBXBAS) || defined(SX1262MBXCAS) || defined(SX1262MBXDAS) + // Wait for chip to be ready. + SX126xWaitOnBusy(); +#endif + + SX126xSetOperatingMode(MODE_STDBY_RC); } /*! @@ -370,9 +396,29 @@ void SX126xReset( void ) */ void SX126xWakeup( void ) { + CRITICAL_SECTION_BEGIN( ); + + ESP_ERROR_CHECK(gpio_set_level(lora_spi.cs, 0)); + ESP_ERROR_CHECK(gpio_set_level(lora_spi.cs, 1)); + +#if defined(SX1261MBXBAS) || defined(SX1262MBXCAS) || defined(SX1262MBXDAS) + // Wait for chip to be ready. + SX126xWaitOnBusy(); +#endif + // Update operating mode context variable + SX126xSetOperatingMode(MODE_STDBY_RC); + + CRITICAL_SECTION_END( ); } +/*! + * \brief Initializes the RF Switch I/Os pins interface + */ +void SX126xAntSwOn( void ) +{ + // No antenna switch available on this board design. +} /*! * \brief De-initializes the RF Switch I/Os pins interface @@ -381,7 +427,7 @@ void SX126xWakeup( void ) */ void SX126xAntSwOff( void ) { - + // No antenna switch available on this board design. } /*! @@ -401,7 +447,11 @@ uint32_t SX126xGetBoardTcxoWakeupTime( void ) */ uint8_t SX126xGetDeviceId( void ) { +#ifdef SX1261MBXBAS + return SX1261; +#elif defined(SX1262MBXCAS) || defined(SX1262MBXDAS) return SX1262; +#endif } /*! @@ -434,8 +484,17 @@ void SX126xSetOperatingMode( RadioOperatingModes_t mode ) */ void SX126xIoIrqInit( DioIrqHandler dioIrq ) { - //GpioSetInterrupt( &SX126x.DIO1, IRQ_RISING_EDGE, IRQ_HIGH_PRIORITY, dioIrq ); - + gpio_config_t io_conf = { + (1ULL< Date: Wed, 27 Dec 2023 01:08:45 -0500 Subject: [PATCH 5/9] Implement SX126x RTC functions for LoRaMac stack --- CMakeLists.txt | 1 + src/board/generic_esp32/generic-esp32-board.c | 79 ++++++++++++++++--- 2 files changed, 67 insertions(+), 13 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c00e313..68e790d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -62,6 +62,7 @@ idf_component_register(SRCS ${COMPONENT_SRCS} include_directories( $ENV{IDF_PATH}/components/driver/gpio/include $ENV{IDF_PATH}/components/driver/spi/include + $ENV{IDF_PATH}/components/esp_timer/include ) add_definitions(-DREGION_EU868=1) diff --git a/src/board/generic_esp32/generic-esp32-board.c b/src/board/generic_esp32/generic-esp32-board.c index 6cc8d2e..9ac7424 100644 --- a/src/board/generic_esp32/generic-esp32-board.c +++ b/src/board/generic_esp32/generic-esp32-board.c @@ -1,9 +1,10 @@ - +/* In this implementation, milliseconds units are used throughout. Ticks are milliseconds. */ #include "sdkconfig.h" #include "freertos/FreeRTOS.h" #include "esp_err.h" #include "esp_log.h" +#include "esp_timer.h" #include "driver/gpio.h" #include "driver/spi_common.h" @@ -13,9 +14,11 @@ // from LoRaMac #include "board.h" +#include "timer.h" // ANSI #include +#include #define ESP_INTR_FLAG_DEFAULT 0 @@ -23,6 +26,10 @@ #define KHZ_PER_MHZ 1000 #define HZ_PER_MHZ (HZ_PER_KHZ * KHZ_PER_MHZ) +#define MS_PER_S 1000 +#define US_PER_MS 1000 +#define US_PER_S (MS_PER_S * US_PER_MS) + #define SX126X_MAX_SPI_CLOCK_SPEED_MHZ 16 #define SX126X_NUM_COMMAND_BITS 8 #define SX126X_NUM_REGISTER_ADDRESS_BITS 16 @@ -48,13 +55,26 @@ static const char *TAG = "ESP32Board"; static portMUX_TYPE my_spinlock = portMUX_INITIALIZER_UNLOCKED; +static esp_timer_handle_t irq_timer_handle; +static uint32_t rtc_timer_context; +static uint32_t alarm_start_time; + +static void IrqTimerExpiryCallback(void* arg) { + TimerIrqHandler(); +} + void BoardInitMcu( void ) { } void BoardInitPeriph(void) { - esp_err_t ret; + // Create timer + const esp_timer_create_args_t timer_args = { + .callback = &IrqTimerExpiryCallback, + .name = "SX126X IRQ Timer" + }; + ESP_ERROR_CHECK(esp_timer_create(&timer_args, &irq_timer_handle)); lora_spi.miso = CONFIG_SX126X_SPI_MISO_GPIO; lora_spi.mosi = CONFIG_SX126X_SPI_MOSI_GPIO; @@ -262,8 +282,12 @@ void RtcBkupRead( uint32_t *data0, uint32_t *data1 ) */ uint32_t RtcGetCalendarTime( uint16_t *milliseconds ) { - *milliseconds = 29; - return 42 /* seconds */; + int64_t time_us = esp_timer_get_time(); + uint32_t time_s = (uint32_t)(time_us / US_PER_S); + + *milliseconds = (uint16_t)((time_us / US_PER_MS) % MS_PER_S); + + return time_s; } /*! @@ -283,7 +307,13 @@ uint32_t RtcGetMinimumTimeout( void ) */ uint32_t RtcGetTimerElapsedTime( void ) { - return 0; + int64_t current_time_ms; + uint32_t elapsed_time_ms; + + current_time_ms = esp_timer_get_time() / US_PER_MS; + elapsed_time_ms = current_time_ms - alarm_start_time; + + return elapsed_time_ms; } /*! @@ -293,7 +323,7 @@ uint32_t RtcGetTimerElapsedTime( void ) */ uint32_t RtcGetTimerValue( void ) { - return 0; + return (esp_timer_get_time() / US_PER_MS); } /*! @@ -304,7 +334,7 @@ uint32_t RtcGetTimerValue( void ) */ uint32_t RtcMs2Tick( TimerTime_t milliseconds ) { - return 0; + return milliseconds; } @@ -316,7 +346,7 @@ uint32_t RtcMs2Tick( TimerTime_t milliseconds ) */ TimerTime_t RtcTick2Ms( uint32_t tick ) { - return 0; + return tick; } @@ -327,7 +357,19 @@ TimerTime_t RtcTick2Ms( uint32_t tick ) */ uint32_t RtcSetTimerContext( void ) { - return 0; + rtc_timer_context = esp_timer_get_time() / US_PER_MS; + + return rtc_timer_context; +} + + +/*! + * \brief Gets the RTC timer reference + * + * \retval value Timer reference value in ticks + */ +uint32_t RtcGetTimerContext( void ) { + return rtc_timer_context; } @@ -340,7 +382,16 @@ uint32_t RtcSetTimerContext( void ) */ void RtcSetAlarm( uint32_t timeout ) { - + uint32_t timeout_us = timeout * US_PER_MS; + + alarm_start_time = esp_timer_get_time() / US_PER_MS; + + if (esp_timer_is_active(irq_timer_handle)) { + ESP_ERROR_CHECK(esp_timer_restart(irq_timer_handle, timeout_us)); + } + else { + ESP_ERROR_CHECK(esp_timer_start_once(irq_timer_handle, timeout_us)); + } } /*! @@ -348,7 +399,9 @@ void RtcSetAlarm( uint32_t timeout ) */ void RtcStopAlarm( void ) { - + if (esp_timer_is_active(irq_timer_handle)) { + ESP_ERROR_CHECK(esp_timer_stop(irq_timer_handle)); + } } @@ -487,8 +540,8 @@ void SX126xIoIrqInit( DioIrqHandler dioIrq ) gpio_config_t io_conf = { (1ULL< Date: Tue, 2 Jan 2024 13:15:00 -0500 Subject: [PATCH 6/9] Replace LoRaMac-node submodule with forked version - contains aes_encrypt() multiple definitions fix Linking error: .espressif/tools/xtensa-esp32s3-elf/esp-12.2.0_20230208/xtensa-esp32s3-elf/bin/../lib/gcc/xtensa-esp32s3-elf/12.2.0/../../../../xtensa-esp32s3-elf/bin/ld: esp-idf/wpa_supplicant/libwpa_supplicant.a(crypto_mbedtls.c.obj): in function `aes_encrypt': esp/esp-idf/components/wpa_supplicant/esp_supplicant/src/crypto/crypto_mbedtls.c:421: multiple definition of `aes_encrypt'; esp-idf/LoRaMac-node-esp32/libLoRaMac-node-esp32.a(aes.c.obj):src/LoRaMac-node/src/peripherals/soft-se/aes.c:569: first defined here collect2: error: ld returned 1 exit status ninja: build stopped: subcommand failed. --- .gitmodules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitmodules b/.gitmodules index b422b45..0a934ed 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ [submodule "src/LoRaMac-node"] path = src/LoRaMac-node - url = https://github.com/Lora-net/LoRaMac-node.git + url = https://github.com/boston-engineering/LoRaMac-node.git From 8d6cf6b9e6e6c8f424cfe56bb71dea0c243a3005 Mon Sep 17 00:00:00 2001 From: Brandon Dester Date: Thu, 4 Jan 2024 01:19:22 -0500 Subject: [PATCH 7/9] Cmake source files for LoRaMac-node library's US 915MHz band support. Remove hard-coding of RegionEU868 definition - should be determined by the application which regions are enabled. --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 68e790d..f980f89 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -36,8 +36,10 @@ set(COMPONENT_SRCS "src/LoRaMac-node/src/apps/LoRaMac/common/LmHandler/packages/LmhpClockSync.c" "src/LoRaMac-node/src/apps/LoRaMac/common/LmHandler/packages/LmhpCompliance.c" "src/LoRaMac-node/src/mac/region/Region.c" +"src/LoRaMac-node/src/mac/region/RegionBaseUS.c" "src/LoRaMac-node/src/mac/region/RegionCommon.c" "src/LoRaMac-node/src/mac/region/RegionEU868.c" +"src/LoRaMac-node/src/mac/region/RegionUS915.c" ) # idf.py build 2>&1 | tee LOG | grep "undefined reference" | sed -e 's/.*reference to//' | sort | uniq @@ -64,6 +66,4 @@ include_directories( $ENV{IDF_PATH}/components/driver/spi/include $ENV{IDF_PATH}/components/esp_timer/include ) - -add_definitions(-DREGION_EU868=1) add_definitions(-DSOFT_SE) From d4b7ed57435c4ce2c900b365e01cd84cfc47e4e1 Mon Sep 17 00:00:00 2001 From: Brandon Dester Date: Sun, 7 Jan 2024 22:35:35 -0500 Subject: [PATCH 8/9] Add some description to README.md --- README.md | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 384e180..5187c1a 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,15 @@ # LoRaMac-node-esp32 -ESP32 port of LoRaMac-node +#### ESP32 port of LoRaMac-node +Creates a Semtech SX126x compatible ESP32 component that pulls in all LoRaMac-node sources, allowing for a custom ESP32 board definition to be used. -This is work in progress - not usable yet +## Compatibility +This library is written for and is currently only compatible with Semtech SX126x LoRaWAN chips. + +## Configuration +- Running menuconfig with LoRaMac-node-esp32 added as a component will allow for configuration of SPI pins and the host to be used. +- Region(s) of operation must be selected by pulling in one of the pre-processor definitions used by LoRaMac-node, e.g. `REGION_US915`. + - Regions are listed in `src/LoRaMac-node/src/mac/region/Region.h` + +## Notes +- `SX126xWaitOnBusy()` indefinitely blocks with a busy wait, waiting for a low BUSY signal +- This is work in progress - not usable yet From 3da81363b1a283acf82393137f0e4517fc22a6ac Mon Sep 17 00:00:00 2001 From: Brandon Dester Date: Thu, 1 Feb 2024 12:43:51 -0500 Subject: [PATCH 9/9] DO NOT PUSH TO MAIN - Update to use master commit for LoRaMac-node BE fork --- src/LoRaMac-node | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/LoRaMac-node b/src/LoRaMac-node index dc2e680..5aa59d0 160000 --- a/src/LoRaMac-node +++ b/src/LoRaMac-node @@ -1 +1 @@ -Subproject commit dc2e680ad9fd6e8177c62dbc89b3d5046de9c1b1 +Subproject commit 5aa59d026a883e00f3226d74101b2a73735ca99e