Get *basic* USB report sending working.

This commit is contained in:
Pete Johanson 2020-05-05 16:09:05 -04:00
parent fe961d54a3
commit a63a773983
8 changed files with 126 additions and 11 deletions

View file

@ -2,6 +2,7 @@
cmake_minimum_required(VERSION 3.13.1) cmake_minimum_required(VERSION 3.13.1)
list(APPEND BOARD_ROOT ${CMAKE_SOURCE_DIR}) list(APPEND BOARD_ROOT ${CMAKE_SOURCE_DIR})
list(APPEND DTS_ROOT ${CMAKE_SOURCE_DIR})
find_package(Zephyr) find_package(Zephyr)
project(zmk) project(zmk)
@ -10,5 +11,6 @@ project(zmk)
# find_package(Zephyr) which defines the target. # find_package(Zephyr) which defines the target.
target_sources(app PRIVATE src/kscan.c) target_sources(app PRIVATE src/kscan.c)
target_sources(app PRIVATE src/keymap.c) target_sources(app PRIVATE src/keymap.c)
target_sources(app PRIVATE src/usb_hid.c)
target_sources(app PRIVATE src/main.c) target_sources(app PRIVATE src/main.c)

View file

@ -1,3 +1,4 @@
#include <dt-bindings/zmk/keys.h>
/ { / {
chosen { chosen {
@ -9,17 +10,17 @@
default: layer_0 { default: layer_0 {
label = "Default"; label = "Default";
keys = <10 2 3 8>; keys = <KC_A KC_B KC_C KC_D>;
}; };
lower: layer_1 { lower: layer_1 {
label = "Default"; label = "Lower";
keys = <9 2 3 5>; keys = <KC_D KC_C KC_B KC_A>;
}; };
raise: layer_2 { raise: layer_2 {
label = "Default"; label = "Raise";
keys = <8 1 2 3>; keys = <KC_C KC_D KC_A KC_B>;
}; };
}; };
@ -34,6 +35,7 @@
compatible = "gpio-kscan"; compatible = "gpio-kscan";
label = "Handwired GPIO KSCAN matrix"; label = "Handwired GPIO KSCAN matrix";
diode-direction = "row2col";
row-gpios = <&arduino_header 8 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>, row-gpios = <&arduino_header 8 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>,
<&arduino_header 10 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; <&arduino_header 10 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;
col-gpios = <&arduino_header 13 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>, col-gpios = <&arduino_header 13 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>,

View file

@ -0,0 +1,5 @@
#define KC_A 4
#define KC_B 5
#define KC_C 6
#define KC_D 7

View file

@ -1,4 +1,6 @@
# CONFIG_RUST=y
# CONFIG_RUST_ALLOC_POOL=y
CONFIG_KSCAN=y CONFIG_KSCAN=y
CONFIG_KSCAN_GPIO=y CONFIG_KSCAN_GPIO=y
CONFIG_USB=y
CONFIG_USB_DEVICE_STACK=y
CONFIG_USB_DEVICE_HID=y
CONFIG_USB_DEVICE_PRODUCT="ZMK Firmware"

View file

@ -12,6 +12,7 @@
LOG_MODULE_REGISTER(zmk_kscan, CONFIG_ZMK_KSCAN_LOG_LEVEL); LOG_MODULE_REGISTER(zmk_kscan, CONFIG_ZMK_KSCAN_LOG_LEVEL);
#include "keymap.h" #include "keymap.h"
#include "usb_hid.h"
#define ZMK_KSCAN_EVENT_STATE_PRESSED 0 #define ZMK_KSCAN_EVENT_STATE_PRESSED 0
#define ZMK_KSCAN_EVENT_STATE_RELEASED 1 #define ZMK_KSCAN_EVENT_STATE_RELEASED 1
@ -35,7 +36,6 @@ static void zmk_kscan_callback(struct device *dev, u32_t row, u32_t column, bool
.column = column, .column = column,
.state = (pressed ? ZMK_KSCAN_EVENT_STATE_PRESSED : ZMK_KSCAN_EVENT_STATE_RELEASED) .state = (pressed ? ZMK_KSCAN_EVENT_STATE_PRESSED : ZMK_KSCAN_EVENT_STATE_RELEASED)
}; };
printk("Row: %d, col: %d, pressed: %s\n", ev.row, ev.column, (pressed ? "true" : "false"));
k_msgq_put(&zmk_kscan_msgq, &ev, K_NO_WAIT); k_msgq_put(&zmk_kscan_msgq, &ev, K_NO_WAIT);
k_work_submit(&msg_processor.work); k_work_submit(&msg_processor.work);
@ -44,13 +44,17 @@ static void zmk_kscan_callback(struct device *dev, u32_t row, u32_t column, bool
void zmk_kscan_process_msgq(struct k_work *item) void zmk_kscan_process_msgq(struct k_work *item)
{ {
struct zmk_kscan_event ev; struct zmk_kscan_event ev;
printk("process messages!\n");
while(k_msgq_get(&zmk_kscan_msgq, &ev, K_NO_WAIT) == 0) { while(k_msgq_get(&zmk_kscan_msgq, &ev, K_NO_WAIT) == 0) {
bool pressed = (ev.state == ZMK_KSCAN_EVENT_STATE_PRESSED); bool pressed = (ev.state == ZMK_KSCAN_EVENT_STATE_PRESSED);
// TODO: More than basic mapping, layers, etc. // TODO: More than basic mapping, layers, etc.
enum hid_kbd_code code = zmk_keymap_keycode_from_position(ev.row, ev.column); enum hid_kbd_code code = zmk_keymap_keycode_from_position(ev.row, ev.column);
printk("Row: %d, col: %d, code: %d, pressed: %s\n", ev.row, ev.column, code, (pressed ? "true" : "false")); LOG_DBG("Row: %d, col: %d, code: %d, pressed: %s\n", ev.row, ev.column, code, (pressed ? "true" : "false"));
if (pressed) {
zmk_usb_hid_press_key(code);
} else {
zmk_usb_hid_release_key(code);
}
} }
} }
@ -62,7 +66,6 @@ int zmk_kscan_init(char* name)
return -EINVAL; return -EINVAL;
} }
k_work_init(&msg_processor.work, zmk_kscan_process_msgq); k_work_init(&msg_processor.work, zmk_kscan_process_msgq);
kscan_config(dev, zmk_kscan_callback); kscan_config(dev, zmk_kscan_callback);

