diff options
author | uvok | 2025-07-18 20:08:30 +0200 |
---|---|---|
committer | uvok | 2025-07-18 20:08:30 +0200 |
commit | 4b2dd3b9f97a7bdf3a0cef36c9e12658f299bfc4 (patch) | |
tree | d3171f815d781646d11024c125080ab7312311c4 /src | |
parent | 64e6ae46579c4a0b30291d30a47857a7b6111eeb (diff) |
Add GPIO interrupt processing
Diffstat (limited to 'src')
-rw-r--r-- | src/gpio.cpp | 71 | ||||
-rw-r--r-- | src/main.cpp | 2 |
2 files changed, 72 insertions, 1 deletions
diff --git a/src/gpio.cpp b/src/gpio.cpp index d7dcd7b..cf26fb3 100644 --- a/src/gpio.cpp +++ b/src/gpio.cpp @@ -1,18 +1,57 @@ #include "badge/gpio.h" -#include <Arduino.h> +#include "badge/config.h" + +#include <Arduino.h> #define BUTTON_PIN 0 +#if UVOK_EPAP_BOARD == BOARD_ESP32_CROWPANEL +// Elecrow +#define EXIT_KEY 1 +#define HOME_KEY 2 +#define NEXT_KEY 4 +#define OK_KEY 5 +#define PRV_KEY 6 +#endif + static unsigned long pressedTime = 0; static unsigned long releasedTime = 0; +static void gpio_loop(void *); + +typedef uint32_t pin_notification_t; + +#define GPIO_STACK 2048 +#define GPIO_QUEUE_LEN 4 + +static StaticTask_t gpio_task; +static StackType_t gpio_stack[GPIO_STACK / sizeof(StackType_t)]; + +static StaticQueue_t gpio_queue_storage; +static uint8_t gpio_queue_content[GPIO_QUEUE_LEN * sizeof(pin_notification_t)]; +static QueueHandle_t gpio_q; + +static ARDUINO_ISR_ATTR void gpio_pin_irq(void *); + void de::uvok::badge::gpio_init(void) { + xTaskCreateStatic(gpio_loop, "gpio", GPIO_STACK, NULL, configMAX_PRIORITIES - 1, gpio_stack, &gpio_task); + gpio_q = xQueueCreateStatic(4, sizeof(pin_notification_t), &(gpio_queue_content[0]), &gpio_queue_storage); +#if UVOK_EPAP_BOARD == BOARD_ESP32_CROWPANEL + uint8_t inPins[] = {EXIT_KEY, HOME_KEY, NEXT_KEY, OK_KEY, PRV_KEY}; + for (uint8_t p : inPins) + { + pinMode(p, GPIO_MODE_INPUT); + // simply use pin number as arg + attachInterruptArg(p, gpio_pin_irq, (void *)(ptrdiff_t)p, CHANGE); + } +#endif } long de::uvok::badge::gpio_poll(void) { + int x = 0; static int lastState = HIGH; int buttonState = digitalRead(BUTTON_PIN); long pressDuration = 0; @@ -33,3 +72,33 @@ long de::uvok::badge::gpio_poll(void) return pressDuration; } + +static void gpio_loop(void *ctx) +{ + Serial.println("Starting GPIO loop"); + while (1) + { + pin_notification_t received; + if (xQueueReceive(gpio_q, &received, portMAX_DELAY) == pdTRUE) + { + const int level = (received & 0x100) ? HIGH : LOW; + const bool pressed = !level; + const int pin = received & 0xff; + Serial.printf("Pin %d was %s\n", pin, pressed ? "pressed" : "released"); + } + } +} + +static ARDUINO_ISR_ATTR void gpio_pin_irq(void *arg) +{ + uint8_t pin_no = (uint8_t)(ptrdiff_t)arg; + int pinLevel = digitalRead(pin_no); + + pin_notification_t send = (pinLevel << 8) | (pin_no); + BaseType_t wakeup = false; + xQueueSendFromISR(gpio_q, &send, &wakeup); + if (wakeup) + { + portYIELD_FROM_ISR(); + } +} diff --git a/src/main.cpp b/src/main.cpp index 4ac8465..ff24090 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -60,6 +60,8 @@ void setup() // gpio_wakeup_enable(GPIO_NUM_0, GPIO_INTR_LOW_LEVEL); // esp_sleep_enable_gpio_wakeup(); // esp_light_sleep_start(); + + de::uvok::badge::gpio_init(); } void loop() |