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