diff --git a/right/Makefile b/right/Makefile index ef7bcda..f58d3ed 100644 --- a/right/Makefile +++ b/right/Makefile @@ -38,7 +38,7 @@ JLINK_SCRIPT = ../scripts/flash-right.jlink BUILD_FLAGS = -DCPU_$(PART)_cm4 -DUSB_STACK_BM -DBL_HAS_BOOTLOADER_CONFIG=1 # Address of the app vector table. The bootloader will take up the flash before this address. -BL_APP_VECTOR_TABLE_ADDRESS = 0xc000 +BL_APP_VECTOR_TABLE_ADDRESS ?= 0xc000 # Source files. SOURCE = $(wildcard src/*.c) \ diff --git a/right/build/.cproject b/right/build/.cproject index 1ac7e8e..1a66322 100644 --- a/right/build/.cproject +++ b/right/build/.cproject @@ -457,4 +457,87 @@ + + <?xml version="1.0" encoding="UTF-8"?> +<TargetConfig> +<Properties property_3="NXP" property_4="MK22FN512xxx12" property_count="5" version="70200"/> +<infoList vendor="NXP"><info chip="MK22FN512xxx12" name="MK22FN512xxx12"><chip><name>MK22FN512xxx12</name> +<family>K2x</family> +<vendor>NXP</vendor> +<memory can_program="true" id="Flash" is_ro="true" size="512" type="Flash"/> +<memory id="RAM" size="128" type="RAM"/> +<memoryInstance derived_from="Flash" driver="FTFA_2K.cfx" id="PROGRAM_FLASH" location="0x0" size="0x80000"/> +<memoryInstance derived_from="RAM" id="SRAM_UPPER" location="0x20000000" size="0x10000"/> +<memoryInstance derived_from="RAM" id="SRAM_LOWER" location="0x1fff0000" size="0x10000"/> +<peripheralInstance derived_from="FTFA_FlashConfig" id="FTFA_FlashConfig" location="0x400"/> +<peripheralInstance derived_from="DMA" id="DMA" location="0x40008000"/> +<peripheralInstance derived_from="FB" id="FB" location="0x4000C000"/> +<peripheralInstance derived_from="FMC" id="FMC" location="0x4001F000"/> +<peripheralInstance derived_from="FTFA" id="FTFA" location="0x40020000"/> +<peripheralInstance derived_from="DMAMUX" id="DMAMUX" location="0x40021000"/> +<peripheralInstance derived_from="FTM0" id="FTM0" location="0x40038000"/> +<peripheralInstance derived_from="FTM1" id="FTM1" location="0x40039000"/> +<peripheralInstance derived_from="FTM2" id="FTM2" location="0x4003A000"/> +<peripheralInstance derived_from="FTM3" id="FTM3" location="0x40026000"/> +<peripheralInstance derived_from="ADC0" id="ADC0" location="0x4003B000"/> +<peripheralInstance derived_from="ADC1" id="ADC1" location="0x40027000"/> +<peripheralInstance derived_from="DAC0" id="DAC0" location="0x4003F000"/> +<peripheralInstance derived_from="DAC1" id="DAC1" location="0x40028000"/> +<peripheralInstance derived_from="RNG" id="RNG" location="0x40029000"/> +<peripheralInstance derived_from="LPUART0" id="LPUART0" location="0x4002A000"/> +<peripheralInstance derived_from="SPI0" id="SPI0" location="0x4002C000"/> +<peripheralInstance derived_from="SPI1" id="SPI1" location="0x4002D000"/> +<peripheralInstance derived_from="I2S0" id="I2S0" location="0x4002F000"/> +<peripheralInstance derived_from="CRC" id="CRC" location="0x40032000"/> +<peripheralInstance derived_from="PDB0" id="PDB0" location="0x40036000"/> +<peripheralInstance derived_from="PIT" id="PIT" location="0x40037000"/> +<peripheralInstance derived_from="RTC" id="RTC" location="0x4003D000"/> +<peripheralInstance derived_from="RFVBAT" id="RFVBAT" location="0x4003E000"/> +<peripheralInstance derived_from="LPTMR0" id="LPTMR0" location="0x40040000"/> +<peripheralInstance derived_from="RFSYS" id="RFSYS" location="0x40041000"/> +<peripheralInstance derived_from="SIM" id="SIM" location="0x40047000"/> +<peripheralInstance derived_from="PORTA" id="PORTA" location="0x40049000"/> +<peripheralInstance derived_from="PORTB" id="PORTB" location="0x4004A000"/> +<peripheralInstance derived_from="PORTC" id="PORTC" location="0x4004B000"/> +<peripheralInstance derived_from="PORTD" id="PORTD" location="0x4004C000"/> +<peripheralInstance derived_from="PORTE" id="PORTE" location="0x4004D000"/> +<peripheralInstance derived_from="WDOG" id="WDOG" location="0x40052000"/> +<peripheralInstance derived_from="EWM" id="EWM" location="0x40061000"/> +<peripheralInstance derived_from="MCG" id="MCG" location="0x40064000"/> +<peripheralInstance derived_from="OSC" id="OSC" location="0x40065000"/> +<peripheralInstance derived_from="I2C0" id="I2C0" location="0x40066000"/> +<peripheralInstance derived_from="I2C1" id="I2C1" location="0x40067000"/> +<peripheralInstance derived_from="UART0" id="UART0" location="0x4006A000"/> +<peripheralInstance derived_from="UART1" id="UART1" location="0x4006B000"/> +<peripheralInstance derived_from="UART2" id="UART2" location="0x4006C000"/> +<peripheralInstance derived_from="USB0" id="USB0" location="0x40072000"/> +<peripheralInstance derived_from="CMP0" id="CMP0" location="0x40073000"/> +<peripheralInstance derived_from="CMP1" id="CMP1" location="0x40073008"/> +<peripheralInstance derived_from="VREF" id="VREF" location="0x40074000"/> +<peripheralInstance derived_from="LLWU" id="LLWU" location="0x4007C000"/> +<peripheralInstance derived_from="PMC" id="PMC" location="0x4007D000"/> +<peripheralInstance derived_from="SMC" id="SMC" location="0x4007E000"/> +<peripheralInstance derived_from="RCM" id="RCM" location="0x4007F000"/> +<peripheralInstance derived_from="GPIOA" id="GPIOA" location="0x400FF000"/> +<peripheralInstance derived_from="GPIOB" id="GPIOB" location="0x400FF040"/> +<peripheralInstance derived_from="GPIOC" id="GPIOC" location="0x400FF080"/> +<peripheralInstance derived_from="GPIOD" id="GPIOD" location="0x400FF0C0"/> +<peripheralInstance derived_from="GPIOE" id="GPIOE" location="0x400FF100"/> +<peripheralInstance derived_from="SystemControl" id="SystemControl" location="0xE000E000"/> +<peripheralInstance derived_from="SysTick" id="SysTick" location="0xE000E010"/> +<peripheralInstance derived_from="NVIC" id="NVIC" location="0xE000E100"/> +<peripheralInstance derived_from="MCM" id="MCM" location="0xE0080000"/> +</chip> +<processor><name gcc_name="cortex-m4">Cortex-M4</name> +<family>Cortex-M</family> +</processor> +<link href="MK22F51212_internal_peripheral.xml" show="embed" type="simple"/> +</info> +</infoList> +</TargetConfig> + + + SDK_2.x_MK22FN512xxx12 + 2.3.1 + diff --git a/right/src/main.c b/right/src/main.c index 104675b..c8918cf 100644 --- a/right/src/main.c +++ b/right/src/main.c @@ -45,7 +45,6 @@ int main(void) InitSlaveScheduler(); KeyMatrix_Init(&RightKeyMatrix); InitKeyScanner(); - UpdateUsbReports(); InitUsb(); while (1) { diff --git a/right/src/timer.c b/right/src/timer.c index 671ec06..3ddf4b9 100644 --- a/right/src/timer.c +++ b/right/src/timer.c @@ -1,6 +1,8 @@ #include "fsl_pit.h" #include "timer.h" +#include "peripherals/test_led.h" +static uint32_t timerClockFrequency; static volatile uint32_t currentTime, delayLength; void PIT_TIMER_HANDLER(void) @@ -9,7 +11,7 @@ void PIT_TIMER_HANDLER(void) if (delayLength) { --delayLength; } - PIT_ClearStatusFlags(PIT, PIT_TIMER_CHANNEL, PIT_TFLG_TIF_MASK); + PIT_ClearStatusFlags(PIT, PIT_TIMER_CHANNEL, kPIT_TimerFlag); } void Timer_Init(void) @@ -18,9 +20,8 @@ void Timer_Init(void) PIT_GetDefaultConfig(&pitConfig); PIT_Init(PIT, &pitConfig); - // TODO: Why the interval needs to be multiplied by two to arrive to the correct timing? - // Figure it out and clean this up. - PIT_SetTimerPeriod(PIT, PIT_TIMER_CHANNEL, MSEC_TO_COUNT(TIMER_INTERVAL_MSEC*2, PIT_SOURCE_CLOCK)); + timerClockFrequency = PIT_SOURCE_CLOCK; + PIT_SetTimerPeriod(PIT, PIT_TIMER_CHANNEL, MSEC_TO_COUNT(TIMER_INTERVAL_MSEC, timerClockFrequency)); PIT_EnableInterrupts(PIT, PIT_TIMER_CHANNEL, kPIT_TimerInterruptEnable); EnableIRQ(PIT_TIMER_IRQ_ID); @@ -31,21 +32,51 @@ uint32_t Timer_GetCurrentTime() { return currentTime; } +uint32_t Timer_GetCurrentTimeMicros() { + uint32_t primask, count, ms; + primask = DisableGlobalIRQ(); // Make sure the read is atomic + count = PIT_GetCurrentTimerCount(PIT, PIT_TIMER_CHANNEL); // Read the current timer count + ms = currentTime; // Read the overflow counter + EnableGlobalIRQ(primask); // Enable interrupts again if they where enabled before - this should make it interrupt safe + + // Calculate the counter value in microseconds - note that the PIT timer is counting downward, so we need to subtract the count from the period value + uint32_t us = 1000U * TIMER_INTERVAL_MSEC - COUNT_TO_USEC(count, timerClockFrequency); + return ms * 1000U * TIMER_INTERVAL_MSEC + us; +} + void Timer_SetCurrentTime(uint32_t *time) { - *time = currentTime; + *time = Timer_GetCurrentTime(); +} + +void Timer_SetCurrentTimeMicros(uint32_t *time) +{ + *time = Timer_GetCurrentTimeMicros(); } uint32_t Timer_GetElapsedTime(uint32_t *time) { - uint32_t elapsedTime = currentTime - *time; + uint32_t elapsedTime = Timer_GetCurrentTime() - *time; + return elapsedTime; +} + +uint32_t Timer_GetElapsedTimeMicros(uint32_t *time) +{ + uint32_t elapsedTime = Timer_GetCurrentTimeMicros() - *time; return elapsedTime; } uint32_t Timer_GetElapsedTimeAndSetCurrent(uint32_t *time) { uint32_t elapsedTime = Timer_GetElapsedTime(time); - *time = currentTime; + *time = Timer_GetCurrentTime(); + return elapsedTime; +} + +uint32_t Timer_GetElapsedTimeAndSetCurrentMicros(uint32_t *time) +{ + uint32_t elapsedTime = Timer_GetElapsedTimeMicros(time); + *time = Timer_GetCurrentTimeMicros(); return elapsedTime; } diff --git a/right/src/timer.h b/right/src/timer.h index 9555838..810bfc1 100644 --- a/right/src/timer.h +++ b/right/src/timer.h @@ -13,9 +13,13 @@ void Timer_Init(void); uint32_t Timer_GetCurrentTime(); + uint32_t Timer_GetCurrentTimeMicros(); void Timer_SetCurrentTime(uint32_t *time); + void Timer_SetCurrentTimeMicros(uint32_t *time); uint32_t Timer_GetElapsedTime(uint32_t *time); + uint32_t Timer_GetElapsedTimeMicros(uint32_t *time); uint32_t Timer_GetElapsedTimeAndSetCurrent(uint32_t *time); + uint32_t Timer_GetElapsedTimeAndSetCurrentMicros(uint32_t *time); void Timer_Delay(uint32_t length); #endif diff --git a/right/src/usb_descriptors/usb_descriptor_configuration.h b/right/src/usb_descriptors/usb_descriptor_configuration.h index 57869cd..d5fa96a 100644 --- a/right/src/usb_descriptors/usb_descriptor_configuration.h +++ b/right/src/usb_descriptors/usb_descriptor_configuration.h @@ -12,7 +12,13 @@ // Macros: #define USB_COMPOSITE_CONFIGURATION_INDEX 1 - #define USB_CONFIGURATION_DESCRIPTOR_TOTAL_LENGTH 141 + #define USB_CONFIGURATION_DESCRIPTOR_TOTAL_LENGTH \ + (5 * USB_DESCRIPTOR_LENGTH_INTERFACE + 5 * USB_DESCRIPTOR_LENGTH_HID + \ + 6 * USB_DESCRIPTOR_LENGTH_ENDPOINT + USB_DESCRIPTOR_LENGTH_CONFIGURE) + +// Variables: + + extern uint8_t UsbConfigurationDescriptor[USB_CONFIGURATION_DESCRIPTOR_TOTAL_LENGTH]; // Functions: diff --git a/right/src/usb_descriptors/usb_descriptor_hid.c b/right/src/usb_descriptors/usb_descriptor_hid.c index 18c005f..f70dfa1 100644 --- a/right/src/usb_descriptors/usb_descriptor_hid.c +++ b/right/src/usb_descriptors/usb_descriptor_hid.c @@ -2,33 +2,80 @@ #include "usb_descriptor_hid.h" #include "usb_descriptor_mouse_report.h" #include "usb_descriptor_generic_hid_report.h" +#include "usb_descriptor_configuration.h" + +#define USB_GENERIC_HID_DESCRIPTOR_INDEX \ + (USB_DESCRIPTOR_LENGTH_CONFIGURE + USB_DESCRIPTOR_LENGTH_INTERFACE) + +#define USB_BASIC_KEYBOARD_HID_DESCRIPTOR_INDEX \ + (USB_GENERIC_HID_DESCRIPTOR_INDEX + USB_DESCRIPTOR_LENGTH_HID + \ + 2 * USB_DESCRIPTOR_LENGTH_ENDPOINT + USB_DESCRIPTOR_LENGTH_INTERFACE) + +#define USB_MEDIA_KEYBOARD_HID_DESCRIPTOR_INDEX \ + (USB_BASIC_KEYBOARD_HID_DESCRIPTOR_INDEX + USB_DESCRIPTOR_LENGTH_HID + \ + USB_DESCRIPTOR_LENGTH_ENDPOINT + USB_DESCRIPTOR_LENGTH_INTERFACE) + +#define USB_SYSTEM_KEYBOARD_HID_DESCRIPTOR_INDEX \ + (USB_MEDIA_KEYBOARD_HID_DESCRIPTOR_INDEX + USB_DESCRIPTOR_LENGTH_HID + \ + USB_DESCRIPTOR_LENGTH_ENDPOINT + USB_DESCRIPTOR_LENGTH_INTERFACE) + +#define USB_MOUSE_HID_DESCRIPTOR_INDEX \ + (USB_SYSTEM_KEYBOARD_HID_DESCRIPTOR_INDEX + USB_DESCRIPTOR_LENGTH_HID + \ + USB_DESCRIPTOR_LENGTH_ENDPOINT + USB_DESCRIPTOR_LENGTH_INTERFACE) usb_status_t USB_DeviceGetHidDescriptor( usb_device_handle handle, usb_device_get_hid_descriptor_struct_t *hidDescriptor) { - return kStatus_USB_InvalidRequest; + hidDescriptor->length = 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 f1bef4f..0548f10 100644 --- a/right/src/usb_interfaces/usb_interface_basic_keyboard.c +++ b/right/src/usb_interfaces/usb_interface_basic_keyboard.c @@ -1,20 +1,20 @@ #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; usb_basic_keyboard_report_t* ActiveUsbBasicKeyboardReport = usbBasicKeyboardReports; -volatile bool IsUsbBasicKeyboardReportSent = false; static uint8_t usbBasicKeyboardInBuffer[USB_BASIC_KEYBOARD_REPORT_LENGTH]; -static usb_basic_keyboard_report_t* getInactiveUsbBasicKeyboardReport(void) +usb_basic_keyboard_report_t* GetInactiveUsbBasicKeyboardReport(void) { return ActiveUsbBasicKeyboardReport == usbBasicKeyboardReports ? usbBasicKeyboardReports+1 : usbBasicKeyboardReports; } -void SwitchActiveUsbBasicKeyboardReport(void) +static void SwitchActiveUsbBasicKeyboardReport(void) { - ActiveUsbBasicKeyboardReport = getInactiveUsbBasicKeyboardReport(); + ActiveUsbBasicKeyboardReport = GetInactiveUsbBasicKeyboardReport(); } void ResetActiveUsbBasicKeyboardReport(void) @@ -22,14 +22,20 @@ void ResetActiveUsbBasicKeyboardReport(void) bzero(ActiveUsbBasicKeyboardReport, USB_BASIC_KEYBOARD_REPORT_LENGTH); } -static usb_status_t UsbBasicKeyboardAction(void) +usb_status_t UsbBasicKeyboardAction(void) { - usb_status_t status = USB_DeviceHidSend( + if (!UsbCompositeDevice.attach) { + return kStatus_USB_Error; // The device is not attached + } + + usb_status_t usb_status = USB_DeviceHidSend( UsbCompositeDevice.basicKeyboardHandle, USB_BASIC_KEYBOARD_ENDPOINT_INDEX, - (uint8_t*)getInactiveUsbBasicKeyboardReport(), USB_BASIC_KEYBOARD_REPORT_LENGTH); - IsUsbBasicKeyboardReportSent = true; - UsbBasicKeyboardActionCounter++; - return status; + (uint8_t *)ActiveUsbBasicKeyboardReport, USB_BASIC_KEYBOARD_REPORT_LENGTH); + if (usb_status == kStatus_USB_Success) { + UsbBasicKeyboardActionCounter++; + SwitchActiveUsbBasicKeyboardReport(); + } + return usb_status; } usb_status_t UsbBasicKeyboardCallback(class_handle_t handle, uint32_t event, void *param) @@ -37,11 +43,14 @@ usb_status_t UsbBasicKeyboardCallback(class_handle_t handle, uint32_t event, voi usb_status_t error = kStatus_USB_Error; switch (event) { + // This event is received when the report has been sent case kUSB_DeviceHidEventSendResponse: + UsbReportUpdateSemaphore &= ~(1 << USB_BASIC_KEYBOARD_INTERFACE_INDEX); if (UsbCompositeDevice.attach) { - return UsbBasicKeyboardAction(); + error = kStatus_USB_Success; } break; + case kUSB_DeviceHidEventRecvResponse: case kUSB_DeviceHidEventGetReport: error = kStatus_USB_InvalidRequest; break; @@ -61,7 +70,7 @@ usb_status_t UsbBasicKeyboardCallback(class_handle_t handle, uint32_t event, voi report->reportBuffer = usbBasicKeyboardInBuffer; error = kStatus_USB_Success; } else { - error = kStatus_USB_InvalidRequest; + error = kStatus_USB_AllocFail; } break; } @@ -79,16 +88,10 @@ usb_status_t UsbBasicKeyboardCallback(class_handle_t handle, uint32_t event, voi usb_status_t UsbBasicKeyboardSetConfiguration(class_handle_t handle, uint8_t configuration) { - if (USB_COMPOSITE_CONFIGURATION_INDEX == configuration) { - return UsbBasicKeyboardAction(); - } return kStatus_USB_Error; } usb_status_t UsbBasicKeyboardSetInterface(class_handle_t handle, uint8_t interface, uint8_t alternateSetting) { - if (USB_BASIC_KEYBOARD_INTERFACE_INDEX == interface) { - return UsbBasicKeyboardAction(); - } return kStatus_USB_Error; } diff --git a/right/src/usb_interfaces/usb_interface_basic_keyboard.h b/right/src/usb_interfaces/usb_interface_basic_keyboard.h index 2a7fea0..2f41c6a 100644 --- a/right/src/usb_interfaces/usb_interface_basic_keyboard.h +++ b/right/src/usb_interfaces/usb_interface_basic_keyboard.h @@ -31,7 +31,6 @@ // Variables: - extern volatile bool IsUsbBasicKeyboardReportSent; extern uint32_t UsbBasicKeyboardActionCounter; extern usb_basic_keyboard_report_t* ActiveUsbBasicKeyboardReport; @@ -42,6 +41,7 @@ usb_status_t UsbBasicKeyboardSetInterface(class_handle_t handle, uint8_t interface, uint8_t alternateSetting); void ResetActiveUsbBasicKeyboardReport(void); - void SwitchActiveUsbBasicKeyboardReport(void); + usb_basic_keyboard_report_t* GetInactiveUsbBasicKeyboardReport(void); + usb_status_t UsbBasicKeyboardAction(void); #endif diff --git a/right/src/usb_interfaces/usb_interface_generic_hid.c b/right/src/usb_interfaces/usb_interface_generic_hid.c index 446821e..349c779 100644 --- a/right/src/usb_interfaces/usb_interface_generic_hid.c +++ b/right/src/usb_interfaces/usb_interface_generic_hid.c @@ -7,6 +7,10 @@ uint8_t GenericHidOutBuffer[USB_GENERIC_HID_OUT_BUFFER_LENGTH]; static usb_status_t UsbReceiveData(void) { + if (!UsbCompositeDevice.attach) { + return kStatus_USB_Error; // The device is not attached + } + return USB_DeviceHidRecv(UsbCompositeDevice.genericHidHandle, USB_GENERIC_HID_ENDPOINT_OUT_INDEX, GenericHidInBuffer, @@ -18,7 +22,11 @@ usb_status_t UsbGenericHidCallback(class_handle_t handle, uint32_t event, void * usb_status_t error = kStatus_USB_Error; switch (event) { + // This event is received when the report has been sent case kUSB_DeviceHidEventSendResponse: + if (UsbCompositeDevice.attach) { + error = kStatus_USB_Success; + } break; case kUSB_DeviceHidEventRecvResponse: UsbProtocolHandler(); diff --git a/right/src/usb_interfaces/usb_interface_media_keyboard.c b/right/src/usb_interfaces/usb_interface_media_keyboard.c index 8147734..7f17de9 100644 --- a/right/src/usb_interfaces/usb_interface_media_keyboard.c +++ b/right/src/usb_interfaces/usb_interface_media_keyboard.c @@ -1,18 +1,18 @@ #include "usb_composite_device.h" +#include "usb_report_updater.h" uint32_t UsbMediaKeyboardActionCounter; static usb_media_keyboard_report_t usbMediaKeyboardReports[2]; usb_media_keyboard_report_t* ActiveUsbMediaKeyboardReport = usbMediaKeyboardReports; -volatile bool IsUsbMediaKeyboardReportSent = false; -static usb_media_keyboard_report_t* getInactiveUsbMediaKeyboardReport(void) +usb_media_keyboard_report_t* GetInactiveUsbMediaKeyboardReport(void) { return ActiveUsbMediaKeyboardReport == usbMediaKeyboardReports ? usbMediaKeyboardReports+1 : usbMediaKeyboardReports; } -void SwitchActiveUsbMediaKeyboardReport(void) +static void SwitchActiveUsbMediaKeyboardReport(void) { - ActiveUsbMediaKeyboardReport = getInactiveUsbMediaKeyboardReport(); + ActiveUsbMediaKeyboardReport = GetInactiveUsbMediaKeyboardReport(); } void ResetActiveUsbMediaKeyboardReport(void) @@ -20,14 +20,20 @@ void ResetActiveUsbMediaKeyboardReport(void) bzero(ActiveUsbMediaKeyboardReport, USB_MEDIA_KEYBOARD_REPORT_LENGTH); } -static usb_status_t UsbMediaKeyboardAction(void) +usb_status_t UsbMediaKeyboardAction(void) { - usb_status_t status = USB_DeviceHidSend( + if (!UsbCompositeDevice.attach) { + return kStatus_USB_Error; // The device is not attached + } + + usb_status_t usb_status = USB_DeviceHidSend( UsbCompositeDevice.mediaKeyboardHandle, USB_MEDIA_KEYBOARD_ENDPOINT_INDEX, - (uint8_t*)getInactiveUsbMediaKeyboardReport(), USB_MEDIA_KEYBOARD_REPORT_LENGTH); - IsUsbMediaKeyboardReportSent = true; - UsbMediaKeyboardActionCounter++; - return status; + (uint8_t *)ActiveUsbMediaKeyboardReport, USB_MEDIA_KEYBOARD_REPORT_LENGTH); + if (usb_status == kStatus_USB_Success) { + UsbMediaKeyboardActionCounter++; + SwitchActiveUsbMediaKeyboardReport(); + } + return usb_status; } usb_status_t UsbMediaKeyboardCallback(class_handle_t handle, uint32_t event, void *param) @@ -35,11 +41,14 @@ usb_status_t UsbMediaKeyboardCallback(class_handle_t handle, uint32_t event, voi usb_status_t error = kStatus_USB_Error; switch (event) { + // This event is received when the report has been sent case kUSB_DeviceHidEventSendResponse: + UsbReportUpdateSemaphore &= ~(1 << USB_MEDIA_KEYBOARD_INTERFACE_INDEX); if (UsbCompositeDevice.attach) { - return UsbMediaKeyboardAction(); + error = kStatus_USB_Success; } break; + case kUSB_DeviceHidEventRecvResponse: case kUSB_DeviceHidEventGetReport: case kUSB_DeviceHidEventSetReport: case kUSB_DeviceHidEventRequestReportBuffer: @@ -59,16 +68,10 @@ usb_status_t UsbMediaKeyboardCallback(class_handle_t handle, uint32_t event, voi usb_status_t UsbMediaKeyboardSetConfiguration(class_handle_t handle, uint8_t configuration) { - if (USB_COMPOSITE_CONFIGURATION_INDEX == configuration) { - return UsbMediaKeyboardAction(); - } return kStatus_USB_Error; } usb_status_t UsbMediaKeyboardSetInterface(class_handle_t handle, uint8_t interface, uint8_t alternateSetting) { - if (USB_MEDIA_KEYBOARD_INTERFACE_INDEX == interface) { - return UsbMediaKeyboardAction(); - } return kStatus_USB_Error; } diff --git a/right/src/usb_interfaces/usb_interface_media_keyboard.h b/right/src/usb_interfaces/usb_interface_media_keyboard.h index 8b39fb2..a236e8d 100644 --- a/right/src/usb_interfaces/usb_interface_media_keyboard.h +++ b/right/src/usb_interfaces/usb_interface_media_keyboard.h @@ -28,7 +28,6 @@ // Variables: - extern volatile bool IsUsbMediaKeyboardReportSent; extern uint32_t UsbMediaKeyboardActionCounter; extern usb_media_keyboard_report_t* ActiveUsbMediaKeyboardReport; @@ -39,6 +38,7 @@ usb_status_t UsbMediaKeyboardSetInterface(class_handle_t handle, uint8_t interface, uint8_t alternateSetting); void ResetActiveUsbMediaKeyboardReport(void); - void SwitchActiveUsbMediaKeyboardReport(void); + usb_media_keyboard_report_t* GetInactiveUsbMediaKeyboardReport(void); + usb_status_t UsbMediaKeyboardAction(); #endif diff --git a/right/src/usb_interfaces/usb_interface_mouse.c b/right/src/usb_interfaces/usb_interface_mouse.c index 711e3cd..f02bff5 100644 --- a/right/src/usb_interfaces/usb_interface_mouse.c +++ b/right/src/usb_interfaces/usb_interface_mouse.c @@ -1,18 +1,18 @@ #include "usb_composite_device.h" +#include "usb_report_updater.h" uint32_t UsbMouseActionCounter; static usb_mouse_report_t usbMouseReports[2]; usb_mouse_report_t* ActiveUsbMouseReport = usbMouseReports; -volatile bool IsUsbMouseReportSent = false; -static usb_mouse_report_t* getInactiveUsbMouseReport(void) +usb_mouse_report_t* GetInactiveUsbMouseReport(void) { return ActiveUsbMouseReport == usbMouseReports ? usbMouseReports+1 : usbMouseReports; } -void SwitchActiveUsbMouseReport(void) +static void SwitchActiveUsbMouseReport(void) { - ActiveUsbMouseReport = getInactiveUsbMouseReport(); + ActiveUsbMouseReport = GetInactiveUsbMouseReport(); } void ResetActiveUsbMouseReport(void) @@ -20,25 +20,35 @@ void ResetActiveUsbMouseReport(void) bzero(ActiveUsbMouseReport, USB_MOUSE_REPORT_LENGTH); } -static volatile usb_status_t usbMouseAction(void) +usb_status_t UsbMouseAction(void) { - usb_mouse_report_t *mouseReport = getInactiveUsbMouseReport(); - IsUsbMouseReportSent = true; - return USB_DeviceHidSend(UsbCompositeDevice.mouseHandle, USB_MOUSE_ENDPOINT_INDEX, - (uint8_t*)mouseReport, USB_MOUSE_REPORT_LENGTH); + if (!UsbCompositeDevice.attach) { + return kStatus_USB_Error; // The device is not attached + } + + usb_status_t usb_status = USB_DeviceHidSend( + UsbCompositeDevice.mouseHandle, USB_MOUSE_ENDPOINT_INDEX, + (uint8_t *)ActiveUsbMouseReport, USB_MOUSE_REPORT_LENGTH); + if (usb_status == kStatus_USB_Success) { + UsbMouseActionCounter++; + SwitchActiveUsbMouseReport(); + } + return usb_status; } usb_status_t UsbMouseCallback(class_handle_t handle, uint32_t event, void *param) { - UsbMouseActionCounter++; usb_status_t error = kStatus_USB_Error; switch (event) { + // This event is received when the report has been sent case kUSB_DeviceHidEventSendResponse: + UsbReportUpdateSemaphore &= ~(1 << USB_MOUSE_INTERFACE_INDEX); if (UsbCompositeDevice.attach) { - return usbMouseAction(); + error = kStatus_USB_Success; } break; + case kUSB_DeviceHidEventRecvResponse: case kUSB_DeviceHidEventGetReport: case kUSB_DeviceHidEventSetReport: case kUSB_DeviceHidEventRequestReportBuffer: @@ -58,16 +68,10 @@ usb_status_t UsbMouseCallback(class_handle_t handle, uint32_t event, void *param usb_status_t UsbMouseSetConfiguration(class_handle_t handle, uint8_t configuration) { - if (USB_COMPOSITE_CONFIGURATION_INDEX == configuration) { - return usbMouseAction(); - } return kStatus_USB_Error; } usb_status_t UsbMouseSetInterface(class_handle_t handle, uint8_t interface, uint8_t alternateSetting) { - if (USB_MOUSE_INTERFACE_INDEX == interface) { - return usbMouseAction(); - } return kStatus_USB_Error; } diff --git a/right/src/usb_interfaces/usb_interface_mouse.h b/right/src/usb_interfaces/usb_interface_mouse.h index e1a2cc7..3c3da99 100644 --- a/right/src/usb_interfaces/usb_interface_mouse.h +++ b/right/src/usb_interfaces/usb_interface_mouse.h @@ -31,7 +31,6 @@ // Variables: - extern volatile bool IsUsbMouseReportSent; extern uint32_t UsbMouseActionCounter; extern usb_mouse_report_t* ActiveUsbMouseReport; @@ -42,6 +41,7 @@ usb_status_t UsbMouseSetInterface(class_handle_t handle, uint8_t interface, uint8_t alternateSetting); void ResetActiveUsbMouseReport(void); - void SwitchActiveUsbMouseReport(void); + usb_mouse_report_t* GetInactiveUsbMouseReport(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 e039069..633f90f 100644 --- a/right/src/usb_interfaces/usb_interface_system_keyboard.c +++ b/right/src/usb_interfaces/usb_interface_system_keyboard.c @@ -1,18 +1,18 @@ #include "usb_composite_device.h" +#include "usb_report_updater.h" uint32_t UsbSystemKeyboardActionCounter; static usb_system_keyboard_report_t usbSystemKeyboardReports[2]; usb_system_keyboard_report_t* ActiveUsbSystemKeyboardReport = usbSystemKeyboardReports; -volatile bool IsUsbSystemKeyboardReportSent = false; -static usb_system_keyboard_report_t* getInactiveUsbSystemKeyboardReport() +usb_system_keyboard_report_t* GetInactiveUsbSystemKeyboardReport() { return ActiveUsbSystemKeyboardReport == usbSystemKeyboardReports ? usbSystemKeyboardReports+1 : usbSystemKeyboardReports; } -void SwitchActiveUsbSystemKeyboardReport(void) +static void SwitchActiveUsbSystemKeyboardReport(void) { - ActiveUsbSystemKeyboardReport = getInactiveUsbSystemKeyboardReport(); + ActiveUsbSystemKeyboardReport = GetInactiveUsbSystemKeyboardReport(); } void ResetActiveUsbSystemKeyboardReport(void) @@ -20,14 +20,20 @@ void ResetActiveUsbSystemKeyboardReport(void) bzero(ActiveUsbSystemKeyboardReport, USB_SYSTEM_KEYBOARD_REPORT_LENGTH); } -static usb_status_t UsbSystemKeyboardAction(void) +usb_status_t UsbSystemKeyboardAction(void) { - usb_status_t status = USB_DeviceHidSend( + if (!UsbCompositeDevice.attach) { + return kStatus_USB_Error; // The device is not attached + } + + usb_status_t usb_status = USB_DeviceHidSend( UsbCompositeDevice.systemKeyboardHandle, USB_SYSTEM_KEYBOARD_ENDPOINT_INDEX, - (uint8_t*)getInactiveUsbSystemKeyboardReport(), USB_SYSTEM_KEYBOARD_REPORT_LENGTH); - IsUsbSystemKeyboardReportSent = true; - UsbSystemKeyboardActionCounter++; - return status; + (uint8_t *)ActiveUsbSystemKeyboardReport, USB_SYSTEM_KEYBOARD_REPORT_LENGTH); + if (usb_status == kStatus_USB_Success) { + UsbSystemKeyboardActionCounter++; + SwitchActiveUsbSystemKeyboardReport(); + } + return usb_status; } usb_status_t UsbSystemKeyboardCallback(class_handle_t handle, uint32_t event, void *param) @@ -35,11 +41,14 @@ usb_status_t UsbSystemKeyboardCallback(class_handle_t handle, uint32_t event, vo usb_status_t error = kStatus_USB_Error; switch (event) { + // This event is received when the report has been sent case kUSB_DeviceHidEventSendResponse: + UsbReportUpdateSemaphore &= ~(1 << USB_SYSTEM_KEYBOARD_INTERFACE_INDEX); if (UsbCompositeDevice.attach) { - return UsbSystemKeyboardAction(); + error = kStatus_USB_Success; } break; + case kUSB_DeviceHidEventRecvResponse: case kUSB_DeviceHidEventGetReport: case kUSB_DeviceHidEventSetReport: case kUSB_DeviceHidEventRequestReportBuffer: @@ -59,16 +68,10 @@ usb_status_t UsbSystemKeyboardCallback(class_handle_t handle, uint32_t event, vo usb_status_t UsbSystemKeyboardSetConfiguration(class_handle_t handle, uint8_t configuration) { - if (USB_COMPOSITE_CONFIGURATION_INDEX == configuration) { - return UsbSystemKeyboardAction(); - } return kStatus_USB_Error; } usb_status_t UsbSystemKeyboardSetInterface(class_handle_t handle, uint8_t interface, uint8_t alternateSetting) { - if (USB_SYSTEM_KEYBOARD_INTERFACE_INDEX == interface) { - return UsbSystemKeyboardAction(); - } return kStatus_USB_Error; } diff --git a/right/src/usb_interfaces/usb_interface_system_keyboard.h b/right/src/usb_interfaces/usb_interface_system_keyboard.h index 0a84353..9c22bda 100644 --- a/right/src/usb_interfaces/usb_interface_system_keyboard.h +++ b/right/src/usb_interfaces/usb_interface_system_keyboard.h @@ -29,7 +29,6 @@ // Variables: - extern volatile bool IsUsbSystemKeyboardReportSent; extern uint32_t UsbSystemKeyboardActionCounter; extern usb_system_keyboard_report_t* ActiveUsbSystemKeyboardReport; @@ -40,6 +39,7 @@ usb_status_t UsbSystemKeyboardSetInterface(class_handle_t handle, uint8_t interface, uint8_t alternateSetting); void ResetActiveUsbSystemKeyboardReport(void); - void SwitchActiveUsbSystemKeyboardReport(void); + usb_system_keyboard_report_t* GetInactiveUsbSystemKeyboardReport(); + usb_status_t UsbSystemKeyboardAction(void); #endif diff --git a/right/src/usb_report_updater.c b/right/src/usb_report_updater.c index cc50f89..2b78ab3 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, @@ -324,6 +326,21 @@ static void updateActiveUsbReports(void) bool layerGotReleased = previousLayer != LayerId_Base && activeLayer == LayerId_Base; LedDisplay_SetLayer(activeLayer); +#if 0 // Used to toggle key presses at the maximum rate - this was used to reproduce: https://github.com/UltimateHackingKeyboard/firmware/issues/122 + static bool simulateKeypresses = false; + static bool sendChar = false; + + key_state_t *testKeyState = &KeyStates[SlotId_LeftKeyboardHalf][0]; + if (!testKeyState->previous && testKeyState->current && activeLayer == LayerId_Fn) { + simulateKeypresses = !simulateKeypresses; + } + + if (simulateKeypresses) { + sendChar = !sendChar; + ActiveUsbBasicKeyboardReport->scancodes[basicScancodeIndex++] = sendChar ? HID_KEYBOARD_SC_A : HID_KEYBOARD_SC_BACKSPACE; + } +#endif + for (uint8_t slotId=0; slotIdx || ActiveUsbMouseReport->y || + ActiveUsbMouseReport->wheelX || ActiveUsbMouseReport->wheelY) { + usb_status_t 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: