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 /** USBX Component */
15 /** */
16 /** Device Audio Class */
17 /** */
18 /**************************************************************************/
19 /**************************************************************************/
20
21 #define UX_SOURCE_CODE
22
23
24 /* Include necessary system files. */
25
26 #include "ux_api.h"
27 #include "ux_device_class_audio.h"
28 #include "ux_device_stack.h"
29
30
31 #if defined(UX_DEVICE_CLASS_AUDIO_FEEDBACK_SUPPORT) && defined(UX_DEVICE_STANDALONE)
32 /**************************************************************************/
33 /* */
34 /* FUNCTION RELEASE */
35 /* */
36 /* _ux_device_class_audio_feedback_task_function PORTABLE C */
37 /* 6.2.0 */
38 /* AUTHOR */
39 /* */
40 /* Yajun Xia, Microsoft Corporation */
41 /* */
42 /* DESCRIPTION */
43 /* */
44 /* This function is background task of ISO OUT/IN (feedback of IN/OUT) */
45 /* for the Audio class. */
46 /* */
47 /* It's for standalone mode. */
48 /* */
49 /* INPUT */
50 /* */
51 /* stream Pointer to audio stream */
52 /* */
53 /* OUTPUT */
54 /* */
55 /* State machine status */
56 /* UX_STATE_EXIT Device not configured */
57 /* UX_STATE_IDLE No feedback transfer running */
58 /* UX_STATE_WAIT Feedback transfer running */
59 /* */
60 /* CALLS */
61 /* */
62 /* _ux_system_error_handler System error trap */
63 /* _ux_device_stack_transfer_run Run transfer state machine */
64 /* */
65 /* CALLED BY */
66 /* */
67 /* Audio Class (task) */
68 /* */
69 /* RELEASE HISTORY */
70 /* */
71 /* DATE NAME DESCRIPTION */
72 /* */
73 /* 10-31-2022 Yajun Xia Initial Version 6.2.0 */
74 /* */
75 /**************************************************************************/
_ux_device_class_audio_feedback_task_function(UX_DEVICE_CLASS_AUDIO_STREAM * stream)76 UINT _ux_device_class_audio_feedback_task_function(UX_DEVICE_CLASS_AUDIO_STREAM *stream)
77 {
78
79 UINT status;
80 UX_SLAVE_DEVICE *device;
81 UX_SLAVE_ENDPOINT *endpoint;
82 UX_SLAVE_TRANSFER *transfer;
83 ULONG transfer_length;
84
85
86 /* Get stack device instance. */
87 device = stream -> ux_device_class_audio_stream_audio -> ux_device_class_audio_device;
88
89 /* Check if the device is configured. */
90 if (device -> ux_slave_device_state != UX_DEVICE_CONFIGURED)
91 {
92
93 /* Error trap. */
94 _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_CONFIGURATION_HANDLE_UNKNOWN);
95
96 stream -> ux_device_class_audio_stream_feedback_task_state = UX_STATE_EXIT;
97 return(UX_STATE_EXIT);
98 }
99
100 /* Get endpoint instance. */
101 endpoint = stream -> ux_device_class_audio_stream_feedback;
102
103 /* Endpoint not available, maybe it's alternate setting 0. */
104 if (endpoint == UX_NULL)
105 {
106
107 /* Error trap. */
108 _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_ENDPOINT_HANDLE_UNKNOWN);
109
110 stream -> ux_device_class_audio_stream_feedback_task_state = UX_STATE_RESET;
111 return(UX_STATE_IDLE);
112 }
113
114 /* Get transfer instance. */
115 transfer = &endpoint -> ux_slave_endpoint_transfer_request;
116
117 /* Length is pre-set on interface alternate setting activate. */
118 transfer_length = transfer -> ux_slave_transfer_request_requested_length;
119
120 switch (stream -> ux_device_class_audio_stream_feedback_task_state)
121 {
122 case UX_STATE_RESET:
123 stream -> ux_device_class_audio_stream_feedback_task_state = UX_DEVICE_CLASS_AUDIO_STREAM_FEEDBACK_RW_WAIT;
124 stream -> ux_device_class_audio_stream_feedback_task_status = UX_TRANSFER_NO_ANSWER;
125
126 /* Fall through. */
127 case UX_DEVICE_CLASS_AUDIO_STREAM_FEEDBACK_RW_WAIT:
128
129 /* Issue transfer request. */
130 status = _ux_device_stack_transfer_run(transfer, transfer_length, transfer_length);
131
132 /* Any error or success case. */
133 if (status < UX_STATE_NEXT)
134 {
135
136 /* Error notification! */
137 _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_TRANSFER_ERROR);
138
139 stream -> ux_device_class_audio_stream_feedback_task_state = UX_STATE_RESET;
140 stream -> ux_device_class_audio_stream_feedback_task_status = transfer -> ux_slave_transfer_request_completion_code;
141 return(UX_STATE_EXIT);
142 }
143
144 /* Success case. */
145 if (status == UX_STATE_NEXT)
146 {
147 stream -> ux_device_class_audio_stream_feedback_task_state = UX_DEVICE_CLASS_AUDIO_STREAM_FEEDBACK_RW_WAIT;
148 stream -> ux_device_class_audio_stream_feedback_task_status = transfer -> ux_slave_transfer_request_completion_code;
149 }
150
151 /* Keep waiting. */
152 return(UX_STATE_WAIT);
153
154 default:
155 stream -> ux_device_class_audio_stream_feedback_task_state = UX_STATE_RESET;
156 stream -> ux_device_class_audio_stream_feedback_task_status = UX_INVALID_STATE;
157 break;
158 }
159
160 /* Error case. */
161 return(UX_STATE_EXIT);
162 }
163 #endif
164