From d70239a20314e1c0b96d2a2a19c3435ec77402ed Mon Sep 17 00:00:00 2001 From: Martin Mares Date: Fri, 18 Apr 2025 23:45:38 +0200 Subject: [PATCH] Waiting room: Scanning keyboard --- waiting/README | 16 ++++----- waiting/firmware/main.c | 78 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 86 insertions(+), 8 deletions(-) diff --git a/waiting/README b/waiting/README index 9c47db3..44c88a9 100644 --- a/waiting/README +++ b/waiting/README @@ -14,14 +14,14 @@ I2C2 display 1602: HD44780U controller via PCF8574 expander, needs pull-up to 5V BluePill LED | PC13 GND | | PC14 5V | | PC15 PB9 | - | PA0 PB8 | TIM4_CH3 - Neopixel data (needs pull-up) - | PA1 PB7 | - | PA2 PB6 | - | PA3 PB5 | - | PA4 PB4 | - | PA5 PB3 | - | PA6 PA15 | - | PA7 PA12 | +kbd2 - col 1 | PA0 PB8 | TIM4_CH3 - Neopixel data (needs pull-up) +kbd3 - col 2 | PA1 PB7 | +kbd4 - col 3 | PA2 PB6 | +kbd5 - col 4 | PA3 PB5 | +kbd6 - row 1 | PA4 PB4 | +kbd7 - row 2 | PA5 PB3 | +kbd8 - row 3 | PA6 PA15 | +kbd9 - row 4 | PA7 PA12 | | PB0 PA11 | | PB1 PA10 | RXD1 - debugging console I2C2_SCL - display (pu) | PB10 PA9 | TXD1 - debugging console diff --git a/waiting/firmware/main.c b/waiting/firmware/main.c index d1f7681..f0c552c 100644 --- a/waiting/firmware/main.c +++ b/waiting/firmware/main.c @@ -58,6 +58,11 @@ static void gpio_init(void) gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO13); gpio_clear(GPIOC, GPIO13); + // PA0-7 = keyboard + gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_OPENDRAIN, 0xf0); + gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_INPUT_FLOAT, 0x0f); + gpio_set(GPIOA, 0xff); + // PB8 = data for Neopixel gpio_set_mode(GPIOB, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_ALTFN_OPENDRAIN, GPIO8); @@ -218,6 +223,13 @@ static void display_char(byte ch) display_write_nibble(((ch << 4) & 0xf0) | LCD_BIT_RS); } +static void display_hex8(uint x) +{ + uint h = (x >> 4) & 0x0f, l = x & 0x0f; + display_char('0' + h + (h >= 10 ? 7 : 0)); + display_char('0' + l + (l >= 10 ? 7 : 0)); +} + static void display_string(const char *str) { while (*str) @@ -268,6 +280,54 @@ static void display_init(void) debug_puts("Display ready\n"); } +/*** Keyboard ***/ + +static byte keyboard_step; +static u16 keyboard_tmp; +static u16 keyboard_debounce_mask; +static byte keyboard_debounce_cnt; +static u16 keyboard_mask; +static char keyboard_char; + +#define KEYBOARD_DEBOUNCE_CYCLES 5 + +static const char keyboard_map[] = "123A456B789C*0#D"; + +static void keyboard_scan(void) +{ + // The first step does nothing since no row is activated. + uint cols = gpio_get(GPIOA, 0x0f) ^ 0x0f; + keyboard_tmp |= cols << 4 * keyboard_step; + + if (++keyboard_step == 4) { + if (keyboard_tmp == keyboard_debounce_mask) { + if (keyboard_debounce_cnt == KEYBOARD_DEBOUNCE_CYCLES) { + keyboard_debounce_cnt++; + keyboard_mask = keyboard_tmp; + if (keyboard_mask && !(keyboard_mask & (keyboard_mask - 1))) { + for (uint i=0; i<16; i++) + if (keyboard_mask & (1 << i)) { + keyboard_char = keyboard_map[i]; + break; + } + } else { + keyboard_char = 0; + } + } else if (keyboard_debounce_cnt < KEYBOARD_DEBOUNCE_CYCLES) { + keyboard_debounce_cnt++; + } + } else { + keyboard_debounce_mask = keyboard_tmp; + keyboard_debounce_cnt = 0; + } + keyboard_step = 0; + keyboard_tmp = 0; + } + + gpio_set(GPIOA, 0xf0); + gpio_clear(GPIOA, 0x10 << keyboard_step); +} + /*** Neopixels ***/ #if 0 @@ -571,8 +631,26 @@ int main(void) u32 last_blink = 0; // u32 last_send = 0; + uint key_column = 0; for (;;) { + keyboard_scan(); +#if 0 + if (keyboard_mask != last_key_mask) { + last_key_mask = keyboard_mask; + display_goto(1, 0); + display_hex8((keyboard_mask >> 8) & 0xff); + display_hex8(keyboard_mask & 0xff); + } +#endif + if (keyboard_char) { + if (key_column < 15) { + display_goto(1, key_column++); + display_char(keyboard_char); + } + keyboard_char = 0; + } + if (ms_ticks - last_blink >= 300) { debug_led_toggle(); last_blink = ms_ticks; -- 2.47.3