1 /***************************************************************************
2 * Copyright (c) 2024 Microsoft Corporation
3 *
4 * This program and the accompanying materials are made available under the
5 * terms of the MIT License which is available at
6 * https://opensource.org/licenses/MIT.
7 *
8 * SPDX-License-Identifier: MIT
9 **************************************************************************/
10
11
12 /**************************************************************************/
13 /**************************************************************************/
14 /** */
15 /** USBX Component */
16 /** */
17 /** HID Keyboard Client */
18 /** */
19 /**************************************************************************/
20 /**************************************************************************/
21
22
23 /* Include necessary system files. */
24
25 #define UX_SOURCE_CODE
26
27 #include "ux_api.h"
28 #include "ux_host_class_hid.h"
29 #include "ux_host_class_hid_keyboard.h"
30 #include "ux_host_stack.h"
31
32
33 /**************************************************************************/
34 /* */
35 /* FUNCTION RELEASE */
36 /* */
37 /* _ux_host_class_hid_keyboard_thread PORTABLE C */
38 /* 6.1.10 */
39 /* AUTHOR */
40 /* */
41 /* Chaoqiong Xiao, Microsoft Corporation */
42 /* */
43 /* DESCRIPTION */
44 /* */
45 /* This file contains the keyboard thread used to process the changes */
46 /* in the keyboard LEDs. */
47 /* */
48 /* It's for RTOS mode. */
49 /* */
50 /* INPUT */
51 /* */
52 /* keyboard_instance The keyboard instance for */
53 /* there was a change in LEDs */
54 /* */
55 /* OUTPUT */
56 /* */
57 /* None */
58 /* */
59 /* CALLS */
60 /* */
61 /* _ux_host_semaphore_get Get signal semaphore */
62 /* _ux_host_class_hid_report_id_get Get report ID */
63 /* _ux_host_class_hid_report_set Do SET_REPORT */
64 /* */
65 /* CALLED BY */
66 /* */
67 /* ThreadX */
68 /* */
69 /* RELEASE HISTORY */
70 /* */
71 /* DATE NAME DESCRIPTION */
72 /* */
73 /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
74 /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */
75 /* resulting in version 6.1 */
76 /* 01-31-2022 Chaoqiong Xiao Modified comment(s), */
77 /* refined macros names, */
78 /* resulting in version 6.1.10 */
79 /* */
80 /**************************************************************************/
_ux_host_class_hid_keyboard_thread(ULONG thread_input)81 VOID _ux_host_class_hid_keyboard_thread(ULONG thread_input)
82 {
83 UX_HOST_CLASS_HID *hid;
84 UX_HOST_CLASS_HID_CLIENT_REPORT client_report;
85 UX_HOST_CLASS_HID_REPORT_GET_ID report_id;
86 UINT status;
87 UX_HOST_CLASS_HID_KEYBOARD *keyboard_instance;
88
89 /* Cast the thread_input variable into the proper format. */
90 UX_THREAD_EXTENSION_PTR_GET(keyboard_instance, UX_HOST_CLASS_HID_KEYBOARD, thread_input)
91
92 /* Loop forever waiting for changes signaled through the semaphore. */
93 while (1)
94 {
95
96 /* Wait for the semaphore to be put by the root hub or a regular hub. */
97 status = _ux_host_semaphore_get(&keyboard_instance -> ux_host_class_hid_keyboard_semaphore, UX_WAIT_FOREVER);
98
99 /* The semaphore could be awaken because the semaphore was destroyed by the HID client
100 when the keyboard is removed. */
101 if (status == UX_SUCCESS)
102 {
103
104 /* We got awaken by the keyboard callback which indicates a change on the LEDs has to happen.
105 We need to build the field for the leds. */
106 keyboard_instance -> ux_host_class_hid_keyboard_led_mask = keyboard_instance -> ux_host_class_hid_keyboard_alternate_key_state &
107 UX_HID_KEYBOARD_STATE_MASK_LOCK;
108
109 /* Recall the HID instance for this client. */
110 hid = keyboard_instance -> ux_host_class_hid_keyboard_hid;
111
112 /* We need to find the OUTPUT report for the keyboard LEDs. */
113 report_id.ux_host_class_hid_report_get_report = UX_NULL;
114 report_id.ux_host_class_hid_report_get_type = UX_HOST_CLASS_HID_REPORT_TYPE_OUTPUT;
115 status = _ux_host_class_hid_report_id_get(hid, &report_id);
116
117 /* The report ID should exist. If there is an error, we do not proceed. */
118 if (status == UX_SUCCESS)
119 {
120
121 /* Memorize the report pointer. */
122 client_report.ux_host_class_hid_client_report = report_id.ux_host_class_hid_report_get_report;
123
124 /* The report set is raw since the LEDs mask is already in the right format. */
125 client_report.ux_host_class_hid_client_report_flags = UX_HOST_CLASS_HID_REPORT_RAW;
126
127 /* The length of this report is 1 byte. */
128 client_report.ux_host_class_hid_client_report_length = 1;
129
130 /* The output report buffer is the LED mask field. */
131 client_report.ux_host_class_hid_client_report_buffer = &keyboard_instance -> ux_host_class_hid_keyboard_led_mask;
132
133 /* The HID class will perform the SET_REPORT command. */
134 _ux_host_class_hid_report_set(hid, &client_report);
135 }
136 }
137 else
138
139 /* The thread should terminate upon a semaphore error. */
140 return;
141 }
142 }
143
144