Fixed GenericHIDHost demo report write routine incorrect for control type requests...
[pub/USBasp.git] / LUFA / Drivers / USB / LowLevel / Endpoint.c
1 /*
2 LUFA Library
3 Copyright (C) Dean Camera, 2009.
4
5 dean [at] fourwalledcubicle [dot] com
6 www.fourwalledcubicle.com
7 */
8
9 /*
10 Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
11
12 Permission to use, copy, modify, and distribute this software
13 and its documentation for any purpose and without fee is hereby
14 granted, provided that the above copyright notice appear in all
15 copies and that both that the copyright notice and this
16 permission notice and warranty disclaimer appear in supporting
17 documentation, and that the name of the author not be used in
18 advertising or publicity pertaining to distribution of the
19 software without specific, written prior permission.
20
21 The author disclaim all warranties with regard to this
22 software, including all implied warranties of merchantability
23 and fitness. In no event shall the author be liable for any
24 special, indirect or consequential damages or any damages
25 whatsoever resulting from loss of use, data or profits, whether
26 in an action of contract, negligence or other tortious action,
27 arising out of or in connection with the use or performance of
28 this software.
29 */
30
31 #include "../HighLevel/USBMode.h"
32
33 #if defined(USB_CAN_BE_DEVICE)
34
35 #define INCLUDE_FROM_ENDPOINT_C
36 #include "Endpoint.h"
37
38 #if !defined(FIXED_CONTROL_ENDPOINT_SIZE)
39 uint8_t USB_ControlEndpointSize = ENDPOINT_CONTROLEP_DEFAULT_SIZE;
40 #endif
41
42 #if !defined(STATIC_ENDPOINT_CONFIGURATION)
43 bool Endpoint_ConfigureEndpoint(const uint8_t Number, const uint8_t Type, const uint8_t Direction,
44 const uint16_t Size, const uint8_t Banks)
45 {
46 Endpoint_SelectEndpoint(Number);
47 Endpoint_EnableEndpoint();
48
49 UECFG1X = 0;
50
51 UECFG0X = ((Type << EPTYPE0) | Direction);
52 UECFG1X = ((1 << ALLOC) | Banks | Endpoint_BytesToEPSizeMask(Size));
53
54 return Endpoint_IsConfigured();
55 }
56 #else
57 bool Endpoint_ConfigureEndpointStatic(const uint8_t Number, const uint8_t UECFG0XData, const uint8_t UECFG1XData)
58 {
59 Endpoint_SelectEndpoint(Number);
60 Endpoint_EnableEndpoint();
61
62 UECFG1X = 0;
63
64 UECFG0X = UECFG0XData;
65 UECFG1X = UECFG1XData;
66
67 return Endpoint_IsConfigured();
68 }
69 #endif
70
71 void Endpoint_ClearEndpoints(void)
72 {
73 UEINT = 0;
74
75 for (uint8_t EPNum = 0; EPNum < ENDPOINT_TOTAL_ENDPOINTS; EPNum++)
76 {
77 Endpoint_SelectEndpoint(EPNum);
78 UEIENX = 0;
79 UEINTX = 0;
80 Endpoint_DeallocateMemory();
81 Endpoint_DisableEndpoint();
82 }
83 }
84
85 uint8_t Endpoint_WaitUntilReady(void)
86 {
87 uint16_t TimeoutMSRem = USB_STREAM_TIMEOUT_MS;
88
89 USB_INT_Clear(USB_INT_SOFI);
90
91 for (;;)
92 {
93 if (Endpoint_GetEndpointDirection() == ENDPOINT_DIR_IN)
94 {
95 if (Endpoint_IsINReady())
96 return ENDPOINT_READYWAIT_NoError;
97 }
98 else
99 {
100 if (Endpoint_IsOUTReceived())
101 return ENDPOINT_READYWAIT_NoError;
102 }
103
104 if (!(USB_IsConnected))
105 return ENDPOINT_READYWAIT_DeviceDisconnected;
106 else if (Endpoint_IsStalled())
107 return ENDPOINT_READYWAIT_EndpointStalled;
108
109 if (USB_INT_HasOccurred(USB_INT_SOFI))
110 {
111 USB_INT_Clear(USB_INT_SOFI);
112
113 if (!(TimeoutMSRem--))
114 return ENDPOINT_READYWAIT_Timeout;
115 }
116 }
117 }
118
119 uint8_t Endpoint_Discard_Stream(uint16_t Length
120 #if !defined(NO_STREAM_CALLBACKS)
121 , uint8_t (* const Callback)(void)
122 #endif
123 )
124 {
125 uint8_t ErrorCode;
126
127 if ((ErrorCode = Endpoint_WaitUntilReady()))
128 return ErrorCode;
129
130 while (Length--)
131 {
132 if (!(Endpoint_IsReadWriteAllowed()))
133 {
134 Endpoint_ClearOUT();
135
136 #if !defined(NO_STREAM_CALLBACKS)
137 if ((Callback != NULL) && (Callback() == STREAMCALLBACK_Abort))
138 return ENDPOINT_RWSTREAM_ERROR_CallbackAborted;
139 #endif
140
141 if ((ErrorCode = Endpoint_WaitUntilReady()))
142 return ErrorCode;
143 }
144 else
145 {
146 Endpoint_Discard_Byte();
147 }
148 }
149
150 return ENDPOINT_RWSTREAM_ERROR_NoError;
151 }
152
153 uint8_t Endpoint_Write_Stream_LE(const void* Buffer, uint16_t Length
154 #if !defined(NO_STREAM_CALLBACKS)
155 , uint8_t (* const Callback)(void)
156 #endif
157 )
158 {
159 uint8_t* DataStream = (uint8_t*)Buffer;
160 uint8_t ErrorCode;
161
162 if ((ErrorCode = Endpoint_WaitUntilReady()))
163 return ErrorCode;
164
165 while (Length--)
166 {
167 if (!(Endpoint_IsReadWriteAllowed()))
168 {
169 Endpoint_ClearIN();
170
171 #if !defined(NO_STREAM_CALLBACKS)
172 if ((Callback != NULL) && (Callback() == STREAMCALLBACK_Abort))
173 return ENDPOINT_RWSTREAM_ERROR_CallbackAborted;
174 #endif
175
176 if ((ErrorCode = Endpoint_WaitUntilReady()))
177 return ErrorCode;
178 }
179 else
180 {
181 Endpoint_Write_Byte(*(DataStream++));
182 }
183 }
184
185 return ENDPOINT_RWSTREAM_ERROR_NoError;
186 }
187
188 uint8_t Endpoint_Write_Stream_BE(const void* Buffer, uint16_t Length
189 #if !defined(NO_STREAM_CALLBACKS)
190 , uint8_t (* const Callback)(void)
191 #endif
192 )
193 {
194 uint8_t* DataStream = (uint8_t*)(Buffer + Length - 1);
195 uint8_t ErrorCode;
196
197 if ((ErrorCode = Endpoint_WaitUntilReady()))
198 return ErrorCode;
199
200 while (Length--)
201 {
202 if (!(Endpoint_IsReadWriteAllowed()))
203 {
204 Endpoint_ClearIN();
205
206 #if !defined(NO_STREAM_CALLBACKS)
207 if ((Callback != NULL) && (Callback() == STREAMCALLBACK_Abort))
208 return ENDPOINT_RWSTREAM_ERROR_CallbackAborted;
209 #endif
210
211 if ((ErrorCode = Endpoint_WaitUntilReady()))
212 return ErrorCode;
213 }
214 else
215 {
216 Endpoint_Write_Byte(*(DataStream--));
217 }
218 }
219
220 return ENDPOINT_RWSTREAM_ERROR_NoError;
221 }
222
223 uint8_t Endpoint_Read_Stream_LE(void* Buffer, uint16_t Length
224 #if !defined(NO_STREAM_CALLBACKS)
225 , uint8_t (* const Callback)(void)
226 #endif
227 )
228 {
229 uint8_t* DataStream = (uint8_t*)Buffer;
230 uint8_t ErrorCode;
231
232 if ((ErrorCode = Endpoint_WaitUntilReady()))
233 return ErrorCode;
234
235 while (Length--)
236 {
237 if (!(Endpoint_IsReadWriteAllowed()))
238 {
239 Endpoint_ClearOUT();
240
241 #if !defined(NO_STREAM_CALLBACKS)
242 if ((Callback != NULL) && (Callback() == STREAMCALLBACK_Abort))
243 return ENDPOINT_RWSTREAM_ERROR_CallbackAborted;
244 #endif
245
246 if ((ErrorCode = Endpoint_WaitUntilReady()))
247 return ErrorCode;
248 }
249 else
250 {
251 *(DataStream++) = Endpoint_Read_Byte();
252 }
253 }
254
255 return ENDPOINT_RWSTREAM_ERROR_NoError;
256 }
257
258 uint8_t Endpoint_Read_Stream_BE(void* Buffer, uint16_t Length
259 #if !defined(NO_STREAM_CALLBACKS)
260 , uint8_t (* const Callback)(void)
261 #endif
262 )
263 {
264 uint8_t* DataStream = (uint8_t*)(Buffer + Length - 1);
265 uint8_t ErrorCode;
266
267 if ((ErrorCode = Endpoint_WaitUntilReady()))
268 return ErrorCode;
269
270 while (Length--)
271 {
272 if (!(Endpoint_IsReadWriteAllowed()))
273 {
274 Endpoint_ClearOUT();
275
276 #if !defined(NO_STREAM_CALLBACKS)
277 if ((Callback != NULL) && (Callback() == STREAMCALLBACK_Abort))
278 return ENDPOINT_RWSTREAM_ERROR_CallbackAborted;
279 #endif
280
281 if ((ErrorCode = Endpoint_WaitUntilReady()))
282 return ErrorCode;
283 }
284 else
285 {
286 *(DataStream--) = Endpoint_Read_Byte();
287 }
288 }
289
290 return ENDPOINT_RWSTREAM_ERROR_NoError;
291 }
292
293 uint8_t Endpoint_Write_Control_Stream_LE(const void* Buffer, uint16_t Length)
294 {
295 uint8_t* DataStream = (uint8_t*)Buffer;
296 bool SendZLP = true;
297
298 while (Length && !(Endpoint_IsOUTReceived()))
299 {
300 while (!(Endpoint_IsINReady()));
301
302 while (Length && (Endpoint_BytesInEndpoint() < USB_ControlEndpointSize))
303 {
304 Endpoint_Write_Byte(*(DataStream++));
305
306 Length--;
307 }
308
309 SendZLP = (Endpoint_BytesInEndpoint() == USB_ControlEndpointSize);
310 Endpoint_ClearControlIN();
311 }
312
313 if (Endpoint_IsOUTReceived())
314 return ENDPOINT_RWCSTREAM_ERROR_HostAborted;
315
316 if (SendZLP)
317 {
318 while (!(Endpoint_IsINReady()));
319 Endpoint_ClearControlIN();
320 }
321
322 while (!(Endpoint_IsOUTReceived()));
323
324 return ENDPOINT_RWCSTREAM_ERROR_NoError;
325 }
326
327 uint8_t Endpoint_Write_Control_Stream_BE(const void* Buffer, uint16_t Length)
328 {
329 uint8_t* DataStream = (uint8_t*)(Buffer + Length - 1);
330 bool SendZLP = true;
331
332 while (Length && !(Endpoint_IsOUTReceived()))
333 {
334 while (!(Endpoint_IsINReady()));
335
336 while (Length && (Endpoint_BytesInEndpoint() < USB_ControlEndpointSize))
337 {
338 Endpoint_Write_Byte(*(DataStream--));
339
340 Length--;
341 }
342
343 SendZLP = (Endpoint_BytesInEndpoint() == USB_ControlEndpointSize);
344 Endpoint_ClearControlIN();
345 }
346
347 if (Endpoint_IsOUTReceived())
348 return ENDPOINT_RWCSTREAM_ERROR_HostAborted;
349
350 if (SendZLP)
351 {
352 while (!(Endpoint_IsINReady()));
353 Endpoint_ClearControlIN();
354 }
355
356 while (!(Endpoint_IsOUTReceived()));
357
358 return ENDPOINT_RWCSTREAM_ERROR_NoError;
359 }
360
361 uint8_t Endpoint_Read_Control_Stream_LE(void* Buffer, uint16_t Length)
362 {
363 uint8_t* DataStream = (uint8_t*)Buffer;
364
365 while (Length)
366 {
367 while (!(Endpoint_IsOUTReceived()));
368
369 while (Length && Endpoint_BytesInEndpoint())
370 {
371 *(DataStream++) = Endpoint_Read_Byte();
372
373 Length--;
374 }
375
376 Endpoint_ClearControlOUT();
377 }
378
379 while (!(Endpoint_IsINReady()));
380
381 return ENDPOINT_RWCSTREAM_ERROR_NoError;
382 }
383
384 uint8_t Endpoint_Read_Control_Stream_BE(void* Buffer, uint16_t Length)
385 {
386 uint8_t* DataStream = (uint8_t*)(Buffer + Length - 1);
387
388 while (Length)
389 {
390 while (!(Endpoint_IsOUTReceived()));
391
392 while (Length && Endpoint_BytesInEndpoint())
393 {
394 *(DataStream--) = Endpoint_Read_Byte();
395
396 Length--;
397 }
398
399 Endpoint_ClearControlOUT();
400 }
401
402 while (!(Endpoint_IsINReady()));
403
404 return ENDPOINT_RWCSTREAM_ERROR_NoError;
405 }
406
407 #endif