Files

109 lines
3.1 KiB
C

/**
* @file ui_task.c
* @brief UI task - button handling and OLED display
*/
#include <stdio.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "esp_log.h"
#include "driver/gpio.h"
#include "app_main.h"
static const char *TAG = "ui";
/* Button debounce parameters */
#define DEBOUNCE_MS 50
#define LONG_PRESS_MS 1000
/* Button state tracking */
typedef struct {
uint8_t gpio;
uint8_t last_state;
uint32_t last_change_ms;
uint32_t press_start_ms;
uint8_t long_press_sent;
} btn_state_t;
static btn_state_t buttons[] = {
{BTN_UP_GPIO, 1, 0, 0, 0},
{BTN_DOWN_GPIO, 1, 0, 0, 0},
{BTN_SEL_GPIO, 1, 0, 0, 0},
{BTN_BACK_GPIO, 1, 0, 0, 0},
};
static void handle_button(btn_state_t *btn, uint8_t idx)
{
uint8_t state = gpio_get_level(btn->gpio);
uint32_t now = xTaskGetTickCount() * portTICK_PERIOD_MS;
if (state != btn->last_state) {
btn->last_change_ms = now;
btn->last_state = state;
if (state == 0) { /* Pressed */
btn->press_start_ms = now;
btn->long_press_sent = 0;
ui_event_t evt = {.key = idx, .action = 0}; /* press */
if (ui_event_queue) {
xQueueSend(ui_event_queue, &evt, 0);
}
} else { /* Released */
if (!btn->long_press_sent) {
ui_event_t evt = {.key = idx, .action = 1}; /* release */
if (ui_event_queue) {
xQueueSend(ui_event_queue, &evt, 0);
}
}
}
} else if (state == 0 && !btn->long_press_sent) {
/* Check for long press */
if ((now - btn->press_start_ms) >= LONG_PRESS_MS) {
btn->long_press_sent = 1;
ui_event_t evt = {.key = idx, .action = 2}; /* long press */
if (ui_event_queue) {
xQueueSend(ui_event_queue, &evt, 0);
}
}
}
}
void ui_task(void *pvParameters)
{
ESP_LOGI(TAG, "UI task started");
/* OLED initialization would go here */
/* display_init(); */
/* Button state initialization */
for (int i = 0; i < 4; i++) {
buttons[i].last_state = gpio_get_level(buttons[i].gpio);
}
while (1) {
/* Scan buttons */
for (int i = 0; i < 4; i++) {
handle_button(&buttons[i], i);
}
/* Process UI events */
ui_event_t evt;
while (xQueueReceive(ui_event_queue, &evt, 0)) {
const char *key_names[] = {"UP", "DOWN", "SEL", "BACK"};
const char *actions[] = {"press", "release", "long_press"};
ESP_LOGI(TAG, "Button: %s - %s", key_names[evt.key], actions[evt.action]);
}
/* Read ADC data for display */
adc_data_t adc_data;
if (adc_data_queue && xQueuePeek(adc_data_queue, &adc_data, 0)) {
/* Update OLED display with ADC data */
/* display_update(&adc_data); */
}
vTaskDelay(pdMS_TO_TICKS(20)); /* 50Hz scan rate */
}
}