#include "pins.h" #include "encoder.h" #include "lcd.h" #include "hid_mixer.h" #include "ui_mixer.h" #include "protocol.h" #include "pico/stdlib.h" #include "pico/stdio_usb.h" #include "hardware/adc.h" #include "hardware/gpio.h" #include "tusb.h" #include #include #define PIN_ONBOARD_LED 25 #define POT_ADC_INPUT 0 #define POT_DEADBAND_PCT 1 static encoder_t enc1; static encoder_t enc2; static int32_t last_pos1; static int32_t last_pos2; static void led_init(void) { gpio_init(PIN_ONBOARD_LED); gpio_set_dir(PIN_ONBOARD_LED, GPIO_OUT); } static void pot_init(void) { adc_init(); adc_gpio_init(PIN_POT); adc_select_input(POT_ADC_INPUT); } static uint8_t pot_read_pct(void) { adc_select_input(POT_ADC_INPUT); uint32_t sum = 0; for (int i = 0; i < 8; i++) { sum += adc_read(); } uint32_t raw = sum / 8u; return (uint8_t)((raw * 100u) / 4095u); } static void toggle_init(void) { gpio_init(PIN_TOGGLE); gpio_set_dir(PIN_TOGGLE, GPIO_IN); gpio_pull_up(PIN_TOGGLE); } static void toggle_poll(void) { static absolute_time_t next; static int last = -1; if (!time_reached(next)) { return; } next = make_timeout_time_ms(30); int level = gpio_get(PIN_TOGGLE) ? 1 : 0; if (level == last) { return; } last = level; /* active-low: 0 = closed to GND */ printf("TOGGLE GP%d = %d (%s)\n", PIN_TOGGLE, level, level ? "open" : "closed"); stdio_flush(); } int main(void) { led_init(); stdio_init_all(); tusb_init(); absolute_time_t mount_deadline = make_timeout_time_ms(3000); absolute_time_t next_blink = make_timeout_time_ms(80); bool led = false; while (!time_reached(mount_deadline) && !tud_mounted()) { tud_task(); if (time_reached(next_blink)) { led = !led; gpio_put(PIN_ONBOARD_LED, led); next_blink = make_timeout_time_ms(80); } tight_loop_contents(); } absolute_time_t cdc_deadline = make_timeout_time_ms(8000); while (!time_reached(cdc_deadline) && !tud_cdc_connected()) { tud_task(); if (time_reached(next_blink)) { led = !led; gpio_put(PIN_ONBOARD_LED, led); next_blink = make_timeout_time_ms(200); } tight_loop_contents(); } gpio_put(PIN_ONBOARD_LED, 1); printf("\n=== Ausiomixer firmware ===\n"); printf("FW=ui-lvgl %s %s\n", __DATE__, __TIME__); printf("VID=0x%04X PID=0x%04X mounted=%d cdc=%d\n", AUSIO_USB_VID, AUSIO_USB_PID, (int)tud_mounted(), (int)tud_cdc_connected()); printf("TOGGLE test: GP%d (pull-up, closed→GND prints closed)\n", PIN_TOGGLE); stdio_flush(); lcd_init(); toggle_init(); ui_mixer_init(); hid_mixer_init(); encoder_pins_t p1 = { .clk_gpio = PIN_ENC1_CLK, .dt_gpio = PIN_ENC1_DT, .sw_gpio = PIN_ENC1_SW, .invert_dir = true, }; encoder_pins_t p2 = { .clk_gpio = PIN_ENC2_CLK, .dt_gpio = PIN_ENC2_DT, .sw_gpio = PIN_ENC2_SW, .invert_dir = false, }; encoder_init(&enc1, &p1); encoder_init(&enc2, &p2); pot_init(); last_pos1 = encoder_get_position(&enc1); last_pos2 = encoder_get_position(&enc2); mixer_state_t *st = hid_mixer_state(); ui_mixer_draw(st); uint8_t last_pot = 0xFF; absolute_time_t next_pot = make_timeout_time_ms(30); while (true) { hid_mixer_task(); ui_mixer_task(); toggle_poll(); encoder_poll(&enc1); encoder_poll(&enc2); int32_t p1pos = encoder_get_position(&enc1); int32_t p2pos = encoder_get_position(&enc2); if (p1pos != last_pos1) { int32_t d = p1pos - last_pos1; if (d > 127) { d = 127; } if (d < -127) { d = -127; } hid_mixer_add_enc1((int8_t)d); last_pos1 = p1pos; } if (p2pos != last_pos2) { int32_t d = p2pos - last_pos2; if (d > 127) { d = 127; } if (d < -127) { d = -127; } hid_mixer_add_enc2((int8_t)d); last_pos2 = p2pos; } if (encoder_btn_was_pressed(&enc1)) { hid_mixer_set_e1_sw(true); } if (encoder_btn_was_pressed(&enc2)) { hid_mixer_set_e2_sw(true); } if (time_reached(next_pot)) { uint8_t pct = pot_read_pct(); if (last_pot == 0xFF || abs((int)pct - (int)last_pot) >= POT_DEADBAND_PCT) { hid_mixer_set_pot(pct); last_pot = pct; } next_pot = make_timeout_time_ms(40); } if (st->ui_dirty) { ui_mixer_draw(st); st->ui_dirty = false; } tight_loop_contents(); sleep_us(200); } }