From 7141d876806712555ea484b5e8326ab061f5a6c4 Mon Sep 17 00:00:00 2001 From: "Morgan 'ARR\\!' Allen" Date: Wed, 17 Nov 2021 13:49:32 -0800 Subject: [PATCH] functional multi-device support --- include/esp32-lora.h | 3 +++ main/esp32-lora.c | 60 ++++++++++++++++++++++++++++++++------------ 2 files changed, 47 insertions(+), 16 deletions(-) diff --git a/include/esp32-lora.h b/include/esp32-lora.h index 39e08f5..81ee6de 100644 --- a/include/esp32-lora.h +++ b/include/esp32-lora.h @@ -77,6 +77,8 @@ #define EV_DIO0 (1 << 0) +#define ERR_LOR_ID_MISMATCH (00) + enum freq { F433, F866, F915 } lora32_freq; @@ -137,6 +139,7 @@ double lora32_calc_datarate(lora32_cfg_t *lora); void lora32_dump_regs(lora32_cfg_t *lora); void lora32_enable_continuous_rx(lora32_cfg_t *lora); void lora32_enable_cad(lora32_cfg_t *lora); +void lora32_toggle_reset(lora32_cfg_t *lora); void lora32_send(lora32_cfg_t *config, uint8_t *data, uint8_t len); void lora32_set_bandwidth(lora32_cfg_t *lora, uint8_t bw); void lora32_set_coding_rate(lora32_cfg_t *lora, uint8_t cr); diff --git a/main/esp32-lora.c b/main/esp32-lora.c index 327ca55..353dd2e 100644 --- a/main/esp32-lora.c +++ b/main/esp32-lora.c @@ -2,6 +2,7 @@ #include #include "freertos/FreeRTOS.h" +#include "freertos/semphr.h" #include "freertos/task.h" #include "freertos/queue.h" @@ -25,7 +26,13 @@ const long bandwidths[] = { 7.8e3, 10.4e3, 15.6e3, 20.8e3, 31.25e3, 41.7e3, 62.5 const char *TAG = "LoRa32"; +static QueueHandle_t dio_event_queue; +static TaskHandle_t dio_task_handle; +static SemaphoreHandle_t spi_semaphore; + uint8_t lora32_read_reg(lora32_cfg_t *lora, uint8_t address) { + //xSemaphoreTake(spi_semaphore, portMAX_DELAY); + spi_transaction_t t; memset(&t, 0, sizeof(spi_transaction_t)); @@ -38,10 +45,14 @@ uint8_t lora32_read_reg(lora32_cfg_t *lora, uint8_t address) { ESP_LOGV(TAG, "<%2X<%2X", address, t.rx_data[1]); + //xSemaphoreGive(spi_semaphore); + return t.rx_data[1]; } void lora32_write_reg(lora32_cfg_t *lora, uint8_t address, uint8_t value) { + //xSemaphoreTake(spi_semaphore, portMAX_DELAY); + spi_device_handle_t spi = lora->spi; spi_transaction_t t; @@ -55,6 +66,8 @@ void lora32_write_reg(lora32_cfg_t *lora, uint8_t address, uint8_t value) { t.tx_data[1] = value; ESP_ERROR_CHECK(spi_device_transmit(spi, &t)); + + //xSemaphoreGive(spi_semaphore); }; double lora32_calc_datarate(lora32_cfg_t *lora) { @@ -326,24 +339,25 @@ static void lora32_handle_receive(lora32_cfg_t *lora) { lora->receive(lora, len); } -static void IRAM_ATTR lora32_dio0_task(void *arg) { - lora32_cfg_t *lora = (lora32_cfg_t*)arg; - ESP_LOGD(TAG, "starting DIO0 handler task"); +static void IRAM_ATTR lora32_dio_task(void *arg) { + // allocate lora32_cfg_t to receive config from Queu + lora32_cfg_t *lora = malloc(sizeof(lora32_cfg_t)); + ESP_LOGI(TAG, "starting DIO handler task"); while(1) { - EventBits_t evbits = xEventGroupWaitBits(lora->handle.events, EV_DIO0, pdTRUE, pdFALSE, portMAX_DELAY); + // wait for event over Queue + if(xQueueReceive(dio_event_queue, (void*)lora, portMAX_DELAY) != pdPASS) continue; - // timed out, loop and continue to wait - if(evbits == 0) continue; - - ESP_LOGD(TAG, "handling DIO0"); + // need a better way to log which event and from which config + //ESP_LOGI(TAG, "handling DIO0 on GPIO%d", lora->dio0); spi_device_acquire_bus(lora->spi, portMAX_DELAY); // read IRQ flags uint8_t irqs = lora32_read_reg(lora, REG_IRQ_FLAGS); ESP_LOGD(TAG, "reading irqs: %02X", irqs); - // clear IRQ flags + + // clear IRQ flags by writing mask back ESP_LOGD(TAG, "clearing irqs"); lora32_write_reg(lora, REG_IRQ_FLAGS, irqs); @@ -388,9 +402,7 @@ void lora32_read_data(lora32_cfg_t *lora, uint8_t *data) { } static void IRAM_ATTR lora32_on_dio0(void *arg) { - BaseType_t woken = pdFALSE; - - xEventGroupSetBitsFromISR(((lora32_cfg_t*)arg)->handle.events, EV_DIO0, &woken); + xQueueSend(dio_event_queue, arg, (TickType_t)0); } uint8_t lora32_spi_init(lora32_cfg_t *lora) { @@ -415,6 +427,10 @@ uint8_t lora32_spi_init(lora32_cfg_t *lora) { } uint8_t lora32_init(lora32_cfg_t *lora) { + if(spi_semaphore == NULL) { + spi_semaphore = xSemaphoreCreateMutex(); + } + gpio_config_t io_conf; io_conf.intr_type = GPIO_PIN_INTR_DISABLE; io_conf.mode = GPIO_MODE_OUTPUT; @@ -477,7 +493,7 @@ uint8_t lora32_init(lora32_cfg_t *lora) { // TODO setup shouldn't be based on just receive callback if(lora->receive != NULL) { - ESP_LOGI(TAG, "Setting callback handler"); + ESP_LOGI(TAG, "Setting GPIO Interrupt"); io_conf.intr_type = GPIO_PIN_INTR_POSEDGE; io_conf.pin_bit_mask = (1ULL << lora->dio0); @@ -488,10 +504,22 @@ uint8_t lora32_init(lora32_cfg_t *lora) { gpio_set_intr_type(lora->dio0, GPIO_INTR_POSEDGE); - gpio_isr_register((void*)lora32_on_dio0, (void*)lora, 0, NULL); + // the DIO interrupt handling for every device is done from one task + if(dio_task_handle == NULL) { + ESP_LOGI(TAG, "Setting callback handler and ISR service"); - // this should probably be high priority - xTaskCreate(&lora32_dio0_task, "lora32_dio0_task", 14048, (void*)lora, 6, NULL); + // enable global ISR service + gpio_install_isr_service(0); + + dio_event_queue = xQueueCreate(10, sizeof(lora32_cfg_t)); + + // this should probably be high priority + xTaskCreate(&lora32_dio_task, "lora32_dio_task", 4096, NULL, 6, &dio_task_handle); + } + + // add ISR handler to the global service started (once) above + ESP_LOGI(TAG, "Installing ISR handler for GPIO%d", lora->dio0); + gpio_isr_handler_add(lora->dio0, lora32_on_dio0, lora); } return 1;