aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cores/arduino/CDC.cpp43
-rw-r--r--cores/arduino/USBCore.cpp7
-rw-r--r--cores/arduino/USBCore.h17
-rw-r--r--cores/arduino/WString.h18
-rw-r--r--libraries/SoftwareSerial/src/SoftwareSerial.cpp2
-rw-r--r--libraries/Wire/src/utility/twi.c6
-rw-r--r--platform.txt9
7 files changed, 74 insertions, 28 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;
diff --git a/cores/arduino/USBCore.cpp b/cores/arduino/USBCore.cpp
index 62b90ed..3c7da86 100644
--- a/cores/arduino/USBCore.cpp
+++ b/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),
@@ -806,6 +807,12 @@ void USBDevice_::attach()
UDIEN = (1<<EORSTE) | (1<<SOFE) | (1<<SUSPE); // Enable interrupts for EOR (End of Reset), SOF (start of frame) and SUSPEND
TX_RX_LED_INIT;
+
+#if MAGIC_KEY_POS != (RAMEND-1)
+ if (pgm_read_word(FLASHEND - 1) == NEW_LUFA_SIGNATURE) {
+ _updatedLUFAbootloader = true;
+ }
+#endif
}
void USBDevice_::detach()
diff --git a/cores/arduino/USBCore.h b/cores/arduino/USBCore.h
index 4e08d71..66f3b5b 100644
--- a/cores/arduino/USBCore.h
+++ b/cores/arduino/USBCore.h
@@ -277,5 +277,22 @@ typedef struct
#define D_CDCCS(_subtype,_d0,_d1) { 5, 0x24, _subtype, _d0, _d1 }
#define D_CDCCS4(_subtype,_d0) { 4, 0x24, _subtype, _d0 }
+// Bootloader related fields
+// Old Caterina bootloader places the MAGIC key into unsafe RAM locations (it can be rewritten
+// by the running sketch before to actual reboot).
+// Newer bootloaders, recognizable by the LUFA "signature" at the end of the flash, can handle both
+// the usafe and the safe location. Check once (in USBCore.cpp) if the bootloader in new, then set the global
+// _updatedLUFAbootloader variable to true/false and place the magic key consequently
+#ifndef MAGIC_KEY
+#define MAGIC_KEY 0x7777
+#endif
+
+#ifndef MAGIC_KEY_POS
+#define MAGIC_KEY_POS 0x0800
+#endif
+
+#ifndef NEW_LUFA_SIGNATURE
+#define NEW_LUFA_SIGNATURE 0xDCFB
+#endif
#endif
diff --git a/cores/arduino/WString.h b/cores/arduino/WString.h
index b047980..de5632c 100644
--- a/cores/arduino/WString.h
+++ b/cores/arduino/WString.h
@@ -81,7 +81,7 @@ public:
inline unsigned int length(void) const {return len;}
// creates a copy of the assigned value. if the value is null or
- // invalid, or if the memory allocation fails, the string will be
+ // invalid, or if the memory allocation fails, the string will be
// marked as invalid ("if (s)" will be false).
String & operator = (const String &rhs);
String & operator = (const char *cstr);
@@ -92,10 +92,10 @@ public:
#endif
// concatenate (works w/ built-in types)
-
+
// returns true on success, false on failure (in which case, the string
- // is left unchanged). if the argument is null or invalid, the
- // concatenation is considered unsucessful.
+ // is left unchanged). if the argument is null or invalid, the
+ // concatenation is considered unsucessful.
unsigned char concat(const String &str);
unsigned char concat(const char *cstr);
unsigned char concat(char c);
@@ -107,7 +107,7 @@ public:
unsigned char concat(float num);
unsigned char concat(double num);
unsigned char concat(const __FlashStringHelper * str);
-
+
// if there's not enough memory for the concatenated value, the string
// will be left unchanged (but this isn't signalled in any way)
String & operator += (const String &rhs) {concat(rhs); return (*this);}
@@ -159,8 +159,12 @@ public:
char& operator [] (unsigned int index);
void getBytes(unsigned char *buf, unsigned int bufsize, unsigned int index=0) const;
void toCharArray(char *buf, unsigned int bufsize, unsigned int index=0) const
- {getBytes((unsigned char *)buf, bufsize, index);}
- const char * c_str() const { return buffer; }
+ { getBytes((unsigned char *)buf, bufsize, index); }
+ const char* c_str() const { return buffer; }
+ char* begin() { return buffer; }
+ char* end() { return buffer + length(); }
+ const char* begin() const { return c_str(); }
+ const char* end() const { return c_str() + length(); }
// search
int indexOf( char ch ) const;
diff --git a/libraries/SoftwareSerial/src/SoftwareSerial.cpp b/libraries/SoftwareSerial/src/SoftwareSerial.cpp
index 376762e..474fe4a 100644
--- a/libraries/SoftwareSerial/src/SoftwareSerial.cpp
+++ b/libraries/SoftwareSerial/src/SoftwareSerial.cpp
@@ -270,7 +270,7 @@ void SoftwareSerial::setTX(uint8_t tx)
{
// First write, then set output. If we do this the other way around,
// the pin would be output low for a short while before switching to
- // output hihg. Now, it is input with pullup for a short while, which
+ // output high. Now, it is input with pullup for a short while, which
// is fine. With inverse logic, either order is fine.
digitalWrite(tx, _inverse_logic ? LOW : HIGH);
pinMode(tx, OUTPUT);
diff --git a/libraries/Wire/src/utility/twi.c b/libraries/Wire/src/utility/twi.c
index f5d7d5b..171af73 100644
--- a/libraries/Wire/src/utility/twi.c
+++ b/libraries/Wire/src/utility/twi.c
@@ -304,7 +304,7 @@ uint8_t twi_transmit(const uint8_t* data, uint8_t length)
uint8_t i;
// ensure data will fit into buffer
- if(TWI_BUFFER_LENGTH < length){
+ if(TWI_BUFFER_LENGTH < (twi_txBufferLength+length)){
return 1;
}
@@ -314,10 +314,10 @@ uint8_t twi_transmit(const uint8_t* data, uint8_t length)
}
// set length and copy data into tx buffer
- twi_txBufferLength = length;
for(i = 0; i < length; ++i){
- twi_txBuffer[i] = data[i];
+ twi_txBuffer[twi_txBufferLength+i] = data[i];
}
+ twi_txBufferLength += length;
return 0;
}
diff --git a/platform.txt b/platform.txt
index ed80bac..50778f1 100644
--- a/platform.txt
+++ b/platform.txt
@@ -6,7 +6,7 @@
# https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5-3rd-party-Hardware-specification
name=Arduino AVR Boards
-version=1.6.10
+version=1.6.11
# AVR compile variables
# ---------------------
@@ -97,11 +97,13 @@ tools.avrdude.config.path={path}/etc/avrdude.conf
tools.avrdude.upload.params.verbose=-v
tools.avrdude.upload.params.quiet=-q -q
-tools.avrdude.upload.pattern="{cmd.path}" "-C{config.path}" {upload.verbose} -p{build.mcu} -c{upload.protocol} -P{serial.port} -b{upload.speed} -D "-Uflash:w:{build.path}/{build.project_name}.hex:i"
+tools.avrdude.upload.params.noverify=-V
+tools.avrdude.upload.pattern="{cmd.path}" "-C{config.path}" {upload.verbose} {upload.verify} -p{build.mcu} -c{upload.protocol} -P{serial.port} -b{upload.speed} -D "-Uflash:w:{build.path}/{build.project_name}.hex:i"
tools.avrdude.program.params.verbose=-v
tools.avrdude.program.params.quiet=-q -q
-tools.avrdude.program.pattern="{cmd.path}" "-C{config.path}" {program.verbose} -p{build.mcu} -c{protocol} {program.extra_params} "-Uflash:w:{build.path}/{build.project_name}.hex:i"
+tools.avrdude.program.params.noverify=-V
+tools.avrdude.program.pattern="{cmd.path}" "-C{config.path}" {program.verbose} {program.verify} -p{build.mcu} -c{protocol} {program.extra_params} "-Uflash:w:{build.path}/{build.project_name}.hex:i"
tools.avrdude.erase.params.verbose=-v
tools.avrdude.erase.params.quiet=-q -q
@@ -111,6 +113,7 @@ tools.avrdude.bootloader.params.verbose=-v
tools.avrdude.bootloader.params.quiet=-q -q
tools.avrdude.bootloader.pattern="{cmd.path}" "-C{config.path}" {bootloader.verbose} -p{build.mcu} -c{protocol} {program.extra_params} "-Uflash:w:{runtime.platform.path}/bootloaders/{bootloader.file}:i" -Ulock:w:{bootloader.lock_bits}:m
+tools.avrdude_remote.upload.pattern=/usr/bin/run-avrdude /tmp/sketch.hex {upload.verbose} -p{build.mcu}
# USB Default Flags
# Default blank usb manufacturer will be filled in at compile time