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 Audio 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_audio.h"
29 #include "ux_device_stack.h"
30
31
32 /**************************************************************************/
33 /* */
34 /* FUNCTION RELEASE */
35 /* */
36 /* _ux_device_class_audio_interrupt_send PORTABLE C */
37 /* 6.2.0 */
38 /* AUTHOR */
39 /* */
40 /* Chaoqiong Xiao, Microsoft Corporation */
41 /* */
42 /* DESCRIPTION */
43 /* */
44 /* This function queues audio interrupt data. */
45 /* */
46 /* Note the interrupt data size is predefined on initialization: */
47 /* - for Audio 1.0 interrupt status word is 2 bytes */
48 /* - for Audio 2.0 interrupt data message is 6 bytes */
49 /* */
50 /* INPUT */
51 /* */
52 /* audio Address of audio instance */
53 /* int_data Interrupt data (2 or 6 bytes) */
54 /* */
55 /* OUTPUT */
56 /* */
57 /* None */
58 /* */
59 /* CALLS */
60 /* */
61 /* */
62 /* CALLED BY */
63 /* */
64 /* Application */
65 /* */
66 /* RELEASE HISTORY */
67 /* */
68 /* DATE NAME DESCRIPTION */
69 /* */
70 /* 07-29-2022 Chaoqiong Xiao Initial Version 6.1.12 */
71 /* 10-31-2022 Yajun Xia Modified comment(s), */
72 /* added standalone support, */
73 /* resulting in version 6.2.0 */
74 /* */
75 /**************************************************************************/
_ux_device_class_audio_interrupt_send(UX_DEVICE_CLASS_AUDIO * audio,UCHAR * int_data)76 UINT _ux_device_class_audio_interrupt_send(UX_DEVICE_CLASS_AUDIO *audio, UCHAR *int_data)
77 {
78 #if !defined(UX_DEVICE_CLASS_AUDIO_INTERRUPT_SUPPORT)
79 UX_PARAMETER_NOT_USED(audio);
80 UX_PARAMETER_NOT_USED(int_data);
81 return(UX_FUNCTION_NOT_SUPPORTED);
82 #else
83
84 UX_SLAVE_DEVICE *device;
85 UX_SLAVE_ENDPOINT *endpoint;
86 UCHAR *buff, *end;
87 ULONG size;
88 ULONG i;
89
90 /* Get the pointer to the device. */
91 device = &_ux_system_slave -> ux_system_slave_device;
92
93 /* As long as the device is in the CONFIGURED state. */
94 if (device -> ux_slave_device_state != UX_DEVICE_CONFIGURED)
95 {
96
97 /* Cannot proceed with command, the interface is down. */
98 return(UX_CONFIGURATION_HANDLE_UNKNOWN);
99 }
100
101 /* Check if endpoint is available. */
102 endpoint = audio -> ux_device_class_audio_interrupt;
103 if (endpoint == UX_NULL)
104 return(UX_FUNCTION_NOT_SUPPORTED);
105
106 /* Get interrupt data size. */
107 size = audio -> ux_device_class_audio_status_size;
108
109 /* Protect queue status. */
110 _ux_device_mutex_on(&audio -> ux_device_class_audio_status_mutex);
111
112 /* Check if data exist. */
113 buff = audio -> ux_device_class_audio_status_tail;
114 end = audio -> ux_device_class_audio_status_queue + audio -> ux_device_class_audio_status_queue_bytes;
115 for (i = 0; i < audio -> ux_device_class_audio_status_queued; i += size)
116 {
117
118 /* Check if data match. */
119 if (_ux_utility_memory_compare(buff, int_data, size) == UX_SUCCESS)
120 {
121
122 /* Already queued. */
123 _ux_device_mutex_off(&audio -> ux_device_class_audio_status_mutex);
124 return(UX_SUCCESS);
125 }
126
127 /* Next saved data. */
128 buff += size;
129 if (buff >= end)
130 buff = audio -> ux_device_class_audio_status_queue;
131 }
132
133 /* No data match before buff achieve head. */
134 UX_ASSERT(buff == audio -> ux_device_class_audio_status_head);
135
136 /* If no free space, return busy (pending). */
137 if (audio -> ux_device_class_audio_status_queued >=
138 audio -> ux_device_class_audio_status_queue_bytes)
139 {
140
141 /* No queue space, pending. */
142 _ux_device_mutex_off(&audio -> ux_device_class_audio_status_mutex);
143 return(UX_BUSY);
144 }
145
146 /* Copy data to head. */
147 _ux_utility_memory_copy(buff, int_data, size); /* Use case of memcpy is verified. */
148
149 /* Move head. */
150 buff += size;
151 if (buff >= end)
152 buff = audio -> ux_device_class_audio_status_queue;
153 audio -> ux_device_class_audio_status_head = buff;
154
155 /* Add to queued bytes. */
156 audio -> ux_device_class_audio_status_queued += size;
157
158 /* Unprotect queue status. */
159 _ux_device_mutex_off(&audio -> ux_device_class_audio_status_mutex);
160
161 /* Notify status thread to issue interrupt request. */
162 _ux_device_semaphore_put(&audio -> ux_device_class_audio_status_semaphore);
163
164 /* Resume interrupt thread. */
165 _ux_device_thread_resume(&audio -> ux_device_class_audio_class -> ux_slave_class_thread);
166
167 /* Return success. */
168 return(UX_SUCCESS);
169 #endif
170 }
171
172
173 /**************************************************************************/
174 /* */
175 /* FUNCTION RELEASE */
176 /* */
177 /* _uxe_device_class_audio_interrupt_send PORTABLE C */
178 /* 6.2.1 */
179 /* AUTHOR */
180 /* */
181 /* Chaoqiong Xiao, Microsoft Corporation */
182 /* */
183 /* DESCRIPTION */
184 /* */
185 /* This function checks errors in queuing audio interrupt data */
186 /* function call. */
187 /* */
188 /* Note the interrupt data size is predefined and not checked: */
189 /* - for Audio 1.0 interrupt status word is 2 bytes */
190 /* - for Audio 2.0 interrupt data message is 6 bytes */
191 /* */
192 /* INPUT */
193 /* */
194 /* audio Address of audio instance */
195 /* int_data Interrupt data (2 or 6 bytes) */
196 /* */
197 /* OUTPUT */
198 /* */
199 /* None */
200 /* */
201 /* CALLS */
202 /* */
203 /* _ux_device_class_audio_interrupt_send Queue interrupt data to send */
204 /* */
205 /* CALLED BY */
206 /* */
207 /* Application */
208 /* */
209 /* RELEASE HISTORY */
210 /* */
211 /* DATE NAME DESCRIPTION */
212 /* */
213 /* 03-08-2023 Chaoqiong Xiao Initial Version 6.2.1 */
214 /* */
215 /**************************************************************************/
_uxe_device_class_audio_interrupt_send(UX_DEVICE_CLASS_AUDIO * audio,UCHAR * int_data)216 UINT _uxe_device_class_audio_interrupt_send(UX_DEVICE_CLASS_AUDIO *audio, UCHAR *int_data)
217 {
218
219 /* Sanity check. */
220 if (audio == UX_NULL || int_data == UX_NULL)
221 return(UX_INVALID_PARAMETER);
222
223 /* Send interrupt data. */
224 return(_ux_device_class_audio_interrupt_send(audio, int_data));
225 }