diff options
author | Jack Humbert <jack.humb@gmail.com> | 2017-07-07 11:55:23 -0400 |
---|---|---|
committer | Jack Humbert <jack.humb@gmail.com> | 2017-07-07 11:55:23 -0400 |
commit | 60b30c036397cb5627fa374bb930794b225daa29 (patch) | |
tree | e156c2d6b27f01db6985f2cc560c9c345d48fdac /LUFA/Drivers/USB/Core/UC3/Endpoint_UC3.c |
Squashed 'lib/lufa/' content from commit 385d40300
git-subtree-dir: lib/lufa
git-subtree-split: 385d4030035dbaf41591309dbde47653bd03841b
Diffstat (limited to 'LUFA/Drivers/USB/Core/UC3/Endpoint_UC3.c')
-rw-r--r-- | LUFA/Drivers/USB/Core/UC3/Endpoint_UC3.c | 196 |
1 files changed, 196 insertions, 0 deletions
diff --git a/LUFA/Drivers/USB/Core/UC3/Endpoint_UC3.c b/LUFA/Drivers/USB/Core/UC3/Endpoint_UC3.c new file mode 100644 index 0000000000..7e24672c50 --- /dev/null +++ b/LUFA/Drivers/USB/Core/UC3/Endpoint_UC3.c @@ -0,0 +1,196 @@ +/* + 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_UC3) + +#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 + +volatile uint32_t USB_Endpoint_SelectedEndpoint = ENDPOINT_CONTROLEP; +volatile uint8_t* USB_Endpoint_FIFOPos[ENDPOINT_TOTAL_ENDPOINTS]; + +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 uint32_t UECFG0Data) +{ + USB_Endpoint_FIFOPos[Number] = &AVR32_USBB_SLAVE[Number * ENDPOINT_HSB_ADDRESS_SPACE_SIZE]; + +#if defined(CONTROL_ONLY_DEVICE) || defined(ORDERED_EP_CONFIG) + Endpoint_SelectEndpoint(Number); + Endpoint_EnableEndpoint(); + + (&AVR32_USBB.uecfg0)[Number] = 0; + (&AVR32_USBB.uecfg0)[Number] = UECFG0Data; + + return Endpoint_IsConfigured(); +#else + for (uint8_t EPNum = Number; EPNum < ENDPOINT_TOTAL_ENDPOINTS; EPNum++) + { + uint32_t UECFG0Temp; + + Endpoint_SelectEndpoint(EPNum); + + if (EPNum == Number) + { + UECFG0Temp = UECFG0Data; + } + else + { + UECFG0Temp = (&AVR32_USBB.uecfg0)[EPNum]; + } + + if (!(UECFG0Temp & AVR32_USBB_ALLOC_MASK)) + continue; + + Endpoint_DisableEndpoint(); + (&AVR32_USBB.uecfg0)[EPNum] &= ~AVR32_USBB_ALLOC_MASK; + + Endpoint_EnableEndpoint(); + (&AVR32_USBB.uecfg0)[EPNum] = UECFG0Temp; + + if (!(Endpoint_IsConfigured())) + return false; + } + + Endpoint_SelectEndpoint(Number); + return true; +#endif +} + +void Endpoint_ClearEndpoints(void) +{ + for (uint8_t EPNum = 0; EPNum < ENDPOINT_TOTAL_ENDPOINTS; EPNum++) + { + Endpoint_SelectEndpoint(EPNum); + (&AVR32_USBB.uecfg0)[EPNum] = 0; + (&AVR32_USBB.uecon0clr)[EPNum] = -1; + USB_Endpoint_FIFOPos[EPNum] = &AVR32_USBB_SLAVE[EPNum * 0x10000]; + 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 |