diff --git a/hardware/arduino/avr/cores/arduino/CDC.cpp b/hardware/arduino/avr/cores/arduino/CDC.cpp index f19b44c7f1e..0a743e1ea95 100644 --- a/hardware/arduino/avr/cores/arduino/CDC.cpp +++ b/hardware/arduino/avr/cores/arduino/CDC.cpp @@ -34,6 +34,8 @@ typedef struct static volatile LineInfo _usbLineInfo = { 57600, 0x00, 0x00, 0x00, 0x00 }; static volatile int32_t breakValue = -1; +bool _updatedLUFAbootloader = false; + #define WEAK __attribute__ ((weak)) extern const CDCDescriptor _cdcInterface PROGMEM; @@ -99,24 +101,32 @@ bool CDC_Setup(USBSetup& setup) // with a relatively long period so it can finish housekeeping tasks // like servicing endpoints before the sketch ends -#ifndef MAGIC_KEY -#define MAGIC_KEY 0x7777 -#endif -#ifndef MAGIC_KEY_POS -#define MAGIC_KEY_POS 0x0800 + uint16_t magic_key_pos = MAGIC_KEY_POS; + +// If we don't use the new RAMEND directly, check manually if we have a newer bootloader. +// This is used to keep compatible with the old leonardo bootloaders. +// You are still able to set the magic key position manually to RAMEND-1 to save a few bytes for this check. +#if MAGIC_KEY_POS != (RAMEND-1) + // For future boards save the key in the inproblematic RAMEND + // Which is reserved for the main() return value (which will never return) + if (_updatedLUFAbootloader) { + // horray, we got a new bootloader! + magic_key_pos = (RAMEND-1); + } #endif // We check DTR state to determine if host port is open (bit 0 of lineState). if (1200 == _usbLineInfo.dwDTERate && (_usbLineInfo.lineState & 0x01) == 0) { #if MAGIC_KEY_POS != (RAMEND-1) - *(uint16_t *)(RAMEND-1) = *(uint16_t *)MAGIC_KEY_POS; - *(uint16_t *)MAGIC_KEY_POS = MAGIC_KEY; -#else - // for future boards save the key in the inproblematic RAMEND - // which is reserved for the main() return value (which will never return) - *(uint16_t *)MAGIC_KEY_POS = MAGIC_KEY; + // Backup ram value if its not a newer bootloader. + // This should avoid memory corruption at least a bit, not fully + if (magic_key_pos != (RAMEND-1)) { + *(uint16_t *)(RAMEND-1) = *(uint16_t *)magic_key_pos; + } #endif + // Store boot key + *(uint16_t *)magic_key_pos = MAGIC_KEY; wdt_enable(WDTO_120MS); } else @@ -129,10 +139,15 @@ bool CDC_Setup(USBSetup& setup) wdt_disable(); wdt_reset(); #if MAGIC_KEY_POS != (RAMEND-1) - *(uint16_t *)MAGIC_KEY_POS = *(uint16_t *)(RAMEND-1); -#else - *(uint16_t *)MAGIC_KEY_POS = 0x0000; + // Restore backed up (old bootloader) magic key data + if (magic_key_pos != (RAMEND-1)) { + *(uint16_t *)magic_key_pos = *(uint16_t *)(RAMEND-1); + } else #endif + { + // Clean up RAMEND key + *(uint16_t *)magic_key_pos = 0x0000; + } } } return true; diff --git a/hardware/arduino/avr/cores/arduino/USBCore.cpp b/hardware/arduino/avr/cores/arduino/USBCore.cpp index 62b90ed47d6..248da62732e 100644 --- a/hardware/arduino/avr/cores/arduino/USBCore.cpp +++ b/hardware/arduino/avr/cores/arduino/USBCore.cpp @@ -35,6 +35,7 @@ extern const u8 STRING_PRODUCT[] PROGMEM; extern const u8 STRING_MANUFACTURER[] PROGMEM; extern const DeviceDescriptor USB_DeviceDescriptor PROGMEM; extern const DeviceDescriptor USB_DeviceDescriptorB PROGMEM; +extern bool _updatedLUFAbootloader; const u16 STRING_LANGUAGE[2] = { (3<<8) | (2+2), @@ -115,16 +116,10 @@ static inline void Recv(volatile u8* data, u8 count) { while (count--) *data++ = UEDATX; - - RXLED1; // light the RX LED - RxLEDPulse = TX_RX_LED_PULSE_MS; } static inline u8 Recv8() { - RXLED1; // light the RX LED - RxLEDPulse = TX_RX_LED_PULSE_MS; - return UEDATX; } @@ -226,6 +221,9 @@ int USB_Recv(u8 ep, void* d, int len) if (!_usbConfiguration || len < 0) return -1; + RXLED1; // light the RX LED + RxLEDPulse = TX_RX_LED_PULSE_MS; + LockEP lock(ep); u8 n = FifoByteCount(); len = min(n,len); @@ -806,6 +804,12 @@ void USBDevice_::attach() UDIEN = (1<