| LPCOpen Platform v1.03 LPCOpen Platform for NXP LPC Microcontrollers

- Main Page
- Modules
- Data Structures
- Files
- Related Pages

- File List
- Globals

All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
AudioClassHost.c
Go to the documentation of this file.
1 /*
2 * @brief Host mode driver for the library USB Audio 1.0 Class driver
3 *
4 * @note
5 * Copyright(C) NXP Semiconductors, 2012
6 * Copyright(C) Dean Camera, 2011, 2012
7 * All rights reserved.
8 *
9 * @par
10 * Software that is described herein is for illustrative purposes only
11 * which provides customers with programming information regarding the
12 * LPC products. This software is supplied "AS IS" without any warranties of
13 * any kind, and NXP Semiconductors and its licensor disclaim any and
14 * all warranties, express or implied, including all implied warranties of
15 * merchantability, fitness for a particular purpose and non-infringement of
16 * intellectual property rights. NXP Semiconductors assumes no responsibility
17 * or liability for the use of the software, conveys no license or rights under any
18 * patent, copyright, mask work right, or any other intellectual property rights in
19 * or to any products. NXP Semiconductors reserves the right to make changes
20 * in the software without notification. NXP Semiconductors also makes no
21 * representation or warranty that such application will be suitable for the
22 * specified use without further testing or modification.
23 *
24 * @par
25 * Permission to use, copy, modify, and distribute this software and its
26 * documentation is hereby granted, under NXP Semiconductors' and its
27 * licensor's relevant copyrights in the software, without fee, provided that it
28 * is used in conjunction with NXP Semiconductors microcontrollers. This
29 * copyright, permission, and disclaimer notice must appear in all copies of
30 * this code.
31 */
32
33
34 #define __INCLUDE_FROM_USB_DRIVER
35 #include "../../Core/USBMode.h"
36
37 #if defined(USB_CAN_BE_HOST)
38
39 #define __INCLUDE_FROM_AUDIO_DRIVER
40 #define __INCLUDE_FROM_AUDIO_HOST_C
41 #include "AudioClassHost.h"
42
43 uint8_t Audio_Host_ConfigurePipes(USB_ClassInfo_Audio_Host_t* const AudioInterfaceInfo,
44 uint16_t ConfigDescriptorSize,
45 void* ConfigDescriptorData)
46 {
47 USB_Descriptor_Endpoint_t* DataINEndpoint = NULL;
48 USB_Descriptor_Endpoint_t* DataOUTEndpoint = NULL;
49 USB_Descriptor_Interface_t* AudioControlInterface = NULL;
50 USB_Descriptor_Interface_t* AudioStreamingInterface = NULL;
51 uint8_t portnum = AudioInterfaceInfo->Config.PortNumber;
52
53 memset(&AudioInterfaceInfo->State, 0x00, sizeof(AudioInterfaceInfo->State));
54
55 if (DESCRIPTOR_TYPE(ConfigDescriptorData) != DTYPE_Configuration)
56 return AUDIO_ENUMERROR_InvalidConfigDescriptor;
57
58 while ((AudioInterfaceInfo->Config.DataINPipeNumber && !(DataINEndpoint)) ||
59 (AudioInterfaceInfo->Config.DataOUTPipeNumber && !(DataOUTEndpoint)))
60 {
61 if (!(AudioControlInterface) ||
62 USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
63 DCOMP_Audio_Host_NextAudioInterfaceDataEndpoint) != DESCRIPTOR_SEARCH_COMP_Found)
64 {
65 if (!(AudioControlInterface) ||
66 USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
67 DCOMP_Audio_Host_NextAudioStreamInterface) != DESCRIPTOR_SEARCH_COMP_Found)
68 {
69 if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
70 DCOMP_Audio_Host_NextAudioControlInterface) != DESCRIPTOR_SEARCH_COMP_Found)
71 {
72 return AUDIO_ENUMERROR_NoCompatibleInterfaceFound;
73 }
74
75 AudioControlInterface = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Interface_t);
76
77 if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
78 DCOMP_Audio_Host_NextAudioStreamInterface) != DESCRIPTOR_SEARCH_COMP_Found)
79 {
80 return AUDIO_ENUMERROR_NoCompatibleInterfaceFound;
81 }
82 }
83
84 AudioStreamingInterface = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Interface_t);
85
86 DataINEndpoint = NULL;
87 DataOUTEndpoint = NULL;
88
89 continue;
90 }
91
92 USB_Descriptor_Endpoint_t* EndpointData = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Endpoint_t);
93
94 if ((EndpointData->EndpointAddress & ENDPOINT_DIR_MASK) == ENDPOINT_DIR_IN)
95 DataINEndpoint = EndpointData;
96 else
97 DataOUTEndpoint = EndpointData;
98 }
99
100 for (uint8_t PipeNum = 1; PipeNum < PIPE_TOTAL_PIPES; PipeNum++)
101 {
102 uint16_t Size;
103 uint8_t Type;
104 uint8_t Token;
105 uint8_t EndpointAddress;
106 bool DoubleBanked;
107
108 if (PipeNum == AudioInterfaceInfo->Config.DataINPipeNumber)
109 {
110 Size = le16_to_cpu(DataINEndpoint->EndpointSize);
111 EndpointAddress = DataINEndpoint->EndpointAddress;
112 Token = PIPE_TOKEN_IN;
113 Type = EP_TYPE_ISOCHRONOUS;
114 DoubleBanked = true;
115
116 AudioInterfaceInfo->State.DataINPipeSize = DataINEndpoint->EndpointSize;
117 }
118 else if (PipeNum == AudioInterfaceInfo->Config.DataOUTPipeNumber)
119 {
120 Size = le16_to_cpu(DataOUTEndpoint->EndpointSize);
121 EndpointAddress = DataOUTEndpoint->EndpointAddress;
122 Token = PIPE_TOKEN_OUT;
123 Type = EP_TYPE_ISOCHRONOUS;
124 DoubleBanked = true;
125
126 AudioInterfaceInfo->State.DataOUTPipeSize = DataOUTEndpoint->EndpointSize;
127 }
128 else
129 {
130 continue;
131 }
132
133 if (!(Pipe_ConfigurePipe(portnum,PipeNum, Type, Token, EndpointAddress, Size,
134 DoubleBanked ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE)))
135 {
136 return AUDIO_ENUMERROR_PipeConfigurationFailed;
137 }
138 }
139
140 AudioInterfaceInfo->State.ControlInterfaceNumber = AudioControlInterface->InterfaceNumber;
141 AudioInterfaceInfo->State.StreamingInterfaceNumber = AudioStreamingInterface->InterfaceNumber;
142 AudioInterfaceInfo->State.EnabledStreamingAltIndex = AudioStreamingInterface->AlternateSetting;
143 AudioInterfaceInfo->State.IsActive = true;
144
145 return AUDIO_ENUMERROR_NoError;
146 }
147
148 static uint8_t DCOMP_Audio_Host_NextAudioControlInterface(void* CurrentDescriptor)
149 {
150 USB_Descriptor_Header_t* Header = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Header_t);
151
152 if (Header->Type == DTYPE_Interface)
153 {
154 USB_Descriptor_Interface_t* Interface = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Interface_t);
155
156 if ((Interface->Class == AUDIO_CSCP_AudioClass) &&
157 (Interface->SubClass == AUDIO_CSCP_ControlSubclass) &&
158 (Interface->Protocol == AUDIO_CSCP_ControlProtocol))
159 {
160 return DESCRIPTOR_SEARCH_Found;
161 }
162 }
163
164 return DESCRIPTOR_SEARCH_NotFound;
165 }
166
167 static uint8_t DCOMP_Audio_Host_NextAudioStreamInterface(void* CurrentDescriptor)
168 {
169 USB_Descriptor_Header_t* Header = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Header_t);
170
171 if (Header->Type == DTYPE_Interface)
172 {
173 USB_Descriptor_Interface_t* Interface = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Interface_t);
174
175 if ((Interface->Class == AUDIO_CSCP_AudioClass) &&
176 (Interface->SubClass == AUDIO_CSCP_AudioStreamingSubclass) &&
177 (Interface->Protocol == AUDIO_CSCP_StreamingProtocol))
178 {
179 return DESCRIPTOR_SEARCH_Found;
180 }
181 }
182
183 return DESCRIPTOR_SEARCH_NotFound;
184 }
185
186 static uint8_t DCOMP_Audio_Host_NextAudioInterfaceDataEndpoint(void* CurrentDescriptor)
187 {
188 USB_Descriptor_Header_t* Header = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Header_t);
189
190 if (Header->Type == DTYPE_Endpoint)
191 {
192 USB_Descriptor_Endpoint_t* Endpoint = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Endpoint_t);
193
194 if ((Endpoint->Attributes & EP_TYPE_MASK) == EP_TYPE_ISOCHRONOUS)
195 return DESCRIPTOR_SEARCH_Found;
196 }
197 else if (Header->Type == DTYPE_Interface)
198 {
199 return DESCRIPTOR_SEARCH_Fail;
200 }
201
202 return DESCRIPTOR_SEARCH_NotFound;
203 }
204
205 uint8_t Audio_Host_StartStopStreaming(USB_ClassInfo_Audio_Host_t* const AudioInterfaceInfo,
206 const bool EnableStreaming)
207 {
208 if (!(AudioInterfaceInfo->State.IsActive))
209 return HOST_SENDCONTROL_DeviceDisconnected;
210
211 return USB_Host_SetInterfaceAltSetting(AudioInterfaceInfo->Config.PortNumber,
212 AudioInterfaceInfo->State.StreamingInterfaceNumber,
213 EnableStreaming ? AudioInterfaceInfo->State.EnabledStreamingAltIndex : 0);
214 }
215
216 uint8_t Audio_Host_GetSetEndpointProperty(USB_ClassInfo_Audio_Host_t* const AudioInterfaceInfo,
217 const uint8_t DataPipeIndex,
218 const uint8_t EndpointProperty,
219 const uint8_t EndpointControl,
220 const uint16_t DataLength,
221 void* const Data)
222 {
223 uint8_t portnum = AudioInterfaceInfo->Config.PortNumber;
224
225 uint8_t RequestType;
226 uint8_t EndpointAddress;
227
228 if (!(AudioInterfaceInfo->State.IsActive))
229 return HOST_SENDCONTROL_DeviceDisconnected;
230 if (EndpointProperty & 0x80)
231 RequestType = (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_ENDPOINT);
232 else
233 RequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_ENDPOINT);
234
235 Pipe_SelectPipe(portnum,DataPipeIndex);
236 EndpointAddress = Pipe_GetBoundEndpointAddress(portnum);
237
238 USB_ControlRequest = (USB_Request_Header_t)
239 {
240 .bmRequestType = RequestType,
241 .bRequest = EndpointProperty,
242 .wValue = ((uint16_t)EndpointControl << 8),
243 .wIndex = EndpointAddress,
244 .wLength = DataLength,
245 };
246
247 Pipe_SelectPipe(portnum,PIPE_CONTROLPIPE);
248
249 return USB_Host_SendControlRequest(portnum,Data);
250 }
251
252 #endif
253