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