diff --git a/samples/device_hid_mouse_rtos/demo_device_hid_descriptors.c b/samples/device_hid_mouse_rtos/demo_device_hid_descriptors.c new file mode 100644 index 00000000..8fe5a47a --- /dev/null +++ b/samples/device_hid_mouse_rtos/demo_device_hid_descriptors.c @@ -0,0 +1,314 @@ +/*************************************************************************** + * Copyright (c) 2025-present Eclipse ThreadX Contributors + * + * This program and the accompanying materials are made available under the + * terms of the MIT License which is available at + * https://opensource.org/licenses/MIT. + * + * + * SPDX-License-Identifier: MIT + **************************************************************************/ + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** AUTHOR */ +/** */ +/** Mohamed AYED */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +#include "demo_device_hid_descriptors.h" + +UCHAR hid_report[] = { + 0x05, 0x01, // USAGE_PAGE (Generic Desktop) + 0x09, 0x02, // USAGE (Mouse) + 0xa1, 0x01, // COLLECTION (Application) + + /* Pointer and Physical are required by Apple Recovery */ + 0x09, 0x01, // USAGE (Pointer) + 0xa1, 0x00, // COLLECTION (Physical) + + /* 3 Buttons */ + 0x05, 0x09, // USAGE_PAGE (Button) + 0x19, 0x01, // USAGE_MINIMUM (Button 1) + 0x29, 0x03, // USAGE_MAXIMUM (Button 3) + 0x15, 0x00, // LOGICAL_MINIMUM (0) + 0x25, 0x01, // LOGICAL_MAXIMUM (1) + 0x75, 0x01, // REPORT_SIZE (1) + 0x95, 0x03, // REPORT_COUNT (3) -> 3 buttons + 0x81, 0x02, // INPUT (Data, Variable, Absolute) -> Buttons + + 0x75, 0x05, // REPORT_SIZE (5) + 0x95, 0x01, // REPORT_COUNT (1) + 0x81, 0x03, // INPUT (Constant, Variable, Absolute) -> Padding bits + + /* X, Y */ + 0x05, 0x01, // USAGE_PAGE (Generic Desktop) + 0x09, 0x30, // USAGE (X) + 0x09, 0x31, // USAGE (Y) +#ifdef UX_DEMO_MOUSE_ABSOLUTE + 0x16, 0x00, 0x00, // LOGICAL_MINIMUM (0) + 0x26, 0xFF, 0x7F, // LOGICAL_MAXIMUM (32767) (0x7FFF) + 0x75, 0x10, // REPORT_SIZE (16) (2 bytes per axis) + 0x95, 0x02, // REPORT_COUNT (2) -> X, Y position + 0x81, 0x02, // INPUT (Data, Variable, Absolute) -> Absolute X, Y position +#else /* UX_DEMO_MOUSE_ABSOLUTE */ + 0x15, 0x81, // LOGICAL_MINIMUM (-127) + 0x25, 0x7F, // LOGICAL_MAXIMUM (127) + 0x75, 0x08, // REPORT_SIZE (8) (1 bytes per axis) + 0x95, 0x02, // REPORT_COUNT (2) -> X, Y movement + 0x81, 0x06, // INPUT (Data, Variable, Relative) -> X, Y are relative +#endif /* UX_DEMO_MOUSE_ABSOLUTE */ + + /* Wheel */ + 0x09, 0x38, // USAGE (Mouse Wheel) + 0x15, 0x81, // LOGICAL_MINIMUM (-127) + 0x25, 0x7F, // LOGICAL_MAXIMUM (127) + 0x75, 0x08, // REPORT_SIZE (8) + 0x95, 0x01, // REPORT_COUNT (1) -> Wheel movement + 0x81, 0x06, // INPUT (Data, Variable, Relative) -> Wheel + + /* End */ + 0xC0, // END_COLLECTION + 0xC0 // END_COLLECTION +}; + +#define UX_HID_MOUSE_REPORT_LENGTH (sizeof(hid_report)/sizeof(hid_report[0])) + +UCHAR ux_demo_device_framework_full_speed[] = { + /* Device descriptor */ + 0x12, /* bLength */ + 0x01, /* bDescriptorType */ + UX_W0(UX_DEMO_BCD_USB), UX_W1(UX_DEMO_BCD_USB), /* bcdUSB */ + 0x00, /* bDeviceClass : 0x00 : Interface-defined */ + 0x00, /* bDeviceSubClass : 0x00 : Reset */ + 0x00, /* bDeviceProtocol : 0x00 : Reset */ + UX_DEMO_MAX_EP0_SIZE, /* bMaxPacketSize0 */ + UX_W0(UX_DEMO_HID_DEVICE_VID), UX_W1(UX_DEMO_HID_DEVICE_VID), /* idVendor : ... */ + UX_W0(UX_DEMO_HID_DEVICE_PID), UX_W1(UX_DEMO_HID_DEVICE_PID), /* idProduct */ + 0x00, 0x00, /* bcdDevice */ + 0x01, /* iManufacturer */ + 0x02, /* iProduct */ + 0x03, /* iSerialNumber */ + 0x01, /* bNumConfigurations */ + + /* Configuration Descriptor, total 34 */ + 0x09, /* bLength */ + 0x02, /* bDescriptorType */ + UX_W0(UX_DEMO_HID_CONFIG_DESC_SIZE), UX_W1(UX_DEMO_HID_CONFIG_DESC_SIZE), /* wTotalLength */ + 0x01, /* bNumInterfaces */ + 0x01, /* bConfigurationValue */ + 0x04, /* iConfiguration */ + 0xC0, /* bmAttributes */ + /* D6 : 0x1 : Self-powered */ + /* D5, Remote Wakeup : 0x0 : Not supported */ + 0x32, /* bMaxPower : 50 : 100mA */ + + /* Interface descriptor */ + 0x09, /* bLength */ + 0x04, /* bDescriptorType */ + 0x00, /* bInterfaceNumber */ + 0x00, /* bAlternateSetting */ + 0x01, /* bNumEndpoints */ + 0x03, /* bInterfaceClass : 0x03 : HID */ + UX_DEMO_HID_SUBCLASS, /* bInterfaceSubClass : ... : Boot/non-boot Subclass */ + 0x02, /* bInterfaceProtocol : 0x00 : Undefined */ + 0x06, /* iInterface */ + + /* HID Descriptor */ + 0x09, /* bLength : 9 */ + 0x21, /* bDescriptorType : 0x21 : HID descriptor */ + 0x10, 0x01, /* bcdHID : 0x0110 */ + 0x21, /* bCountryCode : 33 : US */ + 0x01, /* bNumDescriptors */ + 0x22, /* bReportDescriptorType1 : 0x22 : Report descriptor */ + UX_W0(UX_HID_MOUSE_REPORT_LENGTH), UX_W1(UX_HID_MOUSE_REPORT_LENGTH), /* wDescriptorLength1 */ + + /* Endpoint Descriptor */ + 0x07, /* bLength */ + 0x05, /* bDescriptorType */ + UX_DEMO_HID_ENDPOINT_ADDRESS, /* bEndpointAddress */ + /* D7, Direction : 0x01 */ + /* D3..0, Endpoint number : 2 */ + 0x03, /* bmAttributes */ + /* D1..0, Transfer Type : 0x3 : Interrupt */ + /* D3..2, Synchronization Type : 0x0 : No Synchronization */ + /* D5..4, Usage Type : 0x0 : Data endpoint */ + UX_W0(UX_DEMO_HID_ENDPOINT_SIZE), UX_W1(UX_DEMO_HID_ENDPOINT_SIZE), /* wMaxPacketSize */ + /* D10..0, Max Packet Size */ + /* D12..11, Additional transactions : 0x00 */ + UX_DEMO_HID_ENDPOINT_BINTERVAL, /* bInterval : 8 : 8ms / x128 (FS 128ms/HS 16ms) */ +}; + + +UCHAR ux_demo_device_framework_high_speed[] = { + /* Device descriptor */ + 0x12, /* bLength */ + 0x01, /* bDescriptorType */ + UX_W0(UX_DEMO_BCD_USB), UX_W1(UX_DEMO_BCD_USB), /* bcdUSB */ + 0x00, /* bDeviceClass : 0x00 : Interface-defined */ + 0x00, /* bDeviceSubClass : 0x00 : Reset */ + 0x00, /* bDeviceProtocol : 0x00 : Reset */ + UX_DEMO_MAX_EP0_SIZE, /* bMaxPacketSize0 */ + UX_W0(UX_DEMO_HID_DEVICE_VID), UX_W1(UX_DEMO_HID_DEVICE_VID), /* idVendor : ... */ + UX_W0(UX_DEMO_HID_DEVICE_PID), UX_W1(UX_DEMO_HID_DEVICE_PID), /* idProduct */ + 0x01, 0x00, /* bcdDevice */ + 0x01, /* iManufacturer */ + 0x02, /* iProduct */ + 0x03, /* iSerialNumber */ + 0x01, /* bNumConfigurations */ + + /* Device qualifier descriptor */ + 0x0A, /* bLength */ + 0x06, /* bDescriptorType */ + UX_W0(UX_DEMO_BCD_USB), UX_W1(UX_DEMO_BCD_USB), /* bcdUSB */ + 0x00, /* bDeviceClass : 0x00 : Interface-defined */ + 0x00, /* bDeviceSubClass : 0x00 : Reset */ + 0x00, /* bDeviceProtocol : 0x00 : Reset */ + UX_DEMO_MAX_EP0_SIZE, /* bMaxPacketSize0 */ + 0x01, /* bNumConfigurations */ + 0x00, /* bReserved */ + + /* Configuration descriptor */ + 0x09, /* bLength */ + 0x02, /* bDescriptorType */ + UX_W0(UX_DEMO_HID_CONFIG_DESC_SIZE), UX_W1(UX_DEMO_HID_CONFIG_DESC_SIZE), /* wTotalLength */ + 0x01, /* bNumInterfaces */ + 0x01, /* bConfigurationValue */ + 0x05, /* iConfiguration */ + 0xC0, /* bmAttributes */ + /* D6 : 0x1 : Self-powered */ + /* D5, Remote Wakeup : 0x0 : Not supported */ + 0x19, /* bMaxPower : 50 : 100mA */ + + /* Interface descriptor */ + 0x09, /* bLength */ + 0x04, /* bDescriptorType */ + 0x00, /* bInterfaceNumber */ + 0x00, /* bAlternateSetting */ + 0x01, /* bNumEndpoints */ + 0x03, /* bInterfaceClass : 0x03 : HID */ + UX_DEMO_HID_SUBCLASS, /* bInterfaceSubClass : ... : Boot/non-boot Subclass */ + 0x02, /* bInterfaceProtocol : 0x00 : Undefined */ + 0x06, /* iInterface */ + + /* HID Descriptor */ + 0x09, /* bLength : 9 */ + 0x21, /* bDescriptorType : 0x21 : HID descriptor */ + UX_W0(UX_DEMO_BCD_HID), UX_W1(UX_DEMO_BCD_HID), /* bcdHID : 0x0110 */ + 0x21, /* bCountryCode : 33 : US */ + 0x01, /* bNumDescriptors */ + 0x22, /* bReportDescriptorType1 : 0x22 : Report descriptor */ + UX_W0(UX_HID_MOUSE_REPORT_LENGTH), UX_W1(UX_HID_MOUSE_REPORT_LENGTH), /* wDescriptorLength1 */ + + /* Endpoint Descriptor (Interrupt In) */ + 0x07, /* bLength */ + 0x05, /* bDescriptorType */ + UX_DEMO_HID_ENDPOINT_ADDRESS, /* bEndpointAddress */ + /* D7, Direction : 0x01 */ + /* D3..0, Endpoint number : 2 */ + 0x03, /* bmAttributes */ + /* D1..0, Transfer Type : 0x3 : Interrupt */ + /* D3..2, Synchronization Type : 0x0 : No Synchronization */ + /* D5..4, Usage Type : 0x0 : Data endpoint */ + UX_W0(UX_DEMO_HID_ENDPOINT_SIZE), UX_W1(UX_DEMO_HID_ENDPOINT_SIZE), /* wMaxPacketSize */ + /* D10..0, Max Packet Size */ + /* D12..11, Additional transactions : 0x00 */ + UX_DEMO_HID_ENDPOINT_BINTERVAL, /* bInterval : 8 : 8ms / x128 (FS 128ms/HS 16ms) */ +}; + + +/* String Device Framework : + Byte 0 and 1 : Word containing the language ID : 0x0904 for US + Byte 2 : Byte containing the index of the descriptor + Byte 3 : Byte containing the length of the descriptor string +*/ +UCHAR ux_demo_string_framework[] = { + + /* iManufacturer string descriptor : Index 1 */ + 0x09, 0x04, 0x01, 12, + 'U', 'S', 'B', 'X', ' ', 'e', 'c', 'l', 'i', 'p', 's', 'e', + + /* iProduct string descriptor : Index 2 */ + 0x09, 0x04, 0x02, 14, + 'H', 'I', 'D', ' ', 'M', 'o', 'u', 's', 'e', ' ', 'D', 'e', 'm', 'o', + + /* iSerialNumber Number string descriptor : Index 3 */ + 0x09, 0x04, 0x03, 13, + '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '1', + + /* iConfiguration string descriptor : Index 4 */ + 0x09, 0x04, 0x04, 10, + 'F', 'U', 'L', 'L', ' ', 'S', 'P', 'E', 'E', 'D', + + /* iConfiguration string descriptor : Index 5 */ + 0x09, 0x04, 0x05, 10, + 'H', 'I', 'G', 'H', ' ', 'S', 'P', 'E', 'E', 'D', + + /* iInterface string descriptor : Index 6 */ + 0x09, 0x04, 0x06, 5, + 'M', 'o', 'u', 's', 'e' +}; + + +/* Multiple languages are supported on the device, to add + a language besides english, the unicode language code must + be appended to the language_id_framework array and the length + adjusted accordingly. */ +UCHAR ux_demo_language_id_framework[] = { + /* English. */ + 0x09, 0x04 +}; + + +UCHAR* ux_demo_get_high_speed_framework(VOID) +{ + return ux_demo_device_framework_high_speed; +} + +ULONG ux_demo_get_high_speed_framework_length(VOID) +{ + return sizeof(ux_demo_device_framework_high_speed); +} + +UCHAR* ux_demo_get_full_speed_framework(VOID) +{ + return ux_demo_device_framework_full_speed; +} + +ULONG ux_demo_get_full_speed_framework_length(VOID) +{ + return sizeof(ux_demo_device_framework_full_speed); +} + +UCHAR* ux_demo_get_string_framework(VOID) +{ + return ux_demo_string_framework; +} + +ULONG ux_demo_get_string_framework_length(VOID) +{ + return sizeof(ux_demo_string_framework); +} + +UCHAR* ux_demo_get_language_framework(VOID) +{ + return ux_demo_language_id_framework; +} + +ULONG ux_demo_get_language_framework_length(VOID) +{ + return sizeof(ux_demo_language_id_framework); +} + +UCHAR* ux_demo_device_hid_get_report(VOID) +{ + return hid_report; +} + +ULONG ux_demo_device_hid_get_report_length(VOID) +{ + return (sizeof(hid_report)/sizeof(hid_report[0])); +} diff --git a/samples/device_hid_mouse_rtos/demo_device_hid_descriptors.h b/samples/device_hid_mouse_rtos/demo_device_hid_descriptors.h new file mode 100644 index 00000000..60d54eeb --- /dev/null +++ b/samples/device_hid_mouse_rtos/demo_device_hid_descriptors.h @@ -0,0 +1,70 @@ +/*************************************************************************** + * Copyright (c) 2025-present Eclipse ThreadX Contributors + * + * This program and the accompanying materials are made available under the + * terms of the MIT License which is available at + * https://opensource.org/licenses/MIT. + * + * + * SPDX-License-Identifier: MIT + **************************************************************************/ + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** AUTHOR */ +/** */ +/** Mohamed AYED */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +#ifndef UX_DEMO_DEVICE_DESCRIPTORS_H +#define UX_DEMO_DEVICE_DESCRIPTORS_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "ux_api.h" + +//#define UX_DEMO_MOUSE_ABSOLUTE + +#define DEMO_HID_BOOT_DEVICE +#define UX_DEMO_HID_DEVICE_VID 0x070A +#define UX_DEMO_HID_DEVICE_PID 0x4036 + +#define UX_DEMO_MAX_EP0_SIZE 0x40U +#define UX_DEMO_HID_CONFIG_DESC_SIZE 0x22U + +#define UX_DEMO_BCD_USB 0x0200 + +#define UX_DEMO_BCD_HID 0x0110 + +#define UX_DEMO_HID_ENDPOINT_SIZE 0x08 +#define UX_DEMO_HID_ENDPOINT_ADDRESS 0x81 +#define UX_DEMO_HID_ENDPOINT_BINTERVAL 0x08 + +#ifdef DEMO_HID_BOOT_DEVICE +#define UX_DEMO_HID_SUBCLASS 0x01 +#else /* DEMO_HID_BOOT_DEVICE */ +#define UX_DEMO_HID_SUBCLASS 0x00 +#endif + + +UCHAR* ux_demo_get_high_speed_framework(VOID); +ULONG ux_demo_get_high_speed_framework_length(VOID); +UCHAR* ux_demo_get_full_speed_framework(VOID); +ULONG ux_demo_get_full_speed_framework_length(VOID); +UCHAR* ux_demo_get_string_framework(VOID); +ULONG ux_demo_get_string_framework_length(VOID); +UCHAR* ux_demo_get_language_framework(VOID); +ULONG ux_demo_get_language_framework_length(VOID); + +UCHAR* ux_demo_device_hid_get_report(VOID); +ULONG ux_demo_device_hid_get_report_length(VOID); + +#ifdef __cplusplus +} +#endif +#endif /* UX_DEMO_DEVICE_DESCRIPTORS_H */ diff --git a/samples/device_hid_mouse_rtos/demo_device_hid_mouse.c b/samples/device_hid_mouse_rtos/demo_device_hid_mouse.c new file mode 100644 index 00000000..b4f72469 --- /dev/null +++ b/samples/device_hid_mouse_rtos/demo_device_hid_mouse.c @@ -0,0 +1,634 @@ +/*************************************************************************** + * Copyright (c) 2025-present Eclipse ThreadX Contributors + * + * This program and the accompanying materials are made available under the + * terms of the MIT License which is available at + * https://opensource.org/licenses/MIT. + * + * + * SPDX-License-Identifier: MIT + **************************************************************************/ + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** AUTHOR */ +/** */ +/** Mohamed AYED */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +#include "demo_device_hid_mouse.h" + +/**************************************************/ +/** usbx device hid demo callbacks */ +/**************************************************/ +VOID ux_demo_device_hid_instance_activate(VOID *hid_instance); +VOID ux_demo_device_hid_instance_deactivate(VOID *hid_instance); +UINT ux_demo_device_hid_callback(UX_SLAVE_CLASS_HID *hid_instance, UX_SLAVE_CLASS_HID_EVENT *hid_event); +UINT ux_demo_device_hid_get_callback(UX_SLAVE_CLASS_HID *hid_instance, UX_SLAVE_CLASS_HID_EVENT *hid_event); + +/**************************************************/ +/** usbx device hid demo thread */ +/**************************************************/ +VOID ux_demo_device_hid_thread_entry(ULONG thread_input); + +/**************************************************/ +/** usbx application initialization with RTOS */ +/**************************************************/ +VOID tx_application_define(VOID *first_unused_memory); + +/**************************************************/ +/** usbx device hid demo mouse */ +/**************************************************/ +UINT ux_demo_hid_mouse_cursor_move(UX_SLAVE_CLASS_HID *device_hid); +UINT ux_demo_hid_mouse_buttons(UX_SLAVE_CLASS_HID *device_hid); +UINT ux_demo_hid_mouse_scroll_wheel(UX_SLAVE_CLASS_HID *device_hid); +#ifdef UX_DEMO_MOUSE_ABSOLUTE +UINT ux_demo_hid_mouse_absolute_cursor_move(UX_SLAVE_CLASS_HID *device_hid); +#endif /* UX_DEMO_MOUSE_ABSOLUTE */ + +static VOID ux_demo_error_callback(UINT system_level, UINT system_context, UINT error_code); + +/**************************************************/ +/** usbx device hid mouse instance */ +/**************************************************/ +UX_SLAVE_CLASS_HID *hid_mouse; + +/**************************************************/ +/** thread object */ +/**************************************************/ +static TX_THREAD ux_hid_thread; + +int main(void) +{ + /* Initialize the board. */ + board_setup(); + + /* Enter the ThreadX kernel. */ + tx_kernel_enter(); + + while (1) + { + } + +} + +VOID tx_application_define(VOID *first_unused_memory) +{ +CHAR *stack_pointer; +CHAR *memory_pointer; +UINT status; +UX_SLAVE_CLASS_HID_PARAMETER hid_mouse_parameter; + + /* Initialize the free memory pointer. */ + stack_pointer = (CHAR *) first_unused_memory; + + /* Initialize the RAM disk memory. */ + memory_pointer = stack_pointer + DEMO_STACK_SIZE; + + /* Initialize USBX Memory */ + status = ux_system_initialize(memory_pointer, UX_DEVICE_MEMORY_STACK_SIZE, UX_NULL, 0); + + if(status != UX_SUCCESS) + return; + + printf("USBX System initialized successfully\r\n"); + + /* Install the device portion of USBX */ + status = ux_device_stack_initialize(ux_demo_get_high_speed_framework(), + ux_demo_get_high_speed_framework_length(), + ux_demo_get_full_speed_framework(), + ux_demo_get_full_speed_framework_length(), + ux_demo_get_string_framework(), + ux_demo_get_string_framework_length(), + ux_demo_get_language_framework(), + ux_demo_get_language_framework_length(), + UX_NULL); + + if(status != UX_SUCCESS) + return; + + printf("USBX Device stack initialized successfully\r\n"); + + /* Initialize the hid mouse class parameters for the device */ + hid_mouse_parameter.ux_slave_class_hid_instance_activate = ux_demo_device_hid_instance_activate; + hid_mouse_parameter.ux_slave_class_hid_instance_deactivate = ux_demo_device_hid_instance_deactivate; + hid_mouse_parameter.ux_device_class_hid_parameter_report_address = ux_demo_device_hid_get_report(); + hid_mouse_parameter.ux_device_class_hid_parameter_report_length = ux_demo_device_hid_get_report_length(); + hid_mouse_parameter.ux_device_class_hid_parameter_report_id = UX_FALSE; + hid_mouse_parameter.ux_device_class_hid_parameter_callback = ux_demo_device_hid_callback; + hid_mouse_parameter.ux_device_class_hid_parameter_get_callback = ux_demo_device_hid_get_callback; + + /* Initialize the device storage class. The class is connected with interface 0 on configuration 1. */ + status = ux_device_stack_class_register(_ux_system_slave_class_hid_name, ux_device_class_hid_entry, + 1, 0, (VOID *)&hid_mouse_parameter); + + if(status != UX_SUCCESS) + return; + + /* Create the main demo thread. */ + status = ux_utility_thread_create(&ux_hid_thread, "hid_usbx_app_thread_entry", + ux_demo_device_hid_thread_entry, 0, stack_pointer, + 512, 20, 20, 1, TX_AUTO_START); + + if(status != UX_SUCCESS) + return; + + /* error callback */ + ux_utility_error_callback_register(ux_demo_error_callback); +} + +/********************************************************************/ +/** ux_demo_device_hid_instance_activate */ +/********************************************************************/ +VOID ux_demo_device_hid_instance_activate(VOID *hid_instance) +{ + if (hid_mouse == UX_NULL) + hid_mouse = (UX_SLAVE_CLASS_HID*) hid_instance; +} + +/********************************************************************/ +/** ux_demo_device_hid_instance_deactivate */ +/********************************************************************/ +VOID ux_demo_device_hid_instance_deactivate(VOID *hid_instance) +{ + if (hid_instance == (VOID *)hid_mouse) + hid_mouse = UX_NULL; +} + +/********************************************************************/ +/** ux_demo_device_hid_callback */ +/********************************************************************/ +UINT ux_demo_device_hid_callback(UX_SLAVE_CLASS_HID *hid_instance, UX_SLAVE_CLASS_HID_EVENT *hid_event) +{ + UX_PARAMETER_NOT_USED(hid_instance); + UX_PARAMETER_NOT_USED(hid_event); + + return UX_SUCCESS; +} + +/********************************************************************/ +/** ux_demo_device_hid_get_callback */ +/********************************************************************/ +UINT ux_demo_device_hid_get_callback(UX_SLAVE_CLASS_HID *hid_instance, UX_SLAVE_CLASS_HID_EVENT *hid_event) +{ + UX_PARAMETER_NOT_USED(hid_instance); + UX_PARAMETER_NOT_USED(hid_event); + + return UX_SUCCESS; +} + +/********************************************************************/ +/** ux_demo_device_hid_thread_entry: hid demo thread */ +/********************************************************************/ +VOID ux_demo_device_hid_thread_entry(ULONG thread_input) +{ +UINT status; +UINT demo_state = UX_DEMO_MOUSE_CURSOR; + + UX_PARAMETER_NOT_USED(thread_input); + + usb_device_interrupt_setup(); + + + while (1) + { + /* Check if the device state already configured. */ + if ((UX_SLAVE_DEVICE_CHECK_STATE(UX_DEVICE_CONFIGURED)) && (hid_mouse != UX_NULL)) + { + + switch(demo_state) + { + + case UX_DEMO_MOUSE_CURSOR: + + /* Move cursor */ +#ifdef UX_DEMO_MOUSE_ABSOLUTE + status = ux_demo_hid_mouse_absolute_cursor_move(hid_mouse); +#else /* UX_DEMO_MOUSE_ABSOLUTE */ + status = ux_demo_hid_mouse_cursor_move(hid_mouse); +#endif /* UX_DEMO_MOUSE_ABSOLUTE */ + + if (status == UX_MOUSE_CURSOR_MOVE_DONE) + demo_state = UX_DEMO_MOUSE_WHEEL; + + break; + + case UX_DEMO_MOUSE_WHEEL: + + /* Scroll wheel */ + status = ux_demo_hid_mouse_scroll_wheel(hid_mouse); + + if (status == UX_MOUSE_WHEEL_MOVE_DONE) + demo_state = UX_DEMO_MOUSE_BUTTON; + + break; + + case UX_DEMO_MOUSE_BUTTON: + + /* Click button */ + status = ux_demo_hid_mouse_buttons(hid_mouse); + + if (status == UX_MOUSE_BUTTON_PRESS_DONE) + demo_state = UX_DEMO_MOUSE_DONE; + + break; + + default: + + ux_utility_delay_ms(MS_TO_TICK(10)); + + break; + } + } + else + { + /* Sleep thread for 10ms. */ + ux_utility_delay_ms(MS_TO_TICK(10)); + } + } +} + +#ifndef UX_DEMO_MOUSE_ABSOLUTE +/********************************************************************/ +/** ux_demo_hid_mouse_cursor_move: show how to move mouse cursor */ +/********************************************************************/ +UINT ux_demo_hid_mouse_cursor_move(UX_SLAVE_CLASS_HID *device_hid) +{ +UINT status; +UX_SLAVE_CLASS_HID_EVENT device_hid_event; +static UCHAR mouse_x; +static UCHAR mouse_y; +static UCHAR mouse_move_dir; +static UCHAR mouse_move_count; + + /* Sleep thread for 10ms. */ + ux_utility_delay_ms(MS_TO_TICK(10)); + + /* Initialize mouse event. */ + device_hid_event.ux_device_class_hid_event_report_id = 0; + device_hid_event.ux_device_class_hid_event_report_type = UX_DEVICE_CLASS_HID_REPORT_TYPE_INPUT; + device_hid_event.ux_device_class_hid_event_length = 4; + device_hid_event.ux_device_class_hid_event_buffer[0] = 0; /* ...R|M|L */ + device_hid_event.ux_device_class_hid_event_buffer[1] = mouse_x; /* X */ + device_hid_event.ux_device_class_hid_event_buffer[2] = mouse_y; /* Y */ + device_hid_event.ux_device_class_hid_event_buffer[3] = 0; /* Wheel */ + + /* Move cursor. */ + switch(mouse_move_dir) + { + case UX_MOUSE_CURSOR_MOVE_RIGHT: /* +x. */ + + mouse_x = UX_DEMO_HID_MOUSE_CURSOR_MOVE; + mouse_y = 0; + mouse_move_count ++; + + if (mouse_move_count >= UX_DEMO_HID_MOUSE_CURSOR_MOVE_N) + { + mouse_move_count = 0; + mouse_move_dir = UX_MOUSE_CURSOR_MOVE_DOWN; + } + + break; + + case UX_MOUSE_CURSOR_MOVE_DOWN: /* +y. */ + + mouse_x = 0; + mouse_y = UX_DEMO_HID_MOUSE_CURSOR_MOVE; + mouse_move_count ++; + + if (mouse_move_count >= UX_DEMO_HID_MOUSE_CURSOR_MOVE_N) + { + mouse_move_count = 0; + mouse_move_dir = UX_MOUSE_CURSOR_MOVE_LEFT; + } + + break; + + case UX_MOUSE_CURSOR_MOVE_LEFT: /* -x. */ + + mouse_x = (CHAR)(-UX_DEMO_HID_MOUSE_CURSOR_MOVE); + mouse_y = 0; + mouse_move_count ++; + + if (mouse_move_count >= UX_DEMO_HID_MOUSE_CURSOR_MOVE_N) + { + mouse_move_count = 0; + mouse_move_dir = UX_MOUSE_CURSOR_MOVE_UP; + } + + break; + + case UX_MOUSE_CURSOR_MOVE_UP: /* -y. */ + + mouse_x = 0; + mouse_y = (UCHAR)(-UX_DEMO_HID_MOUSE_CURSOR_MOVE); + mouse_move_count ++; + + if (mouse_move_count >= UX_DEMO_HID_MOUSE_CURSOR_MOVE_N) + { + mouse_move_count = 0; + mouse_move_dir = UX_MOUSE_CURSOR_MOVE_DONE; + } + + break; + + default: + + mouse_x = 0; + mouse_y = 0; + + ux_utility_memory_set(&device_hid_event, 0, sizeof(UX_SLAVE_CLASS_HID_EVENT)); + + break; + } + + status = ux_device_class_hid_event_set(device_hid, &device_hid_event); + + if(status != UX_SUCCESS) + return UX_ERROR; + + return mouse_move_dir; +} +#endif /* !UX_DEMO_MOUSE_ABSOLUTE */ + +#ifdef UX_DEMO_MOUSE_ABSOLUTE +/***************************************************************************************/ +/** ux_demo_hid_mouse_absolute_cursor_move: */ +/** show how to daw a rectangle with width 10000, height 10000, step size 500 */ +/***************************************************************************************/ +UINT ux_demo_hid_mouse_absolute_cursor_move(UX_SLAVE_CLASS_HID *device_hid) +{ +UINT status; +UX_SLAVE_CLASS_HID_EVENT device_hid_event; +ULONG start_mouse_x = 8000; +ULONG start_mouse_y = 8000; +ULONG width = 10000; +ULONG height = 10000; +static ULONG mouse_x; +static ULONG mouse_y; +static UCHAR mouse_move_dir; + + /* Sleep thread for 10ms. */ + ux_utility_delay_ms(MS_TO_TICK(100)); + + /* Initialize mouse event. */ + device_hid_event.ux_device_class_hid_event_report_id = 0; + device_hid_event.ux_device_class_hid_event_report_type = UX_DEVICE_CLASS_HID_REPORT_TYPE_INPUT; + device_hid_event.ux_device_class_hid_event_length = 6; + device_hid_event.ux_device_class_hid_event_buffer[0] = 0; /* ...M|R|L */ + device_hid_event.ux_device_class_hid_event_buffer[1] = UX_W0(mouse_x); /* X */ + device_hid_event.ux_device_class_hid_event_buffer[2] = UX_W1(mouse_x); /* X */ + device_hid_event.ux_device_class_hid_event_buffer[3] = UX_W0(mouse_y); /* Y */ + device_hid_event.ux_device_class_hid_event_buffer[4] = UX_W1(mouse_y); /* Y */ + device_hid_event.ux_device_class_hid_event_buffer[5] = 0; /* Wheel */ + + + switch (mouse_move_dir) + { + case UX_MOUSE_CURSOR_MOVE_RIGHT: /* +x. */ + + mouse_x += UX_DEMO_HID_MOUSE_CURSOR_MOVE; + + if (mouse_x >= start_mouse_x + width) + { + mouse_x = start_mouse_x + width; + mouse_move_dir = UX_MOUSE_CURSOR_MOVE_DOWN; + } + + break; + + case UX_MOUSE_CURSOR_MOVE_DOWN: /* +y. */ + + mouse_y += UX_DEMO_HID_MOUSE_CURSOR_MOVE; + + if (mouse_y >= start_mouse_y + height) + { + mouse_y = start_mouse_y + height; + mouse_move_dir = UX_MOUSE_CURSOR_MOVE_LEFT; + } + + break; + + case UX_MOUSE_CURSOR_MOVE_LEFT: /* -y. */ + + mouse_x -= UX_DEMO_HID_MOUSE_CURSOR_MOVE; + + if (mouse_x <= start_mouse_x) + { + mouse_x = start_mouse_x; + mouse_move_dir = UX_MOUSE_CURSOR_MOVE_UP; + } + + break; + + case UX_MOUSE_CURSOR_MOVE_UP: /* -y. */ + + mouse_y -= UX_DEMO_HID_MOUSE_CURSOR_MOVE; + + if (mouse_y <= start_mouse_y) + { + mouse_y = start_mouse_y; + mouse_move_dir = UX_MOUSE_CURSOR_MOVE_DONE; + } + + break; + + default: + + mouse_x = 0; + mouse_y = 0; + + ux_utility_memory_set(&device_hid_event, 0, sizeof(UX_SLAVE_CLASS_HID_EVENT)); + + break; + } + + /* Set the mouse event. */ + status = ux_device_class_hid_event_set(device_hid, &device_hid_event); + + if(status != UX_SUCCESS) + return UX_ERROR; + + return mouse_move_dir; +} +#endif /* UX_DEMO_MOUSE_ABSOLUTE */ + +/*****************************************************************/ +/** ux_demo_hid_mouse_buttons: show how to click mouse button */ +/*****************************************************************/ +UINT ux_demo_hid_mouse_buttons(UX_SLAVE_CLASS_HID *device_hid) +{ +UINT status; +UX_SLAVE_CLASS_HID_EVENT device_hid_event; +static UCHAR button_status; + + /* Sleep thread for 10ms. */ + ux_utility_delay_ms(MS_TO_TICK(10)); + + /* Initialize mouse event. */ + device_hid_event.ux_device_class_hid_event_report_id = 0; + device_hid_event.ux_device_class_hid_event_report_type = UX_DEVICE_CLASS_HID_REPORT_TYPE_INPUT; +#ifndef UX_DEMO_MOUSE_ABSOLUTE + device_hid_event.ux_device_class_hid_event_length = 4; + device_hid_event.ux_device_class_hid_event_buffer[0] = 0; /* ...M|R|L */ + device_hid_event.ux_device_class_hid_event_buffer[1] = 0; /* X */ + device_hid_event.ux_device_class_hid_event_buffer[2] = 0; /* Y */ + device_hid_event.ux_device_class_hid_event_buffer[3] = 0; /* Wheel */ +#else /* UX_DEMO_MOUSE_ABSOLUTE */ + device_hid_event.ux_device_class_hid_event_length = 6; + device_hid_event.ux_device_class_hid_event_buffer[0] = 0; /* ...M|R|L */ + device_hid_event.ux_device_class_hid_event_buffer[1] = 0; /* X */ + device_hid_event.ux_device_class_hid_event_buffer[2] = 0; /* X */ + device_hid_event.ux_device_class_hid_event_buffer[3] = 0; /* Y */ + device_hid_event.ux_device_class_hid_event_buffer[4] = 0; /* Y */ + device_hid_event.ux_device_class_hid_event_buffer[5] = 0; /* Wheel */ +#endif /* UX_DEMO_MOUSE_ABSOLUTE */ + + switch(button_status) + { + case UX_MOUSE_BUTTON_PRESS_LEFT: + + /* Press L button. */ + device_hid_event.ux_device_class_hid_event_buffer[0] = 0x01; + + button_status = UX_MOUSE_BUTTON_PRESS_RIGHT; + + break; + + case UX_MOUSE_BUTTON_PRESS_RIGHT: + + /* Press R button. */ + device_hid_event.ux_device_class_hid_event_buffer[0] = 0x02; + + button_status = UX_MOUSE_BUTTON_PRESS_MIDDLE; + + break; + + case UX_MOUSE_BUTTON_PRESS_MIDDLE: + + /* Press M button. */ + device_hid_event.ux_device_class_hid_event_buffer[0] = 0x04; + + button_status = UX_MOUSE_BUTTON_PRESS_DONE; + + break; + + default: + + ux_utility_memory_set(&device_hid_event, 0, sizeof(UX_SLAVE_CLASS_HID_EVENT)); + + break; + } + + /* Set the mouse event. */ + status = ux_device_class_hid_event_set(device_hid, &device_hid_event); + + if(status != UX_SUCCESS) + return UX_ERROR; + + /* Sleep thread for 10ms. */ + ux_utility_delay_ms(MS_TO_TICK(10)); + + /* Release button. */ + device_hid_event.ux_device_class_hid_event_buffer[0] = 0x00; + status = ux_device_class_hid_event_set(device_hid, &device_hid_event); + + if(status != UX_SUCCESS) + return UX_ERROR; + + return button_status; +} + +/**************************************************************/ +/** ux_demo_hid_mouse_scroll_wheel: show how to move wheel */ +/**************************************************************/ +UINT ux_demo_hid_mouse_scroll_wheel(UX_SLAVE_CLASS_HID *device_hid) +{ +UINT status; +UX_SLAVE_CLASS_HID_EVENT device_hid_event; +static UCHAR mouse_wheel; +static UCHAR wheel_move_dir; +static UCHAR wheel_move_count; + + /* Sleep thread for 10ms. */ + ux_utility_delay_ms(MS_TO_TICK(10)); + + /* Initialize mouse event. */ + device_hid_event.ux_device_class_hid_event_report_id = 0; + device_hid_event.ux_device_class_hid_event_report_type = UX_DEVICE_CLASS_HID_REPORT_TYPE_INPUT; +#ifndef UX_DEMO_MOUSE_ABSOLUTE + device_hid_event.ux_device_class_hid_event_length = 4; + device_hid_event.ux_device_class_hid_event_buffer[0] = 0; /* ...M|R|L */ + device_hid_event.ux_device_class_hid_event_buffer[1] = 0; /* X */ + device_hid_event.ux_device_class_hid_event_buffer[2] = 0; /* Y */ + device_hid_event.ux_device_class_hid_event_buffer[3] = mouse_wheel; /* Wheel */ +#else /* UX_DEMO_MOUSE_ABSOLUTE */ + device_hid_event.ux_device_class_hid_event_length = 6; + device_hid_event.ux_device_class_hid_event_buffer[0] = 0; /* ...M|R|L */ + device_hid_event.ux_device_class_hid_event_buffer[1] = 0; /* X */ + device_hid_event.ux_device_class_hid_event_buffer[2] = 0; /* X */ + device_hid_event.ux_device_class_hid_event_buffer[3] = 0; /* Y */ + device_hid_event.ux_device_class_hid_event_buffer[4] = 0; /* Y */ + device_hid_event.ux_device_class_hid_event_buffer[5] = mouse_wheel; /* Wheel */ +#endif /* UX_DEMO_MOUSE_ABSOLUTE */ + + /* Move wheel. */ + switch(wheel_move_dir) + { + case UX_MOUSE_WHEEL_MOVE_DOWN: + + mouse_wheel = (UCHAR)(-UX_DEMO_HID_MOUSE_WHEEL_MOVE); + + wheel_move_count ++; + + if (wheel_move_count >= UX_DEMO_HID_MOUSE_WHEEL_MOVE_N) + { + wheel_move_count = 0; + wheel_move_dir = UX_MOUSE_WHEEL_MOVE_UP; + } + + break; + + case UX_MOUSE_WHEEL_MOVE_UP: + + mouse_wheel = UX_DEMO_HID_MOUSE_WHEEL_MOVE; + + wheel_move_count ++; + + if (wheel_move_count >= UX_DEMO_HID_MOUSE_WHEEL_MOVE_N) + { + wheel_move_count = 0; + wheel_move_dir = UX_MOUSE_WHEEL_MOVE_DONE; + } + + break; + + default: + + mouse_wheel = 0; + + ux_utility_memory_set(&device_hid_event, 0, sizeof(UX_SLAVE_CLASS_HID_EVENT)); + + break; + } + + /* Set the mouse event. */ + status = ux_device_class_hid_event_set(device_hid, &device_hid_event); + + if(status != UX_SUCCESS) + return UX_ERROR; + + return wheel_move_dir; +} + +static VOID ux_demo_error_callback(UINT system_level, UINT system_context, UINT error_code) +{ + /* + * Refer to ux_api.h. For example, + * UX_SYSTEM_LEVEL_INTERRUPT, UX_SYSTEM_CONTEXT_DCD, UX_DEVICE_HANDLE_UNKNOWN + */ + printf("USBX error: system level(%d), context(%d), error code(0x%x)\r\n", system_level, system_context, error_code); +} diff --git a/samples/device_hid_mouse_rtos/demo_device_hid_mouse.h b/samples/device_hid_mouse_rtos/demo_device_hid_mouse.h new file mode 100644 index 00000000..288d1793 --- /dev/null +++ b/samples/device_hid_mouse_rtos/demo_device_hid_mouse.h @@ -0,0 +1,90 @@ +/*************************************************************************** + * Copyright (c) 2025-present Eclipse ThreadX Contributors + * + * This program and the accompanying materials are made available under the + * terms of the MIT License which is available at + * https://opensource.org/licenses/MIT. + * + * + * SPDX-License-Identifier: MIT + **************************************************************************/ + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** AUTHOR */ +/** */ +/** Mohamed AYED */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +#ifndef UX_DEMO_DEVICE_HID_MOUSE_H +#define UX_DEMO_DEVICE_HID_MOUSE_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "tx_api.h" +#include "ux_api.h" +#include "ux_device_class_hid.h" + + +#include "demo_device_hid_descriptors.h" + +//#include "usb_otg.h" + + +#define DEMO_STACK_SIZE 2*1024 +#define UX_DEVICE_MEMORY_STACK_SIZE 2*1024 + + +#ifdef UX_DEMO_MOUSE_ABSOLUTE +#define UX_DEMO_HID_MOUSE_CURSOR_MOVE 500 +#else /* UX_DEMO_MOUSE_ABSOLUTE */ +#define UX_DEMO_HID_MOUSE_CURSOR_MOVE 3 +#define UX_DEMO_HID_MOUSE_CURSOR_MOVE_N 100 +#endif /* UX_DEMO_MOUSE_ABSOLUTE */ + +#define UX_DEMO_HID_MOUSE_WHEEL_MOVE 15 +#define UX_DEMO_HID_MOUSE_WHEEL_MOVE_N 100 + + +/******************************/ +/** Mouse cursor direction */ +/******************************/ +#define UX_MOUSE_CURSOR_MOVE_RIGHT 0x00 +#define UX_MOUSE_CURSOR_MOVE_DOWN 0x01 +#define UX_MOUSE_CURSOR_MOVE_LEFT 0x02 +#define UX_MOUSE_CURSOR_MOVE_UP 0x03 +#define UX_MOUSE_CURSOR_MOVE_DONE 0x10 + +/*****************************/ +/** Mouse Buttons */ +/*****************************/ +#define UX_MOUSE_BUTTON_PRESS_LEFT 0x00 +#define UX_MOUSE_BUTTON_PRESS_RIGHT 0x01 +#define UX_MOUSE_BUTTON_PRESS_MIDDLE 0x02 +#define UX_MOUSE_BUTTON_PRESS_DONE 0x10 + +/*****************************/ +/** Mouse wheel direction */ +/*****************************/ +#define UX_MOUSE_WHEEL_MOVE_DOWN 0x00 +#define UX_MOUSE_WHEEL_MOVE_UP 0x01 +#define UX_MOUSE_WHEEL_MOVE_DONE 0x10 + +/*******************************/ +/** Mouse demo state machine */ +/*******************************/ +#define UX_DEMO_MOUSE_CURSOR 0x00 +#define UX_DEMO_MOUSE_WHEEL 0x01 +#define UX_DEMO_MOUSE_BUTTON 0x02 +#define UX_DEMO_MOUSE_DONE 0x10 + + +#ifdef __cplusplus +} +#endif +#endif /* UX_DEMO_DEVICE_HID_MOUSE_H */ diff --git a/samples/device_hid_mouse_rtos/readme.md b/samples/device_hid_mouse_rtos/readme.md new file mode 100644 index 00000000..bfbcd116 --- /dev/null +++ b/samples/device_hid_mouse_rtos/readme.md @@ -0,0 +1,53 @@ + +## Overview + +This example works as a USB HID device. It will appear as a USB mouse device on PC. + + - Move mouse arrow on the PC screen according in a rectangular fashion. + - Scroll mouse wheel. + - Click left middle right mouse buttons. + +This application demo is running in **RTOS** mode. + +To test absolute mouse you need to define **UX_DEMO_MOUSE_ABSOLUTE** in **ux_demo_device_descriptors.h** + +**Note:** +- This demonstration is optimized. +- **DEMO_STACK_SIZE** and **UX_DEVICE_MEMORY_STACK_SIZE** memory size should be adjusted. + +## USB Specification + +- USB 2.0 Universal Serial BUS : https://www.usb.org/document-library/usb-20-specification +- USB HID Class : https://www.usb.org/document-library/device-class-definition-hid-111 +- USB HID Usage Tables : https://usb.org/document-library/hid-usage-tables-16 + +## Report Descriptor + +A HID (Human Interface Device) mouse report descriptor defines how data is sent from the device (mouse) to the host (computer). Below is a standard USB HID mouse report descriptor for a 3-button mouse with X and Y movement and wheel. + +### Report Format Relative + +This descriptor defines a 4-byte report format: + +|Byte | Bits | Usage | +| --- | --- | ----- | +| 0 | 0-2 | Buttons (Bit 0 = Left, Bit 1 = Right, Bit 2 = Middle) | +| 0 | 3-7 | Padding (unused) | +| 1 | 0-7 | X-axis movement (-127 to +127, relative) | +| 2 | 0-7 | Y-axis movement (-127 to +127, relative) | + +### Report Format Absolute +This descriptor defines a 6-byte report format: + +|Byte | Bits | Usage | +| --- | --- | ----- | +| 0 | 0-2 | Buttons (Bit 0 = Left, Bit 1 = Right, Bit 2 = Middle) | +| 0 | 3-7 | Padding (unused) | +| 1-2 | 0-15 | X-axis Position (0 - 32767, absolute) | +| 3-4 | 0-15 | Y-axis Position (0 - 32767, absolute) | + +## Run the example +- Create a project and include **USBX** and **THREADX** files. +- Customize **board_setup** with hardware init and **usb_device_interrupt_setup** with usb hardware init. +- Run Project. +- Plug-in the device, which is running HID mouse example, into the PC. A HID-compliant mouse is enumerated in the Device Manager. diff --git a/samples/device_hid_mouse_rtos/ux_user.h b/samples/device_hid_mouse_rtos/ux_user.h new file mode 100644 index 00000000..6402b071 --- /dev/null +++ b/samples/device_hid_mouse_rtos/ux_user.h @@ -0,0 +1,83 @@ +/*************************************************************************** + * Copyright (c) 2024 Microsoft Corporation + * + * This program and the accompanying materials are made available under the + * terms of the MIT License which is available at + * https://opensource.org/licenses/MIT. + * + * + * SPDX-License-Identifier: MIT + **************************************************************************/ + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** USBX Component */ +/** */ +/** User Specific */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/**************************************************************************/ +/* */ +/* PORT SPECIFIC C INFORMATION RELEASE */ +/* */ +/* ux_user.h PORTABLE C */ +/* 6.3.0 */ +/* */ +/* AUTHOR */ +/* */ +/* Chaoqiong Xiao, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains user defines for configuring USBX in specific */ +/* ways. This file will have an effect only if the application and */ +/* USBX library are built with UX_INCLUDE_USER_DEFINE_FILE defined. */ +/* Note that all the defines in this file may also be made on the */ +/* command line when building USBX library and application objects. */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 05-19-2020 Chaoqiong Xiao Version 6.4.1 */ +/* */ +/**************************************************************************/ + +#ifndef UX_USER_H +#define UX_USER_H + + + +#define UX_MAX_SLAVE_CLASS_DRIVER 1 +#define UX_MAX_SLAVE_INTERFACES 1 + + +#define UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH 64 +#define UX_SLAVE_REQUEST_DATA_MAX_LENGTH 8 + +#define UX_DEVICE_ENDPOINT_BUFFER_OWNER 1 +#define UX_DEVICE_CLASS_HID_ZERO_COPY + + +#define UX_DEVICE_CLASS_HID_EVENT_BUFFER_LENGTH 8 +#define UX_DEVICE_CLASS_HID_MAX_EVENTS_QUEUE 2 + +#define UX_THREAD_STACK_SIZE 512 + +#define UX_DEVICE_ALTERNATE_SETTING_SUPPORT_DISABLE +#define UX_DEVICE_INITIALIZE_FRAMEWORK_SCAN_DISABLE + +#define UX_NAME_REFERENCED_BY_POINTER + +#define UX_ENABLE_ERROR_CHECKING + +#define UX_DEVICE_SIDE_ONLY + + +#define UX_MAX_DEVICE_ENDPOINTS 1 +#define UX_MAX_DEVICE_INTERFACES 1 + +#endif /* UX_USER_H */ diff --git a/samples/device_hid_mouse_standalone/demo_device_hid_descriptors.c b/samples/device_hid_mouse_standalone/demo_device_hid_descriptors.c new file mode 100644 index 00000000..5fbaf702 --- /dev/null +++ b/samples/device_hid_mouse_standalone/demo_device_hid_descriptors.c @@ -0,0 +1,315 @@ +/*************************************************************************** + * Copyright (c) 2025-present Eclipse ThreadX Contributors + * + * This program and the accompanying materials are made available under the + * terms of the MIT License which is available at + * https://opensource.org/licenses/MIT. + * + * + * SPDX-License-Identifier: MIT + **************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** AUTHOR */ +/** */ +/** Mohamed AYED */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +#include "demo_device_hid_descriptors.h" + +UCHAR hid_report[] = { + 0x05, 0x01, // USAGE_PAGE (Generic Desktop) + 0x09, 0x02, // USAGE (Mouse) + 0xa1, 0x01, // COLLECTION (Application) + + /* Pointer and Physical are required by Apple Recovery */ + 0x09, 0x01, // USAGE (Pointer) + 0xa1, 0x00, // COLLECTION (Physical) + + /* 3 Buttons */ + 0x05, 0x09, // USAGE_PAGE (Button) + 0x19, 0x01, // USAGE_MINIMUM (Button 1) + 0x29, 0x03, // USAGE_MAXIMUM (Button 3) + 0x15, 0x00, // LOGICAL_MINIMUM (0) + 0x25, 0x01, // LOGICAL_MAXIMUM (1) + 0x75, 0x01, // REPORT_SIZE (1) + 0x95, 0x03, // REPORT_COUNT (3) -> 3 buttons + 0x81, 0x02, // INPUT (Data, Variable, Absolute) -> Buttons + + 0x75, 0x05, // REPORT_SIZE (5) + 0x95, 0x01, // REPORT_COUNT (1) + 0x81, 0x03, // INPUT (Constant, Variable, Absolute) -> Padding bits + + /* X, Y */ + 0x05, 0x01, // USAGE_PAGE (Generic Desktop) + 0x09, 0x30, // USAGE (X) + 0x09, 0x31, // USAGE (Y) +#ifdef UX_DEMO_MOUSE_ABSOLUTE + 0x16, 0x00, 0x00, // LOGICAL_MINIMUM (0) + 0x26, 0xFF, 0x7F, // LOGICAL_MAXIMUM (32767) (0x7FFF) + 0x75, 0x10, // REPORT_SIZE (16) (2 bytes per axis) + 0x95, 0x02, // REPORT_COUNT (2) -> X, Y position + 0x81, 0x02, // INPUT (Data, Variable, Absolute) -> Absolute X, Y position +#else /* UX_DEMO_MOUSE_ABSOLUTE */ + 0x15, 0x81, // LOGICAL_MINIMUM (-127) + 0x25, 0x7F, // LOGICAL_MAXIMUM (127) + 0x75, 0x08, // REPORT_SIZE (8) (1 bytes per axis) + 0x95, 0x02, // REPORT_COUNT (2) -> X, Y movement + 0x81, 0x06, // INPUT (Data, Variable, Relative) -> X, Y are relative +#endif /* UX_DEMO_MOUSE_ABSOLUTE */ + + /* Wheel */ + 0x09, 0x38, // USAGE (Mouse Wheel) + 0x15, 0x81, // LOGICAL_MINIMUM (-127) + 0x25, 0x7F, // LOGICAL_MAXIMUM (127) + 0x75, 0x08, // REPORT_SIZE (8) + 0x95, 0x01, // REPORT_COUNT (1) -> Wheel movement + 0x81, 0x06, // INPUT (Data, Variable, Relative) -> Wheel + + /* End */ + 0xC0, // END_COLLECTION + 0xC0 // END_COLLECTION +}; + +#define UX_HID_MOUSE_REPORT_LENGTH (sizeof(hid_report)/sizeof(hid_report[0])) + +UCHAR ux_demo_device_framework_full_speed[] = { + /* Device descriptor */ + 0x12, /* bLength */ + 0x01, /* bDescriptorType */ + UX_W0(UX_DEMO_BCD_USB), UX_W1(UX_DEMO_BCD_USB), /* bcdUSB */ + 0x00, /* bDeviceClass : 0x00 : Interface-defined */ + 0x00, /* bDeviceSubClass : 0x00 : Reset */ + 0x00, /* bDeviceProtocol : 0x00 : Reset */ + UX_DEMO_MAX_EP0_SIZE, /* bMaxPacketSize0 */ + UX_W0(UX_DEMO_HID_DEVICE_VID), UX_W1(UX_DEMO_HID_DEVICE_VID), /* idVendor : ... */ + UX_W0(UX_DEMO_HID_DEVICE_PID), UX_W1(UX_DEMO_HID_DEVICE_PID), /* idProduct */ + 0x00, 0x00, /* bcdDevice */ + 0x01, /* iManufacturer */ + 0x02, /* iProduct */ + 0x03, /* iSerialNumber */ + 0x01, /* bNumConfigurations */ + + /* Configuration Descriptor, total 34 */ + 0x09, /* bLength */ + 0x02, /* bDescriptorType */ + UX_W0(UX_DEMO_HID_CONFIG_DESC_SIZE), UX_W1(UX_DEMO_HID_CONFIG_DESC_SIZE), /* wTotalLength */ + 0x01, /* bNumInterfaces */ + 0x01, /* bConfigurationValue */ + 0x04, /* iConfiguration */ + 0xC0, /* bmAttributes */ + /* D6 : 0x1 : Self-powered */ + /* D5, Remote Wakeup : 0x0 : Not supported */ + 0x32, /* bMaxPower : 50 : 100mA */ + + /* Interface descriptor */ + 0x09, /* bLength */ + 0x04, /* bDescriptorType */ + 0x00, /* bInterfaceNumber */ + 0x00, /* bAlternateSetting */ + 0x01, /* bNumEndpoints */ + 0x03, /* bInterfaceClass : 0x03 : HID */ + UX_DEMO_HID_SUBCLASS, /* bInterfaceSubClass : ... : Boot/non-boot Subclass */ + 0x02, /* bInterfaceProtocol : 0x00 : Undefined */ + 0x06, /* iInterface */ + + /* HID Descriptor */ + 0x09, /* bLength : 9 */ + 0x21, /* bDescriptorType : 0x21 : HID descriptor */ + 0x10, 0x01, /* bcdHID : 0x0110 */ + 0x21, /* bCountryCode : 33 : US */ + 0x01, /* bNumDescriptors */ + 0x22, /* bReportDescriptorType1 : 0x22 : Report descriptor */ + UX_W0(UX_HID_MOUSE_REPORT_LENGTH), UX_W1(UX_HID_MOUSE_REPORT_LENGTH), /* wDescriptorLength1 */ + + /* Endpoint Descriptor */ + 0x07, /* bLength */ + 0x05, /* bDescriptorType */ + UX_DEMO_HID_ENDPOINT_ADDRESS, /* bEndpointAddress */ + /* D7, Direction : 0x01 */ + /* D3..0, Endpoint number : 2 */ + 0x03, /* bmAttributes */ + /* D1..0, Transfer Type : 0x3 : Interrupt */ + /* D3..2, Synchronization Type : 0x0 : No Synchronization */ + /* D5..4, Usage Type : 0x0 : Data endpoint */ + UX_W0(UX_DEMO_HID_ENDPOINT_SIZE), UX_W1(UX_DEMO_HID_ENDPOINT_SIZE), /* wMaxPacketSize */ + /* D10..0, Max Packet Size */ + /* D12..11, Additional transactions : 0x00 */ + UX_DEMO_HID_ENDPOINT_BINTERVAL, /* bInterval : 8 : 8ms / x128 (FS 128ms/HS 16ms) */ +}; + + +UCHAR ux_demo_device_framework_high_speed[] = { + /* Device descriptor */ + 0x12, /* bLength */ + 0x01, /* bDescriptorType */ + UX_W0(UX_DEMO_BCD_USB), UX_W1(UX_DEMO_BCD_USB), /* bcdUSB */ + 0x00, /* bDeviceClass : 0x00 : Interface-defined */ + 0x00, /* bDeviceSubClass : 0x00 : Reset */ + 0x00, /* bDeviceProtocol : 0x00 : Reset */ + UX_DEMO_MAX_EP0_SIZE, /* bMaxPacketSize0 */ + UX_W0(UX_DEMO_HID_DEVICE_VID), UX_W1(UX_DEMO_HID_DEVICE_VID), /* idVendor : ... */ + UX_W0(UX_DEMO_HID_DEVICE_PID), UX_W1(UX_DEMO_HID_DEVICE_PID), /* idProduct */ + 0x01, 0x00, /* bcdDevice */ + 0x01, /* iManufacturer */ + 0x02, /* iProduct */ + 0x03, /* iSerialNumber */ + 0x01, /* bNumConfigurations */ + + /* Device qualifier descriptor */ + 0x0A, /* bLength */ + 0x06, /* bDescriptorType */ + UX_W0(UX_DEMO_BCD_USB), UX_W1(UX_DEMO_BCD_USB), /* bcdUSB */ + 0x00, /* bDeviceClass : 0x00 : Interface-defined */ + 0x00, /* bDeviceSubClass : 0x00 : Reset */ + 0x00, /* bDeviceProtocol : 0x00 : Reset */ + UX_DEMO_MAX_EP0_SIZE, /* bMaxPacketSize0 */ + 0x01, /* bNumConfigurations */ + 0x00, /* bReserved */ + + /* Configuration descriptor */ + 0x09, /* bLength */ + 0x02, /* bDescriptorType */ + UX_W0(UX_DEMO_HID_CONFIG_DESC_SIZE), UX_W1(UX_DEMO_HID_CONFIG_DESC_SIZE), /* wTotalLength */ + 0x01, /* bNumInterfaces */ + 0x01, /* bConfigurationValue */ + 0x05, /* iConfiguration */ + 0xC0, /* bmAttributes */ + /* D6 : 0x1 : Self-powered */ + /* D5, Remote Wakeup : 0x0 : Not supported */ + 0x19, /* bMaxPower : 50 : 100mA */ + + /* Interface descriptor */ + 0x09, /* bLength */ + 0x04, /* bDescriptorType */ + 0x00, /* bInterfaceNumber */ + 0x00, /* bAlternateSetting */ + 0x01, /* bNumEndpoints */ + 0x03, /* bInterfaceClass : 0x03 : HID */ + UX_DEMO_HID_SUBCLASS, /* bInterfaceSubClass : ... : Boot/non-boot Subclass */ + 0x02, /* bInterfaceProtocol : 0x00 : Undefined */ + 0x06, /* iInterface */ + + /* HID Descriptor */ + 0x09, /* bLength : 9 */ + 0x21, /* bDescriptorType : 0x21 : HID descriptor */ + UX_W0(UX_DEMO_BCD_HID), UX_W1(UX_DEMO_BCD_HID), /* bcdHID : 0x0110 */ + 0x21, /* bCountryCode : 33 : US */ + 0x01, /* bNumDescriptors */ + 0x22, /* bReportDescriptorType1 : 0x22 : Report descriptor */ + UX_W0(UX_HID_MOUSE_REPORT_LENGTH), UX_W1(UX_HID_MOUSE_REPORT_LENGTH), /* wDescriptorLength1 */ + + /* Endpoint Descriptor (Interrupt In) */ + 0x07, /* bLength */ + 0x05, /* bDescriptorType */ + UX_DEMO_HID_ENDPOINT_ADDRESS, /* bEndpointAddress */ + /* D7, Direction : 0x01 */ + /* D3..0, Endpoint number : 2 */ + 0x03, /* bmAttributes */ + /* D1..0, Transfer Type : 0x3 : Interrupt */ + /* D3..2, Synchronization Type : 0x0 : No Synchronization */ + /* D5..4, Usage Type : 0x0 : Data endpoint */ + UX_W0(UX_DEMO_HID_ENDPOINT_SIZE), UX_W1(UX_DEMO_HID_ENDPOINT_SIZE), /* wMaxPacketSize */ + /* D10..0, Max Packet Size */ + /* D12..11, Additional transactions : 0x00 */ + UX_DEMO_HID_ENDPOINT_BINTERVAL, /* bInterval : 8 : 8ms / x128 (FS 128ms/HS 16ms) */ +}; + + +/* String Device Framework : + Byte 0 and 1 : Word containing the language ID : 0x0904 for US + Byte 2 : Byte containing the index of the descriptor + Byte 3 : Byte containing the length of the descriptor string +*/ +UCHAR ux_demo_string_framework[] = { + + /* iManufacturer string descriptor : Index 1 */ + 0x09, 0x04, 0x01, 12, + 'U', 'S', 'B', 'X', ' ', 'e', 'c', 'l', 'i', 'p', 's', 'e', + + /* iProduct string descriptor : Index 2 */ + 0x09, 0x04, 0x02, 14, + 'H', 'I', 'D', ' ', 'M', 'o', 'u', 's', 'e', ' ', 'D', 'e', 'm', 'o', + + /* iSerialNumber Number string descriptor : Index 3 */ + 0x09, 0x04, 0x03, 13, + '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '1', + + /* iConfiguration string descriptor : Index 4 */ + 0x09, 0x04, 0x04, 10, + 'F', 'U', 'L', 'L', ' ', 'S', 'P', 'E', 'E', 'D', + + /* iConfiguration string descriptor : Index 5 */ + 0x09, 0x04, 0x05, 10, + 'H', 'I', 'G', 'H', ' ', 'S', 'P', 'E', 'E', 'D', + + /* iInterface string descriptor : Index 6 */ + 0x09, 0x04, 0x06, 5, + 'M', 'o', 'u', 's', 'e' +}; + + +/* Multiple languages are supported on the device, to add + a language besides english, the unicode language code must + be appended to the language_id_framework array and the length + adjusted accordingly. */ +UCHAR ux_demo_language_id_framework[] = { + /* English. */ + 0x09, 0x04 +}; + + +UCHAR* ux_demo_get_high_speed_framework(VOID) +{ + return ux_demo_device_framework_high_speed; +} + +ULONG ux_demo_get_high_speed_framework_length(VOID) +{ + return sizeof(ux_demo_device_framework_high_speed); +} + +UCHAR* ux_demo_get_full_speed_framework(VOID) +{ + return ux_demo_device_framework_full_speed; +} + +ULONG ux_demo_get_full_speed_framework_length(VOID) +{ + return sizeof(ux_demo_device_framework_full_speed); +} + +UCHAR* ux_demo_get_string_framework(VOID) +{ + return ux_demo_string_framework; +} + +ULONG ux_demo_get_string_framework_length(VOID) +{ + return sizeof(ux_demo_string_framework); +} + +UCHAR* ux_demo_get_language_framework(VOID) +{ + return ux_demo_language_id_framework; +} + +ULONG ux_demo_get_language_framework_length(VOID) +{ + return sizeof(ux_demo_language_id_framework); +} + +UCHAR* ux_demo_device_hid_get_report(VOID) +{ + return hid_report; +} + +ULONG ux_demo_device_hid_get_report_length(VOID) +{ + return (sizeof(hid_report)/sizeof(hid_report[0])); +} diff --git a/samples/device_hid_mouse_standalone/demo_device_hid_descriptors.h b/samples/device_hid_mouse_standalone/demo_device_hid_descriptors.h new file mode 100644 index 00000000..15931b85 --- /dev/null +++ b/samples/device_hid_mouse_standalone/demo_device_hid_descriptors.h @@ -0,0 +1,71 @@ +/*************************************************************************** + * Copyright (c) 2024 Microsoft Corporation + * + * This program and the accompanying materials are made available under the + * terms of the MIT License which is available at + * https://opensource.org/licenses/MIT. + * + * + * SPDX-License-Identifier: MIT + **************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** AUTHOR */ +/** */ +/** Mohamed AYED */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +#ifndef UX_DEMO_DEVICE_DESCRIPTORS_H +#define UX_DEMO_DEVICE_DESCRIPTORS_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "ux_api.h" + +//#define UX_DEMO_MOUSE_ABSOLUTE + +#define DEMO_HID_BOOT_DEVICE +#define UX_DEMO_HID_DEVICE_VID 0x070A +#define UX_DEMO_HID_DEVICE_PID 0x4036 + +#define UX_DEMO_MAX_EP0_SIZE 0x40U +#define UX_DEMO_HID_CONFIG_DESC_SIZE 0x22U + +#define UX_DEMO_BCD_USB 0x0200 + +#define UX_DEMO_BCD_HID 0x0110 + +#define UX_DEMO_HID_ENDPOINT_SIZE 0x08 +#define UX_DEMO_HID_ENDPOINT_ADDRESS 0x81 +#define UX_DEMO_HID_ENDPOINT_BINTERVAL 0x08 + +#ifdef DEMO_HID_BOOT_DEVICE +#define UX_DEMO_HID_SUBCLASS 0x01 +#else /* DEMO_HID_BOOT_DEVICE */ +#define UX_DEMO_HID_SUBCLASS 0x00 +#endif + + +UCHAR* ux_demo_get_high_speed_framework(VOID); +ULONG ux_demo_get_high_speed_framework_length(VOID); +UCHAR* ux_demo_get_full_speed_framework(VOID); +ULONG ux_demo_get_full_speed_framework_length(VOID); +UCHAR* ux_demo_get_string_framework(VOID); +ULONG ux_demo_get_string_framework_length(VOID); +UCHAR* ux_demo_get_language_framework(VOID); +ULONG ux_demo_get_language_framework_length(VOID); + +UCHAR* ux_demo_device_hid_get_report(VOID); +ULONG ux_demo_device_hid_get_report_length(VOID); + +#ifdef __cplusplus +} +#endif +#endif /* UX_DEMO_DEVICE_DESCRIPTORS_H */ diff --git a/samples/device_hid_mouse_standalone/demo_device_hid_mouse.c b/samples/device_hid_mouse_standalone/demo_device_hid_mouse.c new file mode 100644 index 00000000..efe70754 --- /dev/null +++ b/samples/device_hid_mouse_standalone/demo_device_hid_mouse.c @@ -0,0 +1,644 @@ +/*************************************************************************** + * Copyright (c) 2025-present Eclipse ThreadX Contributors + * + * This program and the accompanying materials are made available under the + * terms of the MIT License which is available at + * https://opensource.org/licenses/MIT. + * + * + * SPDX-License-Identifier: MIT + **************************************************************************/ + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** AUTHOR */ +/** */ +/** Mohamed AYED */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +#include "demo_device_hid_mouse.h" + +/**************************************************/ +/** usbx device hid demo callbacks */ +/**************************************************/ +VOID ux_demo_device_hid_instance_activate(VOID *hid_instance); +VOID ux_demo_device_hid_instance_deactivate(VOID *hid_instance); +UINT ux_demo_device_hid_callback(UX_SLAVE_CLASS_HID *hid_instance, UX_SLAVE_CLASS_HID_EVENT *hid_event); +UINT ux_demo_device_hid_get_callback(UX_SLAVE_CLASS_HID *hid_instance, UX_SLAVE_CLASS_HID_EVENT *hid_event); + +/**************************************************/ +/** usbx device hid demo mouse */ +/**************************************************/ +UINT ux_demo_hid_mouse_cursor_move(UX_SLAVE_CLASS_HID *device_hid); +UINT ux_demo_hid_mouse_buttons(UX_SLAVE_CLASS_HID *device_hid); +UINT ux_demo_hid_mouse_scroll_wheel(UX_SLAVE_CLASS_HID *device_hid); +#ifdef UX_DEMO_MOUSE_ABSOLUTE +UINT ux_demo_hid_mouse_absolute_cursor_move(UX_SLAVE_CLASS_HID *device_hid); +#endif /* UX_DEMO_MOUSE_ABSOLUTE */ + +VOID usbx_app_device_init(VOID); +static VOID ux_demo_error_callback(UINT system_level, UINT system_context, UINT error_code); + +/**************************************************/ +/** usbx device hid mouse instance */ +/**************************************************/ +UX_SLAVE_CLASS_HID *hid_mouse; + + +static CHAR ux_system_memory_pool[UX_DEVICE_MEMORY_STACK_SIZE]; + +int main(void) +{ + /* Initialize the board. */ + board_setup(); + + ux_application_define(); + + while (1) + { + ux_system_tasks_run(); + ux_demo_device_hid_task(); + } + +} + +VOID ux_application_define(VOID) +{ +CHAR *memory_pointer; +UINT status; +UX_SLAVE_CLASS_HID_PARAMETER hid_mouse_parameter; + + /* Use static memory block. */ + memory_pointer = ux_system_memory_pool; + + /* Initialize USBX Memory */ + status = ux_system_initialize(memory_pointer, UX_DEVICE_MEMORY_STACK_SIZE, UX_NULL, 0); + + if(status != UX_SUCCESS) + return; + + printf("USBX System initialized successfully\r\n"); + + /* Install the device portion of USBX */ + status = ux_device_stack_initialize(ux_demo_get_high_speed_framework(), + ux_demo_get_high_speed_framework_length(), + ux_demo_get_full_speed_framework(), + ux_demo_get_full_speed_framework_length(), + ux_demo_get_string_framework(), + ux_demo_get_string_framework_length(), + ux_demo_get_language_framework(), + ux_demo_get_language_framework_length(), + UX_NULL); + + if(status != UX_SUCCESS) + return; + + printf("USBX Device stack initialized successfully\r\n"); + + /* Initialize the hid mouse class parameters for the device */ + hid_mouse_parameter.ux_slave_class_hid_instance_activate = ux_demo_device_hid_instance_activate; + hid_mouse_parameter.ux_slave_class_hid_instance_deactivate = ux_demo_device_hid_instance_deactivate; + hid_mouse_parameter.ux_device_class_hid_parameter_report_address = ux_demo_device_hid_get_report(); + hid_mouse_parameter.ux_device_class_hid_parameter_report_length = ux_demo_device_hid_get_report_length(); + hid_mouse_parameter.ux_device_class_hid_parameter_report_id = UX_FALSE; + hid_mouse_parameter.ux_device_class_hid_parameter_callback = ux_demo_device_hid_callback; + hid_mouse_parameter.ux_device_class_hid_parameter_get_callback = ux_demo_device_hid_get_callback; + + /* Initialize the device storage class. The class is connected with interface 0 on configuration 1. */ + status = ux_device_stack_class_register(_ux_system_slave_class_hid_name, ux_device_class_hid_entry, + 1, 0, (VOID *)&hid_mouse_parameter); + + if(status != UX_SUCCESS) + return; + + /* error callback */ + ux_utility_error_callback_register(ux_demo_error_callback); + + usbx_app_device_init(); +} + +/********************************************************************/ +/** ux_demo_device_hid_instance_activate */ +/********************************************************************/ +VOID ux_demo_device_hid_instance_activate(VOID *hid_instance) +{ + if (hid_mouse == UX_NULL) + hid_mouse = (UX_SLAVE_CLASS_HID*) hid_instance; +} + +/********************************************************************/ +/** ux_demo_device_hid_instance_deactivate */ +/********************************************************************/ +VOID ux_demo_device_hid_instance_deactivate(VOID *hid_instance) +{ + if (hid_instance == (VOID *)hid_mouse) + hid_mouse = UX_NULL; +} + +/********************************************************************/ +/** ux_demo_device_hid_callback */ +/********************************************************************/ +UINT ux_demo_device_hid_callback(UX_SLAVE_CLASS_HID *hid_instance, UX_SLAVE_CLASS_HID_EVENT *hid_event) +{ + UX_PARAMETER_NOT_USED(hid_instance); + UX_PARAMETER_NOT_USED(hid_event); + + return UX_SUCCESS; +} + +/********************************************************************/ +/** ux_demo_device_hid_get_callback */ +/********************************************************************/ +UINT ux_demo_device_hid_get_callback(UX_SLAVE_CLASS_HID *hid_instance, UX_SLAVE_CLASS_HID_EVENT *hid_event) +{ + UX_PARAMETER_NOT_USED(hid_instance); + UX_PARAMETER_NOT_USED(hid_event); + + return UX_SUCCESS; +} + +VOID usbx_app_device_init(VOID) +{ + usb_device_interrupt_setup(); + +} + +/********************************************************************/ +/** demo_delay_with_tasks_running: delay with tasks */ +/********************************************************************/ +static void demo_delay_with_tasks_running(ULONG ms_wait) +{ +ULONG ticks; + + /* Get current time. */ + ticks = ux_utility_time_get(); + + /* Wait until timeout. */ + while(ux_utility_time_elapsed(ticks, ux_utility_time_get()) < UX_MS_TO_TICK_NON_ZERO(ms_wait)) + { + ux_system_tasks_run(); + } +} + +/********************************************************************/ +/** ux_demo_device_hid_task: hid demo task */ +/********************************************************************/ +VOID ux_demo_device_hid_task(VOID) +{ +UINT status; +static UINT demo_state = UX_DEMO_MOUSE_CURSOR; + + + /* Check if the device state already configured. */ + if ((UX_SLAVE_DEVICE_CHECK_STATE(UX_DEVICE_CONFIGURED)) && (hid_mouse != UX_NULL)) + { + + switch(demo_state) + { + + case UX_DEMO_MOUSE_CURSOR: + + /* Move cursor */ +#ifdef UX_DEMO_MOUSE_ABSOLUTE + status = ux_demo_hid_mouse_absolute_cursor_move(hid_mouse); +#else /* UX_DEMO_MOUSE_ABSOLUTE */ + status = ux_demo_hid_mouse_cursor_move(hid_mouse); +#endif /* UX_DEMO_MOUSE_ABSOLUTE */ + + if (status == UX_MOUSE_CURSOR_MOVE_DONE) + demo_state = UX_DEMO_MOUSE_WHEEL; + + break; + + case UX_DEMO_MOUSE_WHEEL: + + /* Scroll wheel */ + status = ux_demo_hid_mouse_scroll_wheel(hid_mouse); + + if (status == UX_MOUSE_WHEEL_MOVE_DONE) + demo_state = UX_DEMO_MOUSE_BUTTON; + + break; + + case UX_DEMO_MOUSE_BUTTON: + + /* Click button */ + status = ux_demo_hid_mouse_buttons(hid_mouse); + + if (status == UX_MOUSE_BUTTON_PRESS_DONE) + demo_state = UX_DEMO_MOUSE_DONE; + + break; + + default: + + ux_utility_delay_ms(MS_TO_TICK(10)); + + break; + } + } +} + +#ifndef UX_DEMO_MOUSE_ABSOLUTE +/********************************************************************/ +/** ux_demo_hid_mouse_cursor_move: show how to move mouse cursor */ +/********************************************************************/ +UINT ux_demo_hid_mouse_cursor_move(UX_SLAVE_CLASS_HID *device_hid) +{ +UINT status; +UX_SLAVE_CLASS_HID_EVENT device_hid_event; +static UCHAR mouse_x; +static UCHAR mouse_y; +static UCHAR mouse_move_dir; +static UCHAR mouse_move_count; + + demo_delay_with_tasks_running(10); + + /* Initialize mouse event. */ + device_hid_event.ux_device_class_hid_event_report_id = 0; + device_hid_event.ux_device_class_hid_event_report_type = UX_DEVICE_CLASS_HID_REPORT_TYPE_INPUT; + device_hid_event.ux_device_class_hid_event_length = 4; + device_hid_event.ux_device_class_hid_event_buffer[0] = 0; /* ...R|M|L */ + device_hid_event.ux_device_class_hid_event_buffer[1] = mouse_x; /* X */ + device_hid_event.ux_device_class_hid_event_buffer[2] = mouse_y; /* Y */ + device_hid_event.ux_device_class_hid_event_buffer[3] = 0; /* Wheel */ + + /* Move cursor. */ + switch(mouse_move_dir) + { + case UX_MOUSE_CURSOR_MOVE_RIGHT: /* +x. */ + + mouse_x = UX_DEMO_HID_MOUSE_CURSOR_MOVE; + mouse_y = 0; + mouse_move_count ++; + + if (mouse_move_count >= UX_DEMO_HID_MOUSE_CURSOR_MOVE_N) + { + mouse_move_count = 0; + mouse_move_dir = UX_MOUSE_CURSOR_MOVE_DOWN; + } + + break; + + case UX_MOUSE_CURSOR_MOVE_DOWN: /* +y. */ + + mouse_x = 0; + mouse_y = UX_DEMO_HID_MOUSE_CURSOR_MOVE; + mouse_move_count ++; + + if (mouse_move_count >= UX_DEMO_HID_MOUSE_CURSOR_MOVE_N) + { + mouse_move_count = 0; + mouse_move_dir = UX_MOUSE_CURSOR_MOVE_LEFT; + } + + break; + + case UX_MOUSE_CURSOR_MOVE_LEFT: /* -x. */ + + mouse_x = (CHAR)(-UX_DEMO_HID_MOUSE_CURSOR_MOVE); + mouse_y = 0; + mouse_move_count ++; + + if (mouse_move_count >= UX_DEMO_HID_MOUSE_CURSOR_MOVE_N) + { + mouse_move_count = 0; + mouse_move_dir = UX_MOUSE_CURSOR_MOVE_UP; + } + + break; + + case UX_MOUSE_CURSOR_MOVE_UP: /* -y. */ + + mouse_x = 0; + mouse_y = (UCHAR)(-UX_DEMO_HID_MOUSE_CURSOR_MOVE); + mouse_move_count ++; + + if (mouse_move_count >= UX_DEMO_HID_MOUSE_CURSOR_MOVE_N) + { + mouse_move_count = 0; + mouse_move_dir = UX_MOUSE_CURSOR_MOVE_DONE; + } + + break; + + default: + + mouse_x = 0; + mouse_y = 0; + + ux_utility_memory_set(&device_hid_event, 0, sizeof(UX_SLAVE_CLASS_HID_EVENT)); + + break; + } + + status = ux_device_class_hid_event_set(device_hid, &device_hid_event); + + if(status != UX_SUCCESS) + return UX_ERROR; + + return mouse_move_dir; +} +#endif /* !UX_DEMO_MOUSE_ABSOLUTE */ + +#ifdef UX_DEMO_MOUSE_ABSOLUTE +/***************************************************************************************/ +/** ux_demo_hid_mouse_absolute_cursor_move: */ +/** show how to daw a rectangle with width 10000, height 10000, step size 500 */ +/***************************************************************************************/ +UINT ux_demo_hid_mouse_absolute_cursor_move(UX_SLAVE_CLASS_HID *device_hid) +{ +UINT status; +UX_SLAVE_CLASS_HID_EVENT device_hid_event; +ULONG start_mouse_x = 8000; +ULONG start_mouse_y = 8000; +ULONG width = 10000; +ULONG height = 10000; +static ULONG mouse_x; +static ULONG mouse_y; +static UCHAR mouse_move_dir; + + demo_delay_with_tasks_running(10); + + /* Initialize mouse event. */ + device_hid_event.ux_device_class_hid_event_report_id = 0; + device_hid_event.ux_device_class_hid_event_report_type = UX_DEVICE_CLASS_HID_REPORT_TYPE_INPUT; + device_hid_event.ux_device_class_hid_event_length = 6; + device_hid_event.ux_device_class_hid_event_buffer[0] = 0; /* ...M|R|L */ + device_hid_event.ux_device_class_hid_event_buffer[1] = UX_W0(mouse_x); /* X */ + device_hid_event.ux_device_class_hid_event_buffer[2] = UX_W1(mouse_x); /* X */ + device_hid_event.ux_device_class_hid_event_buffer[3] = UX_W0(mouse_y); /* Y */ + device_hid_event.ux_device_class_hid_event_buffer[4] = UX_W1(mouse_y); /* Y */ + device_hid_event.ux_device_class_hid_event_buffer[5] = 0; /* Wheel */ + + + switch (mouse_move_dir) + { + case UX_MOUSE_CURSOR_MOVE_RIGHT: /* +x. */ + + mouse_x += UX_DEMO_HID_MOUSE_CURSOR_MOVE; + + if (mouse_x >= start_mouse_x + width) + { + mouse_x = start_mouse_x + width; + mouse_move_dir = UX_MOUSE_CURSOR_MOVE_DOWN; + } + + break; + + case UX_MOUSE_CURSOR_MOVE_DOWN: /* +y. */ + + mouse_y += UX_DEMO_HID_MOUSE_CURSOR_MOVE; + + if (mouse_y >= start_mouse_y + height) + { + mouse_y = start_mouse_y + height; + mouse_move_dir = UX_MOUSE_CURSOR_MOVE_LEFT; + } + + break; + + case UX_MOUSE_CURSOR_MOVE_LEFT: /* -y. */ + + mouse_x -= UX_DEMO_HID_MOUSE_CURSOR_MOVE; + + if (mouse_x <= start_mouse_x) + { + mouse_x = start_mouse_x; + mouse_move_dir = UX_MOUSE_CURSOR_MOVE_UP; + } + + break; + + case UX_MOUSE_CURSOR_MOVE_UP: /* -y. */ + + mouse_y -= UX_DEMO_HID_MOUSE_CURSOR_MOVE; + + if (mouse_y <= start_mouse_y) + { + mouse_y = start_mouse_y; + mouse_move_dir = UX_MOUSE_CURSOR_MOVE_DONE; + } + + break; + + default: + + mouse_x = 0; + mouse_y = 0; + + ux_utility_memory_set(&device_hid_event, 0, sizeof(UX_SLAVE_CLASS_HID_EVENT)); + + break; + } + + /* Set the mouse event. */ + status = ux_device_class_hid_event_set(device_hid, &device_hid_event); + + if(status != UX_SUCCESS) + return UX_ERROR; + + return mouse_move_dir; +} +#endif /* UX_DEMO_MOUSE_ABSOLUTE */ + +/*****************************************************************/ +/** ux_demo_hid_mouse_buttons: show how to click mouse button */ +/*****************************************************************/ +UINT ux_demo_hid_mouse_buttons(UX_SLAVE_CLASS_HID *device_hid) +{ +UINT status; +UX_SLAVE_CLASS_HID_EVENT device_hid_event; +static UCHAR button_status; + + demo_delay_with_tasks_running(10); + + /* Initialize mouse event. */ + device_hid_event.ux_device_class_hid_event_report_id = 0; + device_hid_event.ux_device_class_hid_event_report_type = UX_DEVICE_CLASS_HID_REPORT_TYPE_INPUT; +#ifndef UX_DEMO_MOUSE_ABSOLUTE + device_hid_event.ux_device_class_hid_event_length = 4; + device_hid_event.ux_device_class_hid_event_buffer[0] = 0; /* ...M|R|L */ + device_hid_event.ux_device_class_hid_event_buffer[1] = 0; /* X */ + device_hid_event.ux_device_class_hid_event_buffer[2] = 0; /* Y */ + device_hid_event.ux_device_class_hid_event_buffer[3] = 0; /* Wheel */ +#else /* UX_DEMO_MOUSE_ABSOLUTE */ + device_hid_event.ux_device_class_hid_event_length = 6; + device_hid_event.ux_device_class_hid_event_buffer[0] = 0; /* ...M|R|L */ + device_hid_event.ux_device_class_hid_event_buffer[1] = 0; /* X */ + device_hid_event.ux_device_class_hid_event_buffer[2] = 0; /* X */ + device_hid_event.ux_device_class_hid_event_buffer[3] = 0; /* Y */ + device_hid_event.ux_device_class_hid_event_buffer[4] = 0; /* Y */ + device_hid_event.ux_device_class_hid_event_buffer[5] = 0; /* Wheel */ +#endif /* UX_DEMO_MOUSE_ABSOLUTE */ + + switch(button_status) + { + case UX_MOUSE_BUTTON_PRESS_LEFT: + + /* Press L button. */ + device_hid_event.ux_device_class_hid_event_buffer[0] = 0x01; + + button_status = UX_MOUSE_BUTTON_PRESS_RIGHT; + + break; + + case UX_MOUSE_BUTTON_PRESS_RIGHT: + + /* Press R button. */ + device_hid_event.ux_device_class_hid_event_buffer[0] = 0x02; + + button_status = UX_MOUSE_BUTTON_PRESS_MIDDLE; + + break; + + case UX_MOUSE_BUTTON_PRESS_MIDDLE: + + /* Press M button. */ + device_hid_event.ux_device_class_hid_event_buffer[0] = 0x04; + + button_status = UX_MOUSE_BUTTON_PRESS_DONE; + + break; + + default: + + ux_utility_memory_set(&device_hid_event, 0, sizeof(UX_SLAVE_CLASS_HID_EVENT)); + + break; + } + + /* Set the mouse event. */ + status = ux_device_class_hid_event_set(device_hid, &device_hid_event); + + if(status != UX_SUCCESS) + return UX_ERROR; + + + /* Release button. */ + device_hid_event.ux_device_class_hid_event_buffer[0] = 0x00; + status = ux_device_class_hid_event_set(device_hid, &device_hid_event); + + if(status != UX_SUCCESS) + return UX_ERROR; + + return button_status; +} + +/**************************************************************/ +/** ux_demo_hid_mouse_scroll_wheel: show how to move wheel */ +/**************************************************************/ +UINT ux_demo_hid_mouse_scroll_wheel(UX_SLAVE_CLASS_HID *device_hid) +{ +UINT status; +UX_SLAVE_CLASS_HID_EVENT device_hid_event; +static UCHAR mouse_wheel; +static UCHAR wheel_move_dir; +static UCHAR wheel_move_count; + + demo_delay_with_tasks_running(10); + + /* Initialize mouse event. */ + device_hid_event.ux_device_class_hid_event_report_id = 0; + device_hid_event.ux_device_class_hid_event_report_type = UX_DEVICE_CLASS_HID_REPORT_TYPE_INPUT; +#ifndef UX_DEMO_MOUSE_ABSOLUTE + device_hid_event.ux_device_class_hid_event_length = 4; + device_hid_event.ux_device_class_hid_event_buffer[0] = 0; /* ...M|R|L */ + device_hid_event.ux_device_class_hid_event_buffer[1] = 0; /* X */ + device_hid_event.ux_device_class_hid_event_buffer[2] = 0; /* Y */ + device_hid_event.ux_device_class_hid_event_buffer[3] = mouse_wheel; /* Wheel */ +#else /* UX_DEMO_MOUSE_ABSOLUTE */ + device_hid_event.ux_device_class_hid_event_length = 6; + device_hid_event.ux_device_class_hid_event_buffer[0] = 0; /* ...M|R|L */ + device_hid_event.ux_device_class_hid_event_buffer[1] = 0; /* X */ + device_hid_event.ux_device_class_hid_event_buffer[2] = 0; /* X */ + device_hid_event.ux_device_class_hid_event_buffer[3] = 0; /* Y */ + device_hid_event.ux_device_class_hid_event_buffer[4] = 0; /* Y */ + device_hid_event.ux_device_class_hid_event_buffer[5] = mouse_wheel; /* Wheel */ +#endif /* UX_DEMO_MOUSE_ABSOLUTE */ + + /* Move wheel. */ + switch(wheel_move_dir) + { + case UX_MOUSE_WHEEL_MOVE_DOWN: + + mouse_wheel = (UCHAR)(-UX_DEMO_HID_MOUSE_WHEEL_MOVE); + + wheel_move_count ++; + + if (wheel_move_count >= UX_DEMO_HID_MOUSE_WHEEL_MOVE_N) + { + wheel_move_count = 0; + wheel_move_dir = UX_MOUSE_WHEEL_MOVE_UP; + } + + break; + + case UX_MOUSE_WHEEL_MOVE_UP: + + mouse_wheel = UX_DEMO_HID_MOUSE_WHEEL_MOVE; + + wheel_move_count ++; + + if (wheel_move_count >= UX_DEMO_HID_MOUSE_WHEEL_MOVE_N) + { + wheel_move_count = 0; + wheel_move_dir = UX_MOUSE_WHEEL_MOVE_DONE; + } + + break; + + default: + + mouse_wheel = 0; + + ux_utility_memory_set(&device_hid_event, 0, sizeof(UX_SLAVE_CLASS_HID_EVENT)); + + break; + } + + /* Set the mouse event. */ + status = ux_device_class_hid_event_set(device_hid, &device_hid_event); + + if(status != UX_SUCCESS) + return UX_ERROR; + + return wheel_move_dir; +} + +static VOID ux_demo_error_callback(UINT system_level, UINT system_context, UINT error_code) +{ + /* + * Refer to ux_api.h. For example, + * UX_SYSTEM_LEVEL_INTERRUPT, UX_SYSTEM_CONTEXT_DCD, UX_DEVICE_HANDLE_UNKNOWN + */ + printf("USBX error: system level(%d), context(%d), error code(0x%x)\r\n", system_level, system_context, error_code); +} + +#if defined(UX_STANDALONE) + +#include + +ALIGN_TYPE _ux_utility_interrupt_disable(VOID) +{ + __istate_t interrupt_save; + interrupt_save = __get_interrupt_state(); + __disable_interrupt(); + return interrupt_save; +} + +VOID _ux_utility_interrupt_restore(ALIGN_TYPE flags) +{ + __set_interrupt_state(flags); +} + +/* Time Tick Get for host timing */ +ULONG _ux_utility_time_get(VOID) +{ +// return(HAL_GetTick()); +} + +#endif diff --git a/samples/device_hid_mouse_standalone/demo_device_hid_mouse.h b/samples/device_hid_mouse_standalone/demo_device_hid_mouse.h new file mode 100644 index 00000000..362b67be --- /dev/null +++ b/samples/device_hid_mouse_standalone/demo_device_hid_mouse.h @@ -0,0 +1,92 @@ +/*************************************************************************** + * Copyright (c) 2025-present Eclipse ThreadX Contributors + * + * This program and the accompanying materials are made available under the + * terms of the MIT License which is available at + * https://opensource.org/licenses/MIT. + * + * + * SPDX-License-Identifier: MIT + **************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** AUTHOR */ +/** */ +/** Mohamed AYED */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +#ifndef UX_DEMO_DEVICE_HID_MOUSE_H +#define UX_DEMO_DEVICE_HID_MOUSE_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "ux_api.h" +#include "ux_device_class_hid.h" + + +#include "demo_device_hid_descriptors.h" + +#include "usb_otg.h" + + +#define UX_DEVICE_MEMORY_STACK_SIZE 2*1024 + + +#ifdef UX_DEMO_MOUSE_ABSOLUTE +#define UX_DEMO_HID_MOUSE_CURSOR_MOVE 500 +#else /* UX_DEMO_MOUSE_ABSOLUTE */ +#define UX_DEMO_HID_MOUSE_CURSOR_MOVE 3 +#define UX_DEMO_HID_MOUSE_CURSOR_MOVE_N 100 +#endif /* UX_DEMO_MOUSE_ABSOLUTE */ + +#define UX_DEMO_HID_MOUSE_WHEEL_MOVE 15 +#define UX_DEMO_HID_MOUSE_WHEEL_MOVE_N 100 + + +/******************************/ +/** Mouse cursor direction */ +/******************************/ +#define UX_MOUSE_CURSOR_MOVE_RIGHT 0x00 +#define UX_MOUSE_CURSOR_MOVE_DOWN 0x01 +#define UX_MOUSE_CURSOR_MOVE_LEFT 0x02 +#define UX_MOUSE_CURSOR_MOVE_UP 0x03 +#define UX_MOUSE_CURSOR_MOVE_DONE 0x10 + +/*****************************/ +/** Mouse Buttons */ +/*****************************/ +#define UX_MOUSE_BUTTON_PRESS_LEFT 0x00 +#define UX_MOUSE_BUTTON_PRESS_RIGHT 0x01 +#define UX_MOUSE_BUTTON_PRESS_MIDDLE 0x02 +#define UX_MOUSE_BUTTON_PRESS_DONE 0x10 + +/*****************************/ +/** Mouse wheel direction */ +/*****************************/ +#define UX_MOUSE_WHEEL_MOVE_DOWN 0x00 +#define UX_MOUSE_WHEEL_MOVE_UP 0x01 +#define UX_MOUSE_WHEEL_MOVE_DONE 0x10 + +/*******************************/ +/** Mouse demo state machine */ +/*******************************/ +#define UX_DEMO_MOUSE_CURSOR 0x00 +#define UX_DEMO_MOUSE_WHEEL 0x01 +#define UX_DEMO_MOUSE_BUTTON 0x02 +#define UX_DEMO_MOUSE_DONE 0x10 + + +VOID ux_application_define(VOID); +VOID ux_demo_device_hid_task(VOID); + +#ifdef __cplusplus +} +#endif +#endif /* UX_DEMO_DEVICE_HID_MOUSE_H */ diff --git a/samples/device_hid_mouse_standalone/readme.md b/samples/device_hid_mouse_standalone/readme.md new file mode 100644 index 00000000..1059f7a7 --- /dev/null +++ b/samples/device_hid_mouse_standalone/readme.md @@ -0,0 +1,54 @@ + +## Overview + +This example works as a USB HID device. It will appear as a USB mouse device on PC. + + - Move mouse arrow on the PC screen according in a rectangular fashion. + - Scroll mouse wheel. + - Click left middle right mouse buttons. + +This application demo is running in **standalone** mode (without RTOS). + +To test absolute mouse you need to define **UX_DEMO_MOUSE_ABSOLUTE** in **ux_demo_device_descriptors.h** + +**Note:** +- This demonstration is optimized. +- **DEMO_STACK_SIZE** and **UX_DEVICE_MEMORY_STACK_SIZE** memory size should be adjusted. + +## USB Specification + +- USB 2.0 Universal Serial BUS : https://www.usb.org/document-library/usb-20-specification +- USB HID Class : https://www.usb.org/document-library/device-class-definition-hid-111 +- USB HID Usage Tables : https://usb.org/document-library/hid-usage-tables-16 + +## Report Descriptor + +A HID (Human Interface Device) mouse report descriptor defines how data is sent from the device (mouse) to the host (computer). +Below is a standard USB HID mouse report descriptor for a 3-button mouse with X and Y movement and wheel. + +### Report Format Relative + +This descriptor defines a 4-byte report format: + +|Byte | Bits | Usage | +| --- | --- | ----- | +| 0 | 0-2 | Buttons (Bit 0 = Left, Bit 1 = Right, Bit 2 = Middle) | +| 0 | 3-7 | Padding (unused) | +| 1 | 0-7 | X-axis movement (-127 to +127, relative) | +| 2 | 0-7 | Y-axis movement (-127 to +127, relative) | + +### Report Format Absolute +This descriptor defines a 6-byte report format: + +|Byte | Bits | Usage | +| --- | --- | ----- | +| 0 | 0-2 | Buttons (Bit 0 = Left, Bit 1 = Right, Bit 2 = Middle) | +| 0 | 3-7 | Padding (unused) | +| 1-2 | 0-15 | X-axis Position (0 - 32767, absolute) | +| 3-4 | 0-15 | Y-axis Position (0 - 32767, absolute) | + +## Run the example +- Create a project and include **USBX** and **THREADX** files. +- Customize **board_setup** with hardware init and **usb_device_interrupt_setup** with usb hardware init. +- Run Project. +- Plug-in the device, which is running HID mouse example, into the PC. A HID-compliant mouse is enumerated in the Device Manager. diff --git a/samples/device_hid_mouse_standalone/ux_user.h b/samples/device_hid_mouse_standalone/ux_user.h new file mode 100644 index 00000000..746c391c --- /dev/null +++ b/samples/device_hid_mouse_standalone/ux_user.h @@ -0,0 +1,84 @@ +/*************************************************************************** + * Copyright (c) 2024 Microsoft Corporation + * + * This program and the accompanying materials are made available under the + * terms of the MIT License which is available at + * https://opensource.org/licenses/MIT. + * + * + * SPDX-License-Identifier: MIT + **************************************************************************/ + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** USBX Component */ +/** */ +/** User Specific */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/**************************************************************************/ +/* */ +/* PORT SPECIFIC C INFORMATION RELEASE */ +/* */ +/* ux_user.h PORTABLE C */ +/* 6.3.0 */ +/* */ +/* AUTHOR */ +/* */ +/* Chaoqiong Xiao, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains user defines for configuring USBX in specific */ +/* ways. This file will have an effect only if the application and */ +/* USBX library are built with UX_INCLUDE_USER_DEFINE_FILE defined. */ +/* Note that all the defines in this file may also be made on the */ +/* command line when building USBX library and application objects. */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 05-19-2020 Chaoqiong Xiao Version 6.4.1 */ +/* */ +/**************************************************************************/ + +#ifndef UX_USER_H +#define UX_USER_H + + + +#define UX_MAX_SLAVE_CLASS_DRIVER 1 +#define UX_MAX_SLAVE_INTERFACES 1 + + +#define UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH 64 +#define UX_SLAVE_REQUEST_DATA_MAX_LENGTH 8 + +#define UX_DEVICE_ENDPOINT_BUFFER_OWNER 1 +#define UX_DEVICE_CLASS_HID_ZERO_COPY + + +#define UX_DEVICE_CLASS_HID_EVENT_BUFFER_LENGTH 8 +#define UX_DEVICE_CLASS_HID_MAX_EVENTS_QUEUE 8 + + +#define UX_DEVICE_ALTERNATE_SETTING_SUPPORT_DISABLE +#define UX_DEVICE_INITIALIZE_FRAMEWORK_SCAN_DISABLE + +#define UX_NAME_REFERENCED_BY_POINTER + +#define UX_ENABLE_ERROR_CHECKING + +#define UX_DEVICE_SIDE_ONLY + +#define UX_STANDALONE +#define UX_PERIODIC_RATE 1000 + +#define UX_MAX_DEVICE_ENDPOINTS 1 +#define UX_MAX_DEVICE_INTERFACES 1 + +#endif /* UX_USER_H */