diff options
Diffstat (limited to 'LUFA/Drivers/USB/Core/AVR8/Endpoint_AVR8.c')
-rw-r--r-- | LUFA/Drivers/USB/Core/AVR8/Endpoint_AVR8.c | 201 |
1 files changed, 201 insertions, 0 deletions
diff --git a/LUFA/Drivers/USB/Core/AVR8/Endpoint_AVR8.c b/LUFA/Drivers/USB/Core/AVR8/Endpoint_AVR8.c new file mode 100644 index 0000000000..92cf8360de --- /dev/null +++ b/LUFA/Drivers/USB/Core/AVR8/Endpoint_AVR8.c @@ -0,0 +1,201 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2017. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaims all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +#include "../../../../Common/Common.h" +#if (ARCH == ARCH_AVR8) + +#define __INCLUDE_FROM_USB_DRIVER +#include "../USBMode.h" + +#if defined(USB_CAN_BE_DEVICE) + +#include "../Endpoint.h" + +#if !defined(FIXED_CONTROL_ENDPOINT_SIZE) +uint8_t USB_Device_ControlEndpointSize = ENDPOINT_CONTROLEP_DEFAULT_SIZE; +#endif + +bool Endpoint_ConfigureEndpointTable(const USB_Endpoint_Table_t* const Table, + const uint8_t Entries) +{ + for (uint8_t i = 0; i < Entries; i++) + { + if (!(Table[i].Address)) + continue; + + if (!(Endpoint_ConfigureEndpoint(Table[i].Address, Table[i].Type, Table[i].Size, Table[i].Banks))) + return false; + } + + return true; +} + +bool Endpoint_ConfigureEndpoint_Prv(const uint8_t Number, + const uint8_t UECFG0XData, + const uint8_t UECFG1XData) +{ +#if defined(CONTROL_ONLY_DEVICE) || defined(ORDERED_EP_CONFIG) + Endpoint_SelectEndpoint(Number); + Endpoint_EnableEndpoint(); + + UECFG1X = 0; + UECFG0X = UECFG0XData; + UECFG1X = UECFG1XData; + + return Endpoint_IsConfigured(); +#else + for (uint8_t EPNum = Number; EPNum < ENDPOINT_TOTAL_ENDPOINTS; EPNum++) + { + uint8_t UECFG0XTemp; + uint8_t UECFG1XTemp; + uint8_t UEIENXTemp; + + Endpoint_SelectEndpoint(EPNum); + + if (EPNum == Number) + { + UECFG0XTemp = UECFG0XData; + UECFG1XTemp = UECFG1XData; + UEIENXTemp = 0; + } + else + { + UECFG0XTemp = UECFG0X; + UECFG1XTemp = UECFG1X; + UEIENXTemp = UEIENX; + } + + if (!(UECFG1XTemp & (1 << ALLOC))) + continue; + + Endpoint_DisableEndpoint(); + UECFG1X &= ~(1 << ALLOC); + + Endpoint_EnableEndpoint(); + UECFG0X = UECFG0XTemp; + UECFG1X = UECFG1XTemp; + UEIENX = UEIENXTemp; + + if (!(Endpoint_IsConfigured())) + return false; + } + + Endpoint_SelectEndpoint(Number); + return true; +#endif +} + +void Endpoint_ClearEndpoints(void) +{ + UEINT = 0; + + for (uint8_t EPNum = 0; EPNum < ENDPOINT_TOTAL_ENDPOINTS; EPNum++) + { + Endpoint_SelectEndpoint(EPNum); + UEIENX = 0; + UEINTX = 0; + UECFG1X = 0; + Endpoint_DisableEndpoint(); + } +} + +void Endpoint_ClearStatusStage(void) +{ + if (USB_ControlRequest.bmRequestType & REQDIR_DEVICETOHOST) + { + while (!(Endpoint_IsOUTReceived())) + { + if (USB_DeviceState == DEVICE_STATE_Unattached) + return; + } + + Endpoint_ClearOUT(); + } + else + { + while (!(Endpoint_IsINReady())) + { + if (USB_DeviceState == DEVICE_STATE_Unattached) + return; + } + + Endpoint_ClearIN(); + } +} + +#if !defined(CONTROL_ONLY_DEVICE) +uint8_t Endpoint_WaitUntilReady(void) +{ + #if (USB_STREAM_TIMEOUT_MS < 0xFF) + uint8_t TimeoutMSRem = USB_STREAM_TIMEOUT_MS; + #else + uint16_t TimeoutMSRem = USB_STREAM_TIMEOUT_MS; + #endif + + uint16_t PreviousFrameNumber = USB_Device_GetFrameNumber(); + + for (;;) + { + if (Endpoint_GetEndpointDirection() == ENDPOINT_DIR_IN) + { + if (Endpoint_IsINReady()) + return ENDPOINT_READYWAIT_NoError; + } + else + { + if (Endpoint_IsOUTReceived()) + return ENDPOINT_READYWAIT_NoError; + } + + uint8_t USB_DeviceState_LCL = USB_DeviceState; + + if (USB_DeviceState_LCL == DEVICE_STATE_Unattached) + return ENDPOINT_READYWAIT_DeviceDisconnected; + else if (USB_DeviceState_LCL == DEVICE_STATE_Suspended) + return ENDPOINT_READYWAIT_BusSuspended; + else if (Endpoint_IsStalled()) + return ENDPOINT_READYWAIT_EndpointStalled; + + uint16_t CurrentFrameNumber = USB_Device_GetFrameNumber(); + + if (CurrentFrameNumber != PreviousFrameNumber) + { + PreviousFrameNumber = CurrentFrameNumber; + + if (!(TimeoutMSRem--)) + return ENDPOINT_READYWAIT_Timeout; + } + } +} +#endif + +#endif + +#endif |