// EncoderHandler.cpp #include "pico/stdlib.h" #include "EncoderHandler.h" #include "DisplayHandler.h" #include "globals.h" #include #include #include "hardware/pio.h" #include "quadrature_encoder.pio.h" static EncoderHandler* self = nullptr; EncoderHandler::EncoderHandler(DisplayHandler* display_handler) { this->display_handler = display_handler; self = this; encoder_pos = 0; button_pressed = 0; } void EncoderHandler::gpio_callback(uint gpio, uint32_t events) { uint64_t now = to_us_since_boot(get_absolute_time()); static uint64_t last_sw_time = 0; if (gpio == ENCODER_SW_PIN) { if (now - last_sw_time > 200000) { // 200ms debounce self->display_handler->handleClick(); last_sw_time = now; } } } void EncoderHandler::setup() { self = this; gpio_init(ENCODER_SW_PIN); gpio_set_dir(ENCODER_SW_PIN, GPIO_IN); gpio_pull_up(ENCODER_SW_PIN); gpio_set_irq_enabled_with_callback(ENCODER_SW_PIN, GPIO_IRQ_EDGE_FALL, true, &EncoderHandler::gpio_callback); PIO pio = pio0; uint offset = pio_add_program(pio, &quadrature_encoder_program); this->sm = pio_claim_unused_sm(pio, true); gpio_init(ENCODER_CLK_PIN); gpio_pull_up(ENCODER_CLK_PIN); gpio_init(ENCODER_DT_PIN); gpio_pull_up(ENCODER_DT_PIN); quadrature_encoder_program_init(pio, sm, ENCODER_CLK_PIN, 0); this->last_count = 0; } void EncoderHandler::update() { int32_t current_count = quadrature_encoder_get_count(pio0, this->sm); int32_t delta = current_count - last_count; if (abs(delta) >= TICKS_PER_DETENT) { if (delta < 0) { display_handler->moveCursor(); } else { display_handler->moveCursor(0); } last_count = current_count - (delta % TICKS_PER_DETENT); } }