diff options
author | Tomasz Kramkowski <tk@the-tk.com> | 2017-05-25 21:56:08 +0100 |
---|---|---|
committer | Tomasz Kramkowski <tk@the-tk.com> | 2017-05-25 22:00:15 +0100 |
commit | acb403bcbcbc05256500083d1caea7e22ce4db11 (patch) | |
tree | ca9d4ebe25cc0bd000e4ec6fbad3eda46d8f3e03 /usb | |
parent | 69b0c9e9ca6af68e96e5ff665e61ad3be882a622 (diff) | |
download | fmk-acb403bcbcbc05256500083d1caea7e22ce4db11.tar.gz fmk-acb403bcbcbc05256500083d1caea7e22ce4db11.tar.xz fmk-acb403bcbcbc05256500083d1caea7e22ce4db11.zip |
Basic keyboard implementation
Diffstat (limited to 'usb')
-rw-r--r-- | usb/descriptors.h | 42 | ||||
-rw-r--r-- | usb/endpt1.c | 71 | ||||
-rw-r--r-- | usb/endpt1.h | 7 |
3 files changed, 73 insertions, 47 deletions
diff --git a/usb/descriptors.h b/usb/descriptors.h index df603a5..a81a0f7 100644 --- a/usb/descriptors.h +++ b/usb/descriptors.h @@ -67,17 +67,17 @@ unsigned char ds_conf[] = { 1, // Number of endpoints 3, // Interface class 1, // Interface sub class - 2, // Interface protocol + 1, // Interface protocol 0, // Interface string /* HID */ 9, // Length 33, // Descriptor type U16LE(0x0111), // HID Class spec version - 0, // Country code + 32, // Country code 1, // Number of descriptors 34, // Descriptor type -#define DS_HIDREP_SIZE 52 +#define DS_HIDREP_SIZE 29 U16LE(DS_HIDREP_SIZE), // Descriptor length /* Endpoint */ @@ -93,31 +93,19 @@ _Static_assert(sizeof ds_conf == DS_CONF_SIZE, "sizeof ds_conf != DS_CONF_SIZE") /* HID Report descriptor */ unsigned char ds_hidrep[] = { HR_USAGE_PAGE(1), HR_PAGE_GENERIC_DESKTOP, - HR_USAGE(1), HR_GD_MOUSE, + HR_USAGE(1), HR_GD_KEYBOARD, HR_COLLECTION(1), HR_APPLICATION, - HR_USAGE(1), HR_GD_POINTER, - HR_COLLECTION(1), HR_PHYSICAL, - HR_USAGE_PAGE(1), HR_PAGE_BUTTON, - HR_USAGE_MINIMUM(1), 1, - HR_USAGE_MAXIMUM(1), 5, - HR_LOGICAL_MINIMUM(1), 0, - HR_LOGICAL_MAXIMUM(1), 1, - HR_REPORT_COUNT(1), 5, - HR_REPORT_SIZE(1), 1, - HR_INPUT(1), HR_DATA | HR_VARIABLE | HR_ABSOLUTE | HR_BIT_FIELD, - HR_REPORT_COUNT(1), 1, - HR_REPORT_SIZE(1), 3, - HR_INPUT(1), HR_CONSTANT | HR_ARRAY | HR_ABSOLUTE | HR_BIT_FIELD, - HR_USAGE_PAGE(1), HR_PAGE_GENERIC_DESKTOP, - HR_USAGE(1), HR_GD_X, - HR_USAGE(1), HR_GD_Y, - HR_USAGE(1), HR_GD_WHEEL, - HR_LOGICAL_MINIMUM(1), -127, - HR_LOGICAL_MAXIMUM(1), 127, - HR_REPORT_SIZE(1), 8, - HR_REPORT_COUNT(1), 3, - HR_INPUT(1), HR_DATA | HR_VARIABLE | HR_RELATIVE | HR_BIT_FIELD, - HR_END_COLLECTION(0), + HR_USAGE_PAGE(1), HR_PAGE_KEYBOARD, + HR_USAGE_MINIMUM(1), 4, + HR_USAGE_MAXIMUM(1), 231, + HR_LOGICAL_MINIMUM(1), 0, + HR_LOGICAL_MAXIMUM(1), 1, + HR_REPORT_SIZE(1), 1, + HR_REPORT_COUNT(1), 228, + HR_INPUT(1), HR_DATA | HR_VARIABLE | HR_ABSOLUTE | HR_BIT_FIELD, + HR_REPORT_SIZE(1), 4, + HR_REPORT_COUNT(1), 1, + HR_INPUT(1), HR_CONSTANT | HR_ARRAY | HR_ABSOLUTE | HR_BIT_FIELD, HR_END_COLLECTION(0), }; _Static_assert(sizeof ds_hidrep == DS_HIDREP_SIZE, "sizeof ds_hidrep != DS_HIDREP_SIZE"); diff --git a/usb/endpt1.c b/usb/endpt1.c index 0580349..dcfc61b 100644 --- a/usb/endpt1.c +++ b/usb/endpt1.c @@ -19,40 +19,73 @@ #include <reg/usbotg.h> #include <stddef.h> #include <stdint.h> +#include <stdbool.h> + +#include <reg/gpio.h> #include "../uart.h" #include "bdt.h" #include "endpt1.h" +#include "keycodes.h" +#include "txhandler.h" #define MAX_PACKET 64 -static unsigned char report[4][4] = { - { 0x00, 5, 0, 0x00, }, - { 0x00, 0, 5, 0x00, }, - { 0x00, -5, 0, 0x00, }, - { 0x00, 0, -5, 0x00, }, -}; -static int nextrep; +static struct tx_ctx tx; +#define THIS_EP 1 +static volatile struct usb0_bd (* const this_bdt)[2] = usb_bdt[THIS_EP]; -void usb_endpt1_enable(void) +unsigned char report[29]; +volatile bool sendrep; + +void usb_endpt1_setkey(enum keycode keycode, bool state) { - nextrep = 0; + unsigned char byte, bit; + + if (keycode == KEY_NONE) + return; + + keycode -= 4; + byte = keycode / 8; + bit = keycode % 8; + + if (state) + SET_BIT(report[byte], bit); + else + UNSET_BIT(report[byte], bit); + + sendrep = true; +} - usb_bdt[1][BDT_TX][BDT_EVEN].addr = &report[0]; - usb_bdt[1][BDT_TX][BDT_EVEN].desc = USB0_BD_INIT(4, nextrep % 2); - nextrep++; +void usb_endpt1_send(void) +{ + if (!sendrep) + return; + if (!tx_isempty(&tx)) { + return; + } + + tx_que(&tx, report, sizeof report); + sendrep = false; +} + +void usb_endpt1_enable(void) +{ + this_bdt[BDT_TX][BDT_EVEN].addr = NULL; + this_bdt[BDT_TX][BDT_EVEN].desc = 0; - usb_bdt[1][BDT_TX][BDT_ODD].addr = &report[1]; - usb_bdt[1][BDT_TX][BDT_ODD].desc = USB0_BD_INIT(4, nextrep % 2); - nextrep++; + this_bdt[BDT_TX][BDT_ODD].addr = NULL; + this_bdt[BDT_TX][BDT_ODD].desc = 0; - USB0_ENDPT(1) = BV(ENDPT_EPTXEN) | BV(ENDPT_EPHSHK); + USB0_ENDPT(THIS_EP) = BV(ENDPT_EPTXEN) | BV(ENDPT_EPHSHK); + tx = TX_CTX(this_bdt[BDT_TX], MAX_PACKET); + tx_que(&tx, report, sizeof report); } void usb_endpt1_disable(void) { - USB0_ENDPT(1) = 0; + USB0_ENDPT(THIS_EP) = 0; } void usb_endpt1_token(uint8_t state) @@ -63,9 +96,7 @@ void usb_endpt1_token(uint8_t state) switch (GET_BITS(bd->desc, BD_TOK_PID)) { case BD_TOK_PID_IN: - bd->addr = &report[nextrep]; - bd->desc = USB0_BD_INIT(4, nextrep % 2); - nextrep = (nextrep + 1) % 4; + tx_push(&tx); break; } } diff --git a/usb/endpt1.h b/usb/endpt1.h index fa26bd9..35e1a2c 100644 --- a/usb/endpt1.h +++ b/usb/endpt1.h @@ -19,6 +19,13 @@ #ifndef FMK_USB_ENDPT1_H #define FMK_USB_ENDPT1_H +#include <stdbool.h> +#include <stdint.h> + +#include "keycodes.h" + +void usb_endpt1_setkey(enum keycode keycode, bool state); +void usb_endpt1_send(void); void usb_endpt1_enable(void); void usb_endpt1_disable(void); void usb_endpt1_token(uint8_t state); |