Initial commit - sync AliceRC to Gitea
This commit is contained in:
@@ -0,0 +1,108 @@
|
||||
/**
|
||||
* @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 */
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user