View file

@ -9,6 +9,7 @@
#include <devicetree.h> #include <devicetree.h>
#include "kscan.h" #include "kscan.h"
#include "usb_hid.h"
void main(void) void main(void)
{ {
@ -18,4 +19,9 @@ void main(void)
printk("Keyboard Scan Init Failed\n"); printk("Keyboard Scan Init Failed\n");
return; return;
} }
if (zmk_usb_hid_init() < 0) {
printk("USB HID Init Failed\n");
return;
}
} }

81
src/usb_hid.c Normal file
View file

@ -0,0 +1,81 @@
#include <device.h>
#include <usb/usb_device.h>
#include <usb/class/usb_hid.h>
LOG_MODULE_REGISTER(zmk_usb_hid, CONFIG_ZMK_USB_HID_LOG_LEVEL);
static const u8_t hid_report_desc[] = HID_KEYBOARD_REPORT_DESC();
static enum usb_dc_status_code usb_status;
static struct device *hid_dev;
static u8_t report[8] = { 0x00, 0x00 };
#define KEY_OFFSET 0x02
#define MAX_KEYS 6
int zmk_usb_hid_press_key(enum hid_kbd_code code)
{
if (usb_status == USB_DC_SUSPEND) {
return usb_wakeup_request();
}
for (int idx = 0; idx < MAX_KEYS; idx++) {
if (report[idx + KEY_OFFSET] != 0U) {
continue;
}
report[idx + KEY_OFFSET] = code;
return hid_int_ep_write(hid_dev, report, sizeof(report), NULL);
}
return -EINVAL;
}
int zmk_usb_hid_release_key(enum hid_kbd_code code)
{
for (int idx = 0; idx < MAX_KEYS; idx++) {
if (report[idx + KEY_OFFSET] != code) {
continue;
}
report[idx + KEY_OFFSET] = 0U;
return hid_int_ep_write(hid_dev, report, sizeof(report), NULL);
}
return -EINVAL;
}
void usb_hid_status_cb(enum usb_dc_status_code status, const u8_t *params)
{
usb_status = status;
};
int zmk_usb_hid_init()
{
int usb_enable_ret;
hid_dev = device_get_binding("HID_0");
if (hid_dev == NULL) {
LOG_ERR("Unable to locate HID device");
return -EINVAL;
}
usb_hid_register_device(hid_dev,
hid_report_desc, sizeof(hid_report_desc),
NULL);
usb_hid_init(hid_dev);
usb_enable_ret = usb_enable(usb_hid_status_cb);
if (usb_enable_ret != 0) {
LOG_ERR("Unable to enable USB");
return -EINVAL;
}
return 0;
}

14
src/usb_hid.h Normal file
View file

@ -0,0 +1,14 @@
#ifndef ZMK_USB_HID
#define ZMK_USB_HID
#include <usb/usb_device.h>
#include <usb/class/usb_hid.h>
int zmk_usb_hid_init();
// TODO: Modifiers!
int zmk_usb_hid_press_key(enum hid_kbd_code code);
int zmk_usb_hid_release_key(enum hid_kbd_code code);
#endif