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
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);
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)
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
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;