diff options
26 files changed, 2705 insertions, 423 deletions
| @@ -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, | 
