aboutsummaryrefslogtreecommitdiff
path: root/cores/arduino/CDC.cpp
diff options
context:
space:
mode:
authorMartino Facchin <m.facchin@arduino.cc>2016-04-06 16:33:14 +0200
committerMartino Facchin <m.facchin@arduino.cc>2016-04-06 17:41:06 +0200
commit5e194bd8efe8dcd2fb6eaa13cec1a2a642c5254a (patch)
treef34c3a6aad5f9e3b43e121948bfa3563c1dd3495 /cores/arduino/CDC.cpp
parent71b87bf26bc7b485dc1c111603fd09327c1b6c53 (diff)
[AVR] Discover newer bootloader at runtime
Replaces #4280, only checks for the bootloader once Tested with Hoodloader2, should work with every LUFA-derived bootloader released after 2014 (.apitable_signatures section must be placed at end of the flash) BootloaderAPITable.S : .global BootloaderAPI_Signatures BootloaderAPI_Signatures: .long BOOT_START_ADDR ; Start address of the bootloader .word 0xDF00 ; Signature for the CDC class bootloader .word 0xDCFB ; Signature for a LUFA class bootloader makefile: BOOT_API_LD_FLAGS += $(call BOOT_SECTION_LD_FLAG, .apitable_signatures, BootloaderAPI_Signatures, 8)
Diffstat (limited to 'cores/arduino/CDC.cpp')
-rw-r--r--cores/arduino/CDC.cpp43
1 files changed, 29 insertions, 14 deletions
diff --git a/cores/arduino/CDC.cpp b/cores/arduino/CDC.cpp
index f19b44c..0a743e1 100644
--- a/cores/arduino/CDC.cpp
+++ b/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;