Fixed MassStorage demo not clearing the reset flag when a Mass Storage Reset is issue...
[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 uint8_t Endpoint_BytesToEPSizeMaskDynamic(const uint16_t Size)
43 {
44 return Endpoint_BytesToEPSizeMask(Size);
45 }
46
47 bool Endpoint_ConfigureEndpoint_Prv(const uint8_t Number, const uint8_t UECFG0XData, const uint8_t UECFG1XData)
48 {
49 Endpoint_SelectEndpoint(Number);
50 Endpoint_EnableEndpoint();
51
52 UECFG1X = 0;
53
54 UECFG0X = UECFG0XData;
55 UECFG1X = UECFG1XData;
56
57 return Endpoint_IsConfigured();
58 }
59
60 void Endpoint_ClearEndpoints(void)
61 {
62 UEINT = 0;
63
64 for (uint8_t EPNum = 0; EPNum < ENDPOINT_TOTAL_ENDPOINTS; EPNum++)
65 {
66 Endpoint_SelectEndpoint(EPNum);
67 UEIENX = 0;
68 UEINTX = 0;
69 Endpoint_DeallocateMemory();
70 Endpoint_DisableEndpoint();
71 }
72 }
73
74 #if !defined(CONTROL_ONLY_DEVICE)
75 uint8_t Endpoint_WaitUntilReady(void)
76 {
77 #if (USB_STREAM_TIMEOUT_MS < 0xFF)
78 uint8_t TimeoutMSRem = USB_STREAM_TIMEOUT_MS;
79 #else
80 uint16_t TimeoutMSRem = USB_STREAM_TIMEOUT_MS;
81 #endif
82
83 for (;;)
84 {
85 if (Endpoint_GetEndpointDirection() == ENDPOINT_DIR_IN)
86 {
87 if (Endpoint_IsINReady())
88 return ENDPOINT_READYWAIT_NoError;
89 }
90 else
91 {
92 if (Endpoint_IsOUTReceived())
93 return ENDPOINT_READYWAIT_NoError;
94 }
95
96 if (!(USB_IsConnected))
97 return ENDPOINT_READYWAIT_DeviceDisconnected;
98 else if (Endpoint_IsStalled())
99 return ENDPOINT_READYWAIT_EndpointStalled;
100
101 if (USB_INT_HasOccurred(USB_INT_SOFI))
102 {
103 USB_INT_Clear(USB_INT_SOFI);
104
105 if (!(TimeoutMSRem--))
106 return ENDPOINT_READYWAIT_Timeout;
107 }
108 }
109 }
110
111 uint8_t Endpoint_Discard_Stream(uint16_t Length
112 #if !defined(NO_STREAM_CALLBACKS)
113 , StreamCallbackPtr_t Callback
114 #endif
115 )
116 {
117 uint8_t ErrorCode;
118
119 if ((ErrorCode = Endpoint_WaitUntilReady()))
120 return ErrorCode;
121
122 while (Length)
123 {
124 if (!(Endpoint_IsReadWriteAllowed()))
125 {
126 Endpoint_ClearOUT();
127
128 #if !defined(NO_STREAM_CALLBACKS)
129 if ((Callback != NULL) && (Callback() == STREAMCALLBACK_Abort))
130 return ENDPOINT_RWSTREAM_CallbackAborted;
131 #endif
132
133 if ((ErrorCode = Endpoint_WaitUntilReady()))
134 return ErrorCode;
135 }
136 else
137 {
138 Endpoint_Discard_Byte();
139 Length--;
140 }
141 }
142
143 return ENDPOINT_RWSTREAM_NoError;
144 }
145
146 uint8_t Endpoint_Write_Stream_LE(const void* Buffer, uint16_t Length
147 #if !defined(NO_STREAM_CALLBACKS)
148 , StreamCallbackPtr_t Callback
149 #endif
150 )
151 {
152 uint8_t* DataStream = (uint8_t*)Buffer;
153 uint8_t ErrorCode;
154
155 if ((ErrorCode = Endpoint_WaitUntilReady()))
156 return ErrorCode;
157
158 while (Length)
159 {
160 if (!(Endpoint_IsReadWriteAllowed()))
161 {
162 Endpoint_ClearIN();
163
164 #if !defined(NO_STREAM_CALLBACKS)
165 if ((Callback != NULL) && (Callback() == STREAMCALLBACK_Abort))
166 return ENDPOINT_RWSTREAM_CallbackAborted;
167 #endif
168
169 if ((ErrorCode = Endpoint_WaitUntilReady()))
170 return ErrorCode;
171 }
172 else
173 {
174 Endpoint_Write_Byte(*(DataStream++));
175 Length--;
176 }
177 }
178
179 return ENDPOINT_RWSTREAM_NoError;
180 }
181
182 uint8_t Endpoint_Write_Stream_BE(const void* Buffer, uint16_t Length
183 #if !defined(NO_STREAM_CALLBACKS)
184 , StreamCallbackPtr_t Callback
185 #endif
186 )
187 {
188 uint8_t* DataStream = (uint8_t*)(Buffer + Length - 1);
189 uint8_t ErrorCode;
190
191 if ((ErrorCode = Endpoint_WaitUntilReady()))
192 return ErrorCode;
193
194 while (Length)
195 {
196 if (!(Endpoint_IsReadWriteAllowed()))
197 {
198 Endpoint_ClearIN();
199
200 #if !defined(NO_STREAM_CALLBACKS)
201 if ((Callback != NULL) && (Callback() == STREAMCALLBACK_Abort))
202 return ENDPOINT_RWSTREAM_CallbackAborted;
203 #endif
204
205 if ((ErrorCode = Endpoint_WaitUntilReady()))
206 return ErrorCode;
207 }
208 else
209 {
210 Endpoint_Write_Byte(*(DataStream--));
211 Length--;
212 }
213 }
214
215 return ENDPOINT_RWSTREAM_NoError;
216 }
217
218 uint8_t Endpoint_Read_Stream_LE(void* Buffer, uint16_t Length
219 #if !defined(NO_STREAM_CALLBACKS)
220 , StreamCallbackPtr_t Callback
221 #endif
222 )
223 {
224 uint8_t* DataStream = (uint8_t*)Buffer;
225 uint8_t ErrorCode;
226
227 if ((ErrorCode = Endpoint_WaitUntilReady()))
228 return ErrorCode;
229
230 while (Length)
231 {
232 if (!(Endpoint_IsReadWriteAllowed()))
233 {
234 Endpoint_ClearOUT();
235
236 #if !defined(NO_STREAM_CALLBACKS)
237 if ((Callback != NULL) && (Callback() == STREAMCALLBACK_Abort))
238 return ENDPOINT_RWSTREAM_CallbackAborted;
239 #endif
240
241 if ((ErrorCode = Endpoint_WaitUntilReady()))
242 return ErrorCode;
243 }
244 else
245 {
246 *(DataStream++) = Endpoint_Read_Byte();
247 Length--;
248 }
249 }
250
251 return ENDPOINT_RWSTREAM_NoError;
252 }
253
254 uint8_t Endpoint_Read_Stream_BE(void* Buffer, uint16_t Length
255 #if !defined(NO_STREAM_CALLBACKS)
256 , StreamCallbackPtr_t Callback
257 #endif
258 )
259 {
260 uint8_t* DataStream = (uint8_t*)(Buffer + Length - 1);
261 uint8_t ErrorCode;
262
263 if ((ErrorCode = Endpoint_WaitUntilReady()))
264 return ErrorCode;
265
266 while (Length)
267 {
268 if (!(Endpoint_IsReadWriteAllowed()))
269 {
270 Endpoint_ClearOUT();
271
272 #if !defined(NO_STREAM_CALLBACKS)
273 if ((Callback != NULL) && (Callback() == STREAMCALLBACK_Abort))
274 return ENDPOINT_RWSTREAM_CallbackAborted;
275 #endif
276
277 if ((ErrorCode = Endpoint_WaitUntilReady()))
278 return ErrorCode;
279 }
280 else
281 {
282 *(DataStream--) = Endpoint_Read_Byte();
283 Length--;
284 }
285 }
286
287 return ENDPOINT_RWSTREAM_NoError;
288 }
289 #endif
290
291 uint8_t Endpoint_Write_Control_Stream_LE(const void* Buffer, uint16_t Length)
292 {
293 uint8_t* DataStream = (uint8_t*)Buffer;
294 bool LastPacketFull = false;
295
296 if (Length > USB_ControlRequest.wLength)
297 Length = USB_ControlRequest.wLength;
298
299 while (Length && !(Endpoint_IsOUTReceived()))
300 {
301 while (!(Endpoint_IsINReady()));
302
303 while (Length && (Endpoint_BytesInEndpoint() < USB_ControlEndpointSize))
304 {
305 Endpoint_Write_Byte(*(DataStream++));
306 Length--;
307 }
308
309 LastPacketFull = (Endpoint_BytesInEndpoint() == USB_ControlEndpointSize);
310 Endpoint_ClearIN();
311 }
312
313 if (Endpoint_IsOUTReceived())
314 return ENDPOINT_RWCSTREAM_HostAborted;
315
316 if (LastPacketFull)
317 {
318 while (!(Endpoint_IsINReady()));
319 Endpoint_ClearIN();
320 }
321
322 while (!(Endpoint_IsOUTReceived()));
323
324 return ENDPOINT_RWCSTREAM_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 LastPacketFull = false;
331
332 if (Length > USB_ControlRequest.wLength)
333 Length = USB_ControlRequest.wLength;
334
335 while (Length && !(Endpoint_IsOUTReceived()))
336 {
337 if (Endpoint_IsINReady())
338 {
339 while (Length && (Endpoint_BytesInEndpoint() < USB_ControlEndpointSize))
340 {
341 Endpoint_Write_Byte(*(DataStream--));
342 Length--;
343 }
344
345 LastPacketFull = (Endpoint_BytesInEndpoint() == USB_ControlEndpointSize);
346 Endpoint_ClearIN();
347 }
348 }
349
350 if (Endpoint_IsOUTReceived())
351 return ENDPOINT_RWCSTREAM_HostAborted;
352
353 if (LastPacketFull)
354 {
355 while (!(Endpoint_IsINReady()));
356 Endpoint_ClearIN();
357 }
358
359 while (!(Endpoint_IsOUTReceived()));
360
361 return ENDPOINT_RWCSTREAM_NoError;
362 }
363
364 uint8_t Endpoint_Read_Control_Stream_LE(void* Buffer, uint16_t Length)
365 {
366 uint8_t* DataStream = (uint8_t*)Buffer;
367
368 while (Length)
369 {
370 if (Endpoint_IsOUTReceived())
371 {
372 while (Length && Endpoint_BytesInEndpoint())
373 {
374 *(DataStream++) = Endpoint_Read_Byte();
375 Length--;
376 }
377
378 Endpoint_ClearOUT();
379 }
380 }
381
382 while (!(Endpoint_IsINReady()));
383
384 return ENDPOINT_RWCSTREAM_NoError;
385 }
386
387 uint8_t Endpoint_Read_Control_Stream_BE(void* Buffer, uint16_t Length)
388 {
389 uint8_t* DataStream = (uint8_t*)(Buffer + Length - 1);
390
391 while (Length)
392 {
393 if (Endpoint_IsOUTReceived())
394 {
395 while (Length && Endpoint_BytesInEndpoint())
396 {
397 *(DataStream--) = Endpoint_Read_Byte();
398 Length--;
399 }
400
401 Endpoint_ClearOUT();
402 }
403 }
404
405 while (!(Endpoint_IsINReady()));
406
407 return ENDPOINT_RWCSTREAM_NoError;
408 }
409
410 #endif