Some checks failed
check / check (push) Has been cancelled
First commit of the repo. Contents beyond the v0.1 simulator and layout: - Full Pico 2 W firmware (firmware/app, drivers, engine port, host test). - BANK page and 404 mode A/B removed; learned pads play exactly what was learned. - 404/MiniFreak renamed to KIT/SYNTH throughout (jacks, code, sim, docs, layout labels; wiring rebuilt). - ROLL returns to page select after a re-roll; a freshly learned track turns on. - LCD contrast 66. - ROOT and SCALE pages: 21 scales, AUTO = the seed picks; global and sticky. Intended music change: the scale table grew from 8 to 21 and AUTO picks from all of them, so every seed's scale changed. Vectors regenerated with npm run vectors, plus new key-override cases. Flash record is now version 2. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
51 lines
1.9 KiB
C
51 lines
1.9 KiB
C
#include "inputs.h"
|
|
#include "hardware/gpio.h"
|
|
#include "pico/time.h"
|
|
|
|
static const uint8_t ROWS[3] = {2, 3, 5};
|
|
static const uint8_t COLS[4] = {6, 7, 8, 9};
|
|
static const uint8_t SWITCHES[3] = {13, 14, 12}; /* IN_SEED, IN_RUN, IN_PUSH */
|
|
#define DEBOUNCE_MS 10 /* a change must hold this long to count */
|
|
#define LOCKOUT_MS 40 /* then the input ignores further changes this long (worn switches chatter) */
|
|
|
|
/* (1,1) KICK (1,2) KICK 2 (1,3) SNARE (1,4) none; (2,1) HAT (2,2) HAT 16 (2,3) PERC (2,4) GHOST;
|
|
(3,1) BASS (3,2) MEL A (3,3) MEL B (3,4) PAD */
|
|
const int8_t INPUT_KEY_TRACK[12] = { 0, 1, 2, -1, 4, 5, 6, 3, 7, 8, 9, 10 };
|
|
|
|
static uint32_t state;
|
|
static uint8_t count[IN_COUNT], lockout[IN_COUNT];
|
|
|
|
static void input_pullup(uint pin){ gpio_init(pin); gpio_set_dir(pin, GPIO_IN); gpio_pull_up(pin); }
|
|
|
|
void inputs_init(void){
|
|
int i;
|
|
for(i = 0; i < 3; i++) input_pullup(ROWS[i]);
|
|
for(i = 0; i < 4; i++){ input_pullup(COLS[i]); gpio_put(COLS[i], 0); } /* idle: Hi-Z with pull-up (E9) */
|
|
for(i = 0; i < 3; i++) input_pullup(SWITCHES[i]);
|
|
}
|
|
|
|
static uint32_t raw_read(void){
|
|
uint32_t raw = 0;
|
|
int r, c;
|
|
for(c = 0; c < 4; c++){
|
|
gpio_set_dir(COLS[c], GPIO_OUT); /* output latch is already 0: drive low */
|
|
busy_wait_us(5); /* settle */
|
|
for(r = 0; r < 3; r++) if(!gpio_get(ROWS[r])) raw |= 1u << (r * 4 + c);
|
|
gpio_set_dir(COLS[c], GPIO_IN); /* back to Hi-Z, pull-up holds it high */
|
|
}
|
|
for(r = 0; r < 3; r++) if(!gpio_get(SWITCHES[r])) raw |= 1u << (IN_SEED + r);
|
|
return raw;
|
|
}
|
|
|
|
uint32_t inputs_scan(void){
|
|
uint32_t raw = raw_read();
|
|
int i;
|
|
for(i = 0; i < IN_COUNT; i++){
|
|
uint32_t bit = 1u << i;
|
|
if(lockout[i]){ lockout[i]--; count[i] = 0; continue; }
|
|
if((raw & bit) != (state & bit)){ if(++count[i] >= DEBOUNCE_MS){ state ^= bit; count[i] = 0; lockout[i] = LOCKOUT_MS; } }
|
|
else count[i] = 0;
|
|
}
|
|
return state;
|
|
}
|