diff --git a/CHANGELOG.md b/CHANGELOG.md index 5d8f2ba..fe29f2a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,14 @@ All notable changes to this project will be documented in this file. The format is loosely based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to the [UHK Versioning](VERSIONING.md) conventions. +## [8.3.2] - 2018-06-27 + +Device Protocol: 4.3.1 | Module Protocol: 4.0.0 | User Config: 4.1.0 | Hardware Config: 1.0.0 + +- Make the debouncer debounce not only on key presses but also on key releases, and change the debounce interval from 100ms to the suggested 5ms of MX switches. +- Revert the Windows related commits of firmware 8.3.1 because they introduced a nondeterministic bug that made USB hang. +- Add base layer key mappings for the left and right add-ons for testing purposes. + ## [8.3.1] - 2018-06-07 Device Protocol: 4.3.1 | Module Protocol: 4.0.0 | User Config: 4.1.0 | Hardware Config: 1.0.0 diff --git a/lib/agent b/lib/agent index 81a8399..32d9635 160000 --- a/lib/agent +++ b/lib/agent @@ -1 +1 @@ -Subproject commit 81a83994abe36f653abf18ee2daaa7c2f198b14a +Subproject commit 32d9635b340e4dfbb12fdcfc909ec89e488ce56a diff --git a/right/src/key_debouncer.c b/right/src/key_debouncer.c index 8a85eb3..fceebcb 100644 --- a/right/src/key_debouncer.c +++ b/right/src/key_debouncer.c @@ -11,8 +11,8 @@ void PIT_KEY_DEBOUNCER_HANDLER(void) for (uint8_t slotId=0; slotIdlength = USB_DESCRIPTOR_LENGTH_HID; + + switch (hidDescriptor->interfaceNumber) { + case USB_GENERIC_HID_INTERFACE_INDEX: + hidDescriptor->buffer = &UsbConfigurationDescriptor[USB_GENERIC_HID_DESCRIPTOR_INDEX]; + break; + case USB_BASIC_KEYBOARD_INTERFACE_INDEX: + hidDescriptor->buffer = &UsbConfigurationDescriptor[USB_BASIC_KEYBOARD_HID_DESCRIPTOR_INDEX]; + break; + case USB_MEDIA_KEYBOARD_INTERFACE_INDEX: + hidDescriptor->buffer = &UsbConfigurationDescriptor[USB_MEDIA_KEYBOARD_HID_DESCRIPTOR_INDEX]; + break; + case USB_SYSTEM_KEYBOARD_INTERFACE_INDEX: + hidDescriptor->buffer = &UsbConfigurationDescriptor[USB_SYSTEM_KEYBOARD_HID_DESCRIPTOR_INDEX]; + break; + case USB_MOUSE_INTERFACE_INDEX: + hidDescriptor->buffer = &UsbConfigurationDescriptor[USB_MOUSE_HID_DESCRIPTOR_INDEX]; + break; + default: + return kStatus_USB_InvalidRequest; + } + return kStatus_USB_Success; } usb_status_t USB_DeviceGetHidReportDescriptor( usb_device_handle handle, usb_device_get_hid_report_descriptor_struct_t *hidReportDescriptor) { - if (USB_GENERIC_HID_INTERFACE_INDEX == hidReportDescriptor->interfaceNumber) { - hidReportDescriptor->buffer = UsbGenericHidReportDescriptor; - hidReportDescriptor->length = USB_GENERIC_HID_REPORT_DESCRIPTOR_LENGTH; - } else if (USB_BASIC_KEYBOARD_INTERFACE_INDEX == hidReportDescriptor->interfaceNumber) { - hidReportDescriptor->buffer = UsbBasicKeyboardReportDescriptor; - hidReportDescriptor->length = USB_BASIC_KEYBOARD_REPORT_DESCRIPTOR_LENGTH; - } else if (USB_MEDIA_KEYBOARD_INTERFACE_INDEX == hidReportDescriptor->interfaceNumber) { - hidReportDescriptor->buffer = UsbMediaKeyboardReportDescriptor; - hidReportDescriptor->length = USB_MEDIA_KEYBOARD_REPORT_DESCRIPTOR_LENGTH; - } else if (USB_SYSTEM_KEYBOARD_INTERFACE_INDEX == hidReportDescriptor->interfaceNumber) { - hidReportDescriptor->buffer = UsbSystemKeyboardReportDescriptor; - hidReportDescriptor->length = USB_MEDIA_KEYBOARD_REPORT_DESCRIPTOR_LENGTH; - } else if (USB_MOUSE_INTERFACE_INDEX == hidReportDescriptor->interfaceNumber) { - hidReportDescriptor->buffer = UsbMouseReportDescriptor; - hidReportDescriptor->length = USB_MOUSE_REPORT_DESCRIPTOR_LENGTH; - } else { - return kStatus_USB_InvalidRequest; + switch (hidReportDescriptor->interfaceNumber) { + case USB_GENERIC_HID_INTERFACE_INDEX: + hidReportDescriptor->buffer = UsbGenericHidReportDescriptor; + hidReportDescriptor->length = USB_GENERIC_HID_REPORT_DESCRIPTOR_LENGTH; + break; + case USB_BASIC_KEYBOARD_INTERFACE_INDEX: + hidReportDescriptor->buffer = UsbBasicKeyboardReportDescriptor; + hidReportDescriptor->length = USB_BASIC_KEYBOARD_REPORT_DESCRIPTOR_LENGTH; + break; + case USB_MEDIA_KEYBOARD_INTERFACE_INDEX: + hidReportDescriptor->buffer = UsbMediaKeyboardReportDescriptor; + hidReportDescriptor->length = USB_MEDIA_KEYBOARD_REPORT_DESCRIPTOR_LENGTH; + break; + case USB_SYSTEM_KEYBOARD_INTERFACE_INDEX: + hidReportDescriptor->buffer = UsbSystemKeyboardReportDescriptor; + hidReportDescriptor->length = USB_MEDIA_KEYBOARD_REPORT_DESCRIPTOR_LENGTH; + break; + case USB_MOUSE_INTERFACE_INDEX: + hidReportDescriptor->buffer = UsbMouseReportDescriptor; + hidReportDescriptor->length = USB_MOUSE_REPORT_DESCRIPTOR_LENGTH; + break; + default: + return kStatus_USB_InvalidRequest; } return kStatus_USB_Success; } diff --git a/right/src/usb_interfaces/usb_interface_basic_keyboard.c b/right/src/usb_interfaces/usb_interface_basic_keyboard.c index 1df3fe9..afebbd5 100644 --- a/right/src/usb_interfaces/usb_interface_basic_keyboard.c +++ b/right/src/usb_interfaces/usb_interface_basic_keyboard.c @@ -1,5 +1,6 @@ #include "led_display.h" #include "usb_composite_device.h" +#include "usb_report_updater.h" static usb_basic_keyboard_report_t usbBasicKeyboardReports[2]; uint32_t UsbBasicKeyboardActionCounter; @@ -23,18 +24,17 @@ void ResetActiveUsbBasicKeyboardReport(void) usb_status_t UsbBasicKeyboardAction(void) { - if (!UsbCompositeDevice.attach) + if (!UsbCompositeDevice.attach) { return kStatus_USB_Error; // The device is not attached + } - if (((usb_device_hid_struct_t *)UsbCompositeDevice.basicKeyboardHandle)->interruptInPipeBusy) - return kStatus_USB_Busy; // The previous report has not been sent yet - - UsbBasicKeyboardActionCounter++; SwitchActiveUsbBasicKeyboardReport(); // Switch the active report usb_status_t usb_status = USB_DeviceHidSend( UsbCompositeDevice.basicKeyboardHandle, USB_BASIC_KEYBOARD_ENDPOINT_INDEX, (uint8_t*)GetInactiveUsbBasicKeyboardReport(), USB_BASIC_KEYBOARD_REPORT_LENGTH); - if (usb_status != kStatus_USB_Success) { + if (usb_status == kStatus_USB_Success) { + UsbBasicKeyboardActionCounter++; + } else { SwitchActiveUsbBasicKeyboardReport(); // Switch back, as the command failed } return usb_status; @@ -47,6 +47,7 @@ usb_status_t UsbBasicKeyboardCallback(class_handle_t handle, uint32_t event, voi switch (event) { // This report is received when the report has been sent case kUSB_DeviceHidEventSendResponse: + UsbReportUpdateSemaphore &= ~(1 << USB_BASIC_KEYBOARD_INTERFACE_INDEX); if (UsbCompositeDevice.attach) { error = kStatus_USB_Success; } diff --git a/right/src/usb_interfaces/usb_interface_media_keyboard.c b/right/src/usb_interfaces/usb_interface_media_keyboard.c index bd6eb04..145377e 100644 --- a/right/src/usb_interfaces/usb_interface_media_keyboard.c +++ b/right/src/usb_interfaces/usb_interface_media_keyboard.c @@ -1,4 +1,5 @@ #include "usb_composite_device.h" +#include "usb_report_updater.h" uint32_t UsbMediaKeyboardActionCounter; static usb_media_keyboard_report_t usbMediaKeyboardReports[2]; @@ -21,18 +22,17 @@ void ResetActiveUsbMediaKeyboardReport(void) usb_status_t UsbMediaKeyboardAction(void) { - if (!UsbCompositeDevice.attach) + if (!UsbCompositeDevice.attach) { return kStatus_USB_Error; // The device is not attached + } - if (((usb_device_hid_struct_t *)UsbCompositeDevice.mediaKeyboardHandle)->interruptInPipeBusy) - return kStatus_USB_Busy; // The previous report has not been sent yet - - UsbMediaKeyboardActionCounter++; SwitchActiveUsbMediaKeyboardReport(); // Switch the active report usb_status_t usb_status = USB_DeviceHidSend( UsbCompositeDevice.mediaKeyboardHandle, USB_MEDIA_KEYBOARD_ENDPOINT_INDEX, (uint8_t*)GetInactiveUsbMediaKeyboardReport(), USB_MEDIA_KEYBOARD_REPORT_LENGTH); - if (usb_status != kStatus_USB_Success) { + if (usb_status == kStatus_USB_Success) { + UsbMediaKeyboardActionCounter++; + } else { SwitchActiveUsbMediaKeyboardReport(); // Switch back, as the command failed } return usb_status; @@ -45,6 +45,7 @@ usb_status_t UsbMediaKeyboardCallback(class_handle_t handle, uint32_t event, voi switch (event) { // This report is received when the report has been sent case kUSB_DeviceHidEventSendResponse: + UsbReportUpdateSemaphore &= ~(1 << USB_MEDIA_KEYBOARD_INTERFACE_INDEX); if (UsbCompositeDevice.attach) { error = kStatus_USB_Success; } diff --git a/right/src/usb_interfaces/usb_interface_mouse.c b/right/src/usb_interfaces/usb_interface_mouse.c index 059b92d..94afe11 100644 --- a/right/src/usb_interfaces/usb_interface_mouse.c +++ b/right/src/usb_interfaces/usb_interface_mouse.c @@ -1,4 +1,5 @@ #include "usb_composite_device.h" +#include "usb_report_updater.h" uint32_t UsbMouseActionCounter; static usb_mouse_report_t usbMouseReports[2]; @@ -19,20 +20,19 @@ void ResetActiveUsbMouseReport(void) bzero(ActiveUsbMouseReport, USB_MOUSE_REPORT_LENGTH); } -usb_status_t usbMouseAction(void) +usb_status_t UsbMouseAction(void) { - if (!UsbCompositeDevice.attach) + if (!UsbCompositeDevice.attach) { return kStatus_USB_Error; // The device is not attached + } - if (((usb_device_hid_struct_t *)UsbCompositeDevice.mouseHandle)->interruptInPipeBusy) - return kStatus_USB_Busy; // The previous report has not been sent yet - - UsbMouseActionCounter++; SwitchActiveUsbMouseReport(); // Switch the active report usb_status_t usb_status = USB_DeviceHidSend( UsbCompositeDevice.mouseHandle, USB_MOUSE_ENDPOINT_INDEX, (uint8_t*)GetInactiveUsbMouseReport(), USB_MOUSE_REPORT_LENGTH); - if (usb_status != kStatus_USB_Success) { + if (usb_status == kStatus_USB_Success) { + UsbMouseActionCounter++; + } else { SwitchActiveUsbMouseReport(); // Switch back, as the command failed } return usb_status; @@ -45,6 +45,7 @@ usb_status_t UsbMouseCallback(class_handle_t handle, uint32_t event, void *param switch (event) { // This report is received when the report has been sent case kUSB_DeviceHidEventSendResponse: + UsbReportUpdateSemaphore &= ~(1 << USB_MOUSE_INTERFACE_INDEX); if (UsbCompositeDevice.attach) { error = kStatus_USB_Success; } diff --git a/right/src/usb_interfaces/usb_interface_mouse.h b/right/src/usb_interfaces/usb_interface_mouse.h index b2258a1..3c3da99 100644 --- a/right/src/usb_interfaces/usb_interface_mouse.h +++ b/right/src/usb_interfaces/usb_interface_mouse.h @@ -42,6 +42,6 @@ void ResetActiveUsbMouseReport(void); usb_mouse_report_t* GetInactiveUsbMouseReport(void); - usb_status_t usbMouseAction(void); + usb_status_t UsbMouseAction(void); #endif diff --git a/right/src/usb_interfaces/usb_interface_system_keyboard.c b/right/src/usb_interfaces/usb_interface_system_keyboard.c index 90788d6..f3d1415 100644 --- a/right/src/usb_interfaces/usb_interface_system_keyboard.c +++ b/right/src/usb_interfaces/usb_interface_system_keyboard.c @@ -1,4 +1,5 @@ #include "usb_composite_device.h" +#include "usb_report_updater.h" uint32_t UsbSystemKeyboardActionCounter; static usb_system_keyboard_report_t usbSystemKeyboardReports[2]; @@ -21,18 +22,17 @@ void ResetActiveUsbSystemKeyboardReport(void) usb_status_t UsbSystemKeyboardAction(void) { - if (!UsbCompositeDevice.attach) + if (!UsbCompositeDevice.attach) { return kStatus_USB_Error; // The device is not attached + } - if (((usb_device_hid_struct_t *)UsbCompositeDevice.systemKeyboardHandle)->interruptInPipeBusy) - return kStatus_USB_Busy; // The previous report has not been sent yet - - UsbSystemKeyboardActionCounter++; SwitchActiveUsbSystemKeyboardReport(); // Switch the active report usb_status_t usb_status = USB_DeviceHidSend( UsbCompositeDevice.systemKeyboardHandle, USB_SYSTEM_KEYBOARD_ENDPOINT_INDEX, (uint8_t*)GetInactiveUsbSystemKeyboardReport(), USB_SYSTEM_KEYBOARD_REPORT_LENGTH); - if (usb_status != kStatus_USB_Success) { + if (usb_status == kStatus_USB_Success) { + UsbSystemKeyboardActionCounter++; + } else { SwitchActiveUsbSystemKeyboardReport(); // Switch back, as the command failed } return usb_status; @@ -45,6 +45,7 @@ usb_status_t UsbSystemKeyboardCallback(class_handle_t handle, uint32_t event, vo switch (event) { // This report is received when the report has been sent case kUSB_DeviceHidEventSendResponse: + UsbReportUpdateSemaphore &= ~(1 << USB_SYSTEM_KEYBOARD_INTERFACE_INDEX); if (UsbCompositeDevice.attach) { error = kStatus_USB_Success; } diff --git a/right/src/usb_report_updater.c b/right/src/usb_report_updater.c index a296667..7ec1a90 100644 --- a/right/src/usb_report_updater.c +++ b/right/src/usb_report_updater.c @@ -25,6 +25,8 @@ static uint16_t DoubleTapSwitchLayerReleaseTimeout = 100; static bool activeMouseStates[ACTIVE_MOUSE_STATES_COUNT]; +volatile uint8_t UsbReportUpdateSemaphore = 0; + mouse_kinetic_state_t MouseMoveState = { .isScroll = false, .upState = SerializedMouseAction_MoveUp, @@ -328,7 +330,7 @@ static void updateActiveUsbReports(void) if (simulateKeypresses) { sendChar = !sendChar; - ActiveUsbBasicKeyboardReport->scancodes[basicScancodeIndex++] = sendChar ? HID_KEYBOARD_SC_A : HID_KEYBOARD_SC_B; + ActiveUsbBasicKeyboardReport->scancodes[basicScancodeIndex++] = sendChar ? HID_KEYBOARD_SC_A : HID_KEYBOARD_SC_BACKSPACE; } for (uint8_t slotId=0; slotIddebounceCounter < KEY_DEBOUNCER_TIMEOUT_MSEC) { + if (keyState->debounceCounter) { keyState->current = keyState->previous; } else if (!keyState->previous && keyState->current) { - keyState->debounceCounter = 0; + keyState->debounceCounter = KEY_DEBOUNCER_TIMEOUT_MSEC + 1; } if (keyState->current) { @@ -402,20 +404,13 @@ static void updateActiveUsbReports(void) } uint32_t UsbReportUpdateCounter; -static uint32_t lastMouseUpdateTime; + usb_status_t status; -void UpdateUsbReports(void) -{ - UsbReportUpdateCounter++; - if (((usb_device_hid_struct_t *)UsbCompositeDevice.basicKeyboardHandle)->interruptInPipeBusy || - ((usb_device_hid_struct_t *)UsbCompositeDevice.mediaKeyboardHandle)->interruptInPipeBusy || - ((usb_device_hid_struct_t *)UsbCompositeDevice.systemKeyboardHandle)->interruptInPipeBusy || - ((usb_device_hid_struct_t *)UsbCompositeDevice.mouseHandle)->interruptInPipeBusy) { - return; - } else if (Timer_GetElapsedTime(&lastMouseUpdateTime) < USB_BASIC_KEYBOARD_INTERRUPT_IN_INTERVAL) { + if (UsbReportUpdateSemaphore && !IsHostSleeping) { return; } - Timer_SetCurrentTime(&lastMouseUpdateTime); + + UsbReportUpdateCounter++; ResetActiveUsbBasicKeyboardReport(); ResetActiveUsbMediaKeyboardReport(); @@ -425,28 +420,41 @@ void UpdateUsbReports(void) updateActiveUsbReports(); bool HasUsbBasicKeyboardReportChanged = memcmp(ActiveUsbBasicKeyboardReport, GetInactiveUsbBasicKeyboardReport(), sizeof(usb_basic_keyboard_report_t)) != 0; - if (HasUsbBasicKeyboardReportChanged) { - UsbBasicKeyboardAction(); - } - bool HasUsbMediaKeyboardReportChanged = memcmp(ActiveUsbMediaKeyboardReport, GetInactiveUsbMediaKeyboardReport(), sizeof(usb_media_keyboard_report_t)) != 0; - if (HasUsbMediaKeyboardReportChanged) { - UsbMediaKeyboardAction(); - } - bool HasUsbSystemKeyboardReportChanged = memcmp(ActiveUsbSystemKeyboardReport, GetInactiveUsbSystemKeyboardReport(), sizeof(usb_system_keyboard_report_t)) != 0; - if (HasUsbSystemKeyboardReportChanged) { - UsbSystemKeyboardAction(); - } - - // Send out the mouse position and wheel values continuously if the report is not zeros, but only send the mouse button states when they change. bool HasUsbMouseReportChanged = memcmp(ActiveUsbMouseReport, GetInactiveUsbMouseReport(), sizeof(usb_mouse_report_t)) != 0; - if (HasUsbMouseReportChanged || ActiveUsbMouseReport->x || ActiveUsbMouseReport->y || - ActiveUsbMouseReport->wheelX || ActiveUsbMouseReport->wheelY) { - usbMouseAction(); - } if (IsHostSleeping && (previousLayer != LayerId_Base || HasUsbBasicKeyboardReportChanged || HasUsbMediaKeyboardReportChanged || HasUsbSystemKeyboardReportChanged || HasUsbMouseReportChanged)) { WakeUpHost(true); // Wake up the host if any key is pressed and the computer is sleeping. } + + if (HasUsbBasicKeyboardReportChanged) { + status = UsbBasicKeyboardAction(); + if (status == kStatus_USB_Success) { + UsbReportUpdateSemaphore |= 1 << USB_BASIC_KEYBOARD_INTERFACE_INDEX; + } + } + + if (HasUsbMediaKeyboardReportChanged) { + status = UsbMediaKeyboardAction(); + if (status == kStatus_USB_Success) { + UsbReportUpdateSemaphore |= 1 << USB_MEDIA_KEYBOARD_INTERFACE_INDEX; + } + } + + if (HasUsbSystemKeyboardReportChanged) { + status = UsbSystemKeyboardAction(); + if (status == kStatus_USB_Success) { + UsbReportUpdateSemaphore |= 1 << USB_SYSTEM_KEYBOARD_INTERFACE_INDEX; + } + } + + // Send out the mouse position and wheel values continuously if the report is not zeros, but only send the mouse button states when they change. + if (HasUsbMouseReportChanged || ActiveUsbMouseReport->x || ActiveUsbMouseReport->y || + ActiveUsbMouseReport->wheelX || ActiveUsbMouseReport->wheelY) { + status = UsbMouseAction(); + if (status == kStatus_USB_Success) { + UsbReportUpdateSemaphore |= 1 << USB_MOUSE_INTERFACE_INDEX; + } + } } diff --git a/right/src/usb_report_updater.h b/right/src/usb_report_updater.h index 1a0f28b..33589f8 100644 --- a/right/src/usb_report_updater.h +++ b/right/src/usb_report_updater.h @@ -70,6 +70,7 @@ extern mouse_kinetic_state_t MouseMoveState; extern mouse_kinetic_state_t MouseScrollState; extern uint32_t UsbReportUpdateCounter; + extern volatile uint8_t UsbReportUpdateSemaphore; // Functions: diff --git a/scripts/package.json b/scripts/package.json index 0f3f10e..bf99869 100644 --- a/scripts/package.json +++ b/scripts/package.json @@ -15,7 +15,7 @@ "commander": "^2.11.0", "shelljs": "^0.7.8" }, - "firmwareVersion": "8.3.1", + "firmwareVersion": "8.3.2", "deviceProtocolVersion": "4.3.1", "moduleProtocolVersion": "4.0.0", "userConfigVersion": "4.1.0", diff --git a/shared/versions.h b/shared/versions.h index adbd2f2..36cc614 100644 --- a/shared/versions.h +++ b/shared/versions.h @@ -20,7 +20,7 @@ #define FIRMWARE_MAJOR_VERSION 8 #define FIRMWARE_MINOR_VERSION 3 - #define FIRMWARE_PATCH_VERSION 1 + #define FIRMWARE_PATCH_VERSION 2 #define DEVICE_PROTOCOL_MAJOR_VERSION 4 #define DEVICE_PROTOCOL_MINOR_VERSION 3