From ec537fd84d6ad3fd0dfa1b55efa2c2d554c1db48 Mon Sep 17 00:00:00 2001 From: Dean Camera Date: Fri, 24 Dec 2010 17:05:41 +0000 Subject: Re-add in old Endpoint/Pipe workaround for unordered pipes - add new ORDERED_EP_CONFIG compile time option to override the workaround and use the previous behaviour that imposes correct Endpoint/Pipe ordering but produces smaller compiled code. --- LUFA/Drivers/USB/LowLevel/Endpoint.c | 46 ++++++++++++++++++++++++ LUFA/Drivers/USB/LowLevel/Endpoint.h | 3 +- LUFA/Drivers/USB/LowLevel/Pipe.c | 58 +++++++++++++++++++++++++++++++ LUFA/Drivers/USB/LowLevel/Pipe.h | 3 +- LUFA/Drivers/USB/LowLevel/USBController.c | 1 + LUFA/ManPages/ChangeLog.txt | 3 ++ LUFA/ManPages/CompileTimeTokens.txt | 5 +++ LUFA/ManPages/FutureChanges.txt | 1 + LUFA/ManPages/MigrationInformation.txt | 6 +++- 9 files changed, 123 insertions(+), 3 deletions(-) (limited to 'LUFA') diff --git a/LUFA/Drivers/USB/LowLevel/Endpoint.c b/LUFA/Drivers/USB/LowLevel/Endpoint.c index a7b1e4b58..56c73fc48 100644 --- a/LUFA/Drivers/USB/LowLevel/Endpoint.c +++ b/LUFA/Drivers/USB/LowLevel/Endpoint.c @@ -43,6 +43,7 @@ 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(); @@ -51,6 +52,51 @@ bool Endpoint_ConfigureEndpoint_Prv(const uint8_t Number, UECFG1X = UECFG1XData; return Endpoint_IsConfigured(); +#else + uint8_t UECFG0XTemp[ENDPOINT_TOTAL_ENDPOINTS]; + uint8_t UECFG1XTemp[ENDPOINT_TOTAL_ENDPOINTS]; + uint8_t UEIENXTemp[ENDPOINT_TOTAL_ENDPOINTS]; + + for (uint8_t EPNum = 0; EPNum < ENDPOINT_TOTAL_ENDPOINTS; EPNum++) + { + Endpoint_SelectEndpoint(EPNum); + UECFG0XTemp[EPNum] = UECFG0X; + UECFG1XTemp[EPNum] = UECFG1X; + UEIENXTemp[EPNum] = UEIENX; + } + + UECFG0XTemp[Number] = UECFG0XData; + UECFG1XTemp[Number] = UECFG1XData; + UEIENXTemp[Number] = 0; + + for (uint8_t EPNum = 1; EPNum < ENDPOINT_TOTAL_ENDPOINTS; EPNum++) + { + Endpoint_SelectEndpoint(EPNum); + UEIENX = 0; + UEINTX = 0; + UECFG1X = 0; + Endpoint_DisableEndpoint(); + } + + for (uint8_t EPNum = 0; EPNum < ENDPOINT_TOTAL_ENDPOINTS; EPNum++) + { + if (!(UECFG1XTemp[EPNum] & (1 << ALLOC))) + continue; + + Endpoint_SelectEndpoint(EPNum); + Endpoint_EnableEndpoint(); + + UECFG0X = UECFG0XTemp[EPNum]; + UECFG1X = UECFG1XTemp[EPNum]; + UEIENX = UEIENXTemp[EPNum]; + + if (!(Endpoint_IsConfigured())) + return false; + } + + Endpoint_SelectEndpoint(Number); + return true; +#endif } void Endpoint_ClearEndpoints(void) diff --git a/LUFA/Drivers/USB/LowLevel/Endpoint.h b/LUFA/Drivers/USB/LowLevel/Endpoint.h index ea2e8cc53..c8f9cbfd5 100644 --- a/LUFA/Drivers/USB/LowLevel/Endpoint.h +++ b/LUFA/Drivers/USB/LowLevel/Endpoint.h @@ -273,7 +273,8 @@ * More banks uses more USB DPRAM, but offers better performance. Isochronous type * endpoints must have at least two banks. * - * \note Endpoints must be configured in ascending order, or bank corruption will occur. + * \note When the ORDERED_EP_CONFIG compile time option is used, Endpoints must be configured in ascending + * order, or bank corruption will occur. * \n\n * * \note Certain models of USB AVR's endpoints may have different maximum packet sizes based on the endpoint's diff --git a/LUFA/Drivers/USB/LowLevel/Pipe.c b/LUFA/Drivers/USB/LowLevel/Pipe.c index 3656be20f..fc50060be 100644 --- a/LUFA/Drivers/USB/LowLevel/Pipe.c +++ b/LUFA/Drivers/USB/LowLevel/Pipe.c @@ -44,6 +44,7 @@ bool Pipe_ConfigurePipe(const uint8_t Number, const uint16_t Size, const uint8_t Banks) { +#if defined(ORDERED_EP_CONFIG) Pipe_SelectPipe(Number); Pipe_EnablePipe(); @@ -55,6 +56,63 @@ bool Pipe_ConfigurePipe(const uint8_t Number, Pipe_SetInfiniteINRequests(); return Pipe_IsConfigured(); +#else + uint8_t UPCFG0XTemp[PIPE_TOTAL_PIPES]; + uint8_t UPCFG1XTemp[PIPE_TOTAL_PIPES]; + uint8_t UPCFG2XTemp[PIPE_TOTAL_PIPES]; + uint8_t UPCONXTemp[PIPE_TOTAL_PIPES]; + uint8_t UPINRQXTemp[PIPE_TOTAL_PIPES]; + uint8_t UPIENXTemp[PIPE_TOTAL_PIPES]; + + for (uint8_t PNum = 0; PNum < PIPE_TOTAL_PIPES; PNum++) + { + Pipe_SelectPipe(PNum); + UPCFG0XTemp[PNum] = UPCFG0X; + UPCFG1XTemp[PNum] = UPCFG1X; + UPCFG2XTemp[PNum] = UPCFG2X; + UPCONXTemp[PNum] = UPCONX; + UPINRQXTemp[PNum] = UPINRQX; + UPIENXTemp[PNum] = UPIENX; + } + + UPCFG0XTemp[Number] = ((Type << EPTYPE0) | Token | ((EndpointNumber & PIPE_EPNUM_MASK) << PEPNUM0)); + UPCFG1XTemp[Number] = ((1 << ALLOC) | Banks | Pipe_BytesToEPSizeMask(Size)); + UPCFG2XTemp[Number] = 0; + UPCONXTemp[Number] = (1 << INMODE); + UPINRQXTemp[Number] = 0; + UPIENXTemp[Number] = 0; + + for (uint8_t PNum = 0; PNum < PIPE_TOTAL_PIPES; PNum++) + { + Pipe_SelectPipe(PNum); + UPIENX = 0; + UPINTX = 0; + UPCFG1X = 0; + Pipe_DisablePipe(); + } + + for (uint8_t PNum = 0; PNum < PIPE_TOTAL_PIPES; PNum++) + { + if (!(UPCFG1XTemp[PNum] & (1 << ALLOC))) + continue; + + Pipe_SelectPipe(PNum); + Pipe_EnablePipe(); + + UPCFG0X = UPCFG0XTemp[PNum]; + UPCFG1X = UPCFG1XTemp[PNum]; + UPCFG2X = UPCFG2XTemp[PNum]; + UPCONX |= UPCONXTemp[PNum]; + UPINRQX = UPINRQXTemp[PNum]; + UPIENX = UPIENXTemp[PNum]; + + if (!(Pipe_IsConfigured())) + return false; + } + + Pipe_SelectPipe(Number); + return true; +#endif } void Pipe_ClearPipes(void) diff --git a/LUFA/Drivers/USB/LowLevel/Pipe.h b/LUFA/Drivers/USB/LowLevel/Pipe.h index 0e877f623..f415189c2 100644 --- a/LUFA/Drivers/USB/LowLevel/Pipe.h +++ b/LUFA/Drivers/USB/LowLevel/Pipe.h @@ -861,7 +861,8 @@ * uses more USB DPRAM, but offers better performance. Isochronous type pipes must * have at least two banks. * - * \note Endpoints must be configured in ascending order, or bank corruption will occur. + * \note When the ORDERED_EP_CONFIG compile time option is used, Pipes must be configured in ascending order, + * or bank corruption will occur. * \n\n * * \note Certain models of USB AVR's pipes may have different maximum packet sizes based on the pipe's diff --git a/LUFA/Drivers/USB/LowLevel/USBController.c b/LUFA/Drivers/USB/LowLevel/USBController.c index fc5725675..f778d66bf 100644 --- a/LUFA/Drivers/USB/LowLevel/USBController.c +++ b/LUFA/Drivers/USB/LowLevel/USBController.c @@ -152,6 +152,7 @@ void USB_ResetInterface(void) { #if defined(USB_CAN_BE_HOST) UHWCON &= ~(1 << UIMOD); + USB_Init_Host(); #endif } diff --git a/LUFA/ManPages/ChangeLog.txt b/LUFA/ManPages/ChangeLog.txt index 34e772d63..1bce5faba 100644 --- a/LUFA/ManPages/ChangeLog.txt +++ b/LUFA/ManPages/ChangeLog.txt @@ -10,6 +10,8 @@ * New: * - Core: * - Added new MIDIToneGenerator project + * - Added new ORDERED_EP_CONFIG compile time option to restrict endpoint/pipe configuration to ascending order + * in exchange for a smaller compiled program binary size * - Library Applications: * - Added new incomplete MIDIToneGenerator project * - Added ability to write protect Mass Storage disk write operations from the host OS @@ -17,6 +19,7 @@ * * Changed: * - Core: + * - Unordered Endpoint/Pipe configuration is now allowed once again via the previous reconfig workaround * - Refactored Host mode Class Driver *_Host_ConfigurePipes() routines to be more space efficient when compiled * - Added new *_ENUMERROR_PipeConfigurationFailed error codes for the *_Host_ConfigurePipes() routines * - Library Applications: diff --git a/LUFA/ManPages/CompileTimeTokens.txt b/LUFA/ManPages/CompileTimeTokens.txt index 28b7cfc6b..b120617e0 100644 --- a/LUFA/ManPages/CompileTimeTokens.txt +++ b/LUFA/ManPages/CompileTimeTokens.txt @@ -77,6 +77,11 @@ * \section Sec_SummaryUSBTokens General USB Driver Related Tokens * This section describes compile tokens which affect USB driver stack as a whole in the LUFA library. * + * ORDERED_EP_CONFIG - ( \ref Group_EndpointManagement , \ref Group_PipeManagement )\n + * The USB AVRs do not allow for Endpoints and Pipes to be configured out of order; they must be configured in an ascending order to + * prevent data corruption issues. However, by default LUFA employs a workaround to allow for unordered Endpoint/Pipe initialisation. This compile + * time token may be used to restrict the intialisation order to ascending indexes only in exchange for a smaller compiled binary size. + * * NO_STREAM_CALLBACKS - ( \ref Group_EndpointPacketManagement , \ref Group_PipePacketManagement )\n * Both the endpoint and the pipe driver code contains stream functions, allowing for arrays of data to be sent to or from the * host easily via a single function call (rather than complex routines worrying about sending full packets, waiting for the endpoint/ diff --git a/LUFA/ManPages/FutureChanges.txt b/LUFA/ManPages/FutureChanges.txt index 7ae15aa0b..bfa5a530f 100644 --- a/LUFA/ManPages/FutureChanges.txt +++ b/LUFA/ManPages/FutureChanges.txt @@ -20,6 +20,7 @@ * -# Re-add interrupt Pipe/Endpoint support * -# Add HID report macros to make HID report editing easier * -# Investigate dynamically created device descriptors + * -# Check if ALL the workaround reg save/restore code in the unordered EP config is required * - Documentation/Support * -# Add detailed overviews of how each demo works * -# Add board overviews diff --git a/LUFA/ManPages/MigrationInformation.txt b/LUFA/ManPages/MigrationInformation.txt index d12c3f9e9..3bbe5a195 100644 --- a/LUFA/ManPages/MigrationInformation.txt +++ b/LUFA/ManPages/MigrationInformation.txt @@ -11,7 +11,11 @@ * areas relevant to making older projects compatible with the API changes of each new release. * * \section Sec_MigrationXXXXXX Migrating from 101122 to XXXXXX - * None yet. + * USB Core + * - By default, unordered Endpoint and Pipe configuration is now allowed once again, via the previous workaround of + * reconfiguring all Endpoints/Pipes in order each time a new Endpoint/Pipe is created. To minimise the compiled program + * size, the new ORDERED_EP_CONFIG compile time option may be defined in the project makefile to restrict the ordering + * in exchange for a smaller compiled binary size. * * \section Sec_Migration101122 Migrating from 100807 to 101122 * USB Core -- cgit v1.2.3