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