109 lines
3.1 KiB
C
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 */
|
|
}
|
|
}
|