3 Copyright (C) Dean Camera, 2009.
5 dean [at] fourwalledcubicle [dot] com
6 www.fourwalledcubicle.com
10 Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
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.
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
31 #include "../HighLevel/USBMode.h"
33 #if defined(USB_CAN_BE_DEVICE)
35 #define INCLUDE_FROM_ENDPOINT_C
38 #if !defined(FIXED_CONTROL_ENDPOINT_SIZE)
39 uint8_t USB_ControlEndpointSize
= ENDPOINT_CONTROLEP_DEFAULT_SIZE
;
42 uint8_t Endpoint_BytesToEPSizeMaskDynamic(const uint16_t Size
)
44 return Endpoint_BytesToEPSizeMask(Size
);
47 bool Endpoint_ConfigureEndpoint_Prv(const uint8_t Number
, const uint8_t UECFG0XData
, const uint8_t UECFG1XData
)
49 Endpoint_SelectEndpoint(Number
);
50 Endpoint_EnableEndpoint();
54 UECFG0X
= UECFG0XData
;
55 UECFG1X
= UECFG1XData
;
57 return Endpoint_IsConfigured();
60 void Endpoint_ClearEndpoints(void)
64 for (uint8_t EPNum
= 0; EPNum
< ENDPOINT_TOTAL_ENDPOINTS
; EPNum
++)
66 Endpoint_SelectEndpoint(EPNum
);
69 Endpoint_DeallocateMemory();
70 Endpoint_DisableEndpoint();
74 #if !defined(CONTROL_ONLY_DEVICE)
75 uint8_t Endpoint_WaitUntilReady(void)
77 #if (USB_STREAM_TIMEOUT_MS < 0xFF)
78 uint8_t TimeoutMSRem
= USB_STREAM_TIMEOUT_MS
;
80 uint16_t TimeoutMSRem
= USB_STREAM_TIMEOUT_MS
;
85 if (Endpoint_GetEndpointDirection() == ENDPOINT_DIR_IN
)
87 if (Endpoint_IsINReady())
88 return ENDPOINT_READYWAIT_NoError
;
92 if (Endpoint_IsOUTReceived())
93 return ENDPOINT_READYWAIT_NoError
;
96 if (!(USB_IsConnected
))
97 return ENDPOINT_READYWAIT_DeviceDisconnected
;
98 else if (Endpoint_IsStalled())
99 return ENDPOINT_READYWAIT_EndpointStalled
;
101 if (USB_INT_HasOccurred(USB_INT_SOFI
))
103 USB_INT_Clear(USB_INT_SOFI
);
105 if (!(TimeoutMSRem
--))
106 return ENDPOINT_READYWAIT_Timeout
;
111 uint8_t Endpoint_Discard_Stream(uint16_t Length
112 #if !defined(NO_STREAM_CALLBACKS)
113 , StreamCallbackPtr_t Callback
119 if ((ErrorCode
= Endpoint_WaitUntilReady()))
122 #if defined(FAST_STREAM_TRANSFERS)
123 uint8_t BytesRemToAlignment
= (Endpoint_BytesInEndpoint() & 0x07);
127 Length
-= BytesRemToAlignment
;
129 switch (BytesRemToAlignment
)
134 if (!(Endpoint_IsReadWriteAllowed()))
138 #if !defined(NO_STREAM_CALLBACKS)
139 if ((Callback
!= NULL
) && (Callback() == STREAMCALLBACK_Abort
))
140 return ENDPOINT_RWSTREAM_CallbackAborted
;
143 if ((ErrorCode
= Endpoint_WaitUntilReady()))
149 Endpoint_Discard_Byte();
150 case 7: Endpoint_Discard_Byte();
151 case 6: Endpoint_Discard_Byte();
152 case 5: Endpoint_Discard_Byte();
153 case 4: Endpoint_Discard_Byte();
154 case 3: Endpoint_Discard_Byte();
155 case 2: Endpoint_Discard_Byte();
156 case 1: Endpoint_Discard_Byte();
157 } while (Length
>= 8);
164 if (!(Endpoint_IsReadWriteAllowed()))
168 #if !defined(NO_STREAM_CALLBACKS)
169 if ((Callback
!= NULL
) && (Callback() == STREAMCALLBACK_Abort
))
170 return ENDPOINT_RWSTREAM_CallbackAborted
;
173 if ((ErrorCode
= Endpoint_WaitUntilReady()))
178 Endpoint_Discard_Byte();
183 return ENDPOINT_RWSTREAM_NoError
;
186 uint8_t Endpoint_Write_Stream_LE(const void* Buffer
, uint16_t Length
187 #if !defined(NO_STREAM_CALLBACKS)
188 , StreamCallbackPtr_t Callback
192 uint8_t* DataStream
= (uint8_t*)Buffer
;
195 if ((ErrorCode
= Endpoint_WaitUntilReady()))
198 #if defined(FAST_STREAM_TRANSFERS)
199 uint8_t BytesRemToAlignment
= (Endpoint_BytesInEndpoint() & 0x07);
203 Length
-= BytesRemToAlignment
;
205 switch (BytesRemToAlignment
)
210 if (!(Endpoint_IsReadWriteAllowed()))
214 #if !defined(NO_STREAM_CALLBACKS)
215 if ((Callback
!= NULL
) && (Callback() == STREAMCALLBACK_Abort
))
216 return ENDPOINT_RWSTREAM_CallbackAborted
;
219 if ((ErrorCode
= Endpoint_WaitUntilReady()))
225 Endpoint_Write_Byte(*(DataStream
++));
226 case 7: Endpoint_Write_Byte(*(DataStream
++));
227 case 6: Endpoint_Write_Byte(*(DataStream
++));
228 case 5: Endpoint_Write_Byte(*(DataStream
++));
229 case 4: Endpoint_Write_Byte(*(DataStream
++));
230 case 3: Endpoint_Write_Byte(*(DataStream
++));
231 case 2: Endpoint_Write_Byte(*(DataStream
++));
232 case 1: Endpoint_Write_Byte(*(DataStream
++));
233 } while (Length
>= 8);
240 if (!(Endpoint_IsReadWriteAllowed()))
244 #if !defined(NO_STREAM_CALLBACKS)
245 if ((Callback
!= NULL
) && (Callback() == STREAMCALLBACK_Abort
))
246 return ENDPOINT_RWSTREAM_CallbackAborted
;
249 if ((ErrorCode
= Endpoint_WaitUntilReady()))
254 Endpoint_Write_Byte(*(DataStream
++));
259 return ENDPOINT_RWSTREAM_NoError
;
262 uint8_t Endpoint_Write_Stream_BE(const void* Buffer
, uint16_t Length
263 #if !defined(NO_STREAM_CALLBACKS)
264 , StreamCallbackPtr_t Callback
268 uint8_t* DataStream
= (uint8_t*)(Buffer
+ Length
- 1);
271 if ((ErrorCode
= Endpoint_WaitUntilReady()))
274 #if defined(FAST_STREAM_TRANSFERS)
275 uint8_t BytesRemToAlignment
= (Endpoint_BytesInEndpoint() & 0x07);
279 Length
-= BytesRemToAlignment
;
281 switch (BytesRemToAlignment
)
286 if (!(Endpoint_IsReadWriteAllowed()))
290 #if !defined(NO_STREAM_CALLBACKS)
291 if ((Callback
!= NULL
) && (Callback() == STREAMCALLBACK_Abort
))
292 return ENDPOINT_RWSTREAM_CallbackAborted
;
295 if ((ErrorCode
= Endpoint_WaitUntilReady()))
301 Endpoint_Write_Byte(*(DataStream
--));
302 case 7: Endpoint_Write_Byte(*(DataStream
--));
303 case 6: Endpoint_Write_Byte(*(DataStream
--));
304 case 5: Endpoint_Write_Byte(*(DataStream
--));
305 case 4: Endpoint_Write_Byte(*(DataStream
--));
306 case 3: Endpoint_Write_Byte(*(DataStream
--));
307 case 2: Endpoint_Write_Byte(*(DataStream
--));
308 case 1: Endpoint_Write_Byte(*(DataStream
--));
309 } while (Length
>= 8);
316 if (!(Endpoint_IsReadWriteAllowed()))
320 #if !defined(NO_STREAM_CALLBACKS)
321 if ((Callback
!= NULL
) && (Callback() == STREAMCALLBACK_Abort
))
322 return ENDPOINT_RWSTREAM_CallbackAborted
;
325 if ((ErrorCode
= Endpoint_WaitUntilReady()))
330 Endpoint_Write_Byte(*(DataStream
--));
335 return ENDPOINT_RWSTREAM_NoError
;
338 uint8_t Endpoint_Read_Stream_LE(void* Buffer
, uint16_t Length
339 #if !defined(NO_STREAM_CALLBACKS)
340 , StreamCallbackPtr_t Callback
344 uint8_t* DataStream
= (uint8_t*)Buffer
;
347 if ((ErrorCode
= Endpoint_WaitUntilReady()))
350 #if defined(FAST_STREAM_TRANSFERS)
351 uint8_t BytesRemToAlignment
= (Endpoint_BytesInEndpoint() & 0x07);
355 Length
-= BytesRemToAlignment
;
357 switch (BytesRemToAlignment
)
362 if (!(Endpoint_IsReadWriteAllowed()))
366 #if !defined(NO_STREAM_CALLBACKS)
367 if ((Callback
!= NULL
) && (Callback() == STREAMCALLBACK_Abort
))
368 return ENDPOINT_RWSTREAM_CallbackAborted
;
371 if ((ErrorCode
= Endpoint_WaitUntilReady()))
377 *(DataStream
++) = Endpoint_Read_Byte();
378 case 7: *(DataStream
++) = Endpoint_Read_Byte();
379 case 6: *(DataStream
++) = Endpoint_Read_Byte();
380 case 5: *(DataStream
++) = Endpoint_Read_Byte();
381 case 4: *(DataStream
++) = Endpoint_Read_Byte();
382 case 3: *(DataStream
++) = Endpoint_Read_Byte();
383 case 2: *(DataStream
++) = Endpoint_Read_Byte();
384 case 1: *(DataStream
++) = Endpoint_Read_Byte();
385 } while (Length
>= 8);
392 if (!(Endpoint_IsReadWriteAllowed()))
396 #if !defined(NO_STREAM_CALLBACKS)
397 if ((Callback
!= NULL
) && (Callback() == STREAMCALLBACK_Abort
))
398 return ENDPOINT_RWSTREAM_CallbackAborted
;
401 if ((ErrorCode
= Endpoint_WaitUntilReady()))
406 *(DataStream
++) = Endpoint_Read_Byte();
411 return ENDPOINT_RWSTREAM_NoError
;
414 uint8_t Endpoint_Read_Stream_BE(void* Buffer
, uint16_t Length
415 #if !defined(NO_STREAM_CALLBACKS)
416 , StreamCallbackPtr_t Callback
420 uint8_t* DataStream
= (uint8_t*)(Buffer
+ Length
- 1);
423 if ((ErrorCode
= Endpoint_WaitUntilReady()))
426 #if defined(FAST_STREAM_TRANSFERS)
427 uint8_t BytesRemToAlignment
= (Endpoint_BytesInEndpoint() & 0x07);
431 Length
-= BytesRemToAlignment
;
433 switch (BytesRemToAlignment
)
438 if (!(Endpoint_IsReadWriteAllowed()))
442 #if !defined(NO_STREAM_CALLBACKS)
443 if ((Callback
!= NULL
) && (Callback() == STREAMCALLBACK_Abort
))
444 return ENDPOINT_RWSTREAM_CallbackAborted
;
447 if ((ErrorCode
= Endpoint_WaitUntilReady()))
453 *(DataStream
--) = Endpoint_Read_Byte();
454 case 7: *(DataStream
--) = Endpoint_Read_Byte();
455 case 6: *(DataStream
--) = Endpoint_Read_Byte();
456 case 5: *(DataStream
--) = Endpoint_Read_Byte();
457 case 4: *(DataStream
--) = Endpoint_Read_Byte();
458 case 3: *(DataStream
--) = Endpoint_Read_Byte();
459 case 2: *(DataStream
--) = Endpoint_Read_Byte();
460 case 1: *(DataStream
--) = Endpoint_Read_Byte();
461 } while (Length
>= 8);
468 if (!(Endpoint_IsReadWriteAllowed()))
472 #if !defined(NO_STREAM_CALLBACKS)
473 if ((Callback
!= NULL
) && (Callback() == STREAMCALLBACK_Abort
))
474 return ENDPOINT_RWSTREAM_CallbackAborted
;
477 if ((ErrorCode
= Endpoint_WaitUntilReady()))
482 *(DataStream
--) = Endpoint_Read_Byte();
487 return ENDPOINT_RWSTREAM_NoError
;
491 uint8_t Endpoint_Write_Control_Stream_LE(const void* Buffer
, uint16_t Length
)
493 uint8_t* DataStream
= (uint8_t*)Buffer
;
494 bool LastPacketFull
= false;
496 if (Length
> USB_ControlRequest
.wLength
)
497 Length
= USB_ControlRequest
.wLength
;
499 while (Length
&& !(Endpoint_IsOUTReceived()))
501 while (!(Endpoint_IsINReady()));
503 while (Length
&& (Endpoint_BytesInEndpoint() < USB_ControlEndpointSize
))
505 Endpoint_Write_Byte(*(DataStream
++));
509 LastPacketFull
= (Endpoint_BytesInEndpoint() == USB_ControlEndpointSize
);
513 if (Endpoint_IsOUTReceived())
514 return ENDPOINT_RWCSTREAM_HostAborted
;
518 while (!(Endpoint_IsINReady()));
522 while (!(Endpoint_IsOUTReceived()));
524 return ENDPOINT_RWCSTREAM_NoError
;
527 uint8_t Endpoint_Write_Control_Stream_BE(const void* Buffer
, uint16_t Length
)
529 uint8_t* DataStream
= (uint8_t*)(Buffer
+ Length
- 1);
530 bool LastPacketFull
= false;
532 if (Length
> USB_ControlRequest
.wLength
)
533 Length
= USB_ControlRequest
.wLength
;
535 while (Length
&& !(Endpoint_IsOUTReceived()))
537 if (Endpoint_IsINReady())
539 while (Length
&& (Endpoint_BytesInEndpoint() < USB_ControlEndpointSize
))
541 Endpoint_Write_Byte(*(DataStream
--));
545 LastPacketFull
= (Endpoint_BytesInEndpoint() == USB_ControlEndpointSize
);
550 if (Endpoint_IsOUTReceived())
551 return ENDPOINT_RWCSTREAM_HostAborted
;
555 while (!(Endpoint_IsINReady()));
559 while (!(Endpoint_IsOUTReceived()));
561 return ENDPOINT_RWCSTREAM_NoError
;
564 uint8_t Endpoint_Read_Control_Stream_LE(void* Buffer
, uint16_t Length
)
566 uint8_t* DataStream
= (uint8_t*)Buffer
;
570 if (Endpoint_IsOUTReceived())
572 while (Length
&& Endpoint_BytesInEndpoint())
574 *(DataStream
++) = Endpoint_Read_Byte();
582 while (!(Endpoint_IsINReady()));
584 return ENDPOINT_RWCSTREAM_NoError
;
587 uint8_t Endpoint_Read_Control_Stream_BE(void* Buffer
, uint16_t Length
)
589 uint8_t* DataStream
= (uint8_t*)(Buffer
+ Length
- 1);
593 if (Endpoint_IsOUTReceived())
595 while (Length
&& Endpoint_BytesInEndpoint())
597 *(DataStream
--) = Endpoint_Read_Byte();
605 while (!(Endpoint_IsINReady()));
607 return ENDPOINT_RWCSTREAM_NoError
;