Files
AudioMixer/main.c
T
2026-09-07 14:40:16 +03:00

176 lines
4.5 KiB
C

#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 <stdio.h>
#include <stdlib.h>
#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);
}
int main(void) {
led_init();
stdio_init_all();
tusb_init();
/*
* Pump USB hard until mounted (COM appears). Never sleep 100ms between
* tud_task — that breaks Windows enumeration again.
*/
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();
}
/* Optional: wait a bit for the serial monitor to open (still pumping). */
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-v3 %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());
stdio_flush();
lcd_init();
/* Skip RDID after init — bitbang read was corrupting the panel (bottom noise). */
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();
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_needs_tick()) {
ui_mixer_draw(st);
st->ui_dirty = false;
}
tight_loop_contents();
sleep_us(200);
}
}