| 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
MIDIClassHost.c
Go to the documentation of this file.
1 /*
2 * @brief Host mode driver for the library USB MIDI 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 #define __INCLUDE_FROM_USB_DRIVER
34 #include "../../Core/USBMode.h"
35
36 #if defined(USB_CAN_BE_HOST)
37
38 #define __INCLUDE_FROM_MIDI_DRIVER
39 #define __INCLUDE_FROM_MIDI_HOST_C
40 #include "MIDIClassHost.h"
41
42 uint8_t MIDI_Host_ConfigurePipes(USB_ClassInfo_MIDI_Host_t* const MIDIInterfaceInfo,
43 uint16_t ConfigDescriptorSize,
44 void* ConfigDescriptorData)
45 {
46 USB_Descriptor_Endpoint_t* DataINEndpoint = NULL;
47 USB_Descriptor_Endpoint_t* DataOUTEndpoint = NULL;
48 USB_Descriptor_Interface_t* MIDIInterface = NULL;
49 uint8_t portnum = MIDIInterfaceInfo->Config.PortNumber;
50
51 memset(&MIDIInterfaceInfo->State, 0x00, sizeof(MIDIInterfaceInfo->State));
52
53 if (DESCRIPTOR_TYPE(ConfigDescriptorData) != DTYPE_Configuration)
54 return MIDI_ENUMERROR_InvalidConfigDescriptor;
55
56 while (!(DataINEndpoint) || !(DataOUTEndpoint))
57 {
58 if (!(MIDIInterface) ||
59 USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
60 DCOMP_MIDI_Host_NextMIDIStreamingDataEndpoint) != DESCRIPTOR_SEARCH_COMP_Found)
61 {
62 if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
63 DCOMP_MIDI_Host_NextMIDIStreamingInterface) != DESCRIPTOR_SEARCH_COMP_Found)
64 {
65 return MIDI_ENUMERROR_NoCompatibleInterfaceFound;
66 }
67
68 MIDIInterface = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Interface_t);
69
70 DataINEndpoint = NULL;
71 DataOUTEndpoint = NULL;
72
73 continue;
74 }
75
76 USB_Descriptor_Endpoint_t* EndpointData = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Endpoint_t);
77
78 if ((EndpointData->EndpointAddress & ENDPOINT_DIR_MASK) == ENDPOINT_DIR_IN)
79 DataINEndpoint = EndpointData;
80 else
81 DataOUTEndpoint = EndpointData;
82 }
83
84 for (uint8_t PipeNum = 1; PipeNum < PIPE_TOTAL_PIPES; PipeNum++)
85 {
86 uint16_t Size;
87 uint8_t Type;
88 uint8_t Token;
89 uint8_t EndpointAddress;
90 bool DoubleBanked;
91
92 if (PipeNum == MIDIInterfaceInfo->Config.DataINPipeNumber)
93 {
94 Size = le16_to_cpu(DataINEndpoint->EndpointSize);
95 EndpointAddress = DataINEndpoint->EndpointAddress;
96 Token = PIPE_TOKEN_IN;
97 Type = EP_TYPE_BULK;
98 DoubleBanked = MIDIInterfaceInfo->Config.DataINPipeDoubleBank;
99
100 MIDIInterfaceInfo->State.DataINPipeSize = DataINEndpoint->EndpointSize;
101 }
102 else if (PipeNum == MIDIInterfaceInfo->Config.DataOUTPipeNumber)
103 {
104 Size = le16_to_cpu(DataOUTEndpoint->EndpointSize);
105 EndpointAddress = DataOUTEndpoint->EndpointAddress;
106 Token = PIPE_TOKEN_OUT;
107 Type = EP_TYPE_BULK;
108 DoubleBanked = MIDIInterfaceInfo->Config.DataOUTPipeDoubleBank;
109
110 MIDIInterfaceInfo->State.DataOUTPipeSize = DataOUTEndpoint->EndpointSize;
111 }
112 else
113 {
114 continue;
115 }
116
117 if (!(Pipe_ConfigurePipe(portnum,PipeNum, Type, Token, EndpointAddress, Size,
118 DoubleBanked ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE)))
119 {
120 return MIDI_ENUMERROR_PipeConfigurationFailed;
121 }
122 }
123
124 MIDIInterfaceInfo->State.InterfaceNumber = MIDIInterface->InterfaceNumber;
125 MIDIInterfaceInfo->State.IsActive = true;
126
127 return MIDI_ENUMERROR_NoError;
128 }
129
130 static uint8_t DCOMP_MIDI_Host_NextMIDIStreamingInterface(void* const CurrentDescriptor)
131 {
132 USB_Descriptor_Header_t* Header = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Header_t);
133
134 if (Header->Type == DTYPE_Interface)
135 {
136 USB_Descriptor_Interface_t* Interface = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Interface_t);
137
138 if ((Interface->Class == AUDIO_CSCP_AudioClass) &&
139 (Interface->SubClass == AUDIO_CSCP_MIDIStreamingSubclass) &&
140 (Interface->Protocol == AUDIO_CSCP_StreamingProtocol))
141 {
142 return DESCRIPTOR_SEARCH_Found;
143 }
144 }
145
146 return DESCRIPTOR_SEARCH_NotFound;
147 }
148
149 static uint8_t DCOMP_MIDI_Host_NextMIDIStreamingDataEndpoint(void* const CurrentDescriptor)
150 {
151 USB_Descriptor_Header_t* Header = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Header_t);
152
153 if (Header->Type == DTYPE_Endpoint)
154 {
155 USB_Descriptor_Endpoint_t* Endpoint = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Endpoint_t);
156
157 uint8_t EndpointType = (Endpoint->Attributes & EP_TYPE_MASK);
158
159 if ((EndpointType == EP_TYPE_BULK) && !(Pipe_IsEndpointBound(Endpoint->EndpointAddress)))
160 return DESCRIPTOR_SEARCH_Found;
161 }
162 else if (Header->Type == DTYPE_Interface)
163 {
164 return DESCRIPTOR_SEARCH_Fail;
165 }
166
167 return DESCRIPTOR_SEARCH_NotFound;
168 }
169
170 void MIDI_Host_USBTask(USB_ClassInfo_MIDI_Host_t* const MIDIInterfaceInfo)
171 {
172 if ((USB_HostState[MIDIInterfaceInfo->Config.PortNumber] != HOST_STATE_Configured) || !(MIDIInterfaceInfo->State.IsActive))
173 return;
174
175 #if !defined(NO_CLASS_DRIVER_AUTOFLUSH)
176 MIDI_Host_Flush(MIDIInterfaceInfo);
177 #endif
178 }
179
180 uint8_t MIDI_Host_Flush(USB_ClassInfo_MIDI_Host_t* const MIDIInterfaceInfo)
181 {
182 uint8_t portnum = MIDIInterfaceInfo->Config.PortNumber;
183 uint8_t ErrorCode;
184 if ((USB_HostState[portnum] != HOST_STATE_Configured) || !(MIDIInterfaceInfo->State.IsActive))
185 return PIPE_RWSTREAM_DeviceDisconnected;
186
187 Pipe_SelectPipe(portnum,MIDIInterfaceInfo->Config.DataOUTPipeNumber);
188
189 if (Pipe_BytesInPipe(portnum))
190 {
191 Pipe_ClearOUT(portnum);
192
193 if ((ErrorCode = Pipe_WaitUntilReady(portnum)) != PIPE_READYWAIT_NoError)
194 return ErrorCode;
195 }
196
197 return PIPE_READYWAIT_NoError;
198 }
199
200 uint8_t MIDI_Host_SendEventPacket(USB_ClassInfo_MIDI_Host_t* const MIDIInterfaceInfo,
201 MIDI_EventPacket_t* const Event)
202 {
203 uint8_t portnum = MIDIInterfaceInfo->Config.PortNumber;
204 uint8_t ErrorCode;
205 if ((USB_HostState[portnum] != HOST_STATE_Configured) || !(MIDIInterfaceInfo->State.IsActive))
206 return HOST_SENDCONTROL_DeviceDisconnected;
207
208 Pipe_SelectPipe(portnum,MIDIInterfaceInfo->Config.DataOUTPipeNumber);
209
210 if ((ErrorCode = Pipe_Write_Stream_LE(portnum,Event, sizeof(MIDI_EventPacket_t), NULL)) != PIPE_RWSTREAM_NoError)
211 return ErrorCode;
212
213 if (!(Pipe_IsReadWriteAllowed(portnum)))
214 Pipe_ClearOUT(portnum);
215
216 return PIPE_RWSTREAM_NoError;
217 }
218
219 bool MIDI_Host_ReceiveEventPacket(USB_ClassInfo_MIDI_Host_t* const MIDIInterfaceInfo,
220 MIDI_EventPacket_t* const Event)
221 {
222 uint8_t portnum = MIDIInterfaceInfo->Config.PortNumber;
223
224 if ((USB_HostState[portnum] != HOST_STATE_Configured) || !(MIDIInterfaceInfo->State.IsActive))
225 return HOST_SENDCONTROL_DeviceDisconnected;
226
227 Pipe_SelectPipe(portnum,MIDIInterfaceInfo->Config.DataINPipeNumber);
228
229 if (!(Pipe_IsReadWriteAllowed(portnum)))
230 return false;
231
232 Pipe_Read_Stream_LE(portnum,Event, sizeof(MIDI_EventPacket_t), NULL);
233
234 if (!(Pipe_IsReadWriteAllowed(portnum)))
235 Pipe_ClearIN(portnum);
236
237 return true;
238 }
239
240 #endif
241