#include "ui.h" #include "stm32h7a3xx.h" #include "stm32h7xx_hal.h" #include "stm32h7xx_hal_gpio.h" #include "tx_api.h" #include "hx8357d.h" #include "main.h" #include void ui_thread_entry(ULONG _) { GPIO_TypeDef *button_ports[NUM_BUTTONS] = {BTN1_GPIO_Port, BTN2_GPIO_Port, BTN3_GPIO_Port, BTN4_GPIO_Port, BTN5_GPIO_Port, BTN6_GPIO_Port}; uint16_t button_pins[NUM_BUTTONS] = {BTN1_Pin, BTN2_Pin, BTN3_Pin, BTN4_Pin, BTN5_Pin, BTN6_Pin}; GPIO_PinState button_states[NUM_BUTTONS] = {GPIO_PIN_RESET}; uint32_t button_change_times[NUM_BUTTONS] = {HAL_GetTick()}; while (1) { for (int i = 0; i < NUM_BUTTONS; i++) { GPIO_PinState state = HAL_GPIO_ReadPin(button_ports[i], button_pins[i]); if (state != button_states[i]) { uint32_t now = HAL_GetTick(); if (state == GPIO_PIN_RESET && now - button_change_times[i]) { // Button release event! ButtonMessage msg = {.kind = UMK_BTN_RELEASED, .number = i}; tx_queue_send(&gui_button_queue, &msg, TX_NO_WAIT); } button_change_times[i] = now; button_states[i] = state; } } // Release so other threads can get scheduled tx_thread_sleep(1); } } void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) { // This gets called when an edge on one of the encoder pins is detected. static uint32_t last_change[NUM_ENCS * 2] = {0}; static GPIO_PinState last_state[NUM_ENCS * 2] = {GPIO_PIN_RESET}; if (GPIO_Pin == ENC2B_Pin) { // ENC2A and ENC2B share an interrupt line, so the HAL calls this callback // once with each pin. Since we already handled the interrupt once for // ENC2A, we can just ignore it now. } uint32_t now = HAL_GetTick(); uint16_t pin_a, pin_b; int idx_a, idx_b; ButtonMessage msg; if (GPIO_Pin == ENC1A_Pin || GPIO_Pin == ENC1B_Pin) { pin_a = ENC1A_Pin; pin_b = ENC1B_Pin; idx_a = 0; idx_b = 1; msg.number = 0; } else { pin_a = ENC2A_Pin; pin_b = ENC2B_Pin; idx_a = 2; idx_b = 3; msg.number = 1; } // All encoder pins are on port E GPIO_PinState state_a = HAL_GPIO_ReadPin(GPIOE, pin_a); GPIO_PinState state_b = HAL_GPIO_ReadPin(GPIOE, pin_b); int a_changed = state_a != last_state[idx_a]; int b_changed = state_b != last_state[idx_b]; last_state[idx_a] = state_a; last_state[idx_b] = state_b; if (state_a == GPIO_PIN_RESET && state_b == GPIO_PIN_RESET) { // Second falling edge, direction depends on which pin changed last if (a_changed && b_changed) { // This shouldn't happen. Ignore this event. last_change[idx_a] = now; last_change[idx_b] = now; return; } else if (a_changed) { last_change[idx_a] = now; msg.kind = UMK_ENC_CCW; } else if (b_changed) { last_change[idx_b] = now; msg.kind = UMK_ENC_CW; } else { // This shouldn't happen. Ignore this event. return; } tx_queue_send(&gui_button_queue, &msg, TX_NO_WAIT); } }