diff options
1 files changed, 32 insertions, 9 deletions
| -rw-r--r-- | Year 3/Internet of things/goam/main/buttons.c | 41 |
diff --git a/Year 3/Internet of things/goam/main/buttons.c b/Year 3/Internet of things/goam/main/buttons.c index 9aa3cf4..6dd99ee 100644 --- a/Year 3/Internet of things/goam/main/buttons.c +++ b/Year 3/Internet of things/goam/main/buttons.c @@ -25,20 +25,43 @@ static void IRAM_ATTR gpio_button_interrupt_handler(void* arg) static void (*button_on[40])() = { NULL }; static void (*button_off[40])() = { NULL }; -static void on_button_event(void* arg) +#define BUTTON_ACTION_COMPLETED_BIT 0b1 + +static TaskHandle_t on_button_event_handle = NULL; + +static void button_action(void* arg) { + uint32_t io_num = *(uint32_t*)arg; + if (gpio_get_level(io_num)) { + if (button_on[io_num]) button_on[io_num](); + } + else { + if (button_off[io_num]) button_off[io_num](); + } + + xTaskNotify(on_button_event_handle, BUTTON_ACTION_COMPLETED_BIT, eSetBits); + vTaskDelete(NULL); +} + +static void on_button_event_task(void* arg) { uint32_t io_num; + long unsigned int notification = 0; while (true) { if (!xQueueReceive(gpio_button_queue, &io_num, portMAX_DELAY)) continue; ESP_LOGD(TAG, "GPIO[%ld] intr, val: %d", io_num, gpio_get_level(io_num)); - if (gpio_get_level(io_num)) { - if (button_on[io_num]) button_on[io_num](); - } - else { - if (button_off[io_num]) button_off[io_num](); - } + // button_on/button_off functions require a lot of memory, but most of the time + // we won't be running them, so its more memory efficient to split them off into + // another task, which allocates a lot of memory, but then frees it + xTaskCreate(button_action, "button_action", 2048, &io_num, 10, NULL); + + // We want button_action to be "blocking", in GoAm there is only one button, so + // this logic is good enough. Under normal circumstances there should just be a + // check to not create another task for the same button action + do { + xTaskNotifyWait(ULONG_MAX, 0, ¬ification, 100 / portTICK_PERIOD_MS); + } while (!(notification & BUTTON_ACTION_COMPLETED_BIT)); // If any button was pressed, this effectively blocks all other button presses // that happened in the meantime. @@ -57,9 +80,9 @@ static void on_button_event(void* arg) void buttons_init() { //create a queue to handle gpio event from isr - gpio_button_queue = xQueueCreate(10, sizeof(uint32_t)); + gpio_button_queue = xQueueCreate(5, sizeof(uint32_t)); //start gpio task - xTaskCreate(on_button_event, "on_button_event", 2048, NULL, 10, NULL); + xTaskCreate(on_button_event_task, "on_button_event_task", 768, NULL, 10, &on_button_event_handle); //install gpio isr service gpio_install_isr_service(ESP_INTR_FLAG_DEFAULT); |
