]> git.donarmstrong.com Git - qmk_firmware.git/blob - protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Host/MIDIClassHost.c
Squashed 'tmk_core/' content from commit 05caacc
[qmk_firmware.git] / protocol / lufa / LUFA-120730 / LUFA / Drivers / USB / Class / Host / MIDIClassHost.c
1 /*\r
2              LUFA Library\r
3      Copyright (C) Dean Camera, 2012.\r
4 \r
5   dean [at] fourwalledcubicle [dot] com\r
6            www.lufa-lib.org\r
7 */\r
8 \r
9 /*\r
10   Copyright 2012  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
11 \r
12   Permission to use, copy, modify, distribute, and sell this\r
13   software and its documentation for any purpose is hereby granted\r
14   without fee, provided that the above copyright notice appear in\r
15   all copies and that both that the copyright notice and this\r
16   permission notice and warranty disclaimer appear in supporting\r
17   documentation, and that the name of the author not be used in\r
18   advertising or publicity pertaining to distribution of the\r
19   software without specific, written prior permission.\r
20 \r
21   The author disclaim all warranties with regard to this\r
22   software, including all implied warranties of merchantability\r
23   and fitness.  In no event shall the author be liable for any\r
24   special, indirect or consequential damages or any damages\r
25   whatsoever resulting from loss of use, data or profits, whether\r
26   in an action of contract, negligence or other tortious action,\r
27   arising out of or in connection with the use or performance of\r
28   this software.\r
29 */\r
30 \r
31 #define  __INCLUDE_FROM_USB_DRIVER\r
32 #include "../../Core/USBMode.h"\r
33 \r
34 #if defined(USB_CAN_BE_HOST)\r
35 \r
36 #define  __INCLUDE_FROM_MIDI_DRIVER\r
37 #define  __INCLUDE_FROM_MIDI_HOST_C\r
38 #include "MIDIClassHost.h"\r
39 \r
40 uint8_t MIDI_Host_ConfigurePipes(USB_ClassInfo_MIDI_Host_t* const MIDIInterfaceInfo,\r
41                                  uint16_t ConfigDescriptorSize,\r
42                                  void* ConfigDescriptorData)\r
43 {\r
44         USB_Descriptor_Endpoint_t*  DataINEndpoint  = NULL;\r
45         USB_Descriptor_Endpoint_t*  DataOUTEndpoint = NULL;\r
46         USB_Descriptor_Interface_t* MIDIInterface   = NULL;\r
47 \r
48         memset(&MIDIInterfaceInfo->State, 0x00, sizeof(MIDIInterfaceInfo->State));\r
49 \r
50         if (DESCRIPTOR_TYPE(ConfigDescriptorData) != DTYPE_Configuration)\r
51           return MIDI_ENUMERROR_InvalidConfigDescriptor;\r
52 \r
53         while (!(DataINEndpoint) || !(DataOUTEndpoint))\r
54         {\r
55                 if (!(MIDIInterface) ||\r
56                     USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,\r
57                                               DCOMP_MIDI_Host_NextMIDIStreamingDataEndpoint) != DESCRIPTOR_SEARCH_COMP_Found)\r
58                 {\r
59                         if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,\r
60                                                       DCOMP_MIDI_Host_NextMIDIStreamingInterface) != DESCRIPTOR_SEARCH_COMP_Found)\r
61                         {\r
62                                 return MIDI_ENUMERROR_NoCompatibleInterfaceFound;\r
63                         }\r
64 \r
65                         MIDIInterface = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Interface_t);\r
66 \r
67                         DataINEndpoint  = NULL;\r
68                         DataOUTEndpoint = NULL;\r
69 \r
70                         continue;\r
71                 }\r
72 \r
73                 USB_Descriptor_Endpoint_t* EndpointData = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Endpoint_t);\r
74 \r
75                 if ((EndpointData->EndpointAddress & ENDPOINT_DIR_MASK) == ENDPOINT_DIR_IN)\r
76                   DataINEndpoint  = EndpointData;\r
77                 else\r
78                   DataOUTEndpoint = EndpointData;\r
79         }\r
80 \r
81         MIDIInterfaceInfo->Config.DataINPipe.Size  = le16_to_cpu(DataINEndpoint->EndpointSize);\r
82         MIDIInterfaceInfo->Config.DataINPipe.EndpointAddress = DataINEndpoint->EndpointAddress;\r
83         MIDIInterfaceInfo->Config.DataINPipe.Type  = EP_TYPE_BULK;\r
84         \r
85         MIDIInterfaceInfo->Config.DataOUTPipe.Size = le16_to_cpu(DataOUTEndpoint->EndpointSize);\r
86         MIDIInterfaceInfo->Config.DataOUTPipe.EndpointAddress = DataOUTEndpoint->EndpointAddress;\r
87         MIDIInterfaceInfo->Config.DataOUTPipe.Type = EP_TYPE_BULK;\r
88         \r
89         if (!(Pipe_ConfigurePipeTable(&MIDIInterfaceInfo->Config.DataINPipe, 1)))\r
90           return false;\r
91         \r
92         if (!(Pipe_ConfigurePipeTable(&MIDIInterfaceInfo->Config.DataOUTPipe, 1)))\r
93           return false; \r
94 \r
95         MIDIInterfaceInfo->State.InterfaceNumber = MIDIInterface->InterfaceNumber;\r
96         MIDIInterfaceInfo->State.IsActive = true;\r
97 \r
98         return MIDI_ENUMERROR_NoError;\r
99 }\r
100 \r
101 static uint8_t DCOMP_MIDI_Host_NextMIDIStreamingInterface(void* const CurrentDescriptor)\r
102 {\r
103         USB_Descriptor_Header_t* Header = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Header_t);\r
104 \r
105         if (Header->Type == DTYPE_Interface)\r
106         {\r
107                 USB_Descriptor_Interface_t* Interface = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Interface_t);\r
108 \r
109                 if ((Interface->Class    == AUDIO_CSCP_AudioClass)            &&\r
110                     (Interface->SubClass == AUDIO_CSCP_MIDIStreamingSubclass) &&\r
111                     (Interface->Protocol == AUDIO_CSCP_StreamingProtocol))\r
112                 {\r
113                         return DESCRIPTOR_SEARCH_Found;\r
114                 }\r
115         }\r
116 \r
117         return DESCRIPTOR_SEARCH_NotFound;\r
118 }\r
119 \r
120 static uint8_t DCOMP_MIDI_Host_NextMIDIStreamingDataEndpoint(void* const CurrentDescriptor)\r
121 {\r
122         USB_Descriptor_Header_t* Header = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Header_t);\r
123 \r
124         if (Header->Type == DTYPE_Endpoint)\r
125         {\r
126                 USB_Descriptor_Endpoint_t* Endpoint = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Endpoint_t);\r
127 \r
128                 uint8_t EndpointType = (Endpoint->Attributes & EP_TYPE_MASK);\r
129 \r
130                 if ((EndpointType == EP_TYPE_BULK) && !(Pipe_IsEndpointBound(Endpoint->EndpointAddress)))\r
131                   return DESCRIPTOR_SEARCH_Found;\r
132         }\r
133         else if (Header->Type == DTYPE_Interface)\r
134         {\r
135                 return DESCRIPTOR_SEARCH_Fail;\r
136         }\r
137 \r
138         return DESCRIPTOR_SEARCH_NotFound;\r
139 }\r
140 \r
141 void MIDI_Host_USBTask(USB_ClassInfo_MIDI_Host_t* const MIDIInterfaceInfo)\r
142 {\r
143         if ((USB_HostState != HOST_STATE_Configured) || !(MIDIInterfaceInfo->State.IsActive))\r
144           return;\r
145 \r
146         #if !defined(NO_CLASS_DRIVER_AUTOFLUSH)\r
147         MIDI_Host_Flush(MIDIInterfaceInfo);\r
148         #endif\r
149 }\r
150 \r
151 uint8_t MIDI_Host_Flush(USB_ClassInfo_MIDI_Host_t* const MIDIInterfaceInfo)\r
152 {\r
153         if ((USB_HostState != HOST_STATE_Configured) || !(MIDIInterfaceInfo->State.IsActive))\r
154           return PIPE_RWSTREAM_DeviceDisconnected;\r
155 \r
156         uint8_t ErrorCode;\r
157 \r
158         Pipe_SelectPipe(MIDIInterfaceInfo->Config.DataOUTPipe.Address);\r
159         Pipe_Unfreeze();\r
160         \r
161         if (Pipe_BytesInPipe())\r
162         {\r
163                 Pipe_ClearOUT();\r
164 \r
165                 if ((ErrorCode = Pipe_WaitUntilReady()) != PIPE_READYWAIT_NoError)\r
166                 {\r
167                         Pipe_Freeze();\r
168                         return ErrorCode;\r
169                 }\r
170         }\r
171 \r
172         Pipe_Freeze();\r
173 \r
174         return PIPE_READYWAIT_NoError;\r
175 }\r
176 \r
177 uint8_t MIDI_Host_SendEventPacket(USB_ClassInfo_MIDI_Host_t* const MIDIInterfaceInfo,\r
178                                   MIDI_EventPacket_t* const Event)\r
179 {\r
180         if ((USB_HostState != HOST_STATE_Configured) || !(MIDIInterfaceInfo->State.IsActive))\r
181           return HOST_SENDCONTROL_DeviceDisconnected;\r
182 \r
183         uint8_t ErrorCode;\r
184 \r
185         Pipe_SelectPipe(MIDIInterfaceInfo->Config.DataOUTPipe.Address);\r
186         Pipe_Unfreeze();\r
187         \r
188         if ((ErrorCode = Pipe_Write_Stream_LE(Event, sizeof(MIDI_EventPacket_t), NULL)) != PIPE_RWSTREAM_NoError)\r
189         {\r
190                 Pipe_Freeze();\r
191                 return ErrorCode;\r
192         }\r
193 \r
194         if (!(Pipe_IsReadWriteAllowed()))\r
195           Pipe_ClearOUT();\r
196 \r
197         Pipe_Freeze();\r
198 \r
199         return PIPE_RWSTREAM_NoError;\r
200 }\r
201 \r
202 bool MIDI_Host_ReceiveEventPacket(USB_ClassInfo_MIDI_Host_t* const MIDIInterfaceInfo,\r
203                                   MIDI_EventPacket_t* const Event)\r
204 {\r
205         if ((USB_HostState != HOST_STATE_Configured) || !(MIDIInterfaceInfo->State.IsActive))\r
206           return HOST_SENDCONTROL_DeviceDisconnected;\r
207           \r
208         bool DataReady = false;\r
209 \r
210         Pipe_SelectPipe(MIDIInterfaceInfo->Config.DataINPipe.Address);\r
211         Pipe_Unfreeze();\r
212 \r
213         if (Pipe_IsINReceived())\r
214         {\r
215                 if (Pipe_BytesInPipe())\r
216                 {\r
217                         Pipe_Read_Stream_LE(Event, sizeof(MIDI_EventPacket_t), NULL);\r
218                         DataReady = true;\r
219                 }\r
220 \r
221                 if (!(Pipe_BytesInPipe()))\r
222                   Pipe_ClearIN();\r
223         }\r
224         \r
225         Pipe_Freeze();\r
226         \r
227         return DataReady;\r
228 }\r
229 \r
230 #endif\r
231 \r