Updated changelog to reflect recent commit changes.
[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 "USBMode.h"
32 #if defined(USB_CAN_BE_DEVICE)
33
34 #define INCLUDE_FROM_ENDPOINT_C
35 #include "Endpoint.h"
36
37 #if !defined(FIXED_CONTROL_ENDPOINT_SIZE)
38 uint8_t USB_ControlEndpointSize = ENDPOINT_CONTROLEP_DEFAULT_SIZE;
39 #endif
40
41 #if !defined(STATIC_ENDPOINT_CONFIGURATION)
42 bool Endpoint_ConfigureEndpoint(const uint8_t Number, const uint8_t Type, const uint8_t Direction,
43 const uint16_t Size, const uint8_t Banks)
44 {
45 Endpoint_SelectEndpoint(Number);
46 Endpoint_EnableEndpoint();
47
48 UECFG1X = 0;
49
50 UECFG0X = ((Type << EPTYPE0) | Direction);
51 UECFG1X = ((1 << ALLOC) | Banks | Endpoint_BytesToEPSizeMask(Size));
52
53 return Endpoint_IsConfigured();
54 }
55 #else
56 bool Endpoint_ConfigureEndpointStatic(const uint8_t Number, const uint8_t UECFG0XData, const uint8_t UECFG1XData)
57 {
58 Endpoint_SelectEndpoint(Number);
59 Endpoint_EnableEndpoint();
60
61 UECFG1X = 0;
62
63 UECFG0X = UECFG0XData;
64 UECFG1X = UECFG1XData;
65
66 return Endpoint_IsConfigured();
67 }
68 #endif
69
70 void Endpoint_ClearEndpoints(void)
71 {
72 UEINT = 0;
73
74 for (uint8_t EPNum = 0; EPNum < ENDPOINT_TOTAL_ENDPOINTS; EPNum++)
75 {
76 Endpoint_SelectEndpoint(EPNum);
77 UEIENX = 0;
78 UEINTX = 0;
79 Endpoint_DeallocateMemory();
80 Endpoint_DisableEndpoint();
81 }
82 }
83
84 uint8_t Endpoint_WaitUntilReady(void)
85 {
86 uint16_t TimeoutMSRem = USB_STREAM_TIMEOUT_MS;
87
88 USB_INT_Clear(USB_INT_SOFI);
89
90 while (!(Endpoint_ReadWriteAllowed()))
91 {
92 if (!(USB_IsConnected))
93 return ENDPOINT_READYWAIT_DeviceDisconnected;
94 else if (Endpoint_IsStalled())
95 return ENDPOINT_READYWAIT_EndpointStalled;
96
97 if (USB_INT_HasOccurred(USB_INT_SOFI))
98 {
99 USB_INT_Clear(USB_INT_SOFI);
100
101 if (!(TimeoutMSRem--))
102 return ENDPOINT_READYWAIT_Timeout;
103 }
104 }
105
106 return ENDPOINT_READYWAIT_NoError;
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_ReadWriteAllowed()))
123 {
124 Endpoint_ClearCurrentBank();
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
135 Endpoint_Discard_Byte();
136 }
137
138 return ENDPOINT_RWSTREAM_ERROR_NoError;
139 }
140
141 uint8_t Endpoint_Write_Stream_LE(const void* Buffer, uint16_t Length
142 #if !defined(NO_STREAM_CALLBACKS)
143 , uint8_t (* const Callback)(void)
144 #endif
145 )
146 {
147 uint8_t* DataStream = (uint8_t*)Buffer;
148 uint8_t ErrorCode;
149
150 if ((ErrorCode = Endpoint_WaitUntilReady()))
151 return ErrorCode;
152
153 while (Length--)
154 {
155 if (!(Endpoint_ReadWriteAllowed()))
156 {
157 Endpoint_ClearCurrentBank();
158
159 #if !defined(NO_STREAM_CALLBACKS)
160 if ((Callback != NULL) && (Callback() == STREAMCALLBACK_Abort))
161 return ENDPOINT_RWSTREAM_ERROR_CallbackAborted;
162 #endif
163
164 if ((ErrorCode = Endpoint_WaitUntilReady()))
165 return ErrorCode;
166 }
167
168 Endpoint_Write_Byte(*(DataStream++));
169 }
170
171 return ENDPOINT_RWSTREAM_ERROR_NoError;
172 }
173
174 uint8_t Endpoint_Write_Stream_BE(const void* Buffer, uint16_t Length
175 #if !defined(NO_STREAM_CALLBACKS)
176 , uint8_t (* const Callback)(void)
177 #endif
178 )
179 {
180 uint8_t* DataStream = (uint8_t*)(Buffer + Length - 1);
181 uint8_t ErrorCode;
182
183 if ((ErrorCode = Endpoint_WaitUntilReady()))
184 return ErrorCode;
185
186 while (Length--)
187 {
188 if (!(Endpoint_ReadWriteAllowed()))
189 {
190 Endpoint_ClearCurrentBank();
191
192 #if !defined(NO_STREAM_CALLBACKS)
193 if ((Callback != NULL) && (Callback() == STREAMCALLBACK_Abort))
194 return ENDPOINT_RWSTREAM_ERROR_CallbackAborted;
195 #endif
196
197 if ((ErrorCode = Endpoint_WaitUntilReady()))
198 return ErrorCode;
199 }
200
201 Endpoint_Write_Byte(*(DataStream--));
202 }
203
204 return ENDPOINT_RWSTREAM_ERROR_NoError;
205 }
206
207 uint8_t Endpoint_Read_Stream_LE(void* Buffer, uint16_t Length
208 #if !defined(NO_STREAM_CALLBACKS)
209 , uint8_t (* const Callback)(void)
210 #endif
211 )
212 {
213 uint8_t* DataStream = (uint8_t*)Buffer;
214 uint8_t ErrorCode;
215
216 if ((ErrorCode = Endpoint_WaitUntilReady()))
217 return ErrorCode;
218
219 while (Length--)
220 {
221 if (!(Endpoint_ReadWriteAllowed()))
222 {
223 Endpoint_ClearCurrentBank();
224
225 #if !defined(NO_STREAM_CALLBACKS)
226 if ((Callback != NULL) && (Callback() == STREAMCALLBACK_Abort))
227 return ENDPOINT_RWSTREAM_ERROR_CallbackAborted;
228 #endif
229
230 if ((ErrorCode = Endpoint_WaitUntilReady()))
231 return ErrorCode;
232 }
233
234 *(DataStream++) = Endpoint_Read_Byte();
235 }
236
237 return ENDPOINT_RWSTREAM_ERROR_NoError;
238 }
239
240 uint8_t Endpoint_Read_Stream_BE(void* Buffer, uint16_t Length
241 #if !defined(NO_STREAM_CALLBACKS)
242 , uint8_t (* const Callback)(void)
243 #endif
244 )
245 {
246 uint8_t* DataStream = (uint8_t*)(Buffer + Length - 1);
247 uint8_t ErrorCode;
248
249 if ((ErrorCode = Endpoint_WaitUntilReady()))
250 return ErrorCode;
251
252 while (Length--)
253 {
254 if (!(Endpoint_ReadWriteAllowed()))
255 {
256 Endpoint_ClearCurrentBank();
257
258 #if !defined(NO_STREAM_CALLBACKS)
259 if ((Callback != NULL) && (Callback() == STREAMCALLBACK_Abort))
260 return ENDPOINT_RWSTREAM_ERROR_CallbackAborted;
261 #endif
262
263 if ((ErrorCode = Endpoint_WaitUntilReady()))
264 return ErrorCode;
265 }
266
267 *(DataStream--) = Endpoint_Read_Byte();
268 }
269
270 return ENDPOINT_RWSTREAM_ERROR_NoError;
271 }
272
273 uint8_t Endpoint_Write_Control_Stream_LE(const void* Buffer, uint16_t Length)
274 {
275 uint8_t* DataStream = (uint8_t*)Buffer;
276 bool SendZLP = true;
277
278 while (Length && !(Endpoint_IsSetupOUTReceived()))
279 {
280 while (!(Endpoint_IsSetupINReady()));
281
282 while (Length && (Endpoint_BytesInEndpoint() < USB_ControlEndpointSize))
283 {
284 Endpoint_Write_Byte(*(DataStream++));
285
286 Length--;
287 }
288
289 SendZLP = (Endpoint_BytesInEndpoint() == USB_ControlEndpointSize);
290 Endpoint_ClearSetupIN();
291 }
292
293 if (Endpoint_IsSetupOUTReceived())
294 return ENDPOINT_RWCSTREAM_ERROR_HostAborted;
295
296 if (SendZLP)
297 {
298 while (!(Endpoint_IsSetupINReady()));
299 Endpoint_ClearSetupIN();
300 }
301
302 while (!(Endpoint_IsSetupOUTReceived()));
303
304 return ENDPOINT_RWCSTREAM_ERROR_NoError;
305 }
306
307 uint8_t Endpoint_Write_Control_Stream_BE(const void* Buffer, uint16_t Length)
308 {
309 uint8_t* DataStream = (uint8_t*)(Buffer + Length - 1);
310 bool SendZLP = true;
311
312 while (Length && !(Endpoint_IsSetupOUTReceived()))
313 {
314 while (!(Endpoint_IsSetupINReady()));
315
316 while (Length && (Endpoint_BytesInEndpoint() < USB_ControlEndpointSize))
317 {
318 Endpoint_Write_Byte(*(DataStream--));
319
320 Length--;
321 }
322
323 SendZLP = (Endpoint_BytesInEndpoint() == USB_ControlEndpointSize);
324 Endpoint_ClearSetupIN();
325 }
326
327 if (Endpoint_IsSetupOUTReceived())
328 return ENDPOINT_RWCSTREAM_ERROR_HostAborted;
329
330 if (SendZLP)
331 {
332 while (!(Endpoint_IsSetupINReady()));
333 Endpoint_ClearSetupIN();
334 }
335
336 while (!(Endpoint_IsSetupOUTReceived()));
337
338 return ENDPOINT_RWCSTREAM_ERROR_NoError;
339 }
340
341 uint8_t Endpoint_Read_Control_Stream_LE(void* Buffer, uint16_t Length)
342 {
343 uint8_t* DataStream = (uint8_t*)Buffer;
344
345 while (Length)
346 {
347 while (!(Endpoint_IsSetupOUTReceived()));
348
349 while (Length && Endpoint_BytesInEndpoint())
350 {
351 *(DataStream++) = Endpoint_Read_Byte();
352
353 Length--;
354 }
355
356 Endpoint_ClearSetupOUT();
357 }
358
359 while (!(Endpoint_IsSetupINReady()));
360
361 return ENDPOINT_RWCSTREAM_ERROR_NoError;
362 }
363
364 uint8_t Endpoint_Read_Control_Stream_BE(void* Buffer, uint16_t Length)
365 {
366 uint8_t* DataStream = (uint8_t*)(Buffer + Length - 1);
367
368 while (Length)
369 {
370 while (!(Endpoint_IsSetupOUTReceived()));
371
372 while (Length && Endpoint_BytesInEndpoint())
373 {
374 *(DataStream--) = Endpoint_Read_Byte();
375
376 Length--;
377 }
378
379 Endpoint_ClearSetupOUT();
380 }
381
382 while (!(Endpoint_IsSetupINReady()));
383
384 return ENDPOINT_RWCSTREAM_ERROR_NoError;
385 }
386
387 #endif