Previously, it could happen that SPI::beginTransaction was
interrupted by an ISR, while it is changing the SPI_AVR_EIMSK
register or interruptSave variable (it seems that there is
a small window after changing SPI_AVR_EIMSK where an interrupt
might still occur). If this happens, interruptSave is overwritten
with an invalid value, permanently disabling the pin interrupts.
To prevent this, disable interrupts globally while changing
these values.
From https://github.com/arduino/Arduino/pull/2376#issuecomment-59671152
Quoting Andrew Kroll:
[..this commit..] introduces a small delay that can prevent the wait
loop form iterating when running at the maximum speed. This gives
you a little more speed, even if it seems counter-intuitive. At
lower speeds, it is unnoticed. Watch the output on an oscilloscope
when running full SPI speed, and you should see closer back-to-back
writes.
Quoting Paul Stoffregen:
I did quite a bit of experimenting with the NOP addition. The one
that's in my copy gives about a 10% speedup on AVR.
Previously, when verbose uploads were enabled, avrdude was run with four
-v options, causing it to dump all raw bytes exchanged with the
bootloader. This floods the console so much that meaningful output
mostly disappears.
Most users probably want to enable verbose mode just to see what avrdude
command is ran. Furthermore, users that benefit from the raw bytes
dumped are perfectly capable of either running avrdude manually, or
modifying platform.txt. Given that, running avrdude with just one -v
should be plenty.
This fixes#891.
When checking the `left` argument, it previously allowed having
left == len. However, this means the substring starts one past the last
character in the string and should return the empty string. In practice,
this already worked correctly, because buffer[len] contains the trailing
nul, so it would (re)assign the empty string to `out`.
However, fixing this check makes it a bit more logical, and prevents a
fairly unlikely out-of-buffer write (to address 0x0) when calling
substring on an invalidated String:
String bar = (char*)NULL;
bar.substring(0, 0);
Previously, this method calculated the length of the string from the
given index onwards. However, the other remove() method called already
contains code for this calculation, which is used when the count passed
in is too big. This means we can just pass in a very big count that is
guaranteed to point past the end of the string, shrinking the remove
method by a few bytes.