update arduboy core
This commit is contained in:
parent
d15ba14a82
commit
fedcf36ff2
|
@ -147,6 +147,18 @@ arduboy-homemade.menu.display.ssd1306.usb_product_postfix=1306
|
|||
arduboy-homemade.menu.display.ssd1306.bootloader_display=
|
||||
arduboy-homemade.menu.display.ssd1306.build.extra_flags=-DARDUBOY_10 -DOLED_SSD1306 {build.flash_cs} {build.usb_flags}
|
||||
|
||||
arduboy-homemade.menu.display.ssd1306i2c=SSD1306-I2C (2 Mbps)
|
||||
arduboy-homemade.menu.display.ssd1306i2c.build.display=-ssd1306i2c
|
||||
arduboy-homemade.menu.display.ssd1306i2c.usb_product_postfix=I2C
|
||||
arduboy-homemade.menu.display.ssd1306i2c.bootloader_display=
|
||||
arduboy-homemade.menu.display.ssd1306i2c.build.extra_flags=-DARDUBOY_10 -DOLED_SSD1306_I2C {build.flash_cs} {build.usb_flags}
|
||||
|
||||
arduboy-homemade.menu.display.ssd1306i2cx=SSD1306-I2C (2.66 Mbps)
|
||||
arduboy-homemade.menu.display.ssd1306i2cx.build.display=-ssd1306i2cf
|
||||
arduboy-homemade.menu.display.ssd1306i2cx.usb_product_postfix=I2CX
|
||||
arduboy-homemade.menu.display.ssd1306i2cx.bootloader_display=
|
||||
arduboy-homemade.menu.display.ssd1306i2cx.build.extra_flags=-DARDUBOY_10 -DOLED_SSD1306_I2CX {build.flash_cs} {build.usb_flags}
|
||||
|
||||
arduboy-homemade.menu.display.ssd1309=SSD1309
|
||||
arduboy-homemade.menu.display.ssd1309.build.display=-ssd1309
|
||||
arduboy-homemade.menu.display.ssd1309.usb_product_postfix=1309
|
||||
|
|
|
@ -36,7 +36,7 @@ static volatile LineInfo _usbLineInfo = { 57600, 0x00, 0x00, 0x00, 0x00 };
|
|||
static volatile int32_t breakValue = -1;
|
||||
|
||||
#ifndef ARDUBOY_CORE
|
||||
bool _updatedLUFAbootloader = false;
|
||||
static u8 wdtcsr_save;
|
||||
#else
|
||||
extern volatile unsigned char bootloader_timer;
|
||||
#endif
|
||||
|
@ -62,6 +62,11 @@ const CDCDescriptor _cdcInterface =
|
|||
D_ENDPOINT(USB_ENDPOINT_IN (CDC_ENDPOINT_IN ),USB_ENDPOINT_TYPE_BULK,USB_EP_SIZE,0)
|
||||
};
|
||||
|
||||
bool isLUFAbootloader()
|
||||
{
|
||||
return pgm_read_word(FLASHEND - 1) == NEW_LUFA_SIGNATURE;
|
||||
}
|
||||
|
||||
int CDC_GetInterface(u8* interfaceNum)
|
||||
{
|
||||
interfaceNum[0] += 2; // uses 2
|
||||
|
@ -97,10 +102,7 @@ bool CDC_Setup(USBSetup& setup)
|
|||
if (CDC_SET_CONTROL_LINE_STATE == r)
|
||||
{
|
||||
_usbLineInfo.lineState = setup.wValueL;
|
||||
}
|
||||
|
||||
if (CDC_SET_LINE_CODING == r || CDC_SET_CONTROL_LINE_STATE == r)
|
||||
{
|
||||
// auto-reset into the bootloader is triggered when the port, already
|
||||
// open at 1200 bps, is closed. this is the signal to start the watchdog
|
||||
// with a relatively long period so it can finish housekeeping tasks
|
||||
|
@ -114,41 +116,43 @@ bool CDC_Setup(USBSetup& setup)
|
|||
#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) {
|
||||
if (isLUFAbootloader()) {
|
||||
// horray, we got a new bootloader!
|
||||
magic_key_pos = (RAMEND-1);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// We check DTR state to determine if host port is open (bit 0 of lineState).
|
||||
if (1200 == _usbLineInfo.dwDTERate && (_usbLineInfo.lineState & 0x01) == 0)
|
||||
{
|
||||
#ifndef ARDUBOY_CORE
|
||||
{
|
||||
#if MAGIC_KEY_POS != (RAMEND-1)
|
||||
// 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)) {
|
||||
if (magic_key_pos != (RAMEND-1) && *(uint16_t *)magic_key_pos != MAGIC_KEY) {
|
||||
*(uint16_t *)(RAMEND-1) = *(uint16_t *)magic_key_pos;
|
||||
}
|
||||
#endif
|
||||
// Store boot key
|
||||
*(uint16_t *)magic_key_pos = MAGIC_KEY;
|
||||
// Save the watchdog state in case the reset is aborted.
|
||||
wdtcsr_save = WDTCSR;
|
||||
wdt_enable(WDTO_120MS);
|
||||
#else
|
||||
bootloader_timer = 120; //ms
|
||||
power_timer0_enable(); //power timer0 is disabled by flashlight/safemode in older Arduboy2 libraries
|
||||
#endif
|
||||
}
|
||||
else
|
||||
else if (*(uint16_t *)magic_key_pos == MAGIC_KEY)
|
||||
{
|
||||
#ifndef ARDUBOY_CORE
|
||||
// Most OSs do some intermediate steps when configuring ports and DTR can
|
||||
// twiggle more than once before stabilizing.
|
||||
// To avoid spurious resets we set the watchdog to 250ms and eventually
|
||||
// To avoid spurious resets we set the watchdog to 120ms and eventually
|
||||
// cancel if DTR goes back high.
|
||||
// Cancellation is only done if an auto-reset was started, which is
|
||||
// indicated by the magic key having been set.
|
||||
|
||||
wdt_disable();
|
||||
wdt_reset();
|
||||
// Restore the watchdog state in case the sketch was using it.
|
||||
WDTCSR |= (1<<WDCE) | (1<<WDE);
|
||||
WDTCSR = wdtcsr_save;
|
||||
#if MAGIC_KEY_POS != (RAMEND-1)
|
||||
// Restore backed up (old bootloader) magic key data
|
||||
if (magic_key_pos != (RAMEND-1)) {
|
||||
|
@ -159,10 +163,17 @@ bool CDC_Setup(USBSetup& setup)
|
|||
// Clean up RAMEND key
|
||||
*(uint16_t *)magic_key_pos = 0x0000;
|
||||
}
|
||||
#else
|
||||
bootloader_timer = 0;
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
{
|
||||
bootloader_timer = 120; //ms
|
||||
power_timer0_enable(); //power timer0 is disabled by flashlight/safemode in older Arduboy2 libraries
|
||||
}
|
||||
else
|
||||
{
|
||||
bootloader_timer = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
#include <util/atomic.h>
|
||||
#include "Arduino.h"
|
||||
|
||||
#include "HardwareSerial.h"
|
||||
|
@ -76,6 +77,13 @@ void serialEventRun(void)
|
|||
#endif
|
||||
}
|
||||
|
||||
// macro to guard critical sections when needed for large TX buffer sizes
|
||||
#if (SERIAL_TX_BUFFER_SIZE>256)
|
||||
#define TX_BUFFER_ATOMIC ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
|
||||
#else
|
||||
#define TX_BUFFER_ATOMIC
|
||||
#endif
|
||||
|
||||
// Actual interrupt handlers //////////////////////////////////////////////////////////////
|
||||
|
||||
void HardwareSerial::_tx_udr_empty_irq(void)
|
||||
|
@ -89,8 +97,14 @@ void HardwareSerial::_tx_udr_empty_irq(void)
|
|||
|
||||
// clear the TXC bit -- "can be cleared by writing a one to its bit
|
||||
// location". This makes sure flush() won't return until the bytes
|
||||
// actually got written
|
||||
sbi(*_ucsra, TXC0);
|
||||
// actually got written. Other r/w bits are preserved, and zeroes
|
||||
// written to the rest.
|
||||
|
||||
#ifdef MPCM0
|
||||
*_ucsra = ((*_ucsra) & ((1 << U2X0) | (1 << MPCM0))) | (1 << TXC0);
|
||||
#else
|
||||
*_ucsra = ((*_ucsra) & ((1 << U2X0) | (1 << TXC0)));
|
||||
#endif
|
||||
|
||||
if (_tx_buffer_head == _tx_buffer_tail) {
|
||||
// Buffer empty, so disable interrupts
|
||||
|
@ -177,15 +191,13 @@ int HardwareSerial::read(void)
|
|||
|
||||
int HardwareSerial::availableForWrite(void)
|
||||
{
|
||||
#if (SERIAL_TX_BUFFER_SIZE>256)
|
||||
uint8_t oldSREG = SREG;
|
||||
cli();
|
||||
#endif
|
||||
tx_buffer_index_t head = _tx_buffer_head;
|
||||
tx_buffer_index_t tail = _tx_buffer_tail;
|
||||
#if (SERIAL_TX_BUFFER_SIZE>256)
|
||||
SREG = oldSREG;
|
||||
#endif
|
||||
tx_buffer_index_t head;
|
||||
tx_buffer_index_t tail;
|
||||
|
||||
TX_BUFFER_ATOMIC {
|
||||
head = _tx_buffer_head;
|
||||
tail = _tx_buffer_tail;
|
||||
}
|
||||
if (head >= tail) return SERIAL_TX_BUFFER_SIZE - 1 - head + tail;
|
||||
return tail - head - 1;
|
||||
}
|
||||
|
@ -218,8 +230,22 @@ size_t HardwareSerial::write(uint8_t c)
|
|||
// significantly improve the effective datarate at high (>
|
||||
// 500kbit/s) bitrates, where interrupt overhead becomes a slowdown.
|
||||
if (_tx_buffer_head == _tx_buffer_tail && bit_is_set(*_ucsra, UDRE0)) {
|
||||
// If TXC is cleared before writing UDR and the previous byte
|
||||
// completes before writing to UDR, TXC will be set but a byte
|
||||
// is still being transmitted causing flush() to return too soon.
|
||||
// So writing UDR must happen first.
|
||||
// Writing UDR and clearing TC must be done atomically, otherwise
|
||||
// interrupts might delay the TXC clear so the byte written to UDR
|
||||
// is transmitted (setting TXC) before clearing TXC. Then TXC will
|
||||
// be cleared when no bytes are left, causing flush() to hang
|
||||
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
|
||||
*_udr = c;
|
||||
sbi(*_ucsra, TXC0);
|
||||
#ifdef MPCM0
|
||||
*_ucsra = ((*_ucsra) & ((1 << U2X0) | (1 << MPCM0))) | (1 << TXC0);
|
||||
#else
|
||||
*_ucsra = ((*_ucsra) & ((1 << U2X0) | (1 << TXC0)));
|
||||
#endif
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
tx_buffer_index_t i = (_tx_buffer_head + 1) % SERIAL_TX_BUFFER_SIZE;
|
||||
|
@ -240,9 +266,14 @@ size_t HardwareSerial::write(uint8_t c)
|
|||
}
|
||||
|
||||
_tx_buffer[_tx_buffer_head] = c;
|
||||
_tx_buffer_head = i;
|
||||
|
||||
// make atomic to prevent execution of ISR between setting the
|
||||
// head pointer and setting the interrupt flag resulting in buffer
|
||||
// retransmission
|
||||
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
|
||||
_tx_buffer_head = i;
|
||||
sbi(*_ucsrb, UDRIE0);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -35,9 +35,6 @@ extern const u16 STRING_LANGUAGE[] PROGMEM;
|
|||
extern const u8 STRING_PRODUCT[] PROGMEM;
|
||||
extern const u8 STRING_MANUFACTURER[] PROGMEM;
|
||||
extern const DeviceDescriptor USB_DeviceDescriptorIAD PROGMEM;
|
||||
#ifndef ARDUBOY_CORE
|
||||
extern bool _updatedLUFAbootloader;
|
||||
#endif
|
||||
|
||||
const u16 STRING_LANGUAGE[2] = {
|
||||
(3<<8) | (2+2),
|
||||
|
@ -821,14 +818,6 @@ 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;
|
||||
|
||||
#ifndef ARDUBOY_CORE
|
||||
#if MAGIC_KEY_POS != (RAMEND-1)
|
||||
if (pgm_read_word(FLASHEND - 1) == NEW_LUFA_SIGNATURE) {
|
||||
_updatedLUFAbootloader = true;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
void USBDevice_::detach()
|
||||
|
|
|
@ -285,8 +285,7 @@ typedef struct
|
|||
// 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
|
||||
// the usafe and the safe location.
|
||||
#ifndef MAGIC_KEY
|
||||
#define MAGIC_KEY 0x7777
|
||||
#endif
|
||||
|
|
|
@ -46,7 +46,7 @@ volatile unsigned char button_ticks_now = 0;
|
|||
volatile unsigned char button_ticks_last = 0;
|
||||
volatile unsigned char bootloader_timer = 0;
|
||||
|
||||
#if defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
|
||||
#if defined(TIM0_OVF_vect)
|
||||
ISR(TIM0_OVF_vect)
|
||||
#else
|
||||
ISR(TIMER0_OVF_vect, ISR_NAKED)
|
||||
|
|
Loading…
Reference in New Issue