USB_HostRequest renamed to USB_ControlRequest, entire control request header is now...
[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 LastPacketFull = false;
297 bool ShortTransfer = (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
307 Length--;
308 }
309
310 LastPacketFull = (Endpoint_BytesInEndpoint() == USB_ControlEndpointSize);
311 Endpoint_ClearIN();
312 }
313
314 if (Endpoint_IsOUTReceived())
315 return ENDPOINT_RWCSTREAM_ERROR_HostAborted;
316
317 if (LastPacketFull || ShortTransfer)
318 {
319 while (!(Endpoint_IsINReady()));
320 Endpoint_ClearIN();
321 }
322
323 while (!(Endpoint_IsOUTReceived()));
324
325 return ENDPOINT_RWCSTREAM_ERROR_NoError;
326 }
327
328 uint8_t Endpoint_Write_Control_Stream_BE(const void* Buffer, uint16_t Length)
329 {
330 uint8_t* DataStream = (uint8_t*)(Buffer + Length - 1);
331 bool LastPacketFull = false;
332 bool ShortTransfer = (Length < USB_ControlRequest.wLength);
333
334 while (Length && !(Endpoint_IsOUTReceived()))
335 {
336 while (!(Endpoint_IsINReady()));
337
338 while (Length && (Endpoint_BytesInEndpoint() < USB_ControlEndpointSize))
339 {
340 Endpoint_Write_Byte(*(DataStream--));
341
342 Length--;
343 }
344
345 LastPacketFull = (Endpoint_BytesInEndpoint() == USB_ControlEndpointSize);
346 Endpoint_ClearIN();
347 }
348
349 if (Endpoint_IsOUTReceived())
350 return ENDPOINT_RWCSTREAM_ERROR_HostAborted;
351
352 if (LastPacketFull || ShortTransfer)
353 {
354 while (!(Endpoint_IsINReady()));
355 Endpoint_ClearIN();
356 }
357
358 while (!(Endpoint_IsOUTReceived()));
359
360 return ENDPOINT_RWCSTREAM_ERROR_NoError;
361 }
362
363 uint8_t Endpoint_Read_Control_Stream_LE(void* Buffer, uint16_t Length)
364 {
365 uint8_t* DataStream = (uint8_t*)Buffer;
366
367 while (Length)
368 {
369 while (!(Endpoint_IsOUTReceived()));
370
371 while (Length && Endpoint_BytesInEndpoint())
372 {
373 *(DataStream++) = Endpoint_Read_Byte();
374
375 Length--;
376 }
377
378 Endpoint_ClearOUT();
379 }
380
381 while (!(Endpoint_IsINReady()));
382
383 return ENDPOINT_RWCSTREAM_ERROR_NoError;
384 }
385
386 uint8_t Endpoint_Read_Control_Stream_BE(void* Buffer, uint16_t Length)
387 {
388 uint8_t* DataStream = (uint8_t*)(Buffer + Length - 1);
389
390 while (Length)
391 {
392 while (!(Endpoint_IsOUTReceived()));
393
394 while (Length && Endpoint_BytesInEndpoint())
395 {
396 *(DataStream--) = Endpoint_Read_Byte();
397
398 Length--;
399 }
400
401 Endpoint_ClearOUT();
402 }
403
404 while (!(Endpoint_IsINReady()));
405
406 return ENDPOINT_RWCSTREAM_ERROR_NoError;
407 }
408
409 #endif