diff --git a/.gitignore b/.gitignore index 6b744e2..5feb2e7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ build/ sdkconfig +dev_keys.txt diff --git a/Kconfig b/Kconfig index d489ec2..1f3acba 100644 --- a/Kconfig +++ b/Kconfig @@ -1,7 +1,7 @@ menu "The Things Network" choice TTN_LORA_FREQ - prompt "TTN LoRa Frequency" + prompt "TTN LoRa frequency" default TTN_LORA_FREQ_NONE help LoRa frequency must match the geographic region the device is operated in. @@ -19,7 +19,7 @@ config TTN_LORA_FREQ_US_915 endchoice choice TTN_RADIO_CHIP - prompt "TTN Radio Chip" + prompt "TTN radio chip" default TTN_RADIO_SX1276_77_78_79 help The chip type used for LoRa radio. @@ -32,4 +32,38 @@ config TTN_RADIO_SX1276_77_78_79 endchoice +choice TTN_TIMER + prompt "Timer" + default TTN_TIMER_1_GROUP_0 + help + A timer is used to implement the LoRaWAN protocol. This selects the ESP32's timer. + +config TTN_TIMER_0_GROUP_0 + bool "Timer 0 of group 0" + +config TTN_TIMER_1_GROUP_0 + bool "Timer 1 of group 0" + +config TTN_TIMER_0_GROUP_1 + bool "Timer 0 of group 1" + +config TTN_TIMER_1_GROUP_1 + bool "Timer 1 of group 1" + +endchoice + +config TTN_SPI_FREQ + int "SPI frequency (in Hz)" + default 10000000 + help + SPI frequency to communicate between ESP32 and SX127x radio chip + +config TTN_BG_TASK_PRIO + int "Background task priority" + default 10 + help + Priority of task running in the background and communicating with + the LoRaWAN radio chip. It needs a high priority as the timing is crucial. + Higher numbers indicate higher priority. + endmenu diff --git a/README.md b/README.md index e20604a..8256ec1 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,39 @@ # ttn-esp32 -The Things Network client for ESP-IDF (ESP32) + +**The Things Network device library for ESP-IDF (ESP32)** + +This ESP32 component provides LoRaWAN communication with [The Things Network](https://www.thethingsnetwork.org/). It supports OTAA (over-the-air activation), uplink and downlink messages. + +## Installation + +Install the component by adding it as a git submodule: + + git submodule add https://github.com/manuelbl/ttn-esp32.git components/ttn-esp32 + git submodule update --init --recursive + +The frequency plan must be configured by running `make menuconfig`. Otherwise the component will not compile. In the menu it can be found at *Components* / *The Things Network*. + +More to follow... + +## Resources + +### SPI bus and pins + +Before the TTN device is configured, the SPI bus / host (`SPI_HOST`, `HSPI_HOST` or `VSPI_HOST`) must be configured by calling `spi_bus_initialize()`. In the SPI configuration, the pin number for SCK, MISO and MOSI are specified. + +The pin number of NSS (the radio chip's SPI chip select) is specified by calling `TheThingsNetwork::configurePins()`. + +The SPI bus frequency can be changed by running `make menuconfig`. + +### SX127x pins + +Except for the SPI pins, the pins connected to the SX127x radio chip are configured by calling `TheThingsNetwork::configurePins()`. The pins *RXTX* and *RTS* are optional. The chip can be used without connecting them. + +### Timer + +To implement the LoRaWAN protocol, a timer is needed. The ESP32 has four timers. By default, + timer 1 of timer group 0 is used. It can be changed by running `make menuconfig`. + +### Background thread + +Most of the LoRaWAN code is run in a background process with high priority (as the timing is crucial). The default priority is 10. It can be changed by running `make menuconfig`. diff --git a/src/config.h b/src/config.h index 30cf054..caaa969 100644 --- a/src/config.h +++ b/src/config.h @@ -23,7 +23,7 @@ extern "C" { #elif defined(CONFIG_TTN_LORA_FREQ_US_915) #define CFG_us915 1 #else -#error TTN LoRa frequency must be configured +#error TTN LoRa frequency must be configured using 'make menuconfig' #endif #if defined(CONFIG_TTN_RADIO_SX1272_73) @@ -31,7 +31,23 @@ extern "C" { #elif defined(CONFIG_TTN_RADIO_SX1276_77_78_79) #define CFG_sx1276_radio 1 #else -#error TTN LoRa radio chip must be configured +#error TTN LoRa radio chip must be configured using 'make menuconfig' +#endif + +#if defined(CONFIG_TTN_TIMER_0_GROUP_0) +#define TTN_TIMER TIMER_0 +#define TTN_TIMER_GROUP TIMER_GROUP_0 +#elif defined(CONFIG_TTN_TIMER_1_GROUP_0) +#define TTN_TIMER TIMER_1 +#define TTN_TIMER_GROUP TIMER_GROUP_0 +#elif defined(CONFIG_TTN_TIMER_0_GROUP_1) +#define TTN_TIMER TIMER_0 +#define TTN_TIMER_GROUP TIMER_GROUP_1 +#elif defined(CONFIG_TTN_TIMER_1_GROUP_1) +#define TTN_TIMER TIMER_1 +#define TTN_TIMER_GROUP TIMER_GROUP_1 +#else +#error TTN timer must be configured using 'make menuconfig' #endif // 16 μs per tick diff --git a/src/hal_esp32.c b/src/hal_esp32.c index 3125475..da00221 100755 --- a/src/hal_esp32.c +++ b/src/hal_esp32.c @@ -26,7 +26,7 @@ static const char *TAG = "ttn_hal"; lmic_pinmap lmic_pins; typedef enum { - DIO0, + DIO0 = 0, DIO1, DIO2, TIMER, @@ -46,7 +46,7 @@ static QueueHandle_t dio_queue; void IRAM_ATTR dio_irq_handler(void *arg) { uint64_t now; - timer_get_counter_value(TIMER_GROUP_0, TIMER_1, &now); + timer_get_counter_value(TTN_TIMER_GROUP, TTN_TIMER, &now); event_t ev = (long)arg; BaseType_t higher_prio_task_woken = pdFALSE; queue_item_t item = { @@ -182,7 +182,7 @@ static void hal_spi_init() // init device spi_device_interface_config_t spi_device_intf_config = { .mode = 0, - .clock_speed_hz = 10000000, + .clock_speed_hz = CONFIG_TTN_SPI_FREQ, .command_bits = 0, .address_bits = 8, .spics_io_num = lmic_pins.nss, @@ -281,8 +281,6 @@ static void hal_time_init() { ESP_LOGI(TAG, "Starting initialisation of timer"); - timer_group_t timer_group = TIMER_GROUP_0; - timer_idx_t timer_idx = TIMER_1; timer_config_t config = { .alarm_en = false, .counter_en = false, @@ -291,10 +289,10 @@ static void hal_time_init() .auto_reload = false, .divider = 1280 }; - timer_init(timer_group, timer_idx, &config); - timer_set_counter_value(timer_group, timer_idx, 0x0); - timer_isr_register(timer_group, timer_idx, timer_irq_handler, NULL, ESP_INTR_FLAG_IRAM, NULL); - timer_start(timer_group, timer_idx); + timer_init(TTN_TIMER_GROUP, TTN_TIMER, &config); + timer_set_counter_value(TTN_TIMER_GROUP, TTN_TIMER, 0x0); + timer_isr_register(TTN_TIMER_GROUP, TTN_TIMER, timer_irq_handler, NULL, ESP_INTR_FLAG_IRAM, NULL); + timer_start(TTN_TIMER_GROUP, TTN_TIMER); ESP_LOGI(TAG, "Finished initalisation of timer"); } @@ -302,16 +300,16 @@ static void hal_time_init() u4_t hal_ticks() { uint64_t val; - timer_get_counter_value(TIMER_GROUP_0, TIMER_1, &val); + timer_get_counter_value(TTN_TIMER_GROUP, TTN_TIMER, &val); return (u4_t)val; } void hal_waitUntil(u4_t time) { nextTimerEvent = time; - timer_set_alarm(TIMER_GROUP_0, TIMER_1, TIMER_ALARM_DIS); - timer_set_alarm_value(TIMER_GROUP_0, TIMER_1, nextTimerEvent); - timer_set_alarm(TIMER_GROUP_0, TIMER_1, TIMER_ALARM_EN); + timer_set_alarm(TTN_TIMER_GROUP, TTN_TIMER, TIMER_ALARM_DIS); + timer_set_alarm_value(TTN_TIMER_GROUP, TTN_TIMER, nextTimerEvent); + timer_set_alarm(TTN_TIMER_GROUP, TTN_TIMER, TIMER_ALARM_EN); hal_wait(WAIT_FOR_TIMER); } @@ -326,7 +324,7 @@ void hal_wakeUp() { u1_t hal_checkTimer(u4_t time) { uint64_t now; - timer_get_counter_value(TIMER_GROUP_0, TIMER_1, &now); + timer_get_counter_value(TTN_TIMER_GROUP, TTN_TIMER, &now); if (time <= now) return 1; if (time - now < 5) @@ -356,9 +354,9 @@ void hal_sleep() if (hal_wait(CHECK_IO)) return; - timer_set_alarm(TIMER_GROUP_0, TIMER_1, TIMER_ALARM_DIS); - timer_set_alarm_value(TIMER_GROUP_0, TIMER_1, nextTimerEvent); - timer_set_alarm(TIMER_GROUP_0, TIMER_1, TIMER_ALARM_EN); + timer_set_alarm(TTN_TIMER_GROUP, TTN_TIMER, TIMER_ALARM_DIS); + timer_set_alarm_value(TTN_TIMER_GROUP, TTN_TIMER, nextTimerEvent); + timer_set_alarm(TTN_TIMER_GROUP, TTN_TIMER, TIMER_ALARM_EN); hal_wait(WAIT_FOR_ANY_EVENT); } @@ -399,7 +397,7 @@ void hal_init() } void hal_startBgTask() { - xTaskCreate(hal_bgTask, "ttn_lora_task", 1024 * 4, (void* )0, 10, NULL); + xTaskCreate(hal_bgTask, "ttn_lora_task", 1024 * 4, NULL, CONFIG_TTN_BG_TASK_PRIO, NULL); } void hal_failed(const char *file, u2_t line)