LPCOpen Platform
LPCOpen Platform for NXP LPC Microcontrollers
 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)
55 
56  while (!(DataINEndpoint) || !(DataOUTEndpoint))
57  {
58  if (!(MIDIInterface) ||
59  USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
61  {
62  if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
64  {
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  {
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 {
133 
134  if (Header->Type == DTYPE_Interface)
135  {
137 
138  if ((Interface->Class == AUDIO_CSCP_AudioClass) &&
139  (Interface->SubClass == AUDIO_CSCP_MIDIStreamingSubclass) &&
140  (Interface->Protocol == AUDIO_CSCP_StreamingProtocol))
141  {
143  }
144  }
145 
147 }
148 
149 static uint8_t DCOMP_MIDI_Host_NextMIDIStreamingDataEndpoint(void* const CurrentDescriptor)
150 {
152 
153  if (Header->Type == DTYPE_Endpoint)
154  {
156 
157  uint8_t EndpointType = (Endpoint->Attributes & EP_TYPE_MASK);
158 
159  if ((EndpointType == EP_TYPE_BULK) && !(Pipe_IsEndpointBound(Endpoint->EndpointAddress)))
161  }
162  else if (Header->Type == DTYPE_Interface)
163  {
164  return DESCRIPTOR_SEARCH_Fail;
165  }
166 
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))
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))
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 
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))
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