From 2608fd1dd48096c1867676de337767ff3fb1a951 Mon Sep 17 00:00:00 2001 From: Dean Camera Date: Thu, 3 Jan 2013 10:53:47 +0000 Subject: [PATCH] Fixed hardware race condition that could cause failed device enumerations for AVR8 and UC3 architectures (thanks to Mike Beyhs). Fixed incorrect Minimus board LED definitions (thanks to Joonas Lahtinen). Fixed incorrect LED masks for received data display in the Device GenericHID demos (thanks to Denys Berkovskyy). --- Demos/Device/ClassDriver/GenericHID/GenericHID.c | 6 +++--- Demos/Device/LowLevel/GenericHID/GenericHID.c | 6 +++--- LUFA/Common/Common.h | 4 ++-- LUFA/DoxygenPages/ChangeLog.txt | 9 ++++++--- LUFA/Drivers/Board/AVR8/MINIMUS/LEDs.h | 10 +++------- LUFA/Drivers/USB/Core/AVR8/Device_AVR8.h | 9 ++++++--- LUFA/Drivers/USB/Core/DeviceStandardReq.c | 11 +++++------ LUFA/Drivers/USB/Core/UC3/Device_UC3.h | 7 ++++++- LUFA/Drivers/USB/Core/XMEGA/Device_XMEGA.h | 6 ++++++ 9 files changed, 40 insertions(+), 28 deletions(-) diff --git a/Demos/Device/ClassDriver/GenericHID/GenericHID.c b/Demos/Device/ClassDriver/GenericHID/GenericHID.c index 3a050bbd97..f9222f45ad 100644 --- a/Demos/Device/ClassDriver/GenericHID/GenericHID.c +++ b/Demos/Device/ClassDriver/GenericHID/GenericHID.c @@ -177,13 +177,13 @@ void CALLBACK_HID_Device_ProcessHIDReport(USB_ClassInfo_HID_Device_t* const HIDI NewLEDMask |= LEDS_LED1; if (Data[1]) - NewLEDMask |= LEDS_LED1; + NewLEDMask |= LEDS_LED2; if (Data[2]) - NewLEDMask |= LEDS_LED1; + NewLEDMask |= LEDS_LED3; if (Data[3]) - NewLEDMask |= LEDS_LED1; + NewLEDMask |= LEDS_LED4; LEDs_SetAllLEDs(NewLEDMask); } diff --git a/Demos/Device/LowLevel/GenericHID/GenericHID.c b/Demos/Device/LowLevel/GenericHID/GenericHID.c index e74daff016..beaad03180 100644 --- a/Demos/Device/LowLevel/GenericHID/GenericHID.c +++ b/Demos/Device/LowLevel/GenericHID/GenericHID.c @@ -161,13 +161,13 @@ void ProcessGenericHIDReport(uint8_t* DataArray) NewLEDMask |= LEDS_LED1; if (DataArray[1]) - NewLEDMask |= LEDS_LED1; + NewLEDMask |= LEDS_LED2; if (DataArray[2]) - NewLEDMask |= LEDS_LED1; + NewLEDMask |= LEDS_LED3; if (DataArray[3]) - NewLEDMask |= LEDS_LED1; + NewLEDMask |= LEDS_LED4; LEDs_SetAllLEDs(NewLEDMask); } diff --git a/LUFA/Common/Common.h b/LUFA/Common/Common.h index c302eacb00..082f4d5e7e 100644 --- a/LUFA/Common/Common.h +++ b/LUFA/Common/Common.h @@ -86,7 +86,7 @@ /* Architecture specific utility includes: */ #if defined(__DOXYGEN__) /** Type define for an unsigned integer the same width as the selected architecture's machine register. - * This is distinct from the non-specific standard int data type, whose width is machine dependent but + * This is distinct from the non-specific standard int data type, whose width is machine dependant but * which may not reflect the actual machine register width on some targets (e.g. AVR8). */ typedef MACHINE_REG_t uint_reg_t; @@ -112,7 +112,7 @@ #include // === TODO: Find abstracted way to handle these === - #define PROGMEM + #define PROGMEM #define pgm_read_byte(x) *x #define memcmp_P(...) memcmp(__VA_ARGS__) #define memcpy_P(...) memcpy(__VA_ARGS__) diff --git a/LUFA/DoxygenPages/ChangeLog.txt b/LUFA/DoxygenPages/ChangeLog.txt index b07e666a0c..1e2c10ccbc 100644 --- a/LUFA/DoxygenPages/ChangeLog.txt +++ b/LUFA/DoxygenPages/ChangeLog.txt @@ -23,7 +23,7 @@ * via a software jump without first turning off the OTG pad (thanks to Simon Inns) * - Library Applications: * - Increased throughput in the USBtoSerial project now that data transmission is non-blocking (thanks to Joseph Lacerte) - * - Updated bootloader makefiles to remove dependency on the "bc" command line calculator tool + * - Updated bootloader makefiles to remove dependency on the \c bc command line calculator tool * * Fixed: * - Core: @@ -36,11 +36,14 @@ * - Fixed incorrect definitions of \c HID_KEYBOARD_LED_KANA, \c HID_KEYBOARD_SC_KEYPAD_EQUAL_SIGN and \c HID_KEYBOARD_SC_KEYPAD_EQUAL_SIGN_AS400 * and added a missing definition for \c HID_KEYBOARD_SC_APPLICATION (thanks to David Monro) * - Fixed maximum allowed keyboard key code usage of \c 0x65 rather than \c 0xFF for the \c HID_DESCRIPTOR_KEYBOARD() macro (thanks to David Monro) + * - Fixed hardware race condition that could cause failed device enumerations for AVR8 and UC3 architectures (thanks to Mike Beyhs) + * - Fixed incorrect Minimus board LED definitions (thanks to Joonas Lahtinen) * - Library Applications: * - Fixed broken RESET_TOGGLES_LIBUSB_COMPAT compile time option in the AVRISP-MKII project * - Fixed incompatibility in the CDC class bootloader on some systems (thanks to Sylvain Munaut) * - Fixed lengthy timeouts in the USBtoSerial project if no application on the host is consuming data (thanks to Nicolas Saugnier) * - Fixed lengthy automatic data flushing in the CDC and MIDI device class drivers + * - Fixed incorrect LED masks for received data display in the Device GenericHID demos (thanks to Denys Berkovskyy) * * \section Sec_ChangeLog120730 Version 120730 * New: @@ -54,7 +57,7 @@ * - Added new Endpoint_ConfigureEndpointTable() function * - Added new Pipe_ConfigurePipeTable() function * - Added build test to verify correct compilation of all board drivers using all driver APIs - * - Added build test to verify correct compilation of all bootloaders using all supported devices + * - Added build test to verify correct compilation of all bootloaders using all supported devices * - Added build test to verify that there are no detectable errors in the codebase via static analysis * - Added new JTAG_ENABLE() macro for the AVR8 architecture * - Library Applications: @@ -106,7 +109,7 @@ * - Fixed swapped Little Endian/Big Endian endpoint and pipe write code for the UC3 devices (thanks to Andrew Chu) * - Fixed the JTAG_DISABLE() macro clearing all other bits in MCUSR when called * - Fixed incorrect Micropendous board LED driver LEDs_SetAllLEDs() and LEDs_ChangeLEDs() function implementations (thanks to MitchJS) - * - Fixed endianess issues in the RNDIS host class driver for UC3 devices (thanks to Andrew Chu) + * - Fixed endianess issues in the RNDIS host class driver for UC3 devices (thanks to Andrew Chu) * - Library Applications: * - Fixed error in the AVRISP-MKII programmer when ISP mode is used at 64KHz (thanks to Ben R. Porter) * - Fixed AVRISP-MKII programmer project failing to compile for the U4 chips when VTARGET_ADC_CHANNEL is defined to an invalid channel and NO_VTARGET_DETECT is diff --git a/LUFA/Drivers/Board/AVR8/MINIMUS/LEDs.h b/LUFA/Drivers/Board/AVR8/MINIMUS/LEDs.h index ceeb44bc1e..f153629aec 100644 --- a/LUFA/Drivers/Board/AVR8/MINIMUS/LEDs.h +++ b/LUFA/Drivers/Board/AVR8/MINIMUS/LEDs.h @@ -44,9 +44,8 @@ * * * - * - * - * + * + * *
NameColorInfoActive LevelPort Pin
LEDS_LED1RedGeneral IndicatorLowPORTD.5
LEDS_LED2GreenGeneral IndicatorLowPORTD.6
LEDS_LED3BlueGeneral IndicatorLowPORTD.7
LEDS_LED1BlueGeneral IndicatorLowPORTD.5
LEDS_LED2RedGeneral IndicatorLowPORTD.6
* * @{ @@ -76,11 +75,8 @@ /** LED mask for the second LED on the board. */ #define LEDS_LED2 (1 << 6) - /** LED mask for the third LED on the board. */ - #define LEDS_LED3 (1 << 7) - /** LED mask for all the LEDs on the board. */ - #define LEDS_ALL_LEDS (LEDS_LED1 | LEDS_LED2 | LEDS_LED3) + #define LEDS_ALL_LEDS (LEDS_LED1 | LEDS_LED2) /** LED mask for the none of the board LEDs. */ #define LEDS_NO_LEDS 0 diff --git a/LUFA/Drivers/USB/Core/AVR8/Device_AVR8.h b/LUFA/Drivers/USB/Core/AVR8/Device_AVR8.h index d60cb336ab..e0435e21b8 100644 --- a/LUFA/Drivers/USB/Core/AVR8/Device_AVR8.h +++ b/LUFA/Drivers/USB/Core/AVR8/Device_AVR8.h @@ -210,10 +210,13 @@ static inline void USB_Device_SetDeviceAddress(const uint8_t Address) ATTR_ALWAYS_INLINE; static inline void USB_Device_SetDeviceAddress(const uint8_t Address) { - uint8_t Temp = (UDADDR & (1 << ADDEN)) | (Address & 0x7F); + UDADDR = (UDADDR & (1 << ADDEN)) | (Address & 0x7F); + } - UDADDR = Temp; - UDADDR = Temp | (1 << ADDEN); + static inline void USB_Device_EnableDeviceAddress(void) ATTR_ALWAYS_INLINE; + static inline void USB_Device_EnableDeviceAddress(void) + { + UDADDR |= (1 << ADDEN); } static inline bool USB_Device_IsAddressSet(void) ATTR_ALWAYS_INLINE ATTR_WARN_UNUSED_RESULT; diff --git a/LUFA/Drivers/USB/Core/DeviceStandardReq.c b/LUFA/Drivers/USB/Core/DeviceStandardReq.c index ef1a278d47..514286dc19 100644 --- a/LUFA/Drivers/USB/Core/DeviceStandardReq.c +++ b/LUFA/Drivers/USB/Core/DeviceStandardReq.c @@ -124,9 +124,9 @@ void USB_Device_ProcessControlRequest(void) static void USB_Device_SetAddress(void) { - uint8_t DeviceAddress = (USB_ControlRequest.wValue & 0x7F); - uint_reg_t CurrentGlobalInt = GetGlobalInterruptMask(); - GlobalInterruptDisable(); + uint8_t DeviceAddress = (USB_ControlRequest.wValue & 0x7F); + + USB_Device_SetDeviceAddress(DeviceAddress); Endpoint_ClearSETUP(); @@ -134,10 +134,9 @@ static void USB_Device_SetAddress(void) while (!(Endpoint_IsINReady())); - USB_Device_SetDeviceAddress(DeviceAddress); - USB_DeviceState = (DeviceAddress) ? DEVICE_STATE_Addressed : DEVICE_STATE_Default; + USB_Device_EnableDeviceAddress(); - SetGlobalInterruptMask(CurrentGlobalInt); + USB_DeviceState = (DeviceAddress) ? DEVICE_STATE_Addressed : DEVICE_STATE_Default; } static void USB_Device_SetConfiguration(void) diff --git a/LUFA/Drivers/USB/Core/UC3/Device_UC3.h b/LUFA/Drivers/USB/Core/UC3/Device_UC3.h index 35e081b37c..603caad3f8 100644 --- a/LUFA/Drivers/USB/Core/UC3/Device_UC3.h +++ b/LUFA/Drivers/USB/Core/UC3/Device_UC3.h @@ -209,7 +209,12 @@ static inline void USB_Device_SetDeviceAddress(const uint8_t Address) { AVR32_USBB.UDCON.uadd = Address; - AVR32_USBB.UDCON.adden = (Address ? true : false); + } + + static inline void USB_Device_EnableDeviceAddress(void) ATTR_ALWAYS_INLINE; + static inline void USB_Device_EnableDeviceAddress(void) + { + AVR32_USBB.UDCON.adden = true; } static inline bool USB_Device_IsAddressSet(void) ATTR_ALWAYS_INLINE ATTR_WARN_UNUSED_RESULT; diff --git a/LUFA/Drivers/USB/Core/XMEGA/Device_XMEGA.h b/LUFA/Drivers/USB/Core/XMEGA/Device_XMEGA.h index 7dd020296c..1cf3557b5a 100644 --- a/LUFA/Drivers/USB/Core/XMEGA/Device_XMEGA.h +++ b/LUFA/Drivers/USB/Core/XMEGA/Device_XMEGA.h @@ -208,6 +208,12 @@ USB.ADDR = Address; } + static inline void USB_Device_EnableDeviceAddress(void) ATTR_ALWAYS_INLINE; + static inline void USB_Device_EnableDeviceAddress(void) + { + /* No implementation for XMEGA architecture */ + } + static inline bool USB_Device_IsAddressSet(void) ATTR_ALWAYS_INLINE ATTR_WARN_UNUSED_RESULT; static inline bool USB_Device_IsAddressSet(void) {