commit 8e8c972cbec56d8de31847981149cde4a8fc16cd
parent cbb0ac4dac395ea287cf5e7cc211f81aef16e78f
Author: Louis Burda <quent.burda@gmail.com>
Date: Fri, 16 Dec 2022 20:31:06 +0100
Add stdio command interface, matrix syncing and basic evaluation
Diffstat:
10 files changed, 207 insertions(+), 58 deletions(-)
diff --git a/src/hid.c b/src/hid.c
@@ -1,4 +1,10 @@
#include "hid.h"
+#include "split.h"
+#include "matrix.h"
+#include "keysym.h"
+#include "keymap.h"
+
+#include <pico/types.h>
void
hid_init(void)
@@ -6,6 +12,37 @@ hid_init(void)
}
+inline uint
+layer_index(uint x, uint y)
+{
+ if (y < KEY_ROWS)
+ return y * KEY_COLS + x;
+ else
+ return y * KEY_COLS + (KEY_COLS - 1 - x);
+}
+
+bool
+hid_gen_report(uint8_t *report)
+{
+ int keycnt;
+ uint x, y, p;
+
+ keycnt = 0;
+ for (y = 0; y < KEY_ROWS * 2; y++) {
+ for (x = 0; x < KEY_COLS; x++) {
+ if (!state_matrix[y * KEY_COLS + x])
+ continue;
+ if (keycnt >= 6) break;
+ DEBUG("PRESS %i %", x, y);
+ p = layer_index(x, y);
+ report[keycnt] = TO_CODE(keymap_layers_de[0][p]);
+ keycnt++;
+ }
+ }
+
+ return keycnt > 0;
+}
+
void
hid_task(void)
{
diff --git a/src/hid.h b/src/hid.h
@@ -1,4 +1,8 @@
#pragma once
+#include <stdbool.h>
+#include <stdint.h>
+
void hid_init(void);
+bool hid_gen_report(uint8_t *keycode);
void hid_task(void);
diff --git a/src/keymap.c b/src/keymap.c
@@ -1,4 +1,5 @@
#include "keymap.h"
+#include "keycode.h"
#include "keysym_de.h"
#include "board.h"
#include "util.h"
@@ -19,8 +20,8 @@
0x0, 0x0, 0x0, K44, K45, K46, \
K51, K52, K53, K54, K55, K56, \
K61, K62, K63, K64, K65, K66, \
- K31, K32, K33, K34, K35, K36, \
- K31, K32, K33, 0x0, 0x0, 0x0, \
+ K71, K72, K73, K74, K75, K76, \
+ K81, K82, K83, 0x0, 0x0, 0x0, \
}
enum {
@@ -31,12 +32,12 @@ static const uint32_t layer_base_de[] = KEYMAP(
_______, DE_Q , DE_W , DE_F , DE_P , DE_B ,
_______, DE_A , DE_R , DE_S , DE_T , DE_G ,
_______, DE_Z , DE_X , DE_C , DE_D , DE_V ,
- KC_LALT, KC_LGUI, _______,
+ KC_LGUI, KC_LALT, _______,
- _______, DE_J , DE_L , DE_U , DE_Y , _______,
- _______, DE_N , DE_E , DE_I , DE_O , _______,
- _______, DE_H , DE_SCLN, DE_DOT , DE_MINS, _______,
- _______, _______, _______
+ DE_J , DE_L , DE_U , DE_Y , DE_QUOT, _______,
+ DE_M , DE_N , DE_E , DE_I , DE_O , _______,
+ DE_K , DE_H , DE_COMM, DE_DOT , DE_MINS, _______,
+ _______, KC_SPC , KC_LCTL
);
const uint32_t *keymap_layers_de[] = {
diff --git a/src/main.c b/src/main.c
@@ -1,6 +1,7 @@
#include "board.h"
#include "usb_stdio.h"
#include "matrix.h"
+#include "keysym.h"
#include "split.h"
#include "led.h"
#include "hid.h"
@@ -21,9 +22,9 @@
#include <stdio.h>
#include <string.h>
-bool send_hid_report(int id, bool state);
+bool send_hid_report(int id);
+void cdc_task(void);
-static bool hit_state = false;
const uint32_t **keymap_layers = keymap_layers_de;
int
@@ -39,9 +40,11 @@ main(void)
while (true) {
tud_task();
+ cdc_task();
led_task();
split_task();
//hid_task();
+ send_hid_report(REPORT_ID_MIN);
}
return 0;
@@ -88,7 +91,6 @@ tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts)
void
tud_cdc_rx_cb(uint8_t itf)
{
- printf("ALIVE\n\r");
}
uint16_t
@@ -111,20 +113,22 @@ tud_hid_report_complete_cb(uint8_t instance,
uint8_t id;
for (id = report[0] + 1; id < REPORT_ID_MAX; id++) {
- if (send_hid_report(id, hit_state))
+ if (send_hid_report(id))
break;
}
}
bool
-send_keyboard_report(bool state)
+send_keyboard_report(void)
{
static bool cleared = true;
- uint8_t keycode[6] = { 0 };
+ uint8_t report[6] = { 0 };
+ bool any;
- if (state) {
- keycode[0] = HID_KEY_A;
- tud_hid_keyboard_report(REPORT_ID_KEYBOARD, 0, keycode);
+ any = hid_gen_report(report);
+
+ if (any) {
+ tud_hid_keyboard_report(REPORT_ID_KEYBOARD, 0, report);
cleared = false;
return true;
} else if (!cleared) {
@@ -169,30 +173,85 @@ send_consumer_control_report(bool state)
}
bool
-send_hid_report(int id, bool state)
+send_hid_report(int id)
{
+ if (!tud_hid_ready()) return false;
+
switch (id) {
case REPORT_ID_KEYBOARD:
- return send_keyboard_report(state);
+ return send_keyboard_report();
case REPORT_ID_MOUSE:
- return send_mouse_report(state);
+ return send_mouse_report(false);
case REPORT_ID_CONSUMER_CONTROL:
- return send_consumer_control_report(state);
+ return send_consumer_control_report(false);
}
return false;
}
void
-send_hid_report_timed(void)
+process_cmd(char *cmd)
{
- const uint32_t period_ms = 1000;
- static uint32_t start_ms = 0;
+ char *arg, *tok;
+
+ tok = strchr(cmd, ' ');
+ if (tok) {
+ *tok = '\0';
+ arg = tok + 1;
+ } else {
+ arg = cmd + strlen(cmd);
+ }
- if (!tud_hid_ready()) return;
+ if (!strcmp(cmd, "log")) {
+ if (!strcmp(arg, "")) {
+ printf("Levels: debug, info, warn, err\n");
+ } else if (!strcmp(arg, "debug")) {
+ loglevel = LOG_DEBUG;
+ } else if (!strcmp(arg, "info")) {
+ loglevel = LOG_INFO;
+ } else if (!strcmp(arg, "warn")) {
+ loglevel = LOG_WARN;
+ } else if (!strcmp(arg, "warn")) {
+ loglevel = LOG_ERR;
+ } else {
+ printf("Invalid log level: %s\n", arg);
+ }
+ } else {
+ printf("Invalid command: %s\n", cmd);
+ }
+}
+
+void
+cdc_task(void)
+{
+ static char cmdbuf[256];
+ static int cmdlen = 0;
+ char c;
- hit_state = (board_millis() - start_ms < period_ms);
- if (hit_state) start_ms += period_ms;
+ do {
+ if (cmdlen)
+ tud_task();
- send_hid_report(REPORT_ID_MIN, hit_state);
+ if (tud_cdc_connected() && tud_cdc_available()
+ && tud_cdc_read(&c, 1)) {
+ if (c == '\r' || c == '\n') {
+ printf("\n");
+ tud_cdc_write_flush();
+ if (cmdlen) {
+ cmdbuf[cmdlen] = 0;
+ process_cmd(cmdbuf);
+ cmdlen = 0;
+ }
+ } else if (c == 4) {
+ printf("ALIVE!\n");
+ } else if (cmdlen == ARRLEN(cmdbuf)) {
+ printf("\n--- cmd too long ---\n");
+ cmdlen = 0;
+ } else {
+ printf("%c", c);
+ tud_cdc_write_flush();
+ cmdbuf[cmdlen++] = c;
+ }
+ }
+ } while (cmdlen);
}
diff --git a/src/matrix.c b/src/matrix.c
@@ -1,6 +1,7 @@
#include "keymap.h"
#include "matrix.h"
+#include "split.h"
#include "pico/types.h"
#include "hardware/gpio.h"
#include "hardware/timer.h"
@@ -12,23 +13,23 @@ static const uint matrix_col_pins[] = { 29, 28, 27, 26, 22, 20 };
static_assert(ARRLEN(matrix_row_pins) == KEY_ROWS);
static_assert(ARRLEN(matrix_col_pins) == KEY_COLS);
-bool prev_state_matrix[KEY_COUNT];
-bool state_matrix[KEY_COUNT];
+bool prev_state_matrix[KEY_COUNT * 2];
+bool state_matrix[KEY_COUNT * 2];
void
matrix_init(void)
{
uint x, y;
- for (y = 0; y < KEY_ROWS; y++) {
- gpio_init(matrix_row_pins[y]);
- gpio_set_dir(matrix_row_pins[y], GPIO_IN);
- gpio_pull_up(matrix_row_pins[y]);
- }
-
for (x = 0; x < KEY_COLS; x++) {
gpio_init(matrix_col_pins[x]);
- gpio_set_dir(matrix_col_pins[x], GPIO_OUT);
+ gpio_set_dir(matrix_col_pins[x], GPIO_IN);
+ gpio_pull_up(matrix_col_pins[x]);
+ }
+
+ for (y = 0; y < KEY_ROWS; y++) {
+ gpio_init(matrix_row_pins[y]);
+ gpio_set_dir(matrix_row_pins[y], GPIO_OUT);
}
}
@@ -36,18 +37,50 @@ void
scan_matrix(void)
{
bool pressed;
- uint x, y;
+ uint x, y, p;
memcpy(prev_state_matrix, state_matrix, sizeof(state_matrix));
for (y = 0; y < KEY_ROWS; y++) {
+ gpio_put(matrix_row_pins[y], 0);
+ busy_wait_us(5);
+ for (x = 0; x < KEY_COLS; x++) {
+ pressed = !gpio_get(matrix_col_pins[x]);
+ p = MAT_OFFSET(SPLIT_SIDE) + y * KEY_COLS + x;
+ state_matrix[p] = pressed;
+ }
+ gpio_put(matrix_row_pins[y], 1);
+ busy_wait_us(5);
+ }
+}
+
+uint32_t
+matrix_encode_half(int side)
+{
+ uint32_t mask;
+ uint x, y, p;
+
+ mask = 0;
+ for (y = 0; y < KEY_ROWS; y++) {
+ for (x = 0; x < KEY_COLS; x++) {
+ p = MAT_OFFSET(side) + y * KEY_COLS + x;
+ if (state_matrix[p])
+ mask |= 1 << (y * KEY_COLS + x);
+ }
+ }
+
+ return mask;
+}
+
+void
+matrix_decode_half(int side, uint32_t mask)
+{
+ uint x, y, p;
+
+ for (y = 0; y < KEY_ROWS; y++) {
for (x = 0; x < KEY_COLS; x++) {
- gpio_put(matrix_col_pins[x], 0);
- busy_wait_us(5);
- pressed = !gpio_get(matrix_row_pins[y]);
- state_matrix[y * KEY_COLS + x] = pressed;
- gpio_put(matrix_col_pins[x], 1);
- busy_wait_us(5);
+ p = MAT_OFFSET(side) + y * KEY_COLS + x;
+ state_matrix[p] = (mask >> (y * KEY_COLS + x)) & 1;
}
}
}
diff --git a/src/matrix.h b/src/matrix.h
@@ -8,10 +8,13 @@
#define KEY_COLS 6
#define KEY_COUNT (KEY_ROWS * KEY_COLS)
+#define MAT_OFFSET(side) ((side) == LEFT ? 0 : KEY_COUNT)
+
void matrix_init(void);
void scan_matrix(void);
+uint32_t matrix_encode_half(int side);
+void matrix_decode_half(int side, uint32_t);
-extern bool prev_state_matrix[KEY_COUNT];
-extern bool state_matrix[KEY_COUNT];
-extern uint32_t sym_matrix[KEY_COUNT];
+extern bool prev_state_matrix[KEY_COUNT * 2];
+extern bool state_matrix[KEY_COUNT * 2];
diff --git a/src/split.c b/src/split.c
@@ -26,12 +26,6 @@
#define UART_TIMEOUT 20
#define UART_BAUD 9600
-#define LEFT 0
-#define RIGHT 1
-
-#define SLAVE 0
-#define MASTER 1
-
#if SPLIT_SIDE == LEFT
#define UART_TX_PIN 0
#define UART_RX_PIN 1
@@ -68,6 +62,7 @@ static uint uart_tx_sm_offset;
static uint uart_rx_sm;
static uint uart_rx_sm_offset;
+static uint32_t halfmat;
static bool scan_pending = false;
void
@@ -237,6 +232,8 @@ handle_cmd(uint8_t cmd)
WARN("Got SCAN_MATRIX_RESP as slave");
break;
}
+ if (uart_recv((uint8_t *) &halfmat, 4) != 4)
+ WARN("Incomplete matrix received");
scan_pending = false;
return;
case CMD_STDIO_PUTS:
@@ -295,6 +292,7 @@ split_task(void)
WARN("Slave matrix scan timeout");
} else {
DEBUG("Slave matrix scan success");
+ matrix_decode_half(SPLIT_OPP(SPLIT_SIDE), halfmat);
}
scan_pending = false;
} else {
@@ -309,6 +307,8 @@ split_task(void)
cmd = CMD_SCAN_MATRIX_RESP;
DEBUG("Sending SCAN_MATRIX_RESP %i", cmd);
ASSERT(uart_send(&cmd, 1) == 1);
+ halfmat = matrix_encode_half(SPLIT_SIDE);
+ ASSERT(uart_send((uint8_t *) &halfmat, 4) == 4);
scan_pending = false;
}
}
diff --git a/src/split.h b/src/split.h
@@ -1,4 +1,12 @@
#pragma once
+#define LEFT 0
+#define RIGHT 1
+
+#define SLAVE 0
+#define MASTER 1
+
+#define SPLIT_OPP(x) ((x) == LEFT ? RIGHT : LEFT)
+
void split_init(void);
void split_task(void);
diff --git a/src/usb_stdio.c b/src/usb_stdio.c
@@ -1,5 +1,6 @@
#include "usb_stdio.h"
+#include "pico/stdio.h"
#include "pico/stdio/driver.h"
#include "tusb.h"
@@ -24,6 +25,7 @@ void
usb_stdio_flush(void)
{
tud_cdc_write_flush();
+ tud_task();
}
int
@@ -36,5 +38,6 @@ void
usb_stdio_init(void)
{
stdio_set_driver_enabled(&usb_stdio, true);
+ stdio_set_translate_crlf(&usb_stdio, true);
stdio_init_all();
}
diff --git a/src/util.c b/src/util.c
@@ -1,5 +1,6 @@
#include "util.h"
#include "board.h"
+#include "class/cdc/cdc_device.h"
#include "led.h"
#include "ws2812.h"
@@ -19,7 +20,7 @@ panic_task(const char *fmtstr, va_list ap, uint32_t sleep_ms)
static uint32_t start_ms = 0;
va_list cpy;
- if (!tud_cdc_available())
+ if (!tud_cdc_connected())
return;
if (!start_ms) start_ms = board_millis();
@@ -29,8 +30,8 @@ panic_task(const char *fmtstr, va_list ap, uint32_t sleep_ms)
va_copy(cpy, ap);
vprintf(fmtstr, cpy);
- printf("\n\r");
- stdio_flush();
+ printf("\n");
+ tud_cdc_write_flush();
start_ms += sleep_ms;
}
@@ -41,7 +42,7 @@ stdio_log(int level, const char *fmtstr, ...)
{
va_list ap;
- if (!tud_cdc_available())
+ if (!tud_cdc_connected())
return;
if (level > loglevel)
@@ -50,8 +51,8 @@ stdio_log(int level, const char *fmtstr, ...)
va_start(ap, fmtstr);
vprintf(fmtstr, ap);
va_end(ap);
- printf("\n\r");
- stdio_flush();
+ printf("\n");
+ tud_cdc_write_flush();
}
void