LPCOpen Platform
LPCOpen Platform for NXP LPC Microcontrollers
 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)
57 
58  while ((AudioInterfaceInfo->Config.DataINPipeNumber && !(DataINEndpoint)) ||
59  (AudioInterfaceInfo->Config.DataOUTPipeNumber && !(DataOUTEndpoint)))
60  {
61  if (!(AudioControlInterface) ||
62  USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
64  {
65  if (!(AudioControlInterface) ||
66  USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
68  {
69  if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
71  {
73  }
74 
75  AudioControlInterface = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Interface_t);
76 
77  if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
79  {
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  {
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 
146 }
147 
148 static uint8_t DCOMP_Audio_Host_NextAudioControlInterface(void* CurrentDescriptor)
149 {
151 
152  if (Header->Type == DTYPE_Interface)
153  {
155 
156  if ((Interface->Class == AUDIO_CSCP_AudioClass) &&
157  (Interface->SubClass == AUDIO_CSCP_ControlSubclass) &&
158  (Interface->Protocol == AUDIO_CSCP_ControlProtocol))
159  {
161  }
162  }
163 
165 }
166 
167 static uint8_t DCOMP_Audio_Host_NextAudioStreamInterface(void* CurrentDescriptor)
168 {
170 
171  if (Header->Type == DTYPE_Interface)
172  {
174 
175  if ((Interface->Class == AUDIO_CSCP_AudioClass) &&
176  (Interface->SubClass == AUDIO_CSCP_AudioStreamingSubclass) &&
177  (Interface->Protocol == AUDIO_CSCP_StreamingProtocol))
178  {
180  }
181  }
182 
184 }
185 
186 static uint8_t DCOMP_Audio_Host_NextAudioInterfaceDataEndpoint(void* CurrentDescriptor)
187 {
189 
190  if (Header->Type == DTYPE_Endpoint)
191  {
193 
194  if ((Endpoint->Attributes & EP_TYPE_MASK) == EP_TYPE_ISOCHRONOUS)
196  }
197  else if (Header->Type == DTYPE_Interface)
198  {
199  return DESCRIPTOR_SEARCH_Fail;
200  }
201 
203 }
204 
206  const bool EnableStreaming)
207 {
208  if (!(AudioInterfaceInfo->State.IsActive))
210 
211  return USB_Host_SetInterfaceAltSetting(AudioInterfaceInfo->Config.PortNumber,
212  AudioInterfaceInfo->State.StreamingInterfaceNumber,
213  EnableStreaming ? AudioInterfaceInfo->State.EnabledStreamingAltIndex : 0);
214 }
215 
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))
230  if (EndpointProperty & 0x80)
232  else
234 
235  Pipe_SelectPipe(portnum,DataPipeIndex);
236  EndpointAddress = Pipe_GetBoundEndpointAddress(portnum);
237 
239  {
240  .bmRequestType = RequestType,
241  .bRequest = EndpointProperty,
242  .wValue = ((uint16_t)EndpointControl << 8),
243  .wIndex = EndpointAddress,
244  .wLength = DataLength,
245  };
246 
248 
249  return USB_Host_SendControlRequest(portnum,Data);
250 }
251 
252 #endif
253