Added new XPLAIN serial Bridge project (thanks to John Steggall for the software...
[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 uint8_t Endpoint_BytesToEPSizeMaskDynamic(const uint16_t Size)
43 {
44 return Endpoint_BytesToEPSizeMask(Size);
45 }
46
47 bool Endpoint_ConfigureEndpoint_Prv(const uint8_t Number, const uint8_t UECFG0XData, const uint8_t UECFG1XData)
48 {
49 Endpoint_SelectEndpoint(Number);
50 Endpoint_EnableEndpoint();
51
52 UECFG1X = 0;
53
54 UECFG0X = UECFG0XData;
55 UECFG1X = UECFG1XData;
56
57 return Endpoint_IsConfigured();
58 }
59
60 void Endpoint_ClearEndpoints(void)
61 {
62 UEINT = 0;
63
64 for (uint8_t EPNum = 0; EPNum < ENDPOINT_TOTAL_ENDPOINTS; EPNum++)
65 {
66 Endpoint_SelectEndpoint(EPNum);
67 UEIENX = 0;
68 UEINTX = 0;
69 Endpoint_DeallocateMemory();
70 Endpoint_DisableEndpoint();
71 }
72 }
73
74 void Endpoint_ClearStatusStage(void)
75 {
76 if (USB_ControlRequest.bmRequestType & REQDIR_DEVICETOHOST)
77 {
78 while (!(Endpoint_IsOUTReceived()))
79 {
80 if (USB_DeviceState == DEVICE_STATE_Unattached)
81 return;
82 }
83
84 Endpoint_ClearOUT();
85 }
86 else
87 {
88 while (!(Endpoint_IsINReady()))
89 {
90 if (USB_DeviceState == DEVICE_STATE_Unattached)
91 return;
92 }
93
94 Endpoint_ClearIN();
95 }
96 }
97
98 #if !defined(CONTROL_ONLY_DEVICE)
99 uint8_t Endpoint_WaitUntilReady(void)
100 {
101 #if (USB_STREAM_TIMEOUT_MS < 0xFF)
102 uint8_t TimeoutMSRem = USB_STREAM_TIMEOUT_MS;
103 #else
104 uint16_t TimeoutMSRem = USB_STREAM_TIMEOUT_MS;
105 #endif
106
107 for (;;)
108 {
109 if (Endpoint_GetEndpointDirection() == ENDPOINT_DIR_IN)
110 {
111 if (Endpoint_IsINReady())
112 return ENDPOINT_READYWAIT_NoError;
113 }
114 else
115 {
116 if (Endpoint_IsOUTReceived())
117 return ENDPOINT_READYWAIT_NoError;
118 }
119
120 if (USB_DeviceState == DEVICE_STATE_Unattached)
121 return ENDPOINT_READYWAIT_DeviceDisconnected;
122 else if (Endpoint_IsStalled())
123 return ENDPOINT_READYWAIT_EndpointStalled;
124
125 if (USB_INT_HasOccurred(USB_INT_SOFI))
126 {
127 USB_INT_Clear(USB_INT_SOFI);
128
129 if (!(TimeoutMSRem--))
130 return ENDPOINT_READYWAIT_Timeout;
131 }
132 }
133 }
134
135 uint8_t Endpoint_Discard_Stream(uint16_t Length
136 #if !defined(NO_STREAM_CALLBACKS)
137 , StreamCallbackPtr_t Callback
138 #endif
139 )
140 {
141 uint8_t ErrorCode;
142
143 if ((ErrorCode = Endpoint_WaitUntilReady()))
144 return ErrorCode;
145
146 #if defined(FAST_STREAM_TRANSFERS)
147 uint8_t BytesRemToAlignment = (Endpoint_BytesInEndpoint() & 0x07);
148
149 if (Length >= 8)
150 {
151 Length -= BytesRemToAlignment;
152
153 switch (BytesRemToAlignment)
154 {
155 default:
156 do
157 {
158 if (!(Endpoint_IsReadWriteAllowed()))
159 {
160 Endpoint_ClearOUT();
161
162 #if !defined(NO_STREAM_CALLBACKS)
163 if ((Callback != NULL) && (Callback() == STREAMCALLBACK_Abort))
164 return ENDPOINT_RWSTREAM_CallbackAborted;
165 #endif
166
167 if ((ErrorCode = Endpoint_WaitUntilReady()))
168 return ErrorCode;
169 }
170
171 Length -= 8;
172
173 Endpoint_Discard_Byte();
174 case 7: Endpoint_Discard_Byte();
175 case 6: Endpoint_Discard_Byte();
176 case 5: Endpoint_Discard_Byte();
177 case 4: Endpoint_Discard_Byte();
178 case 3: Endpoint_Discard_Byte();
179 case 2: Endpoint_Discard_Byte();
180 case 1: Endpoint_Discard_Byte();
181 } while (Length >= 8);
182 }
183 }
184 #endif
185
186 while (Length)
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 else
201 {
202 Endpoint_Discard_Byte();
203 Length--;
204 }
205 }
206
207 return ENDPOINT_RWSTREAM_NoError;
208 }
209
210 #define TEMPLATE_FUNC_NAME Endpoint_Write_Stream_LE
211 #define TEMPLATE_BUFFER_TYPE const void*
212 #define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearIN()
213 #define TEMPLATE_BUFFER_OFFSET(Length) 0
214 #define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_Byte(*((uint8_t*)BufferPtr++))
215 #include "Template/Template_Endpoint_RW.c"
216
217 #define TEMPLATE_FUNC_NAME Endpoint_Write_PStream_LE
218 #define TEMPLATE_BUFFER_TYPE const void*
219 #define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearIN()
220 #define TEMPLATE_BUFFER_OFFSET(Length) 0
221 #define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_Byte(pgm_read_byte((uint8_t*)BufferPtr++))
222 #include "Template/Template_Endpoint_RW.c"
223
224 #define TEMPLATE_FUNC_NAME Endpoint_Write_EStream_LE
225 #define TEMPLATE_BUFFER_TYPE const void*
226 #define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearIN()
227 #define TEMPLATE_BUFFER_OFFSET(Length) 0
228 #define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_Byte(eeprom_read_byte((uint8_t*)BufferPtr++))
229 #include "Template/Template_Endpoint_RW.c"
230
231 #define TEMPLATE_FUNC_NAME Endpoint_Write_Stream_BE
232 #define TEMPLATE_BUFFER_TYPE const void*
233 #define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearIN()
234 #define TEMPLATE_BUFFER_OFFSET(Length) Length - 1
235 #define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_Byte(*((uint8_t*)BufferPtr--))
236 #include "Template/Template_Endpoint_RW.c"
237
238 #define TEMPLATE_FUNC_NAME Endpoint_Write_EStream_BE
239 #define TEMPLATE_BUFFER_TYPE const void*
240 #define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearIN()
241 #define TEMPLATE_BUFFER_OFFSET(Length) Length - 1
242 #define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_Byte(eeprom_read_byte((uint8_t*)BufferPtr--))
243 #include "Template/Template_Endpoint_RW.c"
244
245 #define TEMPLATE_FUNC_NAME Endpoint_Write_PStream_BE
246 #define TEMPLATE_BUFFER_TYPE const void*
247 #define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearIN()
248 #define TEMPLATE_BUFFER_OFFSET(Length) Length - 1
249 #define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_Byte(pgm_read_byte((uint8_t*)BufferPtr--))
250 #include "Template/Template_Endpoint_RW.c"
251
252 #define TEMPLATE_FUNC_NAME Endpoint_Read_Stream_LE
253 #define TEMPLATE_BUFFER_TYPE void*
254 #define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearOUT()
255 #define TEMPLATE_BUFFER_OFFSET(Length) 0
256 #define TEMPLATE_TRANSFER_BYTE(BufferPtr) *((uint8_t*)BufferPtr++) = Endpoint_Read_Byte()
257 #include "Template/Template_Endpoint_RW.c"
258
259 #define TEMPLATE_FUNC_NAME Endpoint_Read_EStream_LE
260 #define TEMPLATE_BUFFER_TYPE void*
261 #define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearOUT()
262 #define TEMPLATE_BUFFER_OFFSET(Length) 0
263 #define TEMPLATE_TRANSFER_BYTE(BufferPtr) eeprom_write_byte((uint8_t*)BufferPtr++, Endpoint_Read_Byte())
264 #include "Template/Template_Endpoint_RW.c"
265
266 #define TEMPLATE_FUNC_NAME Endpoint_Read_Stream_BE
267 #define TEMPLATE_BUFFER_TYPE void*
268 #define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearOUT()
269 #define TEMPLATE_BUFFER_OFFSET(Length) Length - 1
270 #define TEMPLATE_TRANSFER_BYTE(BufferPtr) *((uint8_t*)BufferPtr--) = Endpoint_Read_Byte()
271 #include "Template/Template_Endpoint_RW.c"
272
273 #define TEMPLATE_FUNC_NAME Endpoint_Read_EStream_BE
274 #define TEMPLATE_BUFFER_TYPE void*
275 #define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearOUT()
276 #define TEMPLATE_BUFFER_OFFSET(Length) Length - 1
277 #define TEMPLATE_TRANSFER_BYTE(BufferPtr) eeprom_write_byte((uint8_t*)BufferPtr--, Endpoint_Read_Byte())
278 #include "Template/Template_Endpoint_RW.c"
279
280 #endif
281
282 #define TEMPLATE_FUNC_NAME Endpoint_Write_Control_Stream_LE
283 #define TEMPLATE_BUFFER_OFFSET(Length) 0
284 #define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_Byte(*((uint8_t*)BufferPtr++))
285 #include "Template/Template_Endpoint_Control_W.c"
286
287 #define TEMPLATE_FUNC_NAME Endpoint_Write_Control_PStream_LE
288 #define TEMPLATE_BUFFER_OFFSET(Length) 0
289 #define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_Byte(pgm_read_byte((uint8_t*)BufferPtr++))
290 #include "Template/Template_Endpoint_Control_W.c"
291
292 #define TEMPLATE_FUNC_NAME Endpoint_Write_Control_EStream_LE
293 #define TEMPLATE_BUFFER_OFFSET(Length) 0
294 #define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_Byte(eeprom_read_byte((uint8_t*)BufferPtr++))
295 #include "Template/Template_Endpoint_Control_W.c"
296
297 #define TEMPLATE_FUNC_NAME Endpoint_Write_Control_Stream_BE
298 #define TEMPLATE_BUFFER_OFFSET(Length) Length - 1
299 #define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_Byte(*((uint8_t*)BufferPtr--))
300 #include "Template/Template_Endpoint_Control_W.c"
301
302 #define TEMPLATE_FUNC_NAME Endpoint_Write_Control_PStream_BE
303 #define TEMPLATE_BUFFER_OFFSET(Length) Length - 1
304 #define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_Byte(pgm_read_byte((uint8_t*)BufferPtr--))
305 #include "Template/Template_Endpoint_Control_W.c"
306
307 #define TEMPLATE_FUNC_NAME Endpoint_Write_Control_EStream_BE
308 #define TEMPLATE_BUFFER_OFFSET(Length) Length - 1
309 #define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_Byte(eeprom_read_byte((uint8_t*)BufferPtr--))
310 #include "Template/Template_Endpoint_Control_W.c"
311
312 #define TEMPLATE_FUNC_NAME Endpoint_Read_Control_Stream_LE
313 #define TEMPLATE_BUFFER_OFFSET(Length) 0
314 #define TEMPLATE_TRANSFER_BYTE(BufferPtr) *((uint8_t*)BufferPtr++) = Endpoint_Read_Byte()
315 #include "Template/Template_Endpoint_Control_R.c"
316
317 #define TEMPLATE_FUNC_NAME Endpoint_Read_Control_EStream_LE
318 #define TEMPLATE_BUFFER_OFFSET(Length) 0
319 #define TEMPLATE_TRANSFER_BYTE(BufferPtr) eeprom_write_byte((uint8_t*)BufferPtr++, Endpoint_Read_Byte())
320 #include "Template/Template_Endpoint_Control_R.c"
321
322 #define TEMPLATE_FUNC_NAME Endpoint_Read_Control_Stream_BE
323 #define TEMPLATE_BUFFER_OFFSET(Length) Length - 1
324 #define TEMPLATE_TRANSFER_BYTE(BufferPtr) *((uint8_t*)BufferPtr--) = Endpoint_Read_Byte()
325 #include "Template/Template_Endpoint_Control_R.c"
326
327 #define TEMPLATE_FUNC_NAME Endpoint_Read_Control_EStream_BE
328 #define TEMPLATE_BUFFER_OFFSET(Length) Length - 1
329 #define TEMPLATE_TRANSFER_BYTE(BufferPtr) eeprom_write_byte((uint8_t*)BufferPtr--, Endpoint_Read_Byte())
330 #include "Template/Template_Endpoint_Control_R.c"
331
332 #endif