Changed all Device mode LowLevel demos and Device Class drivers so that the control...
[pub/USBasp.git] / LUFA / Drivers / USB / LowLevel / Endpoint.c
1 /*
2 LUFA Library
3 Copyright (C) Dean Camera, 2010.
4
5 dean [at] fourwalledcubicle [dot] com
6 www.fourwalledcubicle.com
7 */
8
9 /*
10 Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
11
12 Permission to use, copy, modify, distribute, and sell this
13 software and its documentation for any purpose is hereby granted
14 without fee, provided that the above copyright notice appear in
15 all 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 #define __INCLUDE_FROM_USB_DRIVER
32 #include "../HighLevel/USBMode.h"
33
34 #if defined(USB_CAN_BE_DEVICE)
35
36 #define __INCLUDE_FROM_ENDPOINT_C
37 #include "Endpoint.h"
38
39 #if !defined(FIXED_CONTROL_ENDPOINT_SIZE)
40 uint8_t USB_ControlEndpointSize = ENDPOINT_CONTROLEP_DEFAULT_SIZE;
41 #endif
42
43 bool Endpoint_ConfigureEndpoint_Prv(const uint8_t Number,
44 const uint8_t UECFG0XData,
45 const uint8_t UECFG1XData)
46 {
47 uint8_t UECFG0XTemp[ENDPOINT_TOTAL_ENDPOINTS];
48 uint8_t UECFG1XTemp[ENDPOINT_TOTAL_ENDPOINTS];
49
50 for (uint8_t EPNum = 0; EPNum < ENDPOINT_TOTAL_ENDPOINTS; EPNum++)
51 {
52 Endpoint_SelectEndpoint(EPNum);
53 UECFG0XTemp[EPNum] = UECFG0X;
54 UECFG1XTemp[EPNum] = UECFG1X;
55 }
56
57 UECFG0XTemp[Number] = UECFG0XData;
58 UECFG1XTemp[Number] = UECFG1XData;
59
60 for (uint8_t EPNum = 1; EPNum < ENDPOINT_TOTAL_ENDPOINTS; EPNum++)
61 {
62 Endpoint_SelectEndpoint(EPNum);
63 UEIENX = 0;
64 UEINTX = 0;
65 UECFG1X = 0;
66 Endpoint_DisableEndpoint();
67 }
68
69 for (uint8_t EPNum = 0; EPNum < ENDPOINT_TOTAL_ENDPOINTS; EPNum++)
70 {
71 if (!(UECFG1XTemp[EPNum] & (1 << ALLOC)))
72 continue;
73
74 Endpoint_SelectEndpoint(EPNum);
75 Endpoint_EnableEndpoint();
76
77 UECFG0X = UECFG0XTemp[EPNum];
78 UECFG1X = UECFG1XTemp[EPNum];
79
80 if (!(Endpoint_IsConfigured()))
81 return false;
82 }
83
84 Endpoint_SelectEndpoint(Number);
85 return true;
86 }
87
88 void Endpoint_ClearEndpoints(void)
89 {
90 UEINT = 0;
91
92 for (uint8_t EPNum = 0; EPNum < ENDPOINT_TOTAL_ENDPOINTS; EPNum++)
93 {
94 Endpoint_SelectEndpoint(EPNum);
95 UEIENX = 0;
96 UEINTX = 0;
97 UECFG1X = 0;
98 Endpoint_DisableEndpoint();
99 }
100 }
101
102 void Endpoint_ClearStatusStage(void)
103 {
104 if (USB_ControlRequest.bmRequestType & REQDIR_DEVICETOHOST)
105 {
106 while (!(Endpoint_IsOUTReceived()))
107 {
108 if (USB_DeviceState == DEVICE_STATE_Unattached)
109 return;
110 }
111
112 Endpoint_ClearOUT();
113 }
114 else
115 {
116 while (!(Endpoint_IsINReady()))
117 {
118 if (USB_DeviceState == DEVICE_STATE_Unattached)
119 return;
120 }
121
122 Endpoint_ClearIN();
123 }
124 }
125
126 #if !defined(CONTROL_ONLY_DEVICE)
127 uint8_t Endpoint_WaitUntilReady(void)
128 {
129 #if (USB_STREAM_TIMEOUT_MS < 0xFF)
130 uint8_t TimeoutMSRem = USB_STREAM_TIMEOUT_MS;
131 #else
132 uint16_t TimeoutMSRem = USB_STREAM_TIMEOUT_MS;
133 #endif
134
135 for (;;)
136 {
137 if (Endpoint_GetEndpointDirection() == ENDPOINT_DIR_IN)
138 {
139 if (Endpoint_IsINReady())
140 return ENDPOINT_READYWAIT_NoError;
141 }
142 else
143 {
144 if (Endpoint_IsOUTReceived())
145 return ENDPOINT_READYWAIT_NoError;
146 }
147
148 if (USB_DeviceState == DEVICE_STATE_Unattached)
149 return ENDPOINT_READYWAIT_DeviceDisconnected;
150 else if (USB_DeviceState == DEVICE_STATE_Suspended)
151 return ENDPOINT_READYWAIT_BusSuspended;
152 else if (Endpoint_IsStalled())
153 return ENDPOINT_READYWAIT_EndpointStalled;
154
155 if (USB_INT_HasOccurred(USB_INT_SOFI))
156 {
157 USB_INT_Clear(USB_INT_SOFI);
158
159 if (!(TimeoutMSRem--))
160 return ENDPOINT_READYWAIT_Timeout;
161 }
162 }
163 }
164
165 uint8_t Endpoint_Discard_Stream(uint16_t Length
166 #if !defined(NO_STREAM_CALLBACKS)
167 , StreamCallbackPtr_t Callback
168 #endif
169 )
170 {
171 uint8_t ErrorCode;
172
173 if ((ErrorCode = Endpoint_WaitUntilReady()))
174 return ErrorCode;
175
176 #if defined(FAST_STREAM_TRANSFERS)
177 uint8_t BytesRemToAlignment = (Endpoint_BytesInEndpoint() & 0x07);
178
179 if (Length >= 8)
180 {
181 Length -= BytesRemToAlignment;
182
183 switch (BytesRemToAlignment)
184 {
185 default:
186 do
187 {
188 if (!(Endpoint_IsReadWriteAllowed()))
189 {
190 Endpoint_ClearOUT();
191
192 #if !defined(NO_STREAM_CALLBACKS)
193 if ((Callback != NULL) && (Callback() == STREAMCALLBACK_Abort))
194 return ENDPOINT_RWSTREAM_CallbackAborted;
195 #endif
196
197 if ((ErrorCode = Endpoint_WaitUntilReady()))
198 return ErrorCode;
199 }
200
201 Length -= 8;
202
203 Endpoint_Discard_Byte();
204 case 7: Endpoint_Discard_Byte();
205 case 6: Endpoint_Discard_Byte();
206 case 5: Endpoint_Discard_Byte();
207 case 4: Endpoint_Discard_Byte();
208 case 3: Endpoint_Discard_Byte();
209 case 2: Endpoint_Discard_Byte();
210 case 1: Endpoint_Discard_Byte();
211 } while (Length >= 8);
212 }
213 }
214 #endif
215
216 while (Length)
217 {
218 if (!(Endpoint_IsReadWriteAllowed()))
219 {
220 Endpoint_ClearOUT();
221
222 #if !defined(NO_STREAM_CALLBACKS)
223 if ((Callback != NULL) && (Callback() == STREAMCALLBACK_Abort))
224 return ENDPOINT_RWSTREAM_CallbackAborted;
225 #endif
226
227 if ((ErrorCode = Endpoint_WaitUntilReady()))
228 return ErrorCode;
229 }
230 else
231 {
232 Endpoint_Discard_Byte();
233 Length--;
234 }
235 }
236
237 return ENDPOINT_RWSTREAM_NoError;
238 }
239
240 /* The following abuses the C preprocessor in order to copy-past common code with slight alterations,
241 * so that the code needs to be written once. It is a crude form of templating to reduce code maintenance. */
242
243 #define TEMPLATE_FUNC_NAME Endpoint_Write_Stream_LE
244 #define TEMPLATE_BUFFER_TYPE const void*
245 #define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearIN()
246 #define TEMPLATE_BUFFER_OFFSET(Length) 0
247 #define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_Byte(*((uint8_t*)BufferPtr++))
248 #include "Template/Template_Endpoint_RW.c"
249
250 #define TEMPLATE_FUNC_NAME Endpoint_Write_PStream_LE
251 #define TEMPLATE_BUFFER_TYPE const void*
252 #define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearIN()
253 #define TEMPLATE_BUFFER_OFFSET(Length) 0
254 #define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_Byte(pgm_read_byte((uint8_t*)BufferPtr++))
255 #include "Template/Template_Endpoint_RW.c"
256
257 #define TEMPLATE_FUNC_NAME Endpoint_Write_EStream_LE
258 #define TEMPLATE_BUFFER_TYPE const void*
259 #define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearIN()
260 #define TEMPLATE_BUFFER_OFFSET(Length) 0
261 #define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_Byte(eeprom_read_byte((uint8_t*)BufferPtr++))
262 #include "Template/Template_Endpoint_RW.c"
263
264 #define TEMPLATE_FUNC_NAME Endpoint_Write_Stream_BE
265 #define TEMPLATE_BUFFER_TYPE const void*
266 #define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearIN()
267 #define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1)
268 #define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_Byte(*((uint8_t*)BufferPtr--))
269 #include "Template/Template_Endpoint_RW.c"
270
271 #define TEMPLATE_FUNC_NAME Endpoint_Write_EStream_BE
272 #define TEMPLATE_BUFFER_TYPE const void*
273 #define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearIN()
274 #define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1)
275 #define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_Byte(eeprom_read_byte((uint8_t*)BufferPtr--))
276 #include "Template/Template_Endpoint_RW.c"
277
278 #define TEMPLATE_FUNC_NAME Endpoint_Write_PStream_BE
279 #define TEMPLATE_BUFFER_TYPE const void*
280 #define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearIN()
281 #define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1)
282 #define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_Byte(pgm_read_byte((uint8_t*)BufferPtr--))
283 #include "Template/Template_Endpoint_RW.c"
284
285 #define TEMPLATE_FUNC_NAME Endpoint_Read_Stream_LE
286 #define TEMPLATE_BUFFER_TYPE void*
287 #define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearOUT()
288 #define TEMPLATE_BUFFER_OFFSET(Length) 0
289 #define TEMPLATE_TRANSFER_BYTE(BufferPtr) *((uint8_t*)BufferPtr++) = Endpoint_Read_Byte()
290 #include "Template/Template_Endpoint_RW.c"
291
292 #define TEMPLATE_FUNC_NAME Endpoint_Read_EStream_LE
293 #define TEMPLATE_BUFFER_TYPE void*
294 #define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearOUT()
295 #define TEMPLATE_BUFFER_OFFSET(Length) 0
296 #define TEMPLATE_TRANSFER_BYTE(BufferPtr) eeprom_update_byte((uint8_t*)BufferPtr++, Endpoint_Read_Byte())
297 #include "Template/Template_Endpoint_RW.c"
298
299 #define TEMPLATE_FUNC_NAME Endpoint_Read_Stream_BE
300 #define TEMPLATE_BUFFER_TYPE void*
301 #define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearOUT()
302 #define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1)
303 #define TEMPLATE_TRANSFER_BYTE(BufferPtr) *((uint8_t*)BufferPtr--) = Endpoint_Read_Byte()
304 #include "Template/Template_Endpoint_RW.c"
305
306 #define TEMPLATE_FUNC_NAME Endpoint_Read_EStream_BE
307 #define TEMPLATE_BUFFER_TYPE void*
308 #define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearOUT()
309 #define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1)
310 #define TEMPLATE_TRANSFER_BYTE(BufferPtr) eeprom_update_byte((uint8_t*)BufferPtr--, Endpoint_Read_Byte())
311 #include "Template/Template_Endpoint_RW.c"
312
313 #endif
314
315 #define TEMPLATE_FUNC_NAME Endpoint_Write_Control_Stream_LE
316 #define TEMPLATE_BUFFER_OFFSET(Length) 0
317 #define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_Byte(*((uint8_t*)BufferPtr++))
318 #include "Template/Template_Endpoint_Control_W.c"
319
320 #define TEMPLATE_FUNC_NAME Endpoint_Write_Control_PStream_LE
321 #define TEMPLATE_BUFFER_OFFSET(Length) 0
322 #define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_Byte(pgm_read_byte((uint8_t*)BufferPtr++))
323 #include "Template/Template_Endpoint_Control_W.c"
324
325 #define TEMPLATE_FUNC_NAME Endpoint_Write_Control_EStream_LE
326 #define TEMPLATE_BUFFER_OFFSET(Length) 0
327 #define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_Byte(eeprom_read_byte((uint8_t*)BufferPtr++))
328 #include "Template/Template_Endpoint_Control_W.c"
329
330 #define TEMPLATE_FUNC_NAME Endpoint_Write_Control_Stream_BE
331 #define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1)
332 #define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_Byte(*((uint8_t*)BufferPtr--))
333 #include "Template/Template_Endpoint_Control_W.c"
334
335 #define TEMPLATE_FUNC_NAME Endpoint_Write_Control_PStream_BE
336 #define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1)
337 #define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_Byte(pgm_read_byte((uint8_t*)BufferPtr--))
338 #include "Template/Template_Endpoint_Control_W.c"
339
340 #define TEMPLATE_FUNC_NAME Endpoint_Write_Control_EStream_BE
341 #define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1)
342 #define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_Byte(eeprom_read_byte((uint8_t*)BufferPtr--))
343 #include "Template/Template_Endpoint_Control_W.c"
344
345 #define TEMPLATE_FUNC_NAME Endpoint_Read_Control_Stream_LE
346 #define TEMPLATE_BUFFER_OFFSET(Length) 0
347 #define TEMPLATE_TRANSFER_BYTE(BufferPtr) *((uint8_t*)BufferPtr++) = Endpoint_Read_Byte()
348 #include "Template/Template_Endpoint_Control_R.c"
349
350 #define TEMPLATE_FUNC_NAME Endpoint_Read_Control_EStream_LE
351 #define TEMPLATE_BUFFER_OFFSET(Length) 0
352 #define TEMPLATE_TRANSFER_BYTE(BufferPtr) eeprom_update_byte((uint8_t*)BufferPtr++, Endpoint_Read_Byte())
353 #include "Template/Template_Endpoint_Control_R.c"
354
355 #define TEMPLATE_FUNC_NAME Endpoint_Read_Control_Stream_BE
356 #define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1)
357 #define TEMPLATE_TRANSFER_BYTE(BufferPtr) *((uint8_t*)BufferPtr--) = Endpoint_Read_Byte()
358 #include "Template/Template_Endpoint_Control_R.c"
359
360 #define TEMPLATE_FUNC_NAME Endpoint_Read_Control_EStream_BE
361 #define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1)
362 #define TEMPLATE_TRANSFER_BYTE(BufferPtr) eeprom_update_byte((uint8_t*)BufferPtr--, Endpoint_Read_Byte())
363 #include "Template/Template_Endpoint_Control_R.c"
364
365 #endif