aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--boards.txt35
-rw-r--r--bootloaders/caterina/Caterina-Leonardo.hex120
-rw-r--r--bootloaders/caterina/Makefile (renamed from bootloaders/diskloader/Makefile)28
-rw-r--r--bootloaders/caterina/src/Caterina.cpp (renamed from bootloaders/diskloader/src/DiskLoader.cpp)90
-rw-r--r--bootloaders/caterina/src/Platform.h (renamed from bootloaders/diskloader/src/Platform.h)32
-rw-r--r--bootloaders/caterina/src/USBCore.cpp (renamed from bootloaders/diskloader/src/USBCore.cpp)144
-rw-r--r--bootloaders/caterina/src/USBCore.h (renamed from bootloaders/diskloader/src/USBCore.h)126
-rw-r--r--bootloaders/caterina/src/USBDesc.cpp (renamed from bootloaders/diskloader/src/USBDesc.cpp)22
-rw-r--r--bootloaders/caterina/src/USBDesc.h (renamed from bootloaders/diskloader/src/USBDesc.h)51
-rwxr-xr-xbootloaders/caterina_LUFA/Caterina.c698
-rwxr-xr-xbootloaders/caterina_LUFA/Caterina.h99
-rw-r--r--bootloaders/caterina_LUFA/Caterina.hex256
-rwxr-xr-xbootloaders/caterina_LUFA/Descriptors.c265
-rwxr-xr-xbootloaders/caterina_LUFA/Descriptors.h139
-rwxr-xr-xbootloaders/caterina_LUFA/makefile717
-rw-r--r--bootloaders/diskloader/DiskLoader-Leonardo.hex115
-rw-r--r--cores/arduino/CDC.cpp92
-rw-r--r--cores/arduino/HID.cpp6
-rw-r--r--cores/arduino/USBAPI.h6
-rw-r--r--cores/arduino/USBCore.cpp2
-rw-r--r--cores/arduino/USBDesc.h2
-rw-r--r--[-rwxr-xr-x]cores/arduino/WInterrupts.c38
-rw-r--r--[-rwxr-xr-x]cores/arduino/wiring.c15
-rw-r--r--cores/arduino/wiring_analog.c18
-rw-r--r--[-rwxr-xr-x]cores/arduino/wiring_digital.c8
-rw-r--r--variants/leonardo/pins_arduino.h4
26 files changed, 2705 insertions, 423 deletions
diff --git a/boards.txt b/boards.txt
index 8ce7cc9..cb603cd 100644
--- a/boards.txt
+++ b/boards.txt
@@ -146,21 +146,22 @@ mega.build.variant=mega
##############################################################
-#leonardo.name=Arduino Leonardo
-#leonardo.upload.protocol=arduino
-#leonardo.upload.maximum_size=28672
-#leonardo.upload.speed=1200
-#leonardo.bootloader.low_fuses=0xde
-#leonardo.bootloader.high_fuses=0xd8
-#leonardo.bootloader.extended_fuses=0xcb
-#leonardo.bootloader.path=diskloader
-#leonardo.bootloader.file=DiskLoader-Leonardo.hex
-#leonardo.bootloader.unlock_bits=0x3F
-#leonardo.bootloader.lock_bits=0x2F
-#leonardo.build.mcu=atmega32u4
-#leonardo.build.f_cpu=16000000L
-#leonardo.build.core=arduino
-#leonardo.build.variant=leonardo
+leonardo.name=Arduino Leonardo
+leonardo.upload.protocol=avr109
+leonardo.upload.maximum_size=28672
+leonardo.upload.speed=57600
+leonardo.upload.disable_flushing=true
+leonardo.bootloader.low_fuses=0xff
+leonardo.bootloader.high_fuses=0xd8
+leonardo.bootloader.extended_fuses=0xcb
+leonardo.bootloader.path=caterina_LUFA
+leonardo.bootloader.file=Caterina.hex
+leonardo.bootloader.unlock_bits=0x3F
+leonardo.bootloader.lock_bits=0x2F
+leonardo.build.mcu=atmega32u4
+leonardo.build.f_cpu=16000000L
+leonardo.build.core=arduino
+leonardo.build.variant=leonardo
##############################################################
@@ -171,8 +172,8 @@ mega.build.variant=mega
#micro.bootloader.low_fuses=0xde
#micro.bootloader.high_fuses=0xda
#micro.bootloader.extended_fuses=0xcb
-#micro.bootloader.path=diskloader
-#micro.bootloader.file=DiskLoader-Micro.hex
+#micro.bootloader.path=caterina
+#micro.bootloader.file=Caterina-Micro.hex
#micro.bootloader.unlock_bits=0x3F
#micro.bootloader.lock_bits=0x2F
#micro.build.mcu=atmega32u4
diff --git a/bootloaders/caterina/Caterina-Leonardo.hex b/bootloaders/caterina/Caterina-Leonardo.hex
new file mode 100644
index 0000000..ea2af98
--- /dev/null
+++ b/bootloaders/caterina/Caterina-Leonardo.hex
@@ -0,0 +1,120 @@
+:1078000011241FBECFEFDAE0DEBFCDBF0BC14101B7
+:1078100042144505560455026403740300001E9586
+:1078200087020110030000C18081C106C0FF0A0069
+:107830000CA10185037508150026FF00954009017C
+:107840008102954009029102C0040309041A033021
+:1078500000300030003000300030003000300031A7
+:1078600000370030003100380341007200640075B9
+:107870000069006E006F0020004C0065006F006E14
+:10788000006100720064006F00200062006F006FF2
+:107890000074006C006F00610064006500720018E5
+:1078A00003410072006400750069006E006F0020E3
+:1078B000004C004C00430012010002020000404155
+:1078C0002334000001000203011201000200000045
+:1078D0004041233400000100020301090264000357
+:1078E00001008032080B00020202010009040000BE
+:1078F0000102020000052400100105240101010419
+:107900002402020524060001070581031000400936
+:10791000040100020A0000000705020240000007FF
+:107920000583024000000904020001030000000971
+:107930002101010001221E000705840340004000D0
+:1079400020918A0130918B012C5F3F4F30938B0146
+:1079500020938A01C901892F99278695982F803411
+:1079600018F08FE7891B982F990F921710F44798FA
+:107970000895479A08955D9A289A81E08093E000DF
+:107980001092E200EE27FF270994089528E088E18D
+:1079900090E00FB6F894A895809360000FBE2093F6
+:1079A0006000FFCF0F931F93CF93DF93982FEB01CE
+:1079B000042F10E088E76030780730F411E083E0AE
+:1079C000FB0180935700E895892F68E071E0402F14
+:1079D00006D1112311F107B600FCFDCF402F4695CB
+:1079E000FE01A8E0B1E020E031E009C08D919D9159
+:1079F0000C0130935700E895112432962F5F24171D
+:107A0000A8F385E0FE0180935700E89507B600FCD7
+:107A1000FDCF81E180935700E895DF91CF911F91D1
+:107A20000F91089584B794B7977F94BF98E10FB6EC
+:107A3000F89490936000109260000FBE5D9A289AAF
+:107A4000479883FF08C0E0E0F0E0859194918F5F54
+:107A50009F4F09F090DF3F9A209A559A90E89093B3
+:107A600061001092610081E885BF95BF9FD084E1DD
+:107A70008093880180E180938901E0E0F0E08591C6
+:107A800094918F5F9F4F19F081E080938F01EE24D6
+:107A9000FF24BB24B39454EFC52E51E0D52E1FD242
+:107AA000082F8EE098E7FC012491319602964491CC
+:107AB000201711F02223B9F7109291011092900132
+:107AC00082E068E071E08BD0013479F460910801C4
+:107AD0006058633028F0683111F064E001C063E061
+:107AE000C62FD0E0CF5DD7480EC0063571F4809127
+:107AF0000801803311F011E022C080910A01C82FE3
+:107B0000D0E0C25ED74811E022C0053721F413E06F
+:107B1000CEE1D8E71CC0053539F4E0900801F090BB
+:107B20000901EE0CFF1C0AC0043631F482E0B701F3
+:107B30004091090137DF02C0043721F010E0C5E2AF
+:107B4000D8E705C010910901E701E10EF11CC7D18A
+:107B50008097B1F483E068E871E041E050E059D0EB
+:107B6000112329F0412F50E083E8BE0152D083E475
+:107B700069E871E041E050E04CD0013509F08FCF69
+:107B8000D0929101C0929001B0928F01EE24FF2417
+:107B900086CFFC01289884E680938D0104C08091F3
+:107BA000F100819361506623D1F7089510929101FD
+:107BB0001092900110928E0110928F0181E08093BB
+:107BC000D70080EA8093D80082E189BD09B400FE25
+:107BD000FDCF80E98093D8001092E0000895FB016A
+:107BE0008093E90024E69BE611C08091E80085FFC0
+:107BF000FCCF289820938D018091F1008193809192
+:107C0000E80085FD02C09093E8004150442369F7E5
+:107C10000895982FFB01282F207287708093E90028
+:107C200064E63AE317C08091E80085FFFCCF97FF38
+:107C300002C0849101C080813196211180E05D985D
+:107C400060938C018093F1008091E80085FD02C073
+:107C50003093E800415050408FEF4F3F580719F7DD
+:107C600096FF03C08AE38093E80008958091930112
+:107C7000813299F45D9884E680938C0120E030E0B5
+:107C800003C080818093F100F901E050FF4F2F5F26
+:107C90003F4F28303105A9F714C0803261F480913C
+:107CA000E80082FFFCCF80E091E067E072DF8BEFBD
+:107CB0008093E80006C0823221F480919401809381
+:107CC000070181E0089520919501223291F1213040
+:107CD00081F48091980190919901089711F4209373
+:107CE0009A0180919A01882309F059C029EC38E75C
+:107CF00058C0223029F484E690E02BED38E71DC00F
+:107D0000233009F04AC080919401882319F429E4B2
+:107D100038E747C0823019F427E638E742C083309D
+:107D200019F42DE438E73DC08130B9F52FE938E783
+:107D300038C082E090E02BE238E740919801509102
+:107D40009901BC014817590708F4BA0190918C01B8
+:107D500040E050E0AEEF8091E8008570E1F3809163
+:107D6000E80082FD16C0F901E40FF51F4F5F5F4F79
+:107D7000E4915D98E093F100842F8F7311F4A09348
+:107D8000E80094E64617570730F390938C0181E0A2
+:107D9000089590938C0180E0089580E0089527EB8A
+:107DA00038E7F901849190E0C8CF1092E900809102
+:107DB000E80083FF61C082E991E068E0EADE82EFDB
+:107DC0008093E8008091920187FF05C08091E800D0
+:107DD00080FFFCCF03C08EEF8093E8008091930179
+:107DE000853051F48091E80080FFFCCF80919401B0
+:107DF00080688093E30039C08930E1F48091940178
+:107E000080938E01E7E2F8E791E031E026E390937A
+:107E1000E9003093EB0084918093EC002093ED0017
+:107E20009F5F3196953099F78EE78093EA00109224
+:107E3000EA001BC0883049F490918E015D9884E679
+:107E400080938C019093F10010C0882339F45D98E1
+:107E500084E680938C011092F10007C0863011F403
+:107E600032DF01C003DF882321F08EEF8093E8002A
+:107E7000089581E28093EB0008958091E1001092D3
+:107E8000E100282F83FF0CC01092E90081E080936D
+:107E9000EB001092EC0082E38093ED0010928E01D3
+:107EA00022FF1CC080918C01882331F08150809387
+:107EB0008C01882309F45D9A80918D01882331F02B
+:107EC000815080938D01882309F4289A80918F0135
+:107ED000882321F4109291011092900108951F932C
+:107EE000CF93DF9312E0C0E9D1E05FDFC6DF1093EC
+:107EF000E9008091E80085FF13C0289884E680930C
+:107F00008D019091F1008091E80085FD03C08BE622
+:107F10008093E800892F90E0DF91CF911F91089521
+:107F2000809190019091910101979093910180939C
+:107F300090018091900190919101892B09F426DDA7
+:0A7F4000CE010197F1F7FCDCD0CF71
+:087F4A0000E10000000000004E
+:040000030000780081
+:00000001FF
diff --git a/bootloaders/diskloader/Makefile b/bootloaders/caterina/Makefile
index 6ac3db3..8075a56 100644
--- a/bootloaders/diskloader/Makefile
+++ b/bootloaders/caterina/Makefile
@@ -1,21 +1,22 @@
###############################################################################
-# Makefile for DiskLoader
+# Makefile for Caterina (formerly DiskLoader)
###############################################################################
## General Flags
-PROJECT = DiskLoader
-TARGET = DiskLoader.elf
+PROJECT = Caterina
+TARGET = Caterina.elf
CC = avr-gcc
# BOARD2
MCU = atmega32u4
-AVR_FREQ = 16000000L
+AVR_FREQ = 16000000L
-# Specify the Arduino model using the assigned PID. This is used by Descriptors.c
-# to set PID and product descriptor string
-# Arduino Leonardo PID
-ARDUINO_MODEL_PID = 0x0034
-# Arduino Micro PID
+# Specify the Arduino model using the assigned PID. This is used by Descriptors.c
+# to set PID and product descriptor string
+
+# Arduino Leonardo bootloader PID
+ARDUINO_MODEL_PID = 0x0034
+# Arduino Micro bootloader PID
#ARDUINO_MODEL_PID = 0x0035
# Change if your programmer is different
@@ -23,7 +24,7 @@ AVRDUDE_PROGRAMMER = avrispmkII
AVRDUDE_PORT = usb
# program name should not be changed...
-PROGRAM = DiskLoader
+PROGRAM = Caterina
AVRDUDE = avrdude
AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) -p $(MCU)
@@ -40,10 +41,9 @@ ASMFLAGS += -x assembler-with-cpp -Wa,-gdwarf2
## Linker flags
LDFLAGS = $(COMMON)
-LDFLAGS += -Wl,-gc-sections,-Map=DiskLoader.map,--section-start=.text=0x7800,--relax
+LDFLAGS += -Wl,-gc-sections,-Map=Caterina.map,--section-start=.text=0x7800,--relax
LDFLAGS += -nodefaultlibs -nostartfiles
-
## Intel Hex file production flags
HEX_EEPROM_FLAGS = -j .eeprom
HEX_EEPROM_FLAGS += --set-section-flags=.eeprom="alloc,load"
@@ -65,7 +65,7 @@ vpath %.cpp $(SRC_DIR)
.PHONY: all checkdirs clean
-all: checkdirs $(TARGET) DiskLoader.hex DiskLoader.lss size
+all: checkdirs $(TARGET) Caterina.hex Caterina.lss size
-include $(DEP)
@@ -102,4 +102,4 @@ size: $(TARGET)
# @avr-size -C --mcu=${MCU} ${TARGET}.elf
program: $(TARGET).hex
- $(AVRDUDE) $(AVRDUDE_FLAGS) -B 5 -u -U flash:w:$(TARGET).hex \ No newline at end of file
+ $(AVRDUDE) $(AVRDUDE_FLAGS) -B 1 -u -U flash:w:$(TARGET).hex \ No newline at end of file
diff --git a/bootloaders/diskloader/src/DiskLoader.cpp b/bootloaders/caterina/src/Caterina.cpp
index 6580618..7ef6fa8 100644
--- a/bootloaders/diskloader/src/DiskLoader.cpp
+++ b/bootloaders/caterina/src/Caterina.cpp
@@ -26,15 +26,15 @@ void entrypoint(void)
::);
}
-u8 _flashbuf[128];
-u8 _inSync;
-u8 _ok;
-extern volatile u8 _ejected;
-extern volatile u16 _timeout;
+uint8_t _flashbuf[128];
+uint8_t _inSync;
+uint8_t _ok;
+extern volatile uint8_t _ejected;
+extern volatile uint16_t _timeout;
-void Program(u8 ep, u16 page, u8 count)
+void Program(uint8_t ep, uint16_t page, uint8_t count)
{
- u8 write = page < 30*1024; // Don't write over firmware please
+ uint8_t write = page < 30*1024; // Don't write over firmware please
if (write)
boot_page_erase(page);
@@ -46,9 +46,9 @@ void Program(u8 ep, u16 page, u8 count)
boot_spm_busy_wait(); // Wait until the memory is erased.
count >>= 1;
- u16* p = (u16*)page;
- u16* b = (u16*)_flashbuf;
- for (u8 i = 0; i < count; i++)
+ uint16_t* p = (uint16_t*)page;
+ uint16_t* b = (uint16_t*)_flashbuf;
+ for (uint8_t i = 0; i < count; i++)
boot_page_fill(p++, b[i]);
boot_page_write(page);
@@ -56,7 +56,7 @@ void Program(u8 ep, u16 page, u8 count)
boot_rww_enable ();
}
-
+void StartSketch();
int USBGetChar();
#define getch USBGetChar
@@ -78,8 +78,8 @@ int USBGetChar();
#define STK_READ_PAGE 0x74 // 't'
#define STK_READ_SIGN 0x75 // 'u'
-extern const u8 _readSize[] PROGMEM;
-const u8 _readSize[] =
+extern const uint8_t _readSize[] PROGMEM;
+const uint8_t _readSize[] =
{
STK_GET_PARAMETER, 1,
STK_SET_DEVICE, 20,
@@ -91,8 +91,8 @@ const u8 _readSize[] =
0,0
};
-extern const u8 _consts[] PROGMEM;
-const u8 _consts[] =
+extern const uint8_t _consts[] PROGMEM;
+const uint8_t _consts[] =
{
SIGNATURE_0,
SIGNATURE_1,
@@ -111,33 +111,38 @@ int main(void) __attribute__ ((naked));
// STK500v1 main loop, very similar to optiboot in protocol and implementation
int main()
{
+ uint8_t MCUSR_state = MCUSR; // store the reason for the reset
+ MCUSR &= ~(1 << WDRF); // must clear the watchdog reset flag before disabling and reenabling WDT
wdt_disable();
- TXLED0;
- RXLED0;
- LED0;
+ TX_LED_OFF();
+ RX_LED_OFF();
+ L_LED_OFF();
+ if (MCUSR_state & (1<<WDRF) && (pgm_read_word(0) != 0xFFFF)) {
+ StartSketch(); // if the reset was caused by WDT and if a sketch is already present then run the sketch instead of the bootloader
+ }
BOARD_INIT();
USBInit();
_inSync = STK_INSYNC;
_ok = STK_OK;
- if (pgm_read_word(0) != -1)
+ if (pgm_read_word(0) != 0xFFFF)
_ejected = 1;
for(;;)
{
- u8* packet = _flashbuf;
- u16 address = 0;
+ uint8_t* packet = _flashbuf;
+ uint16_t address = 0;
for (;;)
{
- u8 cmd = getch();
+ uint8_t cmd = getch();
// Read packet contents
- u8 len;
- const u8* rs = _readSize;
+ uint8_t len;
+ const uint8_t* rs = _readSize;
for(;;)
{
- u8 c = pgm_read_byte(rs++);
+ uint8_t c = pgm_read_byte(rs++);
len = pgm_read_byte(rs++);
if (c == cmd || c == 0)
break;
@@ -147,11 +152,11 @@ int main()
Recv(CDC_RX,packet,len);
// Send a response
- u8 send = 0;
- const u8* pgm = _consts+7; // 0
+ uint8_t send = 0;
+ const uint8_t* pgm = _consts+7; // 0
if (STK_GET_PARAMETER == cmd)
{
- u8 i = packet[0] - 0x80;
+ uint8_t i = packet[0] - 0x80;
if (i > 2)
i = (i == 0x18) ? 3 : 4; // 0x80:HW_VER,0x81:SW_MAJOR,0x82:SW_MINOR,0x18:3 or 0
pgm = _consts + i + 3;
@@ -174,7 +179,7 @@ int main()
else if (STK_LOAD_ADDRESS == cmd)
{
- address = *((u16*)packet); // word addresses
+ address = *((uint16_t*)packet); // word addresses
address += address;
}
@@ -186,7 +191,7 @@ int main()
else if (STK_READ_PAGE == cmd)
{
send = packet[1];
- pgm = (const u8*)address;
+ pgm = (const uint8_t*)address;
address += send; // not sure of this is required
}
@@ -211,25 +216,25 @@ int main()
}
// Nice breathing LED indicates we are in the firmware
-u16 _pulse;
+uint16_t _pulse;
void LEDPulse()
{
_pulse += 4;
- u8 p = _pulse >> 9;
+ uint8_t p = _pulse >> 9;
if (p > 63)
p = 127-p;
p += p;
- if (((u8)_pulse) > p)
- LED0;
+ if (((uint8_t)_pulse) > p)
+ L_LED_OFF();
else
- LED1;
+ L_LED_ON();
}
-void Reboot()
+void StartSketch()
{
- TXLED0; // switch off the RX and TX LEDs before starting the user sketch
- RXLED0;
- UDCON = 1; // Detatch USB
+ TX_LED_OFF(); // switch off the RX and TX LEDs before starting the user sketch
+ RX_LED_OFF();
+ UDCON = 1; // Detach USB
UDIEN = 0;
asm volatile ( // Reset vector to run firmware
"clr r30\n"
@@ -237,3 +242,10 @@ void Reboot()
"ijmp\n"
::);
}
+
+void Reset()
+{
+ wdt_enable(WDTO_15MS); // reset the microcontroller to reinitialize all IO and other registers
+ for (;;)
+ ;
+}
diff --git a/bootloaders/diskloader/src/Platform.h b/bootloaders/caterina/src/Platform.h
index 04c5b79..26c1114 100644
--- a/bootloaders/diskloader/src/Platform.h
+++ b/bootloaders/caterina/src/Platform.h
@@ -11,16 +11,11 @@
#include <stdlib.h>
#include <string.h>
-typedef unsigned char u8;
-typedef unsigned short u16;
-typedef unsigned long u32;
-
-
#define CPU_PRESCALE(n) (CLKPR = 0x80, CLKPR = (n))
#define DISABLE_JTAG() MCUCR = (1 << JTD) | (1 << IVCE) | (0 << PUD); MCUCR = (1 << JTD) | (0 << IVSEL) | (0 << IVCE) | (0 << PUD);
-#define USB_PID_LEONARDO 0x0034
-#define USB_PID_MICRO 0x0035
+#define USB_PID_LEONARDO_BOOTLOADER 0x0034
+#define USB_PID_MICRO_BOOTLOADER 0x0035
#define USB_VID 0x2341 // arduino LLC vid
#define USB_PID ARDUINO_MODEL_PID // passed in by Makefile - 0x0034 for Leonardo, 0x0035 for MIcro
@@ -28,22 +23,25 @@ typedef unsigned long u32;
#define OEM_NAME 'l','e','o','n','a','r','d','o' // 8 chars
#define BOARD_INIT() DDRC |= (1<<7); DDRB |= (1<<0); DDRD |= (1<<5); CPU_PRESCALE(0); DISABLE_JTAG();
-#define LED0 PORTC &= ~(1<<7)
-#define LED1 PORTC |= (1<<7)
-#define TXLED0 PORTD |= (1<<5)
-#define TXLED1 PORTD &= ~(1<<5)
-#define RXLED0 PORTB |= (1<<0)
-#define RXLED1 PORTB &= ~(1<<0)
+#define L_LED_OFF() PORTC &= ~(1<<7)
+#define L_LED_ON() PORTC |= (1<<7)
+#define TX_LED_OFF() PORTD |= (1<<5)
+#define TX_LED_ON() PORTD &= ~(1<<5)
+#define RX_LED_OFF() PORTB |= (1<<0)
+#define RX_LED_ON() PORTB &= ~(1<<0)
#define TRANSFER_PGM 0x80
#define TRANSFER_RELEASE 0x40
#define TRANSFER_ZERO 0x20
-void Transfer(u8 ep, const u8* data, int len);
-void Recv(u8 ep, u8* dst, u8 len);
-void Program(u8 ep, u16 page, u8 count);
+void Transfer(uint8_t ep, const uint8_t* data, int len);
+void Recv(uint8_t ep, uint8_t* dst, uint8_t len);
+void Program(uint8_t ep, uint16_t page, uint8_t count);
-#define CDC_ENABLED
+/* HID is not fully-supported in the bootloader - can be enabled
+ for testing, but note the descriptor report and other parts are
+ not complete */
+#define HID_ENABLED
#include "USBCore.h"
#include "USBDesc.h"
diff --git a/bootloaders/diskloader/src/USBCore.cpp b/bootloaders/caterina/src/USBCore.cpp
index 208121e..0eecacc 100644
--- a/bootloaders/diskloader/src/USBCore.cpp
+++ b/bootloaders/caterina/src/USBCore.cpp
@@ -31,21 +31,21 @@
/** Pulse generation counters to keep track of the number of milliseconds remaining for each pulse type */
#define TX_RX_LED_PULSE_MS 100
-u8 TxLEDPulse; /**< Milliseconds remaining for data Tx LED pulse */
-u8 RxLEDPulse; /**< Milliseconds remaining for data Rx LED pulse */
+uint8_t TxLEDPulse; /**< Milliseconds remaining for data Tx LED pulse */
+uint8_t RxLEDPulse; /**< Milliseconds remaining for data Rx LED pulse */
-void Reboot();
+void Reset();
//==================================================================
//==================================================================
typedef struct
{
- u32 dwDTERate;
- u8 bCharFormat;
- u8 bParityType;
- u8 bDataBits;
- u8 lineState;
+ uint32_t dwDTERate;
+ uint8_t bCharFormat;
+ uint8_t bParityType;
+ uint8_t bDataBits;
+ uint8_t lineState;
} LineInfo;
static volatile LineInfo _usbLineInfo = { 57600, 0x00, 0x00, 0x00, 0x00 };
@@ -54,9 +54,9 @@ static volatile LineInfo _usbLineInfo = { 57600, 0x00, 0x00, 0x00, 0x00 };
//==================================================================
// 4 bytes of RAM
-volatile u8 _usbConfiguration;
-volatile u8 _ejected;
-volatile u16 _timeout;
+volatile uint8_t _usbConfiguration;
+volatile uint8_t _ejected;
+volatile uint16_t _timeout;
static inline void WaitIN(void)
{
@@ -74,7 +74,7 @@ static inline void WaitOUT(void)
;
}
-static inline u8 WaitForINOrOUT()
+static inline uint8_t WaitForINOrOUT()
{
while (!(UEINTX & ((1<<TXINI)|(1<<RXOUTI))))
;
@@ -87,47 +87,47 @@ static inline void ClearOUT(void)
}
static
-void Send(volatile const u8* data, u8 count)
+void Send(volatile const uint8_t* data, uint8_t count)
{
- TXLED1; // light the TX LED
+ TX_LED_ON(); // light the TX LED
TxLEDPulse = TX_RX_LED_PULSE_MS;
while (count--)
UEDATX = *data++;
}
-void Recv(volatile u8* data, u8 count)
+void Recv(volatile uint8_t* data, uint8_t count)
{
- RXLED1; // light the RX LED
+ RX_LED_ON(); // light the RX LED
RxLEDPulse = TX_RX_LED_PULSE_MS;
while (count--)
*data++ = UEDATX;
}
-static inline u8 Recv8()
+static inline uint8_t Recv8()
{
- RXLED1; // light the RX LED
+ RX_LED_ON(); // light the RX LED
RxLEDPulse = TX_RX_LED_PULSE_MS;
return UEDATX;
}
-static inline void Send8(u8 d)
+static inline void Send8(uint8_t d)
{
- TXLED1; // light the TX LED
+ TX_LED_ON(); // light the TX LED
TxLEDPulse = TX_RX_LED_PULSE_MS;
UEDATX = d;
}
-static inline void SetEP(u8 ep)
+static inline void SetEP(uint8_t ep)
{
UENUM = ep;
}
-static inline u8 FifoByteCount()
+static inline uint8_t FifoByteCount()
{
return UEBCLX;
}
-static inline u8 ReceivedSetupInt()
+static inline uint8_t ReceivedSetupInt()
{
return UEINTX & (1<<RXSTPI);
}
@@ -142,17 +142,17 @@ static inline void Stall()
UECONX = (1<<STALLRQ) | (1<<EPEN);
}
-static inline u8 ReadWriteAllowed()
+static inline uint8_t ReadWriteAllowed()
{
return UEINTX & (1<<RWAL);
}
-static inline u8 Stalled()
+static inline uint8_t Stalled()
{
return UEINTX & (1<<STALLEDI);
}
-static inline u8 FifoFree()
+static inline uint8_t FifoFree()
{
return UEINTX & (1<<FIFOCON);
}
@@ -167,7 +167,7 @@ static inline void ReleaseTX()
UEINTX = 0x3A; // FIFOCON=0 NAKINI=0 RWAL=1 NAKOUTI=1 RXSTPI=1 RXOUTI=0 STALLEDI=1 TXINI=0
}
-static inline u8 FrameNumber()
+static inline uint8_t FrameNumber()
{
return UDFNUML;
}
@@ -178,7 +178,7 @@ static inline u8 FrameNumber()
#define EP_SINGLE_64 0x32 // EP0
#define EP_DOUBLE_64 0x36 // Other endpoints
-static void InitEP(u8 index, u8 type, u8 size)
+static void InitEP(uint8_t index, uint8_t type, uint8_t size)
{
UENUM = index;
UECONX = 1;
@@ -202,19 +202,19 @@ void USBInit(void)
UDCON = 0; // enable attach resistor
}
-u8 USBGetConfiguration(void)
+uint8_t USBGetConfiguration(void)
{
return _usbConfiguration;
}
-u8 HasData(u8 ep)
+uint8_t HasData(uint8_t ep)
{
SetEP(ep);
return ReadWriteAllowed(); // count in fifo
}
int USBGetChar();
-void Recv(u8 ep, u8* dst, u8 len)
+void Recv(uint8_t ep, uint8_t* dst, uint8_t len)
{
SetEP(ep);
while (len--)
@@ -228,16 +228,16 @@ void Recv(u8 ep, u8* dst, u8 len)
}
// Transmit a packet to endpoint
-void Transfer(u8 ep, const u8* data, int len)
+void Transfer(uint8_t ep, const uint8_t* data, int len)
{
- u8 zero = ep & TRANSFER_ZERO;
+ uint8_t zero = ep & TRANSFER_ZERO;
SetEP(ep & 7);
while (len--)
{
while (!ReadWriteAllowed())
; // TODO Check for STALL etc
- u8 d = (ep & TRANSFER_PGM) ? pgm_read_byte(data) : data[0];
+ uint8_t d = (ep & TRANSFER_PGM) ? pgm_read_byte(data) : data[0];
data++;
if (zero)
d = 0;
@@ -250,23 +250,23 @@ void Transfer(u8 ep, const u8* data, int len)
ReleaseTX();
}
-extern const u8 _initEndpoints[] PROGMEM;
-const u8 _initEndpoints[] =
+extern const uint8_t _initEndpoints[] PROGMEM;
+const uint8_t _initEndpoints[] =
{
0,
-#ifdef CDC_ENABLED
EP_TYPE_INTERRUPT_IN, // CDC_ENDPOINT_ACM
EP_TYPE_BULK_OUT, // CDC_ENDPOINT_OUT
EP_TYPE_BULK_IN, // CDC_ENDPOINT_IN
-#endif
+#ifdef HID_ENABLED
EP_TYPE_INTERRUPT_IN, // HID_ENDPOINT_INT
+#endif
};
static void InitEndpoints()
{
- for (u8 i = 1; i < sizeof(_initEndpoints); i++)
+ for (uint8_t i = 1; i < sizeof(_initEndpoints); i++)
{
UENUM = i;
UECONX = 1;
@@ -279,12 +279,12 @@ static void InitEndpoints()
typedef struct
{
- u8 bmRequestType;
- u8 bRequest;
- u8 wValueL;
- u8 wValueH;
- u16 wIndex;
- u16 wLength;
+ uint8_t bmRequestType;
+ uint8_t bRequest;
+ uint8_t wValueL;
+ uint8_t wValueH;
+ uint16_t wIndex;
+ uint16_t wLength;
} Setup;
Setup _setup;
@@ -292,18 +292,18 @@ Setup _setup;
bool USBHook()
{
Setup& setup = _setup;
- u8 r = setup.bRequest;
+ uint8_t r = setup.bRequest;
// CDC Requests
if (CDC_GET_LINE_CODING == r)
{
- Send((const volatile u8*)&_usbLineInfo,7);
+ Send((const volatile uint8_t*)&_usbLineInfo,7);
}
else if (CDC_SET_LINE_CODING == r)
{
WaitOUT();
- Recv((volatile u8*)&_usbLineInfo,7);
+ Recv((volatile uint8_t*)&_usbLineInfo,7);
ClearOUT();
}
@@ -315,7 +315,7 @@ bool USBHook()
return true;
}
-extern const u8 _rawHID[] PROGMEM;
+extern const uint8_t _rawHID[] PROGMEM;
#define LSB(_x) ((_x) & 0xFF)
#define MSB(_x) ((_x) >> 8)
@@ -324,7 +324,7 @@ extern const u8 _rawHID[] PROGMEM;
#define RAWHID_TX_SIZE 64
#define RAWHID_RX_SIZE 64
-const u8 _rawHID[] =
+const uint8_t _rawHID[] =
{
// RAW HID
0x06, LSB(RAWHID_USAGE_PAGE), MSB(RAWHID_USAGE_PAGE), // 30
@@ -346,40 +346,42 @@ const u8 _rawHID[] =
0xC0 // end collection
};
-u8 _cdcComposite = 0;
+uint8_t _cdcComposite = 0;
bool SendDescriptor()
{
Setup& setup = _setup;
- u8 desc_length = 0;
- const u8* desc_addr = 0;
+ uint16_t desc_length = 0;
+ const uint8_t* desc_addr = 0;
- u8 t = setup.wValueH;
+ uint8_t t = setup.wValueH;
if (0x22 == t)
{
+#ifdef HID_ENABLED
desc_addr = _rawHID;
desc_length = sizeof(desc_length);
+#endif
} else if (USB_DEVICE_DESCRIPTOR_TYPE == t)
{
if (setup.wLength == 8)
_cdcComposite = 1;
- desc_addr = _cdcComposite ? (const u8*)&USB_DeviceDescriptorA : (const u8*)&USB_DeviceDescriptor;
+ desc_addr = _cdcComposite ? (const uint8_t*)&USB_DeviceDescriptorA : (const uint8_t*)&USB_DeviceDescriptor;
}
else if (USB_CONFIGURATION_DESCRIPTOR_TYPE == t)
{
- desc_addr = (const u8*)&USB_ConfigDescriptor;
+ desc_addr = (const uint8_t*)&USB_ConfigDescriptor;
desc_length = sizeof(USB_ConfigDescriptor);
}
else if (USB_STRING_DESCRIPTOR_TYPE == t)
{
if (setup.wValueL == 0)
- desc_addr = (const u8*)&STRING_LANGUAGE;
+ desc_addr = (const uint8_t*)&STRING_LANGUAGE;
else if (setup.wValueL == IPRODUCT)
- desc_addr = (const u8*)&STRING_IPRODUCT;
+ desc_addr = (const uint8_t*)&STRING_IPRODUCT;
else if (setup.wValueL == ISERIAL)
- desc_addr = (const u8*)&STRING_SERIAL;
+ desc_addr = (const uint8_t*)&STRING_SERIAL;
else if (setup.wValueL == IMANUFACTURER)
- desc_addr = (const u8*)&STRING_IMANUFACTURER;
+ desc_addr = (const uint8_t*)&STRING_IMANUFACTURER;
else
return false;
} else
@@ -387,19 +389,19 @@ bool SendDescriptor()
if (desc_length == 0)
desc_length = pgm_read_byte(desc_addr);
- if ((u8)setup.wLength < desc_length) // bit of a cheat limiting to 255 bytes TODO (saved 8 bytes)
- desc_length = (u8)setup.wLength;
+ if (setup.wLength < desc_length)
+ desc_length = setup.wLength;
// Send descriptor
// EP0 is 64 bytes long
// RWAL and FIFOCON don't work on EP0
- u8 n = 0;
+ uint16_t n = 0;
do
{
if (!WaitForINOrOUT())
return false;
Send8(pgm_read_byte(&desc_addr[n++]));
- u8 clr = n & 0x3F;
+ uint8_t clr = n & 0x3F;
if (!clr)
ClearIN(); // Fifo is full, release this packet
} while (n < desc_length);
@@ -413,7 +415,7 @@ void USBSetupInterrupt()
return;
Setup& setup = _setup; // global saves ~30 bytes
- Recv((u8*)&setup,8);
+ Recv((uint8_t*)&setup,8);
ClearSetupInt();
if (setup.bmRequestType & DEVICETOHOST)
@@ -422,7 +424,7 @@ void USBSetupInterrupt()
ClearIN();
bool ok = true;
- u8 r = setup.bRequest;
+ uint8_t r = setup.bRequest;
if (SET_ADDRESS == r)
{
WaitIN();
@@ -458,7 +460,7 @@ void USBSetupInterrupt()
void USBGeneralInterrupt()
{
- u8 udint = UDINT;
+ uint8_t udint = UDINT;
UDINT = 0;
// End of Reset
@@ -473,9 +475,9 @@ void USBGeneralInterrupt()
{
// check whether the one-shot period has elapsed. if so, turn off the LED
if (TxLEDPulse && !(--TxLEDPulse))
- TXLED0;
+ TX_LED_OFF();
if (RxLEDPulse && !(--RxLEDPulse))
- RXLED0;
+ RX_LED_OFF();
if (!_ejected)
_timeout = 0;
@@ -493,14 +495,14 @@ int USBGetChar()
// Read a char
if (HasData(CDC_RX))
{
- u8 c = Recv8();
+ uint8_t c = Recv8();
if (!ReadWriteAllowed())
ReleaseRX();
return c;
}
if (!--_timeout) {
- Reboot(); // USB not connected, run firmware
+ Reset();
}
_delay_us(100); // stretch out the bootloader period to about 5 seconds after enumeration
diff --git a/bootloaders/diskloader/src/USBCore.h b/bootloaders/caterina/src/USBCore.h
index 537c0ec..313ae3b 100644
--- a/bootloaders/diskloader/src/USBCore.h
+++ b/bootloaders/caterina/src/USBCore.h
@@ -97,32 +97,32 @@
// Device
typedef struct {
- u8 len; // 18
- u8 dtype; // 1 USB_DEVICE_DESCRIPTOR_TYPE
- u16 usbVersion; // 0x200
- u8 deviceClass;
- u8 deviceSubClass;
- u8 deviceProtocol;
- u8 packetSize0; // Packet 0
- u16 idVendor;
- u16 idProduct;
- u16 deviceVersion; // 0x100
- u8 iManufacturer;
- u8 iProduct;
- u8 iSerialNumber;
- u8 bNumConfigurations;
+ uint8_t len; // 18
+ uint8_t dtype; // 1 USB_DEVICE_DESCRIPTOR_TYPE
+ uint16_t usbVersion; // 0x200
+ uint8_t deviceClass;
+ uint8_t deviceSubClass;
+ uint8_t deviceProtocol;
+ uint8_t packetSize0; // Packet 0
+ uint16_t idVendor;
+ uint16_t idProduct;
+ uint16_t deviceVersion; // 0x100
+ uint8_t iManufacturer;
+ uint8_t iProduct;
+ uint8_t iSerialNumber;
+ uint8_t bNumConfigurations;
} DeviceDescriptor;
// Config
typedef struct {
- u8 len; // 9
- u8 dtype; // 2
- u16 clen; // total length
- u8 numInterfaces;
- u8 config;
- u8 iconfig;
- u8 attributes;
- u8 maxPower;
+ uint8_t len; // 9
+ uint8_t dtype; // 2
+ uint16_t clen; // total length
+ uint8_t numInterfaces;
+ uint8_t config;
+ uint8_t iconfig;
+ uint8_t attributes;
+ uint8_t maxPower;
} ConfigDescriptor;
// String
@@ -130,58 +130,58 @@ typedef struct {
// Interface
typedef struct
{
- u8 len; // 9
- u8 dtype; // 4
- u8 number;
- u8 alternate;
- u8 numEndpoints;
- u8 interfaceClass;
- u8 interfaceSubClass;
- u8 protocol;
- u8 iInterface;
+ uint8_t len; // 9
+ uint8_t dtype; // 4
+ uint8_t number;
+ uint8_t alternate;
+ uint8_t numEndpoints;
+ uint8_t interfaceClass;
+ uint8_t interfaceSubClass;
+ uint8_t protocol;
+ uint8_t iInterface;
} InterfaceDescriptor;
// Endpoint
typedef struct
{
- u8 len; // 7
- u8 dtype; // 5
- u8 addr;
- u8 attr;
- u16 packetSize;
- u8 interval;
+ uint8_t len; // 7
+ uint8_t dtype; // 5
+ uint8_t addr;
+ uint8_t attr;
+ uint16_t packetSize;
+ uint8_t interval;
} EndpointDescriptor;
// Interface Association Descriptor
// Used to bind 2 interfaces together in CDC compostite device
typedef struct
{
- u8 len; // 8
- u8 dtype; // 11
- u8 firstInterface;
- u8 interfaceCount;
- u8 functionClass;
- u8 funtionSubClass;
- u8 functionProtocol;
- u8 iInterface;
+ uint8_t len; // 8
+ uint8_t dtype; // 11
+ uint8_t firstInterface;
+ uint8_t interfaceCount;
+ uint8_t functionClass;
+ uint8_t funtionSubClass;
+ uint8_t functionProtocol;
+ uint8_t iInterface;
} IADDescriptor;
// CDC CS interface descriptor
typedef struct
{
- u8 len; // 5
- u8 dtype; // 0x24
- u8 subtype;
- u8 d0;
- u8 d1;
+ uint8_t len; // 5
+ uint8_t dtype; // 0x24
+ uint8_t subtype;
+ uint8_t d0;
+ uint8_t d1;
} CDCCSInterfaceDescriptor;
typedef struct
{
- u8 len; // 4
- u8 dtype; // 0x24
- u8 subtype;
- u8 d0;
+ uint8_t len; // 4
+ uint8_t dtype; // 0x24
+ uint8_t subtype;
+ uint8_t d0;
} CDCCSInterfaceDescriptor4;
typedef struct
@@ -204,15 +204,15 @@ typedef struct
typedef struct
{
- u8 len; // 9
- u8 dtype; // 0x21
- u8 addr;
- u8 versionL; // 0x101
- u8 versionH; // 0x101
- u8 country;
- u8 desctype; // 0x22 report
- u8 descLenL;
- u8 descLenH;
+ uint8_t len; // 9
+ uint8_t dtype; // 0x21
+ uint8_t addr;
+ uint8_t versionL; // 0x101
+ uint8_t versionH; // 0x101
+ uint8_t country;
+ uint8_t desctype; // 0x22 report
+ uint8_t descLenL;
+ uint8_t descLenH;
} HIDDescDescriptor;
typedef struct
diff --git a/bootloaders/diskloader/src/USBDesc.cpp b/bootloaders/caterina/src/USBDesc.cpp
index ade072a..a84f3be 100644
--- a/bootloaders/diskloader/src/USBDesc.cpp
+++ b/bootloaders/caterina/src/USBDesc.cpp
@@ -22,43 +22,37 @@
//====================================================================================================
// Actual device descriptors
-const u16 STRING_LANGUAGE[2] = {
+const uint16_t STRING_LANGUAGE[2] = {
(3<<8) | (2+2),
0x0409 // English
};
-const u16 STRING_SERIAL[13] = {
+const uint16_t STRING_SERIAL[13] = {
(3<<8) | (2+2*12),
USB_SERIAL_STRING
};
-const u16 STRING_IPRODUCT[28] = {
+const uint16_t STRING_IPRODUCT[28] = {
(3<<8) | (2+2*27),
-#if USB_PID == USB_PID_LEONARDO
+#if USB_PID == USB_PID_LEONARDO_BOOTLOADER
'A','r','d','u','i','n','o',' ','L','e','o','n','a','r','d','o',' ','b','o','o','t','l','o','a','d','e','r'
-#elif USB_PID == USB_PID_MICRO
+#elif USB_PID == USB_PID_MICRO_BOOTLOADER
'A','r','d','u','i','n','o',' ','M','i','c','r','o',' ','b','o','o','t','l','o','a','d','e','r',' ',' ',' '
#endif
};
-const u16 STRING_IMANUFACTURER[12] = {
+const uint16_t STRING_IMANUFACTURER[12] = {
(3<<8) | (2+2*11),
'A','r','d','u','i','n','o',' ','L','L','C'
};
-
-//#ifdef CDC_ENABLED
DeviceDescriptor USB_DeviceDescriptorA = D_DEVICE(0X02,0X00,0X00,64,USB_VID,USB_PID,0x100,0,IPRODUCT,ISERIAL,1);
-//#else
DeviceDescriptor USB_DeviceDescriptor = D_DEVICE(0x00,0x00,0x00,64,USB_VID,USB_PID,0x100,0,IPRODUCT,ISERIAL,1);
-//#endif
-
Config USB_ConfigDescriptor =
{
D_CONFIG(sizeof(Config),INTERFACE_COUNT),
-#ifdef CDC_ENABLED
// CDC
{
D_IAD(0,2,CDC_COMMUNICATION_INTERFACE_CLASS,CDC_ABSTRACT_CONTROL_MODEL,1),
@@ -76,12 +70,14 @@ Config USB_ConfigDescriptor =
D_ENDPOINT(USB_ENDPOINT_OUT(CDC_ENDPOINT_OUT),USB_ENDPOINT_TYPE_BULK,0x40,0),
D_ENDPOINT(USB_ENDPOINT_IN (CDC_ENDPOINT_IN ),USB_ENDPOINT_TYPE_BULK,0x40,0)
},
-#endif
+
+#ifdef HID_ENABLED
// HID
{
D_INTERFACE(HID_INTERFACE,1,3,0,0),
D_HIDREPORT(30),
D_ENDPOINT(USB_ENDPOINT_IN (HID_ENDPOINT_INT),USB_ENDPOINT_TYPE_INTERRUPT,0x40,0x40)
}
+#endif
};
diff --git a/bootloaders/diskloader/src/USBDesc.h b/bootloaders/caterina/src/USBDesc.h
index a970fa4..fa962e9 100644
--- a/bootloaders/diskloader/src/USBDesc.h
+++ b/bootloaders/caterina/src/USBDesc.h
@@ -16,46 +16,41 @@
** SOFTWARE.
*/
-
-#ifdef CDC_ENABLED
-
-#define CDC_ACM_INTERFACE 0 // CDC ACM
-#define CDC_DATA_INTERFACE 1 // CDC Data
-#define CDC_ENDPOINT_ACM 1
-#define CDC_ENDPOINT_OUT 2
-#define CDC_ENDPOINT_IN 3
-
-#define HID_INTERFACE 2 // HID Interface
-#define HID_ENDPOINT_INT 4
-
-#define INTERFACE_COUNT 3 // 2 for cdc + 1 for hid
-
-#else
-
-#define HID_INTERFACE 2 // HID Interface
-#define HID_ENDPOINT_INT 4
-
-#define INTERFACE_COUNT 1 // 1 for hid
-
-#endif
+#ifndef HID_ENABLED // HID is NOT enabled
+ #define CDC_ACM_INTERFACE 0 // CDC ACM
+ #define CDC_DATA_INTERFACE 1 // CDC Data
+ #define CDC_ENDPOINT_ACM 1
+ #define CDC_ENDPOINT_OUT 2
+ #define CDC_ENDPOINT_IN 3
+ #define INTERFACE_COUNT 2 // 2 for CDC
+#else // HID is enabled
+ #define CDC_ACM_INTERFACE 0 // CDC ACM
+ #define CDC_DATA_INTERFACE 1 // CDC Data
+ #define CDC_ENDPOINT_ACM 1
+ #define CDC_ENDPOINT_OUT 2
+ #define CDC_ENDPOINT_IN 3
+ #define HID_INTERFACE 2 // HID Interface
+ #define HID_ENDPOINT_INT 4
+ #define INTERFACE_COUNT 3 // 2 for CDC + 1 for hid
+#endif
typedef struct
{
ConfigDescriptor config;
-#ifdef CDC_ENABLED
CDCDescriptor cdc;
-#endif
+#ifdef HID_ENABLED
HIDDescriptor hid;
+#endif
} Config;
extern Config USB_ConfigDescriptor PROGMEM;
extern DeviceDescriptor USB_DeviceDescriptor PROGMEM;
extern DeviceDescriptor USB_DeviceDescriptorA PROGMEM;
-extern const u16 STRING_LANGUAGE[2] PROGMEM;
-extern const u16 STRING_IPRODUCT[28] PROGMEM;
-extern const u16 STRING_IMANUFACTURER[12] PROGMEM;
-extern const u16 STRING_SERIAL[13] PROGMEM;
+extern const uint16_t STRING_LANGUAGE[2] PROGMEM;
+extern const uint16_t STRING_IPRODUCT[28] PROGMEM;
+extern const uint16_t STRING_IMANUFACTURER[12] PROGMEM;
+extern const uint16_t STRING_SERIAL[13] PROGMEM;
#define IMANUFACTURER 1
#define IPRODUCT 2
diff --git a/bootloaders/caterina_LUFA/Caterina.c b/bootloaders/caterina_LUFA/Caterina.c
new file mode 100755
index 0000000..c8e82a9
--- /dev/null
+++ b/bootloaders/caterina_LUFA/Caterina.c
@@ -0,0 +1,698 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2011.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2011 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+ Permission to use, copy, modify, distribute, and sell this
+ software and its documentation for any purpose is hereby granted
+ without fee, provided that the above copyright notice appear in
+ all copies and that both that the copyright notice and this
+ permission notice and warranty disclaimer appear in supporting
+ documentation, and that the name of the author not be used in
+ advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+
+ The author disclaim all warranties with regard to this
+ software, including all implied warranties of merchantability
+ and fitness. In no event shall the author be liable for any
+ special, indirect or consequential damages or any damages
+ whatsoever resulting from loss of use, data or profits, whether
+ in an action of contract, negligence or other tortious action,
+ arising out of or in connection with the use or performance of
+ this software.
+*/
+
+/** \file
+ *
+ * Main source file for the CDC class bootloader. This file contains the complete bootloader logic.
+ */
+
+#define INCLUDE_FROM_CATERINA_C
+#include "Caterina.h"
+
+/** Contains the current baud rate and other settings of the first virtual serial port. This must be retained as some
+ * operating systems will not open the port unless the settings can be set successfully.
+ */
+static CDC_LineEncoding_t LineEncoding = { .BaudRateBPS = 0,
+ .CharFormat = CDC_LINEENCODING_OneStopBit,
+ .ParityType = CDC_PARITY_None,
+ .DataBits = 8 };
+
+/** Current address counter. This stores the current address of the FLASH or EEPROM as set by the host,
+ * and is used when reading or writing to the AVRs memory (either FLASH or EEPROM depending on the issued
+ * command.)
+ */
+static uint32_t CurrAddress;
+
+/** Flag to indicate if the bootloader should be running, or should exit and allow the application code to run
+ * via a watchdog reset. When cleared the bootloader will exit, starting the watchdog and entering an infinite
+ * loop until the AVR restarts and the application runs.
+ */
+static bool RunBootloader = true;
+
+/* Pulse generation counters to keep track of the time remaining for each pulse type */
+#define TX_RX_LED_PULSE_PERIOD 100
+uint16_t TxLEDPulse = 0; // time remaining for Tx LED pulse
+uint16_t RxLEDPulse = 0; // time remaining for Rx LED pulse
+
+/* Bootloader timeout timer */
+uint16_t Timeout = 0;
+
+uint16_t bootKey = 0x7777;
+volatile uint16_t *const bootKeyPtr = (volatile uint16_t *)0x0A00;
+
+void StartSketch(void)
+{
+ cli();
+
+ /* Undo TIMER1 setup and clear the count before running the sketch */
+ TIMSK1 = 0;
+ TCCR1B = 0;
+ TCNT1H = 0; // 16-bit write to TCNT1 requires high byte be written first
+ TCNT1L = 0;
+
+ /* Relocate the interrupt vector table to the application section */
+ MCUCR = (1 << IVCE);
+ MCUCR = 0;
+
+ L_LED_OFF();
+ TX_LED_OFF();
+ RX_LED_OFF();
+
+ /* jump to beginning of application space */
+ __asm__ volatile("jmp 0x0000");
+}
+
+/* Breathing animation on L LED indicates bootloader is running */
+uint16_t LLEDPulse;
+void LEDPulse(void)
+{
+ LLEDPulse++;
+ uint8_t p = LLEDPulse >> 8;
+ if (p > 127)
+ p = 254-p;
+ p += p;
+ if (((uint8_t)LLEDPulse) > p)
+ L_LED_OFF();
+ else
+ L_LED_ON();
+}
+
+/** Main program entry point. This routine configures the hardware required by the bootloader, then continuously
+ * runs the bootloader processing routine until instructed to soft-exit, or hard-reset via the watchdog to start
+ * the loaded application code.
+ */
+int main(void)
+{
+ /* Watchdog may be configured with a 15 ms period so must disable it before doing anything else */
+ wdt_disable();
+
+ /* Check the reason for the reset and act accordingly */
+ uint8_t mcusr_state = MCUSR; // store the initial state of the Status register
+ MCUSR = 0; // clear all reset flags
+ // After a power-on reset skip the bootloader and jump straight to sketch
+ // if one exists.
+ if (mcusr_state & (1<<PORF) && pgm_read_word(0) != 0xFFFF) {
+ StartSketch();
+ }
+ uint16_t bootKeyPtrVal = *bootKeyPtr;
+ *bootKeyPtr = 0;
+ if ((mcusr_state & (1<<WDRF)) && (bootKeyPtrVal != bootKey) && (pgm_read_word(0) != 0xFFFF)) {
+ StartSketch();
+ }
+
+ /* Setup hardware required for the bootloader */
+ SetupHardware();
+
+ /* Enable global interrupts so that the USB stack can function */
+ sei();
+
+ while (RunBootloader)
+ {
+ CDC_Task();
+ USB_USBTask();
+ /* Time out and start the sketch if one is present */
+ if (Timeout > 8000)
+ RunBootloader = false;
+
+ LEDPulse();
+ }
+
+ /* Disconnect from the host - USB interface will be reset later along with the AVR */
+ USB_Detach();
+
+ /* Jump to beginning of application space to run the sketch - do not reset */
+ StartSketch();
+}
+
+/** Configures all hardware required for the bootloader. */
+void SetupHardware(void)
+{
+ /* Disable watchdog if enabled by bootloader/fuses */
+ MCUSR &= ~(1 << WDRF);
+ wdt_disable();
+
+ /* Disable clock division */
+ clock_prescale_set(clock_div_1);
+
+ /* Relocate the interrupt vector table to the bootloader section */
+ MCUCR = (1 << IVCE);
+ MCUCR = (1 << IVSEL);
+
+ LED_SETUP();
+ CPU_PRESCALE(0);
+ L_LED_OFF();
+ TX_LED_OFF();
+ RX_LED_OFF();
+
+ /* Initialize TIMER1 to handle bootloader timeout and LED tasks.
+ * With 16 MHz clock and 1/64 prescaler, timer 1 is clocked at 250 kHz
+ * Our chosen compare match generates an interrupt every 1 ms.
+ * This interrupt is disabled selectively when doing memory reading, erasing,
+ * or writing since SPM has tight timing requirements.
+ */
+ OCR1AH = 0;
+ OCR1AL = 250;
+ TIMSK1 = (1 << OCIE1A); // enable timer 1 output compare A match interrupt
+ TCCR1B = ((1 << CS11) | (1 << CS10)); // 1/64 prescaler on timer 1 input
+
+ /* Initialize USB Subsystem */
+ USB_Init();
+}
+
+//uint16_t ctr = 0;
+ISR(TIMER1_COMPA_vect, ISR_BLOCK)
+{
+ /* Reset counter */
+ TCNT1H = 0;
+ TCNT1L = 0;
+
+ /* Check whether the TX or RX LED one-shot period has elapsed. if so, turn off the LED */
+ if (TxLEDPulse && !(--TxLEDPulse))
+ TX_LED_OFF();
+ if (RxLEDPulse && !(--RxLEDPulse))
+ RX_LED_OFF();
+
+ if (pgm_read_word(0) != 0xFFFF)
+ Timeout++;
+}
+
+/** Event handler for the USB_ConfigurationChanged event. This configures the device's endpoints ready
+ * to relay data to and from the attached USB host.
+ */
+void EVENT_USB_Device_ConfigurationChanged(void)
+{
+ /* Setup CDC Notification, Rx and Tx Endpoints */
+ Endpoint_ConfigureEndpoint(CDC_NOTIFICATION_EPNUM, EP_TYPE_INTERRUPT,
+ ENDPOINT_DIR_IN, CDC_NOTIFICATION_EPSIZE,
+ ENDPOINT_BANK_SINGLE);
+
+ Endpoint_ConfigureEndpoint(CDC_TX_EPNUM, EP_TYPE_BULK,
+ ENDPOINT_DIR_IN, CDC_TXRX_EPSIZE,
+ ENDPOINT_BANK_SINGLE);
+
+ Endpoint_ConfigureEndpoint(CDC_RX_EPNUM, EP_TYPE_BULK,
+ ENDPOINT_DIR_OUT, CDC_TXRX_EPSIZE,
+ ENDPOINT_BANK_SINGLE);
+}
+
+/** Event handler for the USB_ControlRequest event. This is used to catch and process control requests sent to
+ * the device from the USB host before passing along unhandled control requests to the library for processing
+ * internally.
+ */
+void EVENT_USB_Device_ControlRequest(void)
+{
+ /* Ignore any requests that aren't directed to the CDC interface */
+ if ((USB_ControlRequest.bmRequestType & (CONTROL_REQTYPE_TYPE | CONTROL_REQTYPE_RECIPIENT)) !=
+ (REQTYPE_CLASS | REQREC_INTERFACE))
+ {
+ return;
+ }
+
+ /* Process CDC specific control requests */
+ switch (USB_ControlRequest.bRequest)
+ {
+ case CDC_REQ_GetLineEncoding:
+ if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
+ {
+ Endpoint_ClearSETUP();
+
+ /* Write the line coding data to the control endpoint */
+ Endpoint_Write_Control_Stream_LE(&LineEncoding, sizeof(CDC_LineEncoding_t));
+ Endpoint_ClearOUT();
+ }
+
+ break;
+ case CDC_REQ_SetLineEncoding:
+ if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
+ {
+ Endpoint_ClearSETUP();
+
+ /* Read the line coding data in from the host into the global struct */
+ Endpoint_Read_Control_Stream_LE(&LineEncoding, sizeof(CDC_LineEncoding_t));
+ Endpoint_ClearIN();
+ }
+
+ break;
+ }
+}
+
+#if !defined(NO_BLOCK_SUPPORT)
+/** Reads or writes a block of EEPROM or FLASH memory to or from the appropriate CDC data endpoint, depending
+ * on the AVR910 protocol command issued.
+ *
+ * \param[in] Command Single character AVR910 protocol command indicating what memory operation to perform
+ */
+static void ReadWriteMemoryBlock(const uint8_t Command)
+{
+ uint16_t BlockSize;
+ char MemoryType;
+
+ bool HighByte = false;
+ uint8_t LowByte = 0;
+
+ BlockSize = (FetchNextCommandByte() << 8);
+ BlockSize |= FetchNextCommandByte();
+
+ MemoryType = FetchNextCommandByte();
+
+ if ((MemoryType != 'E') && (MemoryType != 'F'))
+ {
+ /* Send error byte back to the host */
+ WriteNextResponseByte('?');
+
+ return;
+ }
+
+ /* Disable timer 1 interrupt - can't afford to process nonessential interrupts
+ * while doing SPM tasks */
+ TIMSK1 = 0;
+
+ /* Check if command is to read memory */
+ if (Command == 'g')
+ {
+ /* Re-enable RWW section */
+ boot_rww_enable();
+
+ while (BlockSize--)
+ {
+ if (MemoryType == 'F')
+ {
+ /* Read the next FLASH byte from the current FLASH page */
+ #if (FLASHEND > 0xFFFF)
+ WriteNextResponseByte(pgm_read_byte_far(CurrAddress | HighByte));
+ #else
+ WriteNextResponseByte(pgm_read_byte(CurrAddress | HighByte));
+ #endif
+
+ /* If both bytes in current word have been read, increment the address counter */
+ if (HighByte)
+ CurrAddress += 2;
+
+ HighByte = !HighByte;
+ }
+ else
+ {
+ /* Read the next EEPROM byte into the endpoint */
+ WriteNextResponseByte(eeprom_read_byte((uint8_t*)(intptr_t)(CurrAddress >> 1)));
+
+ /* Increment the address counter after use */
+ CurrAddress += 2;
+ }
+ }
+ }
+ else
+ {
+ uint32_t PageStartAddress = CurrAddress;
+
+ if (MemoryType == 'F')
+ {
+ boot_page_erase(PageStartAddress);
+ boot_spm_busy_wait();
+ }
+
+ while (BlockSize--)
+ {
+ if (MemoryType == 'F')
+ {
+ /* If both bytes in current word have been written, increment the address counter */
+ if (HighByte)
+ {
+ /* Write the next FLASH word to the current FLASH page */
+ boot_page_fill(CurrAddress, ((FetchNextCommandByte() << 8) | LowByte));
+
+ /* Increment the address counter after use */
+ CurrAddress += 2;
+ }
+ else
+ {
+ LowByte = FetchNextCommandByte();
+ }
+
+ HighByte = !HighByte;
+ }
+ else
+ {
+ /* Write the next EEPROM byte from the endpoint */
+ eeprom_write_byte((uint8_t*)((intptr_t)(CurrAddress >> 1)), FetchNextCommandByte());
+
+ /* Increment the address counter after use */
+ CurrAddress += 2;
+ }
+ }
+
+ /* If in FLASH programming mode, commit the page after writing */
+ if (MemoryType == 'F')
+ {
+ /* Commit the flash page to memory */
+ boot_page_write(PageStartAddress);
+
+ /* Wait until write operation has completed */
+ boot_spm_busy_wait();
+ }
+
+ /* Send response byte back to the host */
+ WriteNextResponseByte('\r');
+ }
+
+ /* Re-enable timer 1 interrupt disabled earlier in this routine */
+ TIMSK1 = (1 << OCIE1A);
+}
+#endif
+
+/** Retrieves the next byte from the host in the CDC data OUT endpoint, and clears the endpoint bank if needed
+ * to allow reception of the next data packet from the host.
+ *
+ * \return Next received byte from the host in the CDC data OUT endpoint
+ */
+static uint8_t FetchNextCommandByte(void)
+{
+ /* Select the OUT endpoint so that the next data byte can be read */
+ Endpoint_SelectEndpoint(CDC_RX_EPNUM);
+
+ /* If OUT endpoint empty, clear it and wait for the next packet from the host */
+ while (!(Endpoint_IsReadWriteAllowed()))
+ {
+ Endpoint_ClearOUT();
+
+ while (!(Endpoint_IsOUTReceived()))
+ {
+ if (USB_DeviceState == DEVICE_STATE_Unattached)
+ return 0;
+ }
+ }
+
+ /* Fetch the next byte from the OUT endpoint */
+ return Endpoint_Read_8();
+}
+
+/** Writes the next response byte to the CDC data IN endpoint, and sends the endpoint back if needed to free up the
+ * bank when full ready for the next byte in the packet to the host.
+ *
+ * \param[in] Response Next response byte to send to the host
+ */
+static void WriteNextResponseByte(const uint8_t Response)
+{
+ /* Select the IN endpoint so that the next data byte can be written */
+ Endpoint_SelectEndpoint(CDC_TX_EPNUM);
+
+ /* If IN endpoint full, clear it and wait until ready for the next packet to the host */
+ if (!(Endpoint_IsReadWriteAllowed()))
+ {
+ Endpoint_ClearIN();
+
+ while (!(Endpoint_IsINReady()))
+ {
+ if (USB_DeviceState == DEVICE_STATE_Unattached)
+ return;
+ }
+ }
+
+ /* Write the next byte to the IN endpoint */
+ Endpoint_Write_8(Response);
+
+ TX_LED_ON();
+ TxLEDPulse = TX_RX_LED_PULSE_PERIOD;
+}
+
+#define STK_OK 0x10
+#define STK_INSYNC 0x14 // ' '
+#define CRC_EOP 0x20 // 'SPACE'
+#define STK_GET_SYNC 0x30 // '0'
+
+#define STK_GET_PARAMETER 0x41 // 'A'
+#define STK_SET_DEVICE 0x42 // 'B'
+#define STK_SET_DEVICE_EXT 0x45 // 'E'
+#define STK_LOAD_ADDRESS 0x55 // 'U'
+#define STK_UNIVERSAL 0x56 // 'V'
+#define STK_PROG_PAGE 0x64 // 'd'
+#define STK_READ_PAGE 0x74 // 't'
+#define STK_READ_SIGN 0x75 // 'u'
+
+/** Task to read in AVR910 commands from the CDC data OUT endpoint, process them, perform the required actions
+ * and send the appropriate response back to the host.
+ */
+void CDC_Task(void)
+{
+ /* Select the OUT endpoint */
+ Endpoint_SelectEndpoint(CDC_RX_EPNUM);
+
+ /* Check if endpoint has a command in it sent from the host */
+ if (!(Endpoint_IsOUTReceived()))
+ return;
+
+ RX_LED_ON();
+ RxLEDPulse = TX_RX_LED_PULSE_PERIOD;
+
+ /* Read in the bootloader command (first byte sent from host) */
+ uint8_t Command = FetchNextCommandByte();
+
+ if (Command == 'E')
+ {
+ RunBootloader = false;
+
+ // Send confirmation byte back to the host
+ WriteNextResponseByte('\r');
+ }
+ else if (Command == 'T')
+ {
+ FetchNextCommandByte();
+
+ // Send confirmation byte back to the host
+ WriteNextResponseByte('\r');
+ }
+ else if ((Command == 'L') || (Command == 'P'))
+ {
+ // Send confirmation byte back to the host
+ WriteNextResponseByte('\r');
+ }
+ else if (Command == 't')
+ {
+ // Return ATMEGA128 part code - this is only to allow AVRProg to use the bootloader
+ WriteNextResponseByte(0x44);
+ WriteNextResponseByte(0x00);
+ }
+ else if (Command == 'a')
+ {
+ // Indicate auto-address increment is supported
+ WriteNextResponseByte('Y');
+ }
+ else if (Command == 'A')
+ {
+ // Set the current address to that given by the host
+ CurrAddress = (FetchNextCommandByte() << 9);
+ CurrAddress |= (FetchNextCommandByte() << 1);
+
+ // Send confirmation byte back to the host
+ WriteNextResponseByte('\r');
+ }
+ else if (Command == 'p')
+ {
+ // Indicate serial programmer back to the host
+ WriteNextResponseByte('S');
+ }
+ else if (Command == 'S')
+ {
+ // Write the 7-byte software identifier to the endpoint
+ for (uint8_t CurrByte = 0; CurrByte < 7; CurrByte++)
+ WriteNextResponseByte(SOFTWARE_IDENTIFIER[CurrByte]);
+ }
+ else if (Command == 'V')
+ {
+ WriteNextResponseByte('0' + BOOTLOADER_VERSION_MAJOR);
+ WriteNextResponseByte('0' + BOOTLOADER_VERSION_MINOR);
+ }
+ else if (Command == 's')
+ {
+ WriteNextResponseByte(AVR_SIGNATURE_3);
+ WriteNextResponseByte(AVR_SIGNATURE_2);
+ WriteNextResponseByte(AVR_SIGNATURE_1);
+ }
+ else if (Command == 'e')
+ {
+ // Clear the application section of flash
+ for (uint32_t CurrFlashAddress = 0; CurrFlashAddress < BOOT_START_ADDR; CurrFlashAddress += SPM_PAGESIZE)
+ {
+ boot_page_erase(CurrFlashAddress);
+ boot_spm_busy_wait();
+ boot_page_write(CurrFlashAddress);
+ boot_spm_busy_wait();
+ }
+
+ // Send confirmation byte back to the host
+ WriteNextResponseByte('\r');
+ }
+ #if !defined(NO_LOCK_BYTE_WRITE_SUPPORT)
+ else if (Command == 'l')
+ {
+ // Set the lock bits to those given by the host
+ boot_lock_bits_set(FetchNextCommandByte());
+
+ // Send confirmation byte back to the host
+ WriteNextResponseByte('\r');
+ }
+ #endif
+ else if (Command == 'r')
+ {
+ WriteNextResponseByte(boot_lock_fuse_bits_get(GET_LOCK_BITS));
+ }
+ else if (Command == 'F')
+ {
+ WriteNextResponseByte(boot_lock_fuse_bits_get(GET_LOW_FUSE_BITS));
+ }
+ else if (Command == 'N')
+ {
+ WriteNextResponseByte(boot_lock_fuse_bits_get(GET_HIGH_FUSE_BITS));
+ }
+ else if (Command == 'Q')
+ {
+ WriteNextResponseByte(boot_lock_fuse_bits_get(GET_EXTENDED_FUSE_BITS));
+ }
+ #if !defined(NO_BLOCK_SUPPORT)
+ else if (Command == 'b')
+ {
+ WriteNextResponseByte('Y');
+
+ // Send block size to the host
+ WriteNextResponseByte(SPM_PAGESIZE >> 8);
+ WriteNextResponseByte(SPM_PAGESIZE & 0xFF);
+ }
+ else if ((Command == 'B') || (Command == 'g'))
+ {
+ Timeout = 0;
+ // Delegate the block write/read to a separate function for clarity
+ ReadWriteMemoryBlock(Command);
+ }
+ #endif
+ #if !defined(NO_FLASH_BYTE_SUPPORT)
+ else if (Command == 'C')
+ {
+ // Write the high byte to the current flash page
+ boot_page_fill(CurrAddress, FetchNextCommandByte());
+
+ // Send confirmation byte back to the host
+ WriteNextResponseByte('\r');
+ }
+ else if (Command == 'c')
+ {
+ // Write the low byte to the current flash page
+ boot_page_fill(CurrAddress | 0x01, FetchNextCommandByte());
+
+ // Increment the address
+ CurrAddress += 2;
+
+ // Send confirmation byte back to the host
+ WriteNextResponseByte('\r');
+ }
+ else if (Command == 'm')
+ {
+ // Commit the flash page to memory
+ boot_page_write(CurrAddress);
+
+ // Wait until write operation has completed
+ boot_spm_busy_wait();
+
+ // Send confirmation byte back to the host
+ WriteNextResponseByte('\r');
+ }
+ else if (Command == 'R')
+ {
+ #if (FLASHEND > 0xFFFF)
+ uint16_t ProgramWord = pgm_read_word_far(CurrAddress);
+ #else
+ uint16_t ProgramWord = pgm_read_word(CurrAddress);
+ #endif
+
+ WriteNextResponseByte(ProgramWord >> 8);
+ WriteNextResponseByte(ProgramWord & 0xFF);
+ }
+ #endif
+ #if !defined(NO_EEPROM_BYTE_SUPPORT)
+ else if (Command == 'D')
+ {
+ // Read the byte from the endpoint and write it to the EEPROM
+ eeprom_write_byte((uint8_t*)((intptr_t)(CurrAddress >> 1)), FetchNextCommandByte());
+
+ // Increment the address after use
+ CurrAddress += 2;
+
+ // Send confirmation byte back to the host
+ WriteNextResponseByte('\r');
+ }
+ else if (Command == 'd')
+ {
+ // Read the EEPROM byte and write it to the endpoint
+ WriteNextResponseByte(eeprom_read_byte((uint8_t*)((intptr_t)(CurrAddress >> 1))));
+
+ // Increment the address after use
+ CurrAddress += 2;
+ }
+ #endif
+ else if (Command != 27)
+ {
+ // Unknown (non-sync) command, return fail code
+ WriteNextResponseByte('?');
+ }
+
+
+ /* Select the IN endpoint */
+ Endpoint_SelectEndpoint(CDC_TX_EPNUM);
+
+ /* Remember if the endpoint is completely full before clearing it */
+ bool IsEndpointFull = !(Endpoint_IsReadWriteAllowed());
+
+ /* Send the endpoint data to the host */
+ Endpoint_ClearIN();
+
+ /* If a full endpoint's worth of data was sent, we need to send an empty packet afterwards to signal end of transfer */
+ if (IsEndpointFull)
+ {
+ while (!(Endpoint_IsINReady()))
+ {
+ if (USB_DeviceState == DEVICE_STATE_Unattached)
+ return;
+ }
+
+ Endpoint_ClearIN();
+ }
+
+ /* Wait until the data has been sent to the host */
+ while (!(Endpoint_IsINReady()))
+ {
+ if (USB_DeviceState == DEVICE_STATE_Unattached)
+ return;
+ }
+
+ /* Select the OUT endpoint */
+ Endpoint_SelectEndpoint(CDC_RX_EPNUM);
+
+ /* Acknowledge the command from the host */
+ Endpoint_ClearOUT();
+}
+
diff --git a/bootloaders/caterina_LUFA/Caterina.h b/bootloaders/caterina_LUFA/Caterina.h
new file mode 100755
index 0000000..f8251d4
--- /dev/null
+++ b/bootloaders/caterina_LUFA/Caterina.h
@@ -0,0 +1,99 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2011.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2011 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+ Permission to use, copy, modify, distribute, and sell this
+ software and its documentation for any purpose is hereby granted
+ without fee, provided that the above copyright notice appear in
+ all copies and that both that the copyright notice and this
+ permission notice and warranty disclaimer appear in supporting
+ documentation, and that the name of the author not be used in
+ advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+
+ The author disclaim all warranties with regard to this
+ software, including all implied warranties of merchantability
+ and fitness. In no event shall the author be liable for any
+ special, indirect or consequential damages or any damages
+ whatsoever resulting from loss of use, data or profits, whether
+ in an action of contract, negligence or other tortious action,
+ arising out of or in connection with the use or performance of
+ this software.
+*/
+
+/** \file
+ *
+ * Header file for BootloaderCDC.c.
+ */
+
+#ifndef _CDC_H_
+#define _CDC_H_
+
+ /* Includes: */
+ #include <avr/io.h>
+ #include <avr/wdt.h>
+ #include <avr/boot.h>
+ #include <avr/eeprom.h>
+ #include <avr/power.h>
+ #include <avr/interrupt.h>
+ #include <stdbool.h>
+
+ #include "Descriptors.h"
+
+ #include <LUFA/Drivers/USB/USB.h>
+ /* Macros: */
+ /** Version major of the CDC bootloader. */
+ #define BOOTLOADER_VERSION_MAJOR 0x01
+
+ /** Version minor of the CDC bootloader. */
+ #define BOOTLOADER_VERSION_MINOR 0x00
+
+ /** Hardware version major of the CDC bootloader. */
+ #define BOOTLOADER_HWVERSION_MAJOR 0x01
+
+ /** Hardware version minor of the CDC bootloader. */
+ #define BOOTLOADER_HWVERSION_MINOR 0x00
+
+ /** Eight character bootloader firmware identifier reported to the host when requested */
+ #define SOFTWARE_IDENTIFIER "CATERINA"
+
+ #define CPU_PRESCALE(n) (CLKPR = 0x80, CLKPR = (n))
+ #define LED_SETUP() DDRC |= (1<<7); DDRB |= (1<<0); DDRD |= (1<<5);
+ #define L_LED_OFF() PORTC &= ~(1<<7)
+ #define L_LED_ON() PORTC |= (1<<7)
+ #define L_LED_TOGGLE() PORTC ^= (1<<7)
+ #define TX_LED_OFF() PORTD |= (1<<5)
+ #define TX_LED_ON() PORTD &= ~(1<<5)
+ #define RX_LED_OFF() PORTB |= (1<<0)
+ #define RX_LED_ON() PORTB &= ~(1<<0)
+
+ /* Type Defines: */
+ /** Type define for a non-returning pointer to the start of the loaded application in flash memory. */
+ typedef void (*AppPtr_t)(void) ATTR_NO_RETURN;
+
+ /* Function Prototypes: */
+ void StartSketch(void);
+ void LEDPulse(void);
+
+ void CDC_Task(void);
+ void SetupHardware(void);
+
+ void EVENT_USB_Device_ConfigurationChanged(void);
+
+ #if defined(INCLUDE_FROM_CATERINA_C) || defined(__DOXYGEN__)
+ #if !defined(NO_BLOCK_SUPPORT)
+ static void ReadWriteMemoryBlock(const uint8_t Command);
+ #endif
+ static uint8_t FetchNextCommandByte(void);
+ static void WriteNextResponseByte(const uint8_t Response);
+ #endif
+
+#endif
+
diff --git a/bootloaders/caterina_LUFA/Caterina.hex b/bootloaders/caterina_LUFA/Caterina.hex
new file mode 100644
index 0000000..98cf01a
--- /dev/null
+++ b/bootloaders/caterina_LUFA/Caterina.hex
@@ -0,0 +1,256 @@
+:1070000055C000006EC000006CC000006AC00000E7
+:1070100068C0000066C0000064C0000062C00000DC
+:1070200060C000005EC00000ECC400005AC0000058
+:1070300058C0000056C0000054C0000052C00000FC
+:1070400050C0000078C000004CC000004AC00000E2
+:1070500048C0000046C0000044C0000042C000001C
+:1070600040C000003EC000003CC000003AC000002C
+:1070700038C0000036C0000034C0000032C000003C
+:1070800030C000002EC000002CC000002AC000004C
+:1070900028C0000026C0000024C0000022C000005C
+:1070A00020C000001EC000001CC0000011241FBE34
+:1070B000CFEFDAE0DEBFCDBF11E0A0E0B1E0E6E265
+:1070C000FFE702C005900D92A83AB107D9F711E089
+:1070D000A8EAB1E001C01D92AE3BB107E1F78ED343
+:1070E00020C78ECFF89410926F00109281001092FA
+:1070F00085001092840081E085BF15BE47985D9A97
+:10710000289A0C94000008952091B2013091B301A7
+:107110002F5F3F4F3093B3012093B201932F37FF7E
+:1071200003C08EEF831B982F990F921710F4479886
+:107130000895479A08951F920F920FB60F92112447
+:107140002F938F939F93EF93FF931092850010924C
+:1071500084008091A8019091A901009741F00197C6
+:107160009093A9018093A801892B09F45D9A8091DD
+:10717000AA019091AB01009741F001979093AB0168
+:107180008093AA01892B09F4289AE0E0F0E0859128
+:1071900094918F5F9F4F49F08091AC019091AD0128
+:1071A00001969093AD018093AC01FF91EF919F9177
+:1071B0008F912F910F900FBE0F901F90189584E024
+:1071C0008093E9000DC08091E8008B778093E80000
+:1071D00003C08EB3882351F08091E80082FFF9CF7D
+:1071E0008091E80085FFEFCF8091F1000895982FFE
+:1071F00083E08093E9008091E80085FD0DC08091D7
+:10720000E8008E778093E80003C08EB3882369F08E
+:107210008091E80080FFF9CF9093F1005D9884E6BB
+:1072200090E09093A9018093A80108954F925F92F6
+:107230006F927F928F929F92AF92BF92CF92DF9286
+:10724000EF92FF920F931F93CF93DF9384E080938D
+:10725000E9008091E80082FF56C2289884E690E019
+:107260009093AB018093AA01AADF182F853419F4FB
+:1072700010920D0103C0843519F4A1DF8DE019C20D
+:107280008C34E1F38035D1F3843721F484E4AFDF2B
+:1072900080E00FC2813611F489E50BC28134B1F46C
+:1072A0008EDF182F8CDF90E0880F991FAA2797FD9B
+:1072B000A095BA2F312F330F20E0442737FD40959A
+:1072C000542F822B932BA42BB52BC4C1803711F4E0
+:1072D00083E5EFC1833549F4C0E0D1E0899187DFD0
+:1072E00021E0C730D207D1F7E5C1863521F481E32B
+:1072F0007EDF80E3DEC1833731F487E878DF85E91C
+:1073000076DF8EE1D6C18536B9F4E0E0F0E093E0B7
+:1073100085E090935700E89507B600FCFDCF809379
+:107320005700E89507B600FCFDCFE058FF4FA0E7F7
+:10733000E030FA0771F7A2CF8C3651F440DF809528
+:1073400099E0E1E0F0E0082E90935700E89596CFA1
+:10735000823739F4E1E0F0E089E0809357008491CE
+:10736000A8C1863439F4E0E0F0E089E0809357006A
+:1073700084919FC18E3439F4E3E0F0E089E080939A
+:107380005700849196C1813539F4E2E0F0E089E05C
+:107390008093570084918DC1823631F489E527DFCF
+:1073A00080E025DF80E885C1823419F0873609F056
+:1073B000E5C01092AD011092AC0101DF082FFFDE95
+:1073C000F82EFDDE682E8554823008F071C1902FB2
+:1073D00080E0CF2DD0E0C82BD92B10926F0017364C
+:1073E00009F04BC081E180935700E895DD24CC245F
+:1073F000C3943FC0E090AE01F090AF010091B001A6
+:107400001091B101B6E46B16D9F4ED2DF0E0EE2940
+:10741000FF29E4918E2FEBDEDD2081F082E090E009
+:10742000A0E0B0E0E80EF91E0A1F1B1FE092AE01BB
+:10743000F092AF010093B0011093B101DC2418C0A9
+:10744000D801C701B695A7959795879554D5CFDEF6
+:1074500082E090E0A0E0B0E0E80EF91E0A1F1B1FDA
+:10746000E092AE01F092AF010093B0011093B10130
+:107470002197209709F0BECF7DC08090AE019090FB
+:10748000AF01A090B001B090B10196E4691609F087
+:107490005DC083E0F40180935700E89507B600FCD7
+:1074A000FDCF54C0F6E46F1661F5772031F1E0901E
+:1074B000AE01F090AF010091B0011091B1017FDEFB
+:1074C000D82ECC24852D90E08C299D29F7010C0124
+:1074D00040925700E895112482E090E0A0E0B0E0EF
+:1074E000E80EF91E0A1F1B1FE092AE01F092AF01D9
+:1074F0000093B0011093B10102C061DE582E7424D4
+:1075000023C0E090AE01F090AF010091B001109166
+:10751000B10116950795F794E79451DE682FC701DE
+:10752000F2D48091AE019091AF01A091B001B091E1
+:10753000B1010296A11DB11D8093AE019093AF01E0
+:10754000A093B001B093B101219704C055247724D2
+:1075500044244394209709F0A5CF96E4691641F49A
+:1075600085E0F40180935700E89507B600FCFDCF55
+:107570008DE03DDE82E080936F009CC0833471F427
+:107580000091AE011091AF011ADE90E021E0F80108
+:107590000C0120935700E895112470CE833619F51D
+:1075A000E090AE01F090AF010091B0011091B101F7
+:1075B00006DEF701E16090E021E00C012093570026
+:1075C000E895112482E090E0A0E0B0E0E80EF91E1A
+:1075D0000A1F1B1FE092AE01F092AF010093B001B1
+:1075E0001093B1014BCE8D3661F4E091AE01F09174
+:1075F000AF0185E080935700E89507B600FCFDCF0A
+:107600003DCE823551F4E091AE01F091AF0105918C
+:107610001491812FECDD802F4CC0843421F5E09053
+:10762000AE01F090AF010091B0011091B10116953B
+:107630000795F794E794C3DD682FC70164D4809160
+:10764000AE019091AF01A091B001B091B10102964D
+:10765000A11DB11D8093AE019093AF01A093B00125
+:10766000B093B1010BCE843609F5E090AE01F090F5
+:10767000AF010091B0011091B101D801C701B695D9
+:10768000A7959795879537D4B2DD82E090E0A0E08A
+:10769000B0E0E80EF91E0A1F1B1FE092AE01F09247
+:1076A000AF010093B0011093B10104C08B3111F010
+:1076B0008FE39DDD83E08093E9009091E800809165
+:1076C000E8008E778093E80095FF04C010C08EB369
+:1076D0008823C9F08091E80080FFF9CF8091E8000D
+:1076E0008E778093E80003C08EB3882361F0809189
+:1076F000E80080FFF9CF84E08093E9008091E80002
+:107700008B778093E800DF91CF911F910F91FF90CD
+:10771000EF90DF90CF90BF90AF909F908F907F9031
+:107720006F905F904F9008959091B601892F8F7759
+:10773000813249F58091B7018032A1F0813219F58B
+:10774000913A09F58091E800877F8093E8008EE008
+:1077500091E067E070E006D28091E8008B7780933B
+:10776000E8000895913279F48091E800877F809352
+:10777000E8008EE091E067E070E058D28091E80088
+:107780008E778093E800089582E061EC42E0B0D00B
+:1077900083E061E842E1ACD084E060E842E1A8C067
+:1077A00084B7877F84BF88E10FB6F8948093600028
+:1077B000109260000FBE20E880E090E00FB6F894D1
+:1077C00020936100809361000FBE81E085BF92E04D
+:1077D00095BF3F9A209A559AE1E6F0E02083108207
+:1077E00047985D9A289A109289008AEF80938800C2
+:1077F00090936F0083E080938100EBC01F9388E13A
+:107800000FB6F89480936000109260000FBE84B7AA
+:1078100014BE182F10FF08C0E0E0F0E085919491AD
+:107820008F5F9F4F09F05EDC2091000A3091010AC2
+:107830001092010A1092000A13FF0FC080910901F3
+:1078400090910A012817390741F0E0E0F0E08591B6
+:1078500094918F5F9F4F09F045DCA2DF78940CC0B4
+:10786000E5DC37D38091AC019091AD0181549F410B
+:1078700010F010920D0148DC80910D01882381F7F2
+:107880008091E00081608093E0002CDC80E090E05B
+:107890001F910895FA01923049F0933061F09130D0
+:1078A000F9F485E191E022E130E01EC087E291E049
+:1078B0002EE330E019C0882329F485E691E024E026
+:1078C00030E012C0813029F489E691E022E230E014
+:1078D0000BC0823029F48DE891E028E130E004C04B
+:1078E00080E090E020E030E091838083C90108953A
+:1078F0008093E9008091EB0081608093EB0010920F
+:10790000ED006093EC004093ED008091EE00881F45
+:107910008827881F08958091B60188238CF403C0BE
+:107920008EB38823B1F08091E80082FFF9CF809177
+:10793000E8008B778093E80008958EB3882349F0A0
+:107940008091E80080FFF9CF8091E8008E778093E6
+:10795000E8000895EF92FF920F931F9345D04CD00B
+:1079600008ED10E0F80180818F7780838081806846
+:10797000808380818F7D808319BC1EBA1092B401F0
+:1079800080EEE82EF12CF70180818B7F8083F80157
+:1079900080818160808380E060E042E0A9DFE1EEE9
+:1079A000F0E080818E7F8083E2EEF0E08081816074
+:1079B0008083808188608083F70180818E7F8083CF
+:1079C000F8018081806180831F910F91FF90EF907B
+:1079D0000895E7EDF0E08081816080838AE482BFD2
+:1079E00081E08093B501B6CFE8EDF0E080818E7F35
+:1079F00080831092E20008951092DA001092E10064
+:107A000008951F920F920FB60F9211242F933F9358
+:107A10004F935F936F937F938F939F93AF93BF9396
+:107A2000EF93FF938091DA0080FF1BC08091D80014
+:107A300080FF17C08091DA008E7F8093DA008091FA
+:107A4000D90080FF0BC080E189BD82E189BD09B406
+:107A500000FEFDCF81E08EBB3BD203C019BC1EBA35
+:107A600037D28091E10080FF17C08091E20080FF53
+:107A700013C08091E2008E7F8093E2008091E2004B
+:107A800080618093E2008091D80080628093D8006A
+:107A900019BC85E08EBB1CD28091E10084FF2CC014
+:107AA0008091E20084FF28C080E189BD82E189BD28
+:107AB00009B400FEFDCF8091D8008F7D8093D8005F
+:107AC0008091E1008F7E8093E1008091E2008F7EC3
+:107AD0008093E2008091E20081608093E2008091D7
+:107AE000B401882331F48091E30087FD02C081E076
+:107AF00001C084E08EBBECD18091E10083FF21C006
+:107B00008091E20083FF1DC08091E100877F809318
+:107B1000E10082E08EBB1092B4018091E1008E7F83
+:107B20008093E1008091E2008E7F8093E20080915B
+:107B3000E20080618093E20080E060E042E0D8DE15
+:107B4000C7D1FF91EF91BF91AF919F918F917F919D
+:107B50006F915F914F913F912F910F900FBE0F90BA
+:107B60001F9018959C014091BC015091BD01461792
+:107B7000570718F4F90190E044C06115710511F040
+:107B8000AB01F8CF8091E8008E778093E80040E069
+:107B900050E0F0CF8EB3882309F444C0853009F457
+:107BA00043C08091E80083FF02C081E00895809186
+:107BB000E80082FD31C08091E80080FF22C0809102
+:107BC000F3009091F200782F60E0292F30E0262B0F
+:107BD000372B07C081918093F100415050402F5FB7
+:107BE0003F4F4115510519F02830310598F390E0C9
+:107BF0002830310509F491E08091E8008E77809378
+:107C0000E8004115510531F6992321F605C08EB3E0
+:107C1000882341F0853041F08091E80082FFF7CF62
+:107C200080E0089582E0089583E008959C01611545
+:107C3000710529F48091E8008B778093E800F901C1
+:107C400026C08EB3882391F1853091F18091E800B0
+:107C500083FF02C081E008958091E80082FFF1CFA8
+:107C600006C08091F10081936150704059F02091DD
+:107C7000F3008091F200322F20E090E0822B932BD2
+:107C8000892B79F78091E8008B778093E800611564
+:107C90007105B9F605C08EB3882341F0853041F0F7
+:107CA0008091E80080FFF7CF80E0089582E008959A
+:107CB00083E008950F931F93DF93CF9300D0CDB748
+:107CC000DEB7E6EBF1E08091F100819381E0EE3BDD
+:107CD000F807C9F729DD8091E80083FFE4C08091AF
+:107CE000B6019091B701953009F46DC0963040F41B
+:107CF000913081F1913070F0933009F0D4C02AC0F6
+:107D0000983009F4A3C0993009F4B2C0963009F054
+:107D1000CAC07CC0803809F4C6C0823809F0C3C02C
+:107D20008091BA0187708093E9008091EB001092F6
+:107D3000E9002091E800277F2093E80090E025E00B
+:107D4000969587952A95E1F781708093F1001092BE
+:107D5000F10087C0882319F0823009F0A4C08F7128
+:107D6000823009F0A0C08091B801882331F52091BC
+:107D7000BA01277009F497C02093E9008091EB00C5
+:107D800080FF1BC0933021F48091EB00806213C010
+:107D90008091EB0080618093EB0081E090E002C075
+:107DA000880F991F2A95E2F78093EA001092EA0063
+:107DB0008091EB0088608093EB001092E900809145
+:107DC000E800877F51C0882309F06DC01091B80189
+:107DD0001F770FB7F8948091E800877F8093E800C1
+:107DE0009ADD8091E80080FFFCCF8091E3008078ED
+:107DF000812B8093E30080688093E300112311F4CA
+:107E000082E001C083E08EBB0FBF4DC0805882303E
+:107E100008F049C08091B8019091B9016091BA0110
+:107E2000AE014F5F5F4F36DDBC01009709F43BC0E8
+:107E30008091E800877F8093E80089819A8192DEB3
+:107E40008091E8008B778093E8002DC0803859F549
+:107E50008091E800877F8093E8008091B40180934F
+:107E6000F1008091E8008E778093E80054DD1BC01C
+:107E70008823C9F49091B8019230A8F48091E80069
+:107E8000877F8093E8009093B40145DD8091B40131
+:107E9000882331F48091E30087FD02C081E001C0B6
+:107EA00084E08EBB71DC8091E80083FF0AC0809182
+:107EB000EB0080628093EB008091E800877F8093E5
+:107EC000E8000F900F90CF91DF911F910F910895CF
+:107ED00008951F938EB3882361F01091E9001092EA
+:107EE000E9008091E80083FF01C0E4DE1770109381
+:107EF000E9001F910895F999FECF92BD81BDF89ACE
+:107F0000992780B50895262FF999FECF1FBA92BD03
+:107F100081BD20BD0FB6F894FA9AF99A0FBE01966A
+:067F20000895F894FFCF64
+:107F26004341544552494E41007777000A0100000B
+:107F360000000000081201100102000008412301A0
+:107F46000701000201000109023E00020100803221
+:107F560009040000010202010005240010010424A6
+:107F660002040524060001070582030800FF090430
+:107F76000100020A000000070504021000010705BF
+:107F86008302100001040309042203410072006405
+:107F960000750069006E006F0020004C0065006FE0
+:107FA600006E006100720064006F0000001803415B
+:107FB6000072006400750069006E006F0020004CBE
+:087FC600004C00430000000024
+:040000030000700089
+:00000001FF
diff --git a/bootloaders/caterina_LUFA/Descriptors.c b/bootloaders/caterina_LUFA/Descriptors.c
new file mode 100755
index 0000000..f1756e2
--- /dev/null
+++ b/bootloaders/caterina_LUFA/Descriptors.c
@@ -0,0 +1,265 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2011.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2011 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+ Permission to use, copy, modify, distribute, and sell this
+ software and its documentation for any purpose is hereby granted
+ without fee, provided that the above copyright notice appear in
+ all copies and that both that the copyright notice and this
+ permission notice and warranty disclaimer appear in supporting
+ documentation, and that the name of the author not be used in
+ advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+
+ The author disclaim all warranties with regard to this
+ software, including all implied warranties of merchantability
+ and fitness. In no event shall the author be liable for any
+ special, indirect or consequential damages or any damages
+ whatsoever resulting from loss of use, data or profits, whether
+ in an action of contract, negligence or other tortious action,
+ arising out of or in connection with the use or performance of
+ this software.
+*/
+
+/** \file
+ *
+ * USB Device Descriptors, for library use when in USB device mode. Descriptors are special
+ * computer-readable structures which the host requests upon device enumeration, to determine
+ * the device's capabilities and functions.
+ */
+
+#include "Descriptors.h"
+
+/** Device descriptor structure. This descriptor, located in SRAM memory, describes the overall
+ * device characteristics, including the supported USB version, control endpoint size and the
+ * number of device configurations. The descriptor is read out by the USB host when the enumeration
+ * process begins.
+ */
+const USB_Descriptor_Device_t DeviceDescriptor =
+{
+ .Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device},
+
+ .USBSpecification = VERSION_BCD(01.10),
+ .Class = CDC_CSCP_CDCClass,
+ .SubClass = CDC_CSCP_NoSpecificSubclass,
+ .Protocol = CDC_CSCP_NoSpecificProtocol,
+
+ .Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE,
+
+ .VendorID = 0x2341,
+ .ProductID = 0x0701,
+ .ReleaseNumber = VERSION_BCD(00.01),
+
+ .ManufacturerStrIndex = 0x02,
+ .ProductStrIndex = 0x01,
+ .SerialNumStrIndex = NO_DESCRIPTOR,
+
+ .NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS
+};
+
+/** Configuration descriptor structure. This descriptor, located in SRAM memory, describes the usage
+ * of the device in one of its supported configurations, including information about any device interfaces
+ * and endpoints. The descriptor is read out by the USB host during the enumeration process when selecting
+ * a configuration so that the host may correctly communicate with the USB device.
+ */
+const USB_Descriptor_Configuration_t ConfigurationDescriptor =
+{
+ .Config =
+ {
+ .Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration},
+
+ .TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t),
+ .TotalInterfaces = 2,
+
+ .ConfigurationNumber = 1,
+ .ConfigurationStrIndex = NO_DESCRIPTOR,
+
+ .ConfigAttributes = USB_CONFIG_ATTR_BUSPOWERED,
+
+ .MaxPowerConsumption = USB_CONFIG_POWER_MA(100)
+ },
+
+ .CDC_CCI_Interface =
+ {
+ .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
+
+ .InterfaceNumber = 0,
+ .AlternateSetting = 0,
+
+ .TotalEndpoints = 1,
+
+ .Class = CDC_CSCP_CDCClass,
+ .SubClass = CDC_CSCP_ACMSubclass,
+ .Protocol = CDC_CSCP_ATCommandProtocol,
+
+ .InterfaceStrIndex = NO_DESCRIPTOR
+ },
+
+ .CDC_Functional_Header =
+ {
+ .Header = {.Size = sizeof(USB_CDC_Descriptor_FunctionalHeader_t), .Type = DTYPE_CSInterface},
+ .Subtype = 0x00,
+
+ .CDCSpecification = VERSION_BCD(01.10),
+ },
+
+ .CDC_Functional_ACM =
+ {
+ .Header = {.Size = sizeof(USB_CDC_Descriptor_FunctionalACM_t), .Type = DTYPE_CSInterface},
+ .Subtype = 0x02,
+
+ .Capabilities = 0x04,
+ },
+
+ .CDC_Functional_Union =
+ {
+ .Header = {.Size = sizeof(USB_CDC_Descriptor_FunctionalUnion_t), .Type = DTYPE_CSInterface},
+ .Subtype = 0x06,
+
+ .MasterInterfaceNumber = 0,
+ .SlaveInterfaceNumber = 1,
+ },
+
+ .CDC_NotificationEndpoint =
+ {
+ .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
+
+ .EndpointAddress = (ENDPOINT_DIR_IN | CDC_NOTIFICATION_EPNUM),
+ .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
+ .EndpointSize = CDC_NOTIFICATION_EPSIZE,
+ .PollingIntervalMS = 0xFF
+ },
+
+ .CDC_DCI_Interface =
+ {
+ .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
+
+ .InterfaceNumber = 1,
+ .AlternateSetting = 0,
+
+ .TotalEndpoints = 2,
+
+ .Class = CDC_CSCP_CDCDataClass,
+ .SubClass = CDC_CSCP_NoDataSubclass,
+ .Protocol = CDC_CSCP_NoDataProtocol,
+
+ .InterfaceStrIndex = NO_DESCRIPTOR
+ },
+
+ .CDC_DataOutEndpoint =
+ {
+ .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
+
+ .EndpointAddress = (ENDPOINT_DIR_OUT | CDC_RX_EPNUM),
+ .Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
+ .EndpointSize = CDC_TXRX_EPSIZE,
+ .PollingIntervalMS = 0x01
+ },
+
+ .CDC_DataInEndpoint =
+ {
+ .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
+
+ .EndpointAddress = (ENDPOINT_DIR_IN | CDC_TX_EPNUM),
+ .Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
+ .EndpointSize = CDC_TXRX_EPSIZE,
+ .PollingIntervalMS = 0x01
+ }
+};
+
+/** Language descriptor structure. This descriptor, located in SRAM memory, is returned when the host requests
+ * the string descriptor with index 0 (the first index). It is actually an array of 16-bit integers, which indicate
+ * via the language ID table available at USB.org what languages the device supports for its string descriptors.
+ */
+const USB_Descriptor_String_t LanguageString =
+{
+ .Header = {.Size = USB_STRING_LEN(1), .Type = DTYPE_String},
+
+ .UnicodeString = {LANGUAGE_ID_ENG}
+};
+
+/** Product descriptor string. This is a Unicode string containing the product's details in human readable form,
+ * and is read out upon request by the host when the appropriate string ID is requested, listed in the Device
+ * Descriptor.
+ */
+const USB_Descriptor_String_t ProductString =
+{
+ .Header = {.Size = USB_STRING_LEN(16), .Type = DTYPE_String},
+
+ .UnicodeString = L"Arduino Leonardo"
+};
+/*
+const USB_Descriptor_String_t SerialNumString =
+{
+ .Header = {.Size = USB_STRING_LEN(12), .Type = DTYPE_String},
+
+ .UnicodeString = L"000000001452"
+};
+*/
+const USB_Descriptor_String_t ManufNameString =
+{
+ .Header = {.Size = USB_STRING_LEN(11), .Type = DTYPE_String},
+
+ .UnicodeString = L"Arduino LLC"
+};
+
+/** This function is called by the library when in device mode, and must be overridden (see LUFA library "USB Descriptors"
+ * documentation) by the application code so that the address and size of a requested descriptor can be given
+ * to the USB library. When the device receives a Get Descriptor request on the control endpoint, this function
+ * is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the
+ * USB host.
+ */
+uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
+ const uint8_t wIndex,
+ const void** const DescriptorAddress)
+{
+ const uint8_t DescriptorType = (wValue >> 8);
+ const uint8_t DescriptorNumber = (wValue & 0xFF);
+
+ const void* Address = NULL;
+ uint16_t Size = NO_DESCRIPTOR;
+
+ switch (DescriptorType)
+ {
+ case DTYPE_Device:
+ Address = &DeviceDescriptor;
+ Size = sizeof(USB_Descriptor_Device_t);
+ break;
+ case DTYPE_Configuration:
+ Address = &ConfigurationDescriptor;
+ Size = sizeof(USB_Descriptor_Configuration_t);
+ break;
+ case DTYPE_String:
+ if (!(DescriptorNumber))
+ {
+ Address = &LanguageString;
+ Size = LanguageString.Header.Size;
+ }
+ else if (DescriptorNumber == DeviceDescriptor.ProductStrIndex)
+ {
+ Address = &ProductString;
+ Size = ProductString.Header.Size;
+// } else if (DescriptorNumber == DeviceDescriptor.SerialNumStrIndex)
+// {
+// Address = &SerialNumString;
+// Size = SerialNumString.Header.Size;
+ } else if (DescriptorNumber == DeviceDescriptor.ManufacturerStrIndex)
+ {
+ Address = &ManufNameString;
+ Size = ManufNameString.Header.Size;
+ }
+
+ break;
+ }
+
+ *DescriptorAddress = Address;
+ return Size;
+}
+
diff --git a/bootloaders/caterina_LUFA/Descriptors.h b/bootloaders/caterina_LUFA/Descriptors.h
new file mode 100755
index 0000000..94091ae
--- /dev/null
+++ b/bootloaders/caterina_LUFA/Descriptors.h
@@ -0,0 +1,139 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2011.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2011 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+ Permission to use, copy, modify, distribute, and sell this
+ software and its documentation for any purpose is hereby granted
+ without fee, provided that the above copyright notice appear in
+ all copies and that both that the copyright notice and this
+ permission notice and warranty disclaimer appear in supporting
+ documentation, and that the name of the author not be used in
+ advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+
+ The author disclaim all warranties with regard to this
+ software, including all implied warranties of merchantability
+ and fitness. In no event shall the author be liable for any
+ special, indirect or consequential damages or any damages
+ whatsoever resulting from loss of use, data or profits, whether
+ in an action of contract, negligence or other tortious action,
+ arising out of or in connection with the use or performance of
+ this software.
+*/
+
+/** \file
+ *
+ * Header file for Descriptors.c.
+ */
+
+#ifndef _DESCRIPTORS_H_
+#define _DESCRIPTORS_H_
+
+ /* Includes: */
+ #include <LUFA/Drivers/USB/USB.h>
+
+ /* Macros: */
+ #if defined(__AVR_AT90USB1287__)
+ #define AVR_SIGNATURE_1 0x1E
+ #define AVR_SIGNATURE_2 0x97
+ #define AVR_SIGNATURE_3 0x82
+ #elif defined(__AVR_AT90USB647__)
+ #define AVR_SIGNATURE_1 0x1E
+ #define AVR_SIGNATURE_2 0x96
+ #define AVR_SIGNATURE_3 0x82
+ #elif defined(__AVR_AT90USB1286__)
+ #define AVR_SIGNATURE_1 0x1E
+ #define AVR_SIGNATURE_2 0x97
+ #define AVR_SIGNATURE_3 0x82
+ #elif defined(__AVR_AT90USB646__)
+ #define AVR_SIGNATURE_1 0x1E
+ #define AVR_SIGNATURE_2 0x96
+ #define AVR_SIGNATURE_3 0x82
+ #elif defined(__AVR_ATmega32U6__)
+ #define AVR_SIGNATURE_1 0x1E
+ #define AVR_SIGNATURE_2 0x95
+ #define AVR_SIGNATURE_3 0x88
+ #elif defined(__AVR_ATmega32U4__)
+ #define AVR_SIGNATURE_1 0x1E
+ #define AVR_SIGNATURE_2 0x95
+ #define AVR_SIGNATURE_3 0x87
+ #elif defined(__AVR_ATmega16U4__)
+ #define AVR_SIGNATURE_1 0x1E
+ #define AVR_SIGNATURE_2 0x94
+ #define AVR_SIGNATURE_3 0x88
+ #elif defined(__AVR_ATmega32U2__)
+ #define AVR_SIGNATURE_1 0x1E
+ #define AVR_SIGNATURE_2 0x95
+ #define AVR_SIGNATURE_3 0x8A
+ #elif defined(__AVR_ATmega16U2__)
+ #define AVR_SIGNATURE_1 0x1E
+ #define AVR_SIGNATURE_2 0x94
+ #define AVR_SIGNATURE_3 0x89
+ #elif defined(__AVR_AT90USB162__)
+ #define AVR_SIGNATURE_1 0x1E
+ #define AVR_SIGNATURE_2 0x94
+ #define AVR_SIGNATURE_3 0x82
+ #elif defined(__AVR_ATmega8U2__)
+ #define AVR_SIGNATURE_1 0x1E
+ #define AVR_SIGNATURE_2 0x93
+ #define AVR_SIGNATURE_3 0x89
+ #elif defined(__AVR_AT90USB82__)
+ #define AVR_SIGNATURE_1 0x1E
+ #define AVR_SIGNATURE_2 0x94
+ #define AVR_SIGNATURE_3 0x82
+ #else
+ #error The selected AVR part is not currently supported by this bootloader.
+ #endif
+
+ /** Endpoint number for the CDC control interface event notification endpoint. */
+ #define CDC_NOTIFICATION_EPNUM 2
+
+ /** Endpoint number for the CDC data interface TX (data IN) endpoint. */
+ #define CDC_TX_EPNUM 3
+
+ /** Endpoint number for the CDC data interface RX (data OUT) endpoint. */
+ #define CDC_RX_EPNUM 4
+
+ /** Size of the CDC data interface TX and RX data endpoint banks, in bytes. */
+ #define CDC_TXRX_EPSIZE 16
+
+ /** Size of the CDC control interface notification endpoint bank, in bytes. */
+ #define CDC_NOTIFICATION_EPSIZE 8
+
+ /* Type Defines: */
+ /** Type define for the device configuration descriptor structure. This must be defined in the
+ * application code, as the configuration descriptor contains several sub-descriptors which
+ * vary between devices, and which describe the device's usage to the host.
+ */
+ typedef struct
+ {
+ USB_Descriptor_Configuration_Header_t Config;
+
+ // CDC Control Interface
+ USB_Descriptor_Interface_t CDC_CCI_Interface;
+ USB_CDC_Descriptor_FunctionalHeader_t CDC_Functional_Header;
+ USB_CDC_Descriptor_FunctionalACM_t CDC_Functional_ACM;
+ USB_CDC_Descriptor_FunctionalUnion_t CDC_Functional_Union;
+ USB_Descriptor_Endpoint_t CDC_NotificationEndpoint;
+
+ // CDC Data Interface
+ USB_Descriptor_Interface_t CDC_DCI_Interface;
+ USB_Descriptor_Endpoint_t CDC_DataOutEndpoint;
+ USB_Descriptor_Endpoint_t CDC_DataInEndpoint;
+ } USB_Descriptor_Configuration_t;
+
+ /* Function Prototypes: */
+ uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
+ const uint8_t wIndex,
+ const void** const DescriptorAddress)
+ ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3);
+
+#endif
+
diff --git a/bootloaders/caterina_LUFA/makefile b/bootloaders/caterina_LUFA/makefile
new file mode 100755
index 0000000..5439b5b
--- /dev/null
+++ b/bootloaders/caterina_LUFA/makefile
@@ -0,0 +1,717 @@
+# Hey Emacs, this is a -*- makefile -*-
+#----------------------------------------------------------------------------
+# WinAVR Makefile Template written by Eric B. Weddington, Jörg Wunsch, et al.
+# >> Modified for use with the LUFA project. <<
+#
+# Released to the Public Domain
+#
+# Additional material for this makefile was written by:
+# Peter Fleury
+# Tim Henigan
+# Colin O'Flynn
+# Reiner Patommel
+# Markus Pfaff
+# Sander Pool
+# Frederik Rouleau
+# Carlos Lamas
+# Dean Camera
+# Opendous Inc.
+# Denver Gingerich
+#
+#----------------------------------------------------------------------------
+# On command line:
+#
+# make all = Make software.
+#
+# make clean = Clean out built project files.
+#
+# make coff = Convert ELF to AVR COFF.
+#
+# make extcoff = Convert ELF to AVR Extended COFF.
+#
+# make program = Download the hex file to the device, using avrdude.
+# Please customize the avrdude settings below first!
+#
+# make doxygen = Generate DoxyGen documentation for the project (must have
+# DoxyGen installed)
+#
+# make debug = Start either simulavr or avarice as specified for debugging,
+# with avr-gdb or avr-insight as the front end for debugging.
+#
+# make filename.s = Just compile filename.c into the assembler code only.
+#
+# make filename.i = Create a preprocessed source file for use in submitting
+# bug reports to the GCC project.
+#
+# To rebuild project do "make clean" then "make all".
+#----------------------------------------------------------------------------
+
+
+# MCU name
+MCU = atmega32u4
+
+
+# Target architecture (see library "Board Types" documentation).
+ARCH = AVR8
+
+
+# Target board (see library "Board Types" documentation, NONE for projects not requiring
+# LUFA board drivers). If USER is selected, put custom board drivers in a directory called
+# "Board" inside the application directory.
+BOARD = USER
+
+
+# Processor frequency.
+# This will define a symbol, F_CPU, in all source code files equal to the
+# processor frequency in Hz. You can then use this symbol in your source code to
+# calculate timings. Do NOT tack on a 'UL' at the end, this will be done
+# automatically to create a 32-bit value in your source code.
+#
+# This will be an integer division of F_USB below, as it is sourced by
+# F_USB after it has run through any CPU prescalers. Note that this value
+# does not *change* the processor frequency - it should merely be updated to
+# reflect the processor speed set externally so that the code can use accurate
+# software delays.
+F_CPU = 16000000
+
+
+# Input clock frequency.
+# This will define a symbol, F_USB, in all source code files equal to the
+# input clock frequency (before any prescaling is performed) in Hz. This value may
+# differ from F_CPU if prescaling is used on the latter, and is required as the
+# raw input clock is fed directly to the PLL sections of the AVR for high speed
+# clock generation for the USB and other AVR subsections. Do NOT tack on a 'UL'
+# at the end, this will be done automatically to create a 32-bit value in your
+# source code.
+#
+# If no clock division is performed on the input clock inside the AVR (via the
+# CPU clock adjust registers or the clock division fuses), this will be equal to F_CPU.
+F_USB = $(F_CPU)
+
+
+# Starting byte address of the bootloader, as a byte address - computed via the formula
+# BOOT_START = ((FLASH_SIZE_KB - BOOT_SECTION_SIZE_KB) * 1024)
+#
+# Note that the bootloader size and start address given in AVRStudio is in words and not
+# bytes, and so will need to be doubled to obtain the byte address needed by AVR-GCC.
+FLASH_SIZE_KB = 32
+BOOT_SECTION_SIZE_KB = 4
+BOOT_START = 0x$(shell echo "obase=16; ($(FLASH_SIZE_KB) - $(BOOT_SECTION_SIZE_KB)) * 1024" | bc)
+
+
+# Output format. (can be srec, ihex, binary)
+FORMAT = ihex
+
+
+# Target file name (without extension).
+TARGET = Caterina
+
+
+# Object files directory
+# To put object files in current directory, use a dot (.), do NOT make
+# this an empty or blank macro!
+OBJDIR = .
+
+
+# Path to the LUFA library
+LUFA_PATH = ../../../../../LUFA-111009
+
+
+# LUFA library compile-time options and predefined tokens
+LUFA_OPTS = -D USB_DEVICE_ONLY
+LUFA_OPTS += -D DEVICE_STATE_AS_GPIOR=0
+LUFA_OPTS += -D ORDERED_EP_CONFIG
+LUFA_OPTS += -D FIXED_CONTROL_ENDPOINT_SIZE=8
+LUFA_OPTS += -D FIXED_NUM_CONFIGURATIONS=1
+LUFA_OPTS += -D USE_RAM_DESCRIPTORS
+LUFA_OPTS += -D USE_STATIC_OPTIONS="(USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL)"
+LUFA_OPTS += -D NO_INTERNAL_SERIAL
+LUFA_OPTS += -D NO_DEVICE_SELF_POWER
+LUFA_OPTS += -D NO_DEVICE_REMOTE_WAKEUP
+LUFA_OPTS += -D NO_SOF_EVENTS
+
+#LUFA_OPTS += -D NO_BLOCK_SUPPORT
+#LUFA_OPTS += -D NO_EEPROM_BYTE_SUPPORT
+#LUFA_OPTS += -D NO_FLASH_BYTE_SUPPORT
+#LUFA_OPTS += -D NO_LOCK_BYTE_WRITE_SUPPORT
+
+
+# Create the LUFA source path variables by including the LUFA root makefile
+include $(LUFA_PATH)/LUFA/makefile
+
+
+# List C source files here. (C dependencies are automatically generated.)
+SRC = $(TARGET).c \
+ Descriptors.c \
+ $(LUFA_SRC_USB) \
+
+
+# List C++ source files here. (C dependencies are automatically generated.)
+CPPSRC =
+
+
+# List Assembler source files here.
+# Make them always end in a capital .S. Files ending in a lowercase .s
+# will not be considered source files but generated files (assembler
+# output from the compiler), and will be deleted upon "make clean"!
+# Even though the DOS/Win* filesystem matches both .s and .S the same,
+# it will preserve the spelling of the filenames, and gcc itself does
+# care about how the name is spelled on its command-line.
+ASRC =
+
+
+# Optimization level, can be [0, 1, 2, 3, s].
+# 0 = turn off optimization. s = optimize for size.
+# (Note: 3 is not always the best optimization level. See avr-libc FAQ.)
+OPT = s
+
+
+# Debugging format.
+# Native formats for AVR-GCC's -g are dwarf-2 [default] or stabs.
+# AVR Studio 4.10 requires dwarf-2.
+# AVR [Extended] COFF format requires stabs, plus an avr-objcopy run.
+DEBUG = dwarf-2
+
+
+# List any extra directories to look for include files here.
+# Each directory must be seperated by a space.
+# Use forward slashes for directory separators.
+# For a directory that has spaces, enclose it in quotes.
+EXTRAINCDIRS = $(LUFA_PATH)/
+
+
+# Compiler flag to set the C Standard level.
+# c89 = "ANSI" C
+# gnu89 = c89 plus GCC extensions
+# c99 = ISO C99 standard (not yet fully implemented)
+# gnu99 = c99 plus GCC extensions
+CSTANDARD = -std=c99
+
+
+# Place -D or -U options here for C sources
+CDEFS = -DF_CPU=$(F_CPU)UL
+CDEFS += -DF_USB=$(F_USB)UL
+CDEFS += -DBOARD=BOARD_$(BOARD) -DARCH=ARCH_$(ARCH)
+CDEFS += -DBOOT_START_ADDR=$(BOOT_START)UL
+CDEFS += $(LUFA_OPTS)
+
+
+# Place -D or -U options here for ASM sources
+ADEFS = -DF_CPU=$(F_CPU)
+ADEFS += -DF_USB=$(F_USB)UL
+ADEFS += -DBOARD=BOARD_$(BOARD)
+ADEFS += -DBOOT_START_ADDR=$(BOOT_START)UL
+ADEFS += $(LUFA_OPTS)
+
+
+# Place -D or -U options here for C++ sources
+CPPDEFS = -DF_CPU=$(F_CPU)UL
+CPPDEFS += -DF_USB=$(F_USB)UL
+CPPDEFS += -DBOARD=BOARD_$(BOARD)
+CPPDEFS += -DBOOT_START_ADDR=$(BOOT_START)UL
+CPPDEFS += $(LUFA_OPTS)
+#CPPDEFS += -D__STDC_LIMIT_MACROS
+#CPPDEFS += -D__STDC_CONSTANT_MACROS
+
+
+
+#---------------- Compiler Options C ----------------
+# -g*: generate debugging information
+# -O*: optimization level
+# -f...: tuning, see GCC manual and avr-libc documentation
+# -Wall...: warning level
+# -Wa,...: tell GCC to pass this to the assembler.
+# -adhlns...: create assembler listing
+CFLAGS = -g$(DEBUG)
+CFLAGS += $(CDEFS)
+CFLAGS += -O$(OPT)
+CFLAGS += -funsigned-char
+CFLAGS += -funsigned-bitfields
+CFLAGS += -ffunction-sections
+CFLAGS += -fno-inline-small-functions
+CFLAGS += -fpack-struct
+CFLAGS += -fshort-enums
+CFLAGS += -fno-strict-aliasing
+CFLAGS += -Wall
+CFLAGS += -Wstrict-prototypes
+#CFLAGS += -mshort-calls
+#CFLAGS += -fno-unit-at-a-time
+#CFLAGS += -Wundef
+#CFLAGS += -Wunreachable-code
+#CFLAGS += -Wsign-compare
+CFLAGS += -Wa,-adhlns=$(<:%.c=$(OBJDIR)/%.lst)
+CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS))
+CFLAGS += $(CSTANDARD)
+
+
+#---------------- Compiler Options C++ ----------------
+# -g*: generate debugging information
+# -O*: optimization level
+# -f...: tuning, see GCC manual and avr-libc documentation
+# -Wall...: warning level
+# -Wa,...: tell GCC to pass this to the assembler.
+# -adhlns...: create assembler listing
+CPPFLAGS = -g$(DEBUG)
+CPPFLAGS += $(CPPDEFS)
+CPPFLAGS += -O$(OPT)
+CPPFLAGS += -funsigned-char
+CPPFLAGS += -funsigned-bitfields
+CPPFLAGS += -fpack-struct
+CPPFLAGS += -fshort-enums
+CPPFLAGS += -fno-exceptions
+CPPFLAGS += -Wall
+CPPFLAGS += -Wundef
+#CPPFLAGS += -mshort-calls
+#CPPFLAGS += -fno-unit-at-a-time
+#CPPFLAGS += -Wstrict-prototypes
+#CPPFLAGS += -Wunreachable-code
+#CPPFLAGS += -Wsign-compare
+CPPFLAGS += -Wa,-adhlns=$(<:%.cpp=$(OBJDIR)/%.lst)
+CPPFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS))
+#CPPFLAGS += $(CSTANDARD)
+
+
+#---------------- Assembler Options ----------------
+# -Wa,...: tell GCC to pass this to the assembler.
+# -adhlns: create listing
+# -gstabs: have the assembler create line number information; note that
+# for use in COFF files, additional information about filenames
+# and function names needs to be present in the assembler source
+# files -- see avr-libc docs [FIXME: not yet described there]
+# -listing-cont-lines: Sets the maximum number of continuation lines of hex
+# dump that will be displayed for a given single line of source input.
+ASFLAGS = $(ADEFS) -Wa,-adhlns=$(<:%.S=$(OBJDIR)/%.lst),-gstabs,--listing-cont-lines=100
+
+
+#---------------- Library Options ----------------
+# Minimalistic printf version
+PRINTF_LIB_MIN = -Wl,-u,vfprintf -lprintf_min
+
+# Floating point printf version (requires MATH_LIB = -lm below)
+PRINTF_LIB_FLOAT = -Wl,-u,vfprintf -lprintf_flt
+
+# If this is left blank, then it will use the Standard printf version.
+PRINTF_LIB =
+#PRINTF_LIB = $(PRINTF_LIB_MIN)
+#PRINTF_LIB = $(PRINTF_LIB_FLOAT)
+
+
+# Minimalistic scanf version
+SCANF_LIB_MIN = -Wl,-u,vfscanf -lscanf_min
+
+# Floating point + %[ scanf version (requires MATH_LIB = -lm below)
+SCANF_LIB_FLOAT = -Wl,-u,vfscanf -lscanf_flt
+
+# If this is left blank, then it will use the Standard scanf version.
+SCANF_LIB =
+#SCANF_LIB = $(SCANF_LIB_MIN)
+#SCANF_LIB = $(SCANF_LIB_FLOAT)
+
+
+MATH_LIB = -lm
+
+
+# List any extra directories to look for libraries here.
+# Each directory must be seperated by a space.
+# Use forward slashes for directory separators.
+# For a directory that has spaces, enclose it in quotes.
+EXTRALIBDIRS =
+
+
+
+#---------------- External Memory Options ----------------
+
+# 64 KB of external RAM, starting after internal RAM (ATmega128!),
+# used for variables (.data/.bss) and heap (malloc()).
+#EXTMEMOPTS = -Wl,-Tdata=0x801100,--defsym=__heap_end=0x80ffff
+
+# 64 KB of external RAM, starting after internal RAM (ATmega128!),
+# only used for heap (malloc()).
+#EXTMEMOPTS = -Wl,--section-start,.data=0x801100,--defsym=__heap_end=0x80ffff
+
+EXTMEMOPTS =
+
+
+
+#---------------- Linker Options ----------------
+# -Wl,...: tell GCC to pass this to linker.
+# -Map: create map file
+# --cref: add cross reference to map file
+LDFLAGS = -Wl,-Map=$(TARGET).map,--cref
+LDFLAGS += -Wl,--section-start=.text=$(BOOT_START)
+LDFLAGS += -Wl,--relax
+LDFLAGS += -Wl,--gc-sections
+LDFLAGS += $(EXTMEMOPTS)
+LDFLAGS += $(patsubst %,-L%,$(EXTRALIBDIRS))
+LDFLAGS += $(PRINTF_LIB) $(SCANF_LIB) $(MATH_LIB)
+#LDFLAGS += -T linker_script.x
+
+
+
+#---------------- Programming Options (avrdude) ----------------
+
+# Programming hardware
+# Type: avrdude -c ?
+# to get a full listing.
+#
+AVRDUDE_PROGRAMMER = avrispmkII
+
+# com1 = serial port. Use lpt1 to connect to parallel port.
+AVRDUDE_PORT = usb
+
+AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex
+#AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep
+
+
+# Uncomment the following if you want avrdude's erase cycle counter.
+# Note that this counter needs to be initialized first using -Yn,
+# see avrdude manual.
+#AVRDUDE_ERASE_COUNTER = -y
+
+# Uncomment the following if you do /not/ wish a verification to be
+# performed after programming the device.
+#AVRDUDE_NO_VERIFY = -V
+
+# Increase verbosity level. Please use this when submitting bug
+# reports about avrdude. See <http://savannah.nongnu.org/projects/avrdude>
+# to submit bug reports.
+#AVRDUDE_VERBOSE = -v -v
+
+AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER)
+AVRDUDE_FLAGS += $(AVRDUDE_NO_VERIFY)
+AVRDUDE_FLAGS += $(AVRDUDE_VERBOSE)
+AVRDUDE_FLAGS += $(AVRDUDE_ERASE_COUNTER)
+
+
+
+#---------------- Debugging Options ----------------
+
+# For simulavr only - target MCU frequency.
+DEBUG_MFREQ = $(F_CPU)
+
+# Set the DEBUG_UI to either gdb or insight.
+# DEBUG_UI = gdb
+DEBUG_UI = insight
+
+# Set the debugging back-end to either avarice, simulavr.
+DEBUG_BACKEND = avarice
+#DEBUG_BACKEND = simulavr
+
+# GDB Init Filename.
+GDBINIT_FILE = __avr_gdbinit
+
+# When using avarice settings for the JTAG
+JTAG_DEV = /dev/com1
+
+# Debugging port used to communicate between GDB / avarice / simulavr.
+DEBUG_PORT = 4242
+
+# Debugging host used to communicate between GDB / avarice / simulavr, normally
+# just set to localhost unless doing some sort of crazy debugging when
+# avarice is running on a different computer.
+DEBUG_HOST = localhost
+
+
+
+#============================================================================
+
+
+# Define programs and commands.
+SHELL = sh
+CC = avr-gcc
+OBJCOPY = avr-objcopy
+OBJDUMP = avr-objdump
+SIZE = avr-size
+AR = avr-ar rcs
+NM = avr-nm
+AVRDUDE = /Applications/avrdude -C /Applications/avrdude.conf -B 1
+REMOVE = rm -f
+REMOVEDIR = rm -rf
+COPY = cp
+WINSHELL = cmd
+
+
+# Define Messages
+# English
+MSG_ERRORS_NONE = Errors: none
+MSG_BEGIN = -------- begin --------
+MSG_END = -------- end --------
+MSG_SIZE_BEFORE = Size before:
+MSG_SIZE_AFTER = Size after:
+MSG_COFF = Converting to AVR COFF:
+MSG_EXTENDED_COFF = Converting to AVR Extended COFF:
+MSG_FLASH = Creating load file for Flash:
+MSG_EEPROM = Creating load file for EEPROM:
+MSG_EXTENDED_LISTING = Creating Extended Listing:
+MSG_SYMBOL_TABLE = Creating Symbol Table:
+MSG_LINKING = Linking:
+MSG_COMPILING = Compiling C:
+MSG_COMPILING_CPP = Compiling C++:
+MSG_ASSEMBLING = Assembling:
+MSG_CLEANING = Cleaning project:
+MSG_CREATING_LIBRARY = Creating library:
+
+
+
+
+# Define all object files.
+OBJ = $(SRC:%.c=$(OBJDIR)/%.o) $(CPPSRC:%.cpp=$(OBJDIR)/%.o) $(ASRC:%.S=$(OBJDIR)/%.o)
+
+# Define all listing files.
+LST = $(SRC:%.c=$(OBJDIR)/%.lst) $(CPPSRC:%.cpp=$(OBJDIR)/%.lst) $(ASRC:%.S=$(OBJDIR)/%.lst)
+
+
+# Compiler flags to generate dependency files.
+GENDEPFLAGS = -MMD -MP -MF .dep/$(@F).d
+
+
+# Combine all necessary flags and optional flags.
+# Add target processor to flags.
+ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) $(GENDEPFLAGS)
+ALL_CPPFLAGS = -mmcu=$(MCU) -I. -x c++ $(CPPFLAGS) $(GENDEPFLAGS)
+ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS)
+
+
+
+
+
+# Default target.
+all: begin gccversion sizebefore build sizeafter end
+
+# Change the build target to build a HEX file or a library.
+build: elf hex eep lss sym
+#build: lib
+
+
+elf: $(TARGET).elf
+hex: $(TARGET).hex
+eep: $(TARGET).eep
+lss: $(TARGET).lss
+sym: $(TARGET).sym
+LIBNAME=lib$(TARGET).a
+lib: $(LIBNAME)
+
+
+
+# Eye candy.
+# AVR Studio 3.x does not check make's exit code but relies on
+# the following magic strings to be generated by the compile job.
+begin:
+ @echo
+ @echo $(MSG_BEGIN)
+
+end:
+ @echo $(MSG_END)
+ @echo
+
+
+# Display size of file.
+HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex
+ELFSIZE = $(SIZE) $(MCU_FLAG) $(FORMAT_FLAG) $(TARGET).elf
+MCU_FLAG = $(shell $(SIZE) --help | grep -- --mcu > /dev/null && echo --mcu=$(MCU) )
+FORMAT_FLAG = $(shell $(SIZE) --help | grep -- --format=.*avr > /dev/null && echo --format=avr )
+
+
+sizebefore:
+ @if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); \
+ 2>/dev/null; echo; fi
+
+sizeafter:
+ @if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); \
+ 2>/dev/null; echo; fi
+
+
+
+# Display compiler version information.
+gccversion :
+ @$(CC) --version
+
+
+# Program the device.
+program: $(TARGET).hex $(TARGET).eep
+ $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM)
+
+
+# Generate avr-gdb config/init file which does the following:
+# define the reset signal, load the target file, connect to target, and set
+# a breakpoint at main().
+gdb-config:
+ @$(REMOVE) $(GDBINIT_FILE)
+ @echo define reset >> $(GDBINIT_FILE)
+ @echo SIGNAL SIGHUP >> $(GDBINIT_FILE)
+ @echo end >> $(GDBINIT_FILE)
+ @echo file $(TARGET).elf >> $(GDBINIT_FILE)
+ @echo target remote $(DEBUG_HOST):$(DEBUG_PORT) >> $(GDBINIT_FILE)
+ifeq ($(DEBUG_BACKEND),simulavr)
+ @echo load >> $(GDBINIT_FILE)
+endif
+ @echo break main >> $(GDBINIT_FILE)
+
+debug: gdb-config $(TARGET).elf
+ifeq ($(DEBUG_BACKEND), avarice)
+ @echo Starting AVaRICE - Press enter when "waiting to connect" message displays.
+ @$(WINSHELL) /c start avarice --jtag $(JTAG_DEV) --erase --program --file \
+ $(TARGET).elf $(DEBUG_HOST):$(DEBUG_PORT)
+ @$(WINSHELL) /c pause
+
+else
+ @$(WINSHELL) /c start simulavr --gdbserver --device $(MCU) --clock-freq \
+ $(DEBUG_MFREQ) --port $(DEBUG_PORT)
+endif
+ @$(WINSHELL) /c start avr-$(DEBUG_UI) --command=$(GDBINIT_FILE)
+
+
+
+
+# Convert ELF to COFF for use in debugging / simulating in AVR Studio or VMLAB.
+COFFCONVERT = $(OBJCOPY) --debugging
+COFFCONVERT += --change-section-address .data-0x800000
+COFFCONVERT += --change-section-address .bss-0x800000
+COFFCONVERT += --change-section-address .noinit-0x800000
+COFFCONVERT += --change-section-address .eeprom-0x810000
+
+
+
+coff: $(TARGET).elf
+ @echo
+ @echo $(MSG_COFF) $(TARGET).cof
+ $(COFFCONVERT) -O coff-avr $< $(TARGET).cof
+
+
+extcoff: $(TARGET).elf
+ @echo
+ @echo $(MSG_EXTENDED_COFF) $(TARGET).cof
+ $(COFFCONVERT) -O coff-ext-avr $< $(TARGET).cof
+
+
+
+# Create final output files (.hex, .eep) from ELF output file.
+%.hex: %.elf
+ @echo
+ @echo $(MSG_FLASH) $@
+ $(OBJCOPY) -O $(FORMAT) -R .eeprom -R .fuse -R .lock $< $@
+
+%.eep: %.elf
+ @echo
+ @echo $(MSG_EEPROM) $@
+ -$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \
+ --change-section-lma .eeprom=0 --no-change-warnings -O $(FORMAT) $< $@ || exit 0
+
+# Create extended listing file from ELF output file.
+%.lss: %.elf
+ @echo
+ @echo $(MSG_EXTENDED_LISTING) $@
+ $(OBJDUMP) -h -S -z $< > $@
+
+# Create a symbol table from ELF output file.
+%.sym: %.elf
+ @echo
+ @echo $(MSG_SYMBOL_TABLE) $@
+ $(NM) -n $< > $@
+
+
+
+# Create library from object files.
+.SECONDARY : $(TARGET).a
+.PRECIOUS : $(OBJ)
+%.a: $(OBJ)
+ @echo
+ @echo $(MSG_CREATING_LIBRARY) $@
+ $(AR) $@ $(OBJ)
+
+
+# Link: create ELF output file from object files.
+.SECONDARY : $(TARGET).elf
+.PRECIOUS : $(OBJ)
+%.elf: $(OBJ)
+ @echo
+ @echo $(MSG_LINKING) $@
+ $(CC) $(ALL_CFLAGS) $^ --output $@ $(LDFLAGS)
+
+
+# Compile: create object files from C source files.
+$(OBJDIR)/%.o : %.c
+ @echo
+ @echo $(MSG_COMPILING) $<
+ $(CC) -c $(ALL_CFLAGS) $< -o $@
+
+
+# Compile: create object files from C++ source files.
+$(OBJDIR)/%.o : %.cpp
+ @echo
+ @echo $(MSG_COMPILING_CPP) $<
+ $(CC) -c $(ALL_CPPFLAGS) $< -o $@
+
+
+# Compile: create assembler files from C source files.
+%.s : %.c
+ $(CC) -S $(ALL_CFLAGS) $< -o $@
+
+
+# Compile: create assembler files from C++ source files.
+%.s : %.cpp
+ $(CC) -S $(ALL_CPPFLAGS) $< -o $@
+
+
+# Assemble: create object files from assembler source files.
+$(OBJDIR)/%.o : %.S
+ @echo
+ @echo $(MSG_ASSEMBLING) $<
+ $(CC) -c $(ALL_ASFLAGS) $< -o $@
+
+
+# Create preprocessed source for use in sending a bug report.
+%.i : %.c
+ $(CC) -E -mmcu=$(MCU) -I. $(CFLAGS) $< -o $@
+
+
+# Target: clean project.
+clean: begin clean_list end
+
+clean_list :
+ @echo
+ @echo $(MSG_CLEANING)
+ $(REMOVE) $(TARGET).hex
+ $(REMOVE) $(TARGET).eep
+ $(REMOVE) $(TARGET).cof
+ $(REMOVE) $(TARGET).elf
+ $(REMOVE) $(TARGET).map
+ $(REMOVE) $(TARGET).sym
+ $(REMOVE) $(TARGET).lss
+ $(REMOVE) $(SRC:%.c=$(OBJDIR)/%.o) $(CPPSRC:%.cpp=$(OBJDIR)/%.o) $(ASRC:%.S=$(OBJDIR)/%.o)
+ $(REMOVE) $(SRC:%.c=$(OBJDIR)/%.lst) $(CPPSRC:%.cpp=$(OBJDIR)/%.lst) $(ASRC:%.S=$(OBJDIR)/%.lst)
+ $(REMOVE) $(SRC:.c=.s)
+ $(REMOVE) $(SRC:.c=.d)
+ $(REMOVE) $(SRC:.c=.i)
+ $(REMOVEDIR) .dep
+
+doxygen:
+ @echo Generating Project Documentation \($(TARGET)\)...
+ @doxygen Doxygen.conf
+ @echo Documentation Generation Complete.
+
+clean_doxygen:
+ rm -rf Documentation
+
+checksource:
+ @for f in $(SRC) $(CPPSRC) $(ASRC); do \
+ if [ -f $$f ]; then \
+ echo "Found Source File: $$f" ; \
+ else \
+ echo "Source File Not Found: $$f" ; \
+ fi; done
+
+
+# Create object files directory
+$(shell mkdir $(OBJDIR) 2>/dev/null)
+
+
+# Include the dependency files.
+-include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*)
+
+
+# Listing of phony targets.
+.PHONY : all begin finish end sizebefore sizeafter gccversion \
+build elf hex eep lss sym coff extcoff doxygen clean \
+clean_list clean_doxygen program debug gdb-config checksource
+
diff --git a/bootloaders/diskloader/DiskLoader-Leonardo.hex b/bootloaders/diskloader/DiskLoader-Leonardo.hex
deleted file mode 100644
index 0d0c167..0000000
--- a/bootloaders/diskloader/DiskLoader-Leonardo.hex
+++ /dev/null
@@ -1,115 +0,0 @@
-:1078000011241FBECFEFDAE0DEBFCDBFFFC04101C4
-:1078100042144505560455026403740300001E9586
-:1078200087020110030000C18081C106C0FF0A0069
-:107830000CA10185037508150026FF00954009017C
-:107840008102954009029102C0040309041A033021
-:1078500000300030003000300030003000300031A7
-:1078600000370030003100380341007200640075B9
-:107870000069006E006F0020004C0065006F006E14
-:10788000006100720064006F00200062006F006FF2
-:107890000074006C006F00610064006500720018E5
-:1078A00003410072006400750069006E006F0020E3
-:1078B000004C004C00430012010002020000404155
-:1078C0002334000001000203011201000200000045
-:1078D0004041233400000100020301090264000357
-:1078E00001008032080B00020202010009040000BE
-:1078F0000102020000052400100105240101010419
-:107900002402020524060001070581031000400936
-:10791000040100020A0000000705020240000007FF
-:107920000583024000000904020001030000000971
-:107930002101010001221E000705840340004000D0
-:1079400020918A0130918B012C5F3F4F30938B0146
-:1079500020938A01C901892F99278695982F803411
-:1079600018F08FE7891B982F990F921710F44798FA
-:107970000895479A08955D9A289A81E08093E000DF
-:107980001092E200EE27FF27099408950F931F93AA
-:10799000CF93DF93982FEB01042F10E088E760303E
-:1079A000780730F411E083E0FB0180935700E895FD
-:1079B000892F68E071E0402FF8D0112311F107B64C
-:1079C00000FCFDCF402F4695FE01A8E0B1E020E08D
-:1079D00031E009C08D919D910C0130935700E895DD
-:1079E000112432962F5F2417A8F385E0FE018093BF
-:1079F0005700E89507B600FCFDCF81E18093570062
-:107A0000E895DF91CF911F910F91089588E10FB60E
-:107A1000F89480936000109260000FBE5D9A289ADF
-:107A200047983F9A209A559A90E890936100109257
-:107A3000610081E885BF95BF9FD084E18093880174
-:107A400080E180938901E0E0F0E0859194918F5F7F
-:107A50009F4F19F081E080938F01EE24FF24BB2417
-:107A6000B39454EFC52E51E0D52E13D2082F8EE0DB
-:107A700098E7FC012491319602964491201711F069
-:107A80002223B9F7109291011092900182E068E0F0
-:107A900071E08BD0013479F4609108016058633053
-:107AA00028F0683111F064E001C063E0C62FD0E037
-:107AB000CF5DD7480EC0063571F480910801803340
-:107AC00011F011E022C080910A01C82FD0E0C25EFF
-:107AD000D74811E022C0053721F413E0CEE1D8E702
-:107AE0001CC0053539F4E0900801F0900901EE0C56
-:107AF000FF1C0AC0043631F482E0B701409109014D
-:107B000045DF02C0043721F010E0C5E2D8E705C028
-:107B100010910901E701E10EF11CBBD18097B1F48E
-:107B200083E068E871E041E050E059D0112329F08A
-:107B3000412F50E083E8BE0152D083E469E871E050
-:107B400041E050E04CD0013509F08FCFD092910147
-:107B5000C0929001B0928F01EE24FF2486CFFC01E9
-:107B6000289884E680938D0104C08091F100819370
-:107B700061506623D1F708951092910110929001FF
-:107B800010928E0110928F0181E08093D70080EADD
-:107B90008093D80082E189BD09B400FEFDCF80E961
-:107BA0008093D8001092E0000895FB018093E900D3
-:107BB00024E69BE611C08091E80085FFFCCF289861
-:107BC00020938D018091F10081938091E80085FDE3
-:107BD00002C09093E8004150442369F70895982F1C
-:107BE000FB01282F207287708093E90064E63AE356
-:107BF00017C08091E80085FFFCCF97FF02C08491F9
-:107C000001C080813196211180E05D9860938C01E4
-:107C10008093F1008091E80085FD02C03093E80078
-:107C2000415050408FEF4F3F580719F796FF03C060
-:107C30008AE38093E800089580919301813299F45A
-:107C40005D9884E680938C0120E030E003C0808161
-:107C50008093F100F901E050FF4F2F5F3F4F283034
-:107C60003105A9F714C0803261F48091E80082FFE9
-:107C7000FCCF80E091E067E072DF8BEF8093E8005B
-:107C800006C0823221F4809194018093070181E043
-:107C9000089520919501223289F1213081F480915B
-:107CA000980190919901089711F420939A0180917D
-:107CB0009A01882309F04FC0E9ECF8E74EC0223062
-:107CC00021F484E6EBEDF8E71CC0233009F041C055
-:107CD00080919401882319F4E9E4F8E73EC08230EA
-:107CE00019F4E7E6F8E739C0833019F4EDE4F8E772
-:107CF00034C0813071F5EFE9F8E72FC081E0EBE2A5
-:107D0000F8E790919801382F981708F4392F90913F
-:107D10008C0120E04EEF8091E8008570E1F38091C6
-:107D2000E80082FD12C02F5F84915D988093F1007E
-:107D3000822F8F7311F44093E800319694E6231755
-:107D400050F390938C0181E0089590938C0180E032
-:107D5000089580E00895E7EBF8E78491D2CF109280
-:107D6000E9008091E80083FF61C082E991E068E06A
-:107D7000F6DE82EF8093E8008091920187FF05C0D4
-:107D80008091E80080FFFCCF03C08EEF8093E80075
-:107D900080919301853051F48091E80080FFFCCF01
-:107DA0008091940180688093E30039C08930E1F4C8
-:107DB0008091940180938E01E7E2F8E791E031E051
-:107DC00026E39093E9003093EB0084918093EC00DC
-:107DD0002093ED009F5F3196953099F78EE7809361
-:107DE000EA001092EA001BC0883049F490918E019D
-:107DF0005D9884E680938C019093F10010C08823F5
-:107E000039F45D9884E680938C011092F10007C0EC
-:107E1000863011F43EDF01C00FDF882321F08EEFA2
-:107E20008093E800089581E28093EB0008958091AB
-:107E3000E1001092E100282F83FF0CC01092E900AE
-:107E400081E08093EB001092EC0082E38093ED00E0
-:107E500010928E0122FF1CC080918C01882331F08A
-:107E6000815080938C01882309F45D9A80918D0163
-:107E7000882331F0815080938D01882309F4289A5A
-:107E800080918F01882321F410929101109290012A
-:107E900008951F93CF93DF9312E0C0E9D1E05FDF35
-:107EA000C6DF1093E9008091E80085FF13C0289891
-:107EB00084E680938D019091F1008091E80085FD2A
-:107EC00003C08BE68093E800892F90E0DF91CF918B
-:107ED0001F91089580919001909191010197909345
-:107EE0009101809390018091900190919101892B53
-:0E7EF00009F441DDCE010197F1F722DDD0CF7C
-:087EFE0000E10000000000009B
-:040000030000780081
-:00000001FF
diff --git a/cores/arduino/CDC.cpp b/cores/arduino/CDC.cpp
index 14a0eae..94faf2e 100644
--- a/cores/arduino/CDC.cpp
+++ b/cores/arduino/CDC.cpp
@@ -23,12 +23,20 @@
#if defined(USBCON)
#ifdef CDC_ENABLED
-void Reboot()
+#if (RAMEND < 1000)
+#define SERIAL_BUFFER_SIZE 16
+#else
+#define SERIAL_BUFFER_SIZE 64
+#endif
+
+struct ring_buffer
{
- USB.detach();
- cli();
- asm volatile("jmp 0x7800"); // jump to bootloader - DiskLoader takes up last 2 kB
-}
+ unsigned char buffer[SERIAL_BUFFER_SIZE];
+ volatile int head;
+ volatile int tail;
+};
+
+ring_buffer cdc_rx_buffer = { { 0 }, 0, 0};
typedef struct
{
@@ -92,9 +100,29 @@ bool WEAK CDC_Setup(Setup& setup)
if (CDC_SET_CONTROL_LINE_STATE == r)
{
- if (0 != _usbLineInfo.lineState && 1200 == _usbLineInfo.dwDTERate) // auto-reset is triggered when the port, already open at 1200 bps, is closed
- Reboot();
_usbLineInfo.lineState = setup.wValueL;
+
+ // 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
+ // like servicing endpoints before the sketch ends
+ if (1200 == _usbLineInfo.dwDTERate) {
+ // We check DTR state to determine if host port is open (bit 0 of lineState).
+ // Serial1.print(">"); Serial1.println(_usbLineInfo.lineState, HEX);
+ if ((_usbLineInfo.lineState & 0x01) == 0) {
+ *(uint16_t *)0x0A00 = 0x7777;
+ wdt_enable(WDTO_250MS);
+ } else {
+ // 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
+ // cancel if DTR goes back high.
+
+ wdt_disable();
+ wdt_reset();
+ *(uint16_t *)0x0A00 = 0x0;
+ }
+ }
return true;
}
}
@@ -111,33 +139,49 @@ void Serial_::end(void)
{
}
+void Serial_::accept(void)
+{
+ ring_buffer *buffer = &cdc_rx_buffer;
+ int c = USB_Recv(CDC_RX);
+ int i = (unsigned int)(buffer->head+1) % SERIAL_BUFFER_SIZE;
+
+ // if we should be storing the received character into the location
+ // just before the tail (meaning that the head would advance to the
+ // current location of the tail), we're about to overflow the buffer
+ // and so we don't write the character or advance the head.
+ if (i != buffer->tail) {
+ buffer->buffer[buffer->head] = c;
+ buffer->head = i;
+ }
+}
+
int Serial_::available(void)
{
- u8 avail = USB_Available(CDC_RX);
- if (_serialPeek != -1)
- avail++;
- return avail;
+ ring_buffer *buffer = &cdc_rx_buffer;
+ return (unsigned int)(SERIAL_BUFFER_SIZE + buffer->head - buffer->tail) % SERIAL_BUFFER_SIZE;
}
-// peek is nasty
int Serial_::peek(void)
{
- if (_serialPeek == -1)
- _serialPeek = read();
- return _serialPeek;
+ ring_buffer *buffer = &cdc_rx_buffer;
+ if (buffer->head == buffer->tail) {
+ return -1;
+ } else {
+ return buffer->buffer[buffer->tail];
+ }
}
int Serial_::read(void)
{
- int c;
- if (_serialPeek != -1)
- {
- c = _serialPeek;
- _serialPeek = -1;
+ ring_buffer *buffer = &cdc_rx_buffer;
+ // if the head isn't ahead of the tail, we don't have any characters
+ if (buffer->head == buffer->tail) {
+ return -1;
} else {
- c = USB_Recv(CDC_RX);
- }
- return c;
+ unsigned char c = buffer->buffer[buffer->tail];
+ buffer->tail = (unsigned int)(buffer->tail + 1) % SERIAL_BUFFER_SIZE;
+ return c;
+ }
}
void Serial_::flush(void)
@@ -172,4 +216,4 @@ size_t Serial_::write(uint8_t c)
Serial_ Serial;
#endif
-#endif /* if defined(USBCON) */ \ No newline at end of file
+#endif /* if defined(USBCON) */
diff --git a/cores/arduino/HID.cpp b/cores/arduino/HID.cpp
index 8ed1566..b60b3c0 100644
--- a/cores/arduino/HID.cpp
+++ b/cores/arduino/HID.cpp
@@ -144,7 +144,6 @@ u8 _hid_protocol = 1;
u8 _hid_idle = 1;
#define WEAK __attribute__ ((weak))
-#define WEAK
int WEAK HID_GetInterface(u8* interfaceNum)
{
@@ -245,7 +244,7 @@ void Mouse_::release(uint8_t b)
bool Mouse_::isPressed(uint8_t b)
{
- if (b & _buttons > 0)
+ if ((b & _buttons) > 0)
return true;
return false;
}
@@ -406,7 +405,8 @@ const uint8_t _asciimap[128] =
};
uint8_t USBPutChar(uint8_t c);
-size_t Keyboard_::write(uint8_t c)
+
+size_t Keyboard_::type(uint8_t c)
{
// Keydown
{
diff --git a/cores/arduino/USBAPI.h b/cores/arduino/USBAPI.h
index 26a2032..3c97ff1 100644
--- a/cores/arduino/USBAPI.h
+++ b/cores/arduino/USBAPI.h
@@ -27,11 +27,14 @@ extern USB_ USB;
class Serial_ : public Stream
{
+private:
+ ring_buffer *_cdc_rx_buffer;
public:
void begin(uint16_t baud_count);
void end(void);
virtual int available(void);
+ virtual void accept(void);
virtual int peek(void);
virtual int read(void);
virtual void flush(void);
@@ -101,7 +104,8 @@ private:
void setKeyMap(KeyMap* keyMap);
public:
Keyboard_();
- virtual size_t write(uint8_t);
+ virtual size_t write(uint8_t c) {return type(c);};
+ virtual size_t type(uint8_t c);
};
extern Keyboard_ Keyboard;
diff --git a/cores/arduino/USBCore.cpp b/cores/arduino/USBCore.cpp
index 398bc73..7924078 100644
--- a/cores/arduino/USBCore.cpp
+++ b/cores/arduino/USBCore.cpp
@@ -599,6 +599,8 @@ ISR(USB_GEN_vect)
{
#ifdef CDC_ENABLED
USB_Flush(CDC_TX); // Send a tx frame if found
+ while (USB_Available(CDC_RX)) // Handle received bytes (if any)
+ Serial.accept();
#endif
// check whether the one-shot period has elapsed. if so, turn off the LED
diff --git a/cores/arduino/USBDesc.h b/cores/arduino/USBDesc.h
index 549ed9e..5cd90ad 100644
--- a/cores/arduino/USBDesc.h
+++ b/cores/arduino/USBDesc.h
@@ -60,7 +60,7 @@
#define IMANUFACTURER 1
#define IPRODUCT 2
-#define USB_PID_LEONARDO 0x0034
+#define USB_PID_LEONARDO 0x0801
#define USB_PID_MICRO 0x0035
#define USB_VID 0x2341 // arduino LLC vid
#define USB_PID ARDUINO_MODEL_USB_PID
diff --git a/cores/arduino/WInterrupts.c b/cores/arduino/WInterrupts.c
index 3b9fe08..8f3ec84 100755..100644
--- a/cores/arduino/WInterrupts.c
+++ b/cores/arduino/WInterrupts.c
@@ -47,7 +47,19 @@ void attachInterrupt(uint8_t interruptNum, void (*userFunc)(void), int mode) {
// Enable the interrupt.
switch (interruptNum) {
-#if defined(EICRA) && defined(EICRB) && defined(EIMSK)
+#if defined(__AVR_ATmega32U4__)
+ // I hate doing this, but the register assignment differs between the 1280/2560
+ // and the 32U4. Since avrlib defines registers PCMSK1 and PCMSK2 that aren't
+ // even present on the 32U4 this is the only way to distinguish between them.
+ case 0:
+ EICRA = (EICRA & ~((1<<ISC00) | (1<<ISC01))) | (mode << ISC00);
+ EIMSK |= (1<<INT0);
+ break;
+ case 1:
+ EICRA = (EICRA & ~((1<<ISC10) | (1<<ISC11))) | (mode << ISC10);
+ EIMSK |= (1<<INT1);
+ break;
+#elif defined(EICRA) && defined(EICRB) && defined(EIMSK)
case 2:
EICRA = (EICRA & ~((1 << ISC00) | (1 << ISC01))) | (mode << ISC00);
EIMSK |= (1 << INT0);
@@ -80,7 +92,7 @@ void attachInterrupt(uint8_t interruptNum, void (*userFunc)(void), int mode) {
EICRB = (EICRB & ~((1 << ISC70) | (1 << ISC71))) | (mode << ISC70);
EIMSK |= (1 << INT7);
break;
-#else
+#else
case 0:
#if defined(EICRA) && defined(ISC00) && defined(EIMSK)
EICRA = (EICRA & ~((1 << ISC00) | (1 << ISC01))) | (mode << ISC00);
@@ -134,7 +146,14 @@ void detachInterrupt(uint8_t interruptNum) {
// to the number of the EIMSK bit to clear, as this isn't true on the
// ATmega8. There, INT0 is 6 and INT1 is 7.)
switch (interruptNum) {
-#if defined(EICRA) && defined(EICRB) && defined(EIMSK)
+#if defined(__AVR_ATmega32U4__)
+ case 0:
+ EIMSK &= ~(1<<INT0);
+ break;
+ case 1:
+ EIMSK &= ~(1<<INT1);
+ break;
+#elif defined(EICRA) && defined(EICRB) && defined(EIMSK)
case 2:
EIMSK &= ~(1 << INT0);
break;
@@ -196,7 +215,18 @@ void attachInterruptTwi(void (*userFunc)(void) ) {
}
*/
-#if defined(EICRA) && defined(EICRB)
+#if defined(__AVR_ATmega32U4__)
+SIGNAL(INT0_vect) {
+ if(intFunc[EXTERNAL_INT_0])
+ intFunc[EXTERNAL_INT_0]();
+}
+
+SIGNAL(INT1_vect) {
+ if(intFunc[EXTERNAL_INT_1])
+ intFunc[EXTERNAL_INT_1]();
+}
+
+#elif defined(EICRA) && defined(EICRB)
SIGNAL(INT0_vect) {
if(intFunc[EXTERNAL_INT_2])
diff --git a/cores/arduino/wiring.c b/cores/arduino/wiring.c
index e7f7cde..fb447eb 100755..100644
--- a/cores/arduino/wiring.c
+++ b/cores/arduino/wiring.c
@@ -278,12 +278,25 @@ void init()
sbi(TCCR3B, CS30);
sbi(TCCR3A, WGM30); // put timer 3 in 8-bit phase correct pwm mode
#endif
-
+
+#if defined(TCCR4A) && defined(TCCR4B) && defined(TCCR4D) /* beginning of timer4 block for 32U4 and similar */
+ sbi(TCCR4A, COM4A1); // clear channel A on output compare match
+ cbi(TCCR4A, COM4A0);
+ sbi(TCCR4C, COM4D1); // clear channel D on output compare match
+ cbi(TCCR4C, COM4D0);
+ sbi(TCCR4B, CS42); // set timer4 prescale factor to 64
+ sbi(TCCR4B, CS41);
+ sbi(TCCR4B, CS40);
+ sbi(TCCR4D, WGM40); // put timer 4 in phase- and frequency-correct PWM mode
+ sbi(TCCR4A, PWM4A); // enable PWM mode for comparator OCR4A
+ sbi(TCCR4C, PWM4D); // enable PWM mode for comparator OCR4D
+#else /* beginning of timer4 block for ATMEGA1280 and ATMEGA2560 */
#if defined(TCCR4B) && defined(CS41) && defined(WGM40)
sbi(TCCR4B, CS41); // set timer 4 prescale factor to 64
sbi(TCCR4B, CS40);
sbi(TCCR4A, WGM40); // put timer 4 in 8-bit phase correct pwm mode
#endif
+#endif /* end timer4 block for ATMEGA1280/2560 and similar */
#if defined(TCCR5B) && defined(CS51) && defined(WGM50)
sbi(TCCR5B, CS51); // set timer 5 prescale factor to 64
diff --git a/cores/arduino/wiring_analog.c b/cores/arduino/wiring_analog.c
index a8bc817..40a3363 100644
--- a/cores/arduino/wiring_analog.c
+++ b/cores/arduino/wiring_analog.c
@@ -206,14 +206,14 @@ void analogWrite(uint8_t pin, int val)
break;
#endif
- #if defined(TCCR4A) && defined(COM4A1)
+ #if defined(TCCR4A)
case TIMER4A:
- // connect pwm to pin on timer 4, channel A
+ //connect pwm to pin on timer 4, channel A
sbi(TCCR4A, COM4A1);
- OCR4A = val; // set pwm duty
+ OCR4A = val; // set pwm duty
break;
#endif
-
+
#if defined(TCCR4A) && defined(COM4B1)
case TIMER4B:
// connect pwm to pin on timer 4, channel B
@@ -230,14 +230,15 @@ void analogWrite(uint8_t pin, int val)
break;
#endif
- #if defined(TCCR4A) && defined(COM4D1)
- case TIMER4D:
+ #if defined(TCCR4C)
+ case TIMER4D:
// connect pwm to pin on timer 4, channel D
- sbi(TCCR4A, COM4D1);
- OCR4D = val; // set pwm duty
+ sbi(TCCR4C, COM4D1);
+ OCR4D = val; // set pwm duty
break;
#endif
+
#if defined(TCCR5A) && defined(COM5A1)
case TIMER5A:
// connect pwm to pin on timer 5, channel A
@@ -272,3 +273,4 @@ void analogWrite(uint8_t pin, int val)
}
}
}
+
diff --git a/cores/arduino/wiring_digital.c b/cores/arduino/wiring_digital.c
index 584a28a..be323b1 100755..100644
--- a/cores/arduino/wiring_digital.c
+++ b/cores/arduino/wiring_digital.c
@@ -115,13 +115,17 @@ static void turnOffPWM(uint8_t timer)
#if defined(TCCR4A) && defined(COM4A1)
case TIMER4A: cbi(TCCR4A, COM4A1); break;
- #endif
+ #endif
#if defined(TCCR4A) && defined(COM4B1)
case TIMER4B: cbi(TCCR4A, COM4B1); break;
#endif
#if defined(TCCR4A) && defined(COM4C1)
case TIMER4C: cbi(TCCR4A, COM4C1); break;
- #endif
+ #endif
+ #if defined(TCCR4C) && defined(COM4D1)
+ case TIMER4D: cbi(TCCR4C, COM4D1); break;
+ #endif
+
#if defined(TCCR5A)
case TIMER5A: cbi(TCCR5A, COM5A1); break;
case TIMER5B: cbi(TCCR5A, COM5B1); break;
diff --git a/variants/leonardo/pins_arduino.h b/variants/leonardo/pins_arduino.h
index 5a15146..753aa93 100644
--- a/variants/leonardo/pins_arduino.h
+++ b/variants/leonardo/pins_arduino.h
@@ -27,7 +27,7 @@
#include <avr/pgmspace.h>
-#define ARDUINO_MODEL_USB_PID 0x0034
+#define ARDUINO_MODEL_USB_PID 0x0801
#define TX_RX_LED_INIT DDRD |= (1<<5), DDRB |= (1<<0)
#define TXLED0 PORTD |= (1<<5)
@@ -212,7 +212,7 @@ const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[30] = {
_BV(6), // D29 / D12 - A11 - PD6
};
-const uint8_t PROGMEM digital_pin_to_timer_PGM[18] = {
+const uint8_t PROGMEM digital_pin_to_timer_PGM[16] = {
NOT_ON_TIMER,
NOT_ON_TIMER,
NOT_ON_TIMER,