176 lines
4.5 KiB
C
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);
|
|
}
|
|
}
|