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