diff options
Diffstat (limited to 'firmware/src/keyboard.c')
-rw-r--r-- | firmware/src/keyboard.c | 119 |
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)); +} |