summaryrefslogtreecommitdiff
path: root/firmware/src/keyboard.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/src/keyboard.c')
-rw-r--r--firmware/src/keyboard.c119
1 files changed, 119 insertions, 0 deletions
diff --git a/firmware/src/keyboard.c b/firmware/src/keyboard.c
new file mode 100644
index 0000000..317d232
--- /dev/null
+++ b/firmware/src/keyboard.c
@@ -0,0 +1,119 @@
+#include "keyboard.h"
+#include "system_config.h"
+#include "system_definitions.h"
+#include "system/tmr/sys_tmr.h"
+
+typedef struct {
+ USB_HOST_HID_KEYBOARD_HANDLE handle;
+ USB_HOST_HID_KEYBOARD_DATA data;
+ USB_HOST_HID_KEYBOARD_DATA prevData;
+ bool attached;
+ bool capsLockPressed;
+ void(*keyHandler)(USB_HID_KEYBOARD_KEYPAD);
+} KEYBOARD_STATE;
+
+static KEYBOARD_STATE keyboard_state;
+
+USB_HOST_EVENT_RESPONSE keyboard_hostEventHandler(USB_HOST_EVENT event, void* eventData, uintptr_t context) {
+ if (keyboard_state.keyHandler != NULL) {
+ keyboard_state.keyHandler(USB_HID_KEYBOARD_KEYPAD_KEYBOARD_B);
+ }
+ switch (event) {
+ case USB_HOST_EVENT_DEVICE_UNSUPPORTED:
+ break;
+ case USB_HOST_EVENT_DEVICE_REJECTED_INSUFFICIENT_POWER:
+ break;
+ case USB_HOST_EVENT_HUB_TIER_LEVEL_EXCEEDED:
+ break;
+ case USB_HOST_EVENT_PORT_OVERCURRENT_DETECTED:
+ break;
+ default:
+ break;
+ }
+ if (keyboard_state.keyHandler != NULL) {
+ keyboard_state.keyHandler(USB_HID_KEYBOARD_KEYPAD_KEYBOARD_B);
+ }
+ return USB_HOST_EVENT_RESPONSE_NONE;
+}
+
+void keyboard_hostHIDKeyboardEventHandler(USB_HOST_HID_KEYBOARD_HANDLE handle,
+ USB_HOST_HID_KEYBOARD_EVENT event,
+ void* pData) {
+ if (keyboard_state.keyHandler != NULL) {
+ keyboard_state.keyHandler(USB_HID_KEYBOARD_KEYPAD_KEYBOARD_A);
+ }
+ switch (event) {
+ case USB_HOST_HID_KEYBOARD_EVENT_ATTACH:
+ keyboard_state.handle = handle;
+ keyboard_state.attached = true;
+ keyboard_state.capsLockPressed = false;
+ break;
+ case USB_HOST_HID_KEYBOARD_EVENT_DETACH:
+ keyboard_state.handle = handle;
+ keyboard_state.attached = false;
+ keyboard_state.capsLockPressed = false;
+ break;
+ case USB_HOST_HID_KEYBOARD_EVENT_REPORT_RECEIVED:
+ keyboard_state.handle = handle;
+ memcpy(&keyboard_state.data, pData, sizeof(keyboard_state.data));
+ break;
+ }
+ if (keyboard_state.keyHandler != NULL) {
+ keyboard_state.keyHandler(USB_HID_KEYBOARD_KEYPAD_KEYBOARD_A);
+ }
+}
+
+void BSP_USBVBUSPowerEnable(uint8_t port, bool enable) {
+ TRISBbits.TRISB5 = 0;
+ if (enable) {
+ LATBbits.LATB5 = 1;
+ U1OTGCONbits.VBUSON = 1;
+ } else {
+ LATBbits.LATB5 = 0;
+ U1OTGCONbits.VBUSON = 0;
+ }
+}
+
+bool BSP_USBVBUSSwitchOverCurrentDetect(uint8_t port) {
+ return false;
+}
+
+bool keyboard_init() {
+ USB_HOST_EventHandlerSet(keyboard_hostEventHandler, 0);
+ USB_HOST_HID_KEYBOARD_EventHandlerSet(keyboard_hostHIDKeyboardEventHandler);
+ bool ret = USB_HOST_BusEnable(0) != USB_HOST_RESULT_BUS_UNKNOWN;
+ U1CONbits.SOFEN = 1;
+ return ret;
+}
+
+void keyboard_setKeyHandler(void(*keyHandler)(USB_HID_KEYBOARD_KEYPAD)) {
+ keyboard_state.keyHandler = keyHandler;
+}
+
+void keyboard_handleKeys() {
+ uint8_t i, j;
+ bool foundInPrev;
+
+ for (i = 0; i < 6; i++) {
+ if (keyboard_state.data.nonModifierKeysData[i].event == USB_HID_KEY_PRESSED) {
+ for (j = 0; j < 6; j++) {
+ if (keyboard_state.prevData.nonModifierKeysData[j].event == USB_HID_KEY_PRESSED
+ && keyboard_state.prevData.nonModifierKeysData[j].keyCode == keyboard_state.data.nonModifierKeysData[i].keyCode) {
+ foundInPrev = !(200 <= 1000
+ * (SYS_TMR_SystemCountGet() - keyboard_state.prevData.nonModifierKeysData[j].sysCount)
+ / SYS_TMR_SystemCountFrequencyGet());
+ }
+ }
+ if (!foundInPrev) {
+ if (keyboard_state.data.nonModifierKeysData[i].keyCode == 57) { // Caps lock
+ keyboard_state.capsLockPressed = ~keyboard_state.capsLockPressed;
+ } else {
+ keyboard_state.keyHandler(keyboard_state.data.nonModifierKeysData[i].keyCode);
+ }
+ }
+ foundInPrev = false;
+ }
+ }
+
+ memcpy(&keyboard_state.prevData, &keyboard_state.data, sizeof(keyboard_state.data));
+}