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 /** USBX Component                                                        */
16 /**                                                                       */
17 /**   Device HID Class                                                    */
18 /**                                                                       */
19 /**************************************************************************/
20 /**************************************************************************/
21 
22 #define UX_SOURCE_CODE
23 
24 
25 /* Include necessary system files.  */
26 
27 #include "ux_api.h"
28 #include "ux_device_class_hid.h"
29 #include "ux_device_stack.h"
30 
31 
32 /**************************************************************************/
33 /*                                                                        */
34 /*  FUNCTION                                               RELEASE        */
35 /*                                                                        */
36 /*    _ux_device_class_hid_event_set                      PORTABLE C      */
37 /*                                                           6.1.11       */
38 /*  AUTHOR                                                                */
39 /*                                                                        */
40 /*    Chaoqiong Xiao, Microsoft Corporation                               */
41 /*                                                                        */
42 /*  DESCRIPTION                                                           */
43 /*                                                                        */
44 /*    This function sends an event to the hid class. It is processed      */
45 /*    asynchronously by the interrupt thread.                             */
46 /*                                                                        */
47 /*  INPUT                                                                 */
48 /*                                                                        */
49 /*    hid                                      Address of hid class       */
50 /*    event                                    Pointer of the event       */
51 /*                                                                        */
52 /*  OUTPUT                                                                */
53 /*                                                                        */
54 /*    status                                   UX_SUCCESS if there is an  */
55 /*                                             event                      */
56 /*  CALLS                                                                 */
57 /*                                                                        */
58 /*    _ux_utility_memory_copy                  Copy memory                */
59 /*    _ux_device_event_flags_set               Set event flags            */
60 /*                                                                        */
61 /*  CALLED BY                                                             */
62 /*                                                                        */
63 /*    ThreadX                                                             */
64 /*                                                                        */
65 /*  RELEASE HISTORY                                                       */
66 /*                                                                        */
67 /*    DATE              NAME                      DESCRIPTION             */
68 /*                                                                        */
69 /*  05-19-2020     Chaoqiong Xiao           Initial Version 6.0           */
70 /*  09-30-2020     Chaoqiong Xiao           Modified comment(s),          */
71 /*                                            added standalone support,   */
72 /*                                            verified memset and memcpy  */
73 /*                                            cases, used UX prefix to    */
74 /*                                            refer to TX symbols instead */
75 /*                                            of using them directly,     */
76 /*                                            resulting in version 6.1    */
77 /*  01-31-2022     Chaoqiong Xiao           Modified comment(s),          */
78 /*                                            added standalone support,   */
79 /*                                            resulting in version 6.1.10 */
80 /*  04-25-2022     Chaoqiong Xiao           Modified comment(s),          */
81 /*                                            resulting in version 6.1.11 */
82 /*                                                                        */
83 /**************************************************************************/
_ux_device_class_hid_event_set(UX_SLAVE_CLASS_HID * hid,UX_SLAVE_CLASS_HID_EVENT * hid_event)84 UINT  _ux_device_class_hid_event_set(UX_SLAVE_CLASS_HID *hid,
85                                       UX_SLAVE_CLASS_HID_EVENT *hid_event)
86 {
87 
88 UX_SLAVE_CLASS_HID_EVENT   *current_hid_event;
89 UX_SLAVE_CLASS_HID_EVENT   *next_hid_event;
90 
91     /* If trace is enabled, insert this event into the trace buffer.  */
92     UX_TRACE_IN_LINE_INSERT(UX_TRACE_DEVICE_CLASS_HID_EVENT_SET, hid, hid_event, 0, 0, UX_TRACE_DEVICE_CLASS_EVENTS, 0, 0)
93 
94     /* Current position of the head.  */
95     current_hid_event =  hid -> ux_device_class_hid_event_array_head;
96 
97     /* If the pointer is NULL, the round robin buffer has not been activated.  */
98     if (current_hid_event == UX_NULL)
99         return (UX_ERROR);
100 
101     /* Calculate the next position.  */
102     if ((current_hid_event + 1) == hid -> ux_device_class_hid_event_array_end)
103 
104         /* We are at the end, go back to the beginning.  */
105         next_hid_event =  hid -> ux_device_class_hid_event_array;
106 
107     else
108 
109         /* We are not at the end, increment the head position.  */
110         next_hid_event = current_hid_event + 1;
111 
112 
113     /* Any place left for this event ? */
114     if (next_hid_event == hid -> ux_device_class_hid_event_array_tail)
115         return (UX_ERROR);
116 
117     /* There is an event to report, get the current pointer to the event.  */
118     current_hid_event =  hid -> ux_device_class_hid_event_array_head;
119 
120     /* Update the head.  */
121     hid -> ux_device_class_hid_event_array_head = next_hid_event;
122 
123     /* Check if this event has a report ID.  */
124     if (hid -> ux_device_class_hid_report_id == UX_TRUE)
125     {
126 
127         /* Yes, there's a report ID. Check to see if our event buffer can also
128            fit the extra byte.  */
129         if (hid_event -> ux_device_class_hid_event_length + 1 > UX_DEVICE_CLASS_HID_EVENT_BUFFER_LENGTH)
130         {
131 
132             /* Error trap. */
133             _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_MEMORY_INSUFFICIENT);
134 
135             /* If trace is enabled, insert this event into the trace buffer.  */
136             UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_MEMORY_INSUFFICIENT, 0, 0, 0, UX_TRACE_ERRORS, 0, 0)
137 
138             /* Return overflow error.  */
139             return(UX_MEMORY_INSUFFICIENT);
140         }
141 
142         /* Store the report ID.  */
143         *current_hid_event -> ux_device_class_hid_event_buffer =  (UCHAR)(hid_event -> ux_device_class_hid_event_report_id);
144 
145         /* Store the data itself.  */
146         _ux_utility_memory_copy(current_hid_event -> ux_device_class_hid_event_buffer + 1, hid_event -> ux_device_class_hid_event_buffer,
147                                 hid_event -> ux_device_class_hid_event_length); /* Use case of memcpy is verified. */
148 
149         /* fill in the event structure from the user.  */
150         current_hid_event -> ux_device_class_hid_event_length =  hid_event -> ux_device_class_hid_event_length + 1;
151     }
152     else
153     {
154 
155         /* No report ID to consider.  */
156         _ux_utility_memory_copy(current_hid_event -> ux_device_class_hid_event_buffer, hid_event -> ux_device_class_hid_event_buffer,
157                                 hid_event -> ux_device_class_hid_event_length); /* Use case of memcpy is verified. */
158 
159         /* fill in the event structure from the user.  */
160         current_hid_event -> ux_device_class_hid_event_length = hid_event -> ux_device_class_hid_event_length;
161     }
162 
163 #if defined(UX_DEVICE_STANDALONE)
164 
165     /* Set state machine to start sending if no transfer on going.  */
166     if (hid -> ux_device_class_hid_event_state != UX_STATE_WAIT &&
167         hid -> ux_device_class_hid_event_state != UX_STATE_EXIT)
168         hid -> ux_device_class_hid_event_state = UX_STATE_RESET;
169 #else
170 
171     /* Set an event to wake up the interrupt thread.  */
172     _ux_device_event_flags_set(&hid -> ux_device_class_hid_event_flags_group, UX_DEVICE_CLASS_HID_NEW_EVENT, UX_OR);
173 #endif
174 
175     /* Return event status to the user.  */
176     return(UX_SUCCESS);
177 }
178 
179