aboutsummaryrefslogtreecommitdiff
path: root/bootloaders/caterina_LUFA
diff options
context:
space:
mode:
Diffstat (limited to 'bootloaders/caterina_LUFA')
-rwxr-xr-xbootloaders/caterina_LUFA/Caterina.c609
-rwxr-xr-xbootloaders/caterina_LUFA/Caterina.h86
-rw-r--r--bootloaders/caterina_LUFA/Caterina.hex228
-rwxr-xr-xbootloaders/caterina_LUFA/Descriptors.c243
-rwxr-xr-xbootloaders/caterina_LUFA/Descriptors.h139
-rwxr-xr-xbootloaders/caterina_LUFA/makefile717
6 files changed, 2022 insertions, 0 deletions
diff --git a/bootloaders/caterina_LUFA/Caterina.c b/bootloaders/caterina_LUFA/Caterina.c
new file mode 100755
index 0000000..f95613f
--- /dev/null
+++ b/bootloaders/caterina_LUFA/Caterina.c
@@ -0,0 +1,609 @@
+/*
+ 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;
+
+void StartSketch()
+{
+ cli();
+ /* Relocate the interrupt vector table to the application section */
+ MCUCR = (1 << IVCE);
+ MCUCR = 0;
+
+// UDCON = 1; // Detach USB
+// UDIEN = 0;
+
+ /* jump to beginning of application space */
+ __asm__ volatile("jmp 0x0000");
+}
+
+/** 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)
+{
+ wdt_disable();
+
+ /* 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
+ * TODO - handle ctr now that TIMER1 is gone */
+// if (ctr++ > 10000 && pgm_read_word(0) != 0xFFFF)
+// RunBootloader = false;
+ }
+
+ /* 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);
+
+ /* Initialize USB Subsystem */
+ USB_Init();
+}
+
+/** 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;
+ }
+
+ /* 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');
+ }
+}
+#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);
+}
+
+#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;
+
+ /* Read in the bootloader command (first byte sent from host) */
+ uint8_t Command = FetchNextCommandByte();
+
+ /*
+ if (STK_UNIVERSAL == Command) {
+ WriteNextResponseByte(')');
+ } else {
+ WriteNextResponseByte(Command);
+ }
+ */
+
+
+ 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'))
+ {
+ // 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..4260166
--- /dev/null
+++ b/bootloaders/caterina_LUFA/Caterina.h
@@ -0,0 +1,86 @@
+/*
+ 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 "LUFACDC"
+
+ /* 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 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..c3c1d93
--- /dev/null
+++ b/bootloaders/caterina_LUFA/Caterina.hex
@@ -0,0 +1,228 @@
+:1070000055C000006EC000006CC000006AC00000E7
+:1070100068C0000066C0000064C0000062C00000DC
+:1070200060C000005EC000001FC400005AC0000025
+:1070300058C0000056C0000054C0000052C00000FC
+:1070400050C000004EC000004CC000004AC000000C
+:1070500048C0000046C0000044C0000042C000001C
+:1070600040C000003EC000003CC000003AC000002C
+:1070700038C0000036C0000034C0000032C000003C
+:1070800030C000002EC000002CC000002AC000004C
+:1070900028C0000026C0000024C0000022C000005C
+:1070A00020C000001EC000001CC0000011241FBE34
+:1070B000CFEFDAE0DEBFCDBF11E0A0E0B1E0ECE859
+:1070C000FDE702C005900D92AC38B107D9F711E089
+:1070D000ACE8B1E001C01D92AA39B107E1F7FCD2DA
+:1070E00053C68ECFF89481E085BF15BE0C94000086
+:1070F000089584E08093E9000DC08091E8008B77CB
+:107100008093E80003C08EB3882351F08091E8009B
+:1071100082FFF9CF8091E80085FFEFCF8091F100E9
+:107120000895982F83E08093E9008091E80085FD21
+:107130000DC08091E8008E778093E80003C08EB385
+:10714000882331F08091E80080FFF9CF9093F1001F
+:1071500008954F925F926F927F928F929F92AF921B
+:10716000BF92CF92DF92EF92FF920F931F93CF9334
+:10717000DF9384E08093E9008091E80082FF45C2BC
+:10718000B8DF182F853419F41092080103C0843534
+:1071900019F4AFDF8DE00FC28C34E1F38035D1F309
+:1071A000843721F484E4BDDF80E005C2813611F428
+:1071B00089E501C28134B1F49CDF182F9ADF90E099
+:1071C000880F991FAA2797FDA095BA2F312F330F4B
+:1071D00020E0442737FD4095542F822B932BA42B7E
+:1071E000B52BBAC1803711F483E5E5C1833549F485
+:1071F000C0E0D1E0899195DF21E0C730D207D1F717
+:10720000DBC1863521F481E38CDF80E3D4C1833791
+:1072100031F487E886DF85E984DF8EE1CCC18536ED
+:10722000B9F4E0E0F0E093E085E090935700E89552
+:1072300007B600FCFDCF80935700E89507B600FC29
+:10724000FDCFE058FF4FA0E7E030FA0771F7A2CF7B
+:107250008C3651F44EDF809599E0E1E0F0E0082EA5
+:1072600090935700E89596CF823739F4E1E0F0E04B
+:1072700089E08093570084919EC1863439F4E0E020
+:10728000F0E089E080935700849195C18E3439F401
+:10729000E3E0F0E089E08093570084918CC1813570
+:1072A00039F4E2E0F0E089E080935700849183C1F3
+:1072B000823631F489E535DF80E033DF80E87BC159
+:1072C000823419F0873609F0DBC013DF082F11DF95
+:1072D000F82E0FDF682E8554823008F06BC1902F96
+:1072E00080E0CF2DD0E0C82BD92B173609F04BC04A
+:1072F00081E180935700E895DD24CC24C3943FC0FE
+:10730000E0908C01F0908D0100918E0110918F0121
+:10731000B6E46B16D9F4ED2DF0E0EE29FF29E491E7
+:107320008E2FFFDEDD2081F082E090E0A0E0B0E073
+:10733000E80EF91E0A1F1B1FE0928C01F0928D01CE
+:1073400000938E0110938F01DC2418C0D801C7016F
+:10735000B695A7959795879501D5E3DE82E090E0F5
+:10736000A0E0B0E0E80EF91E0A1F1B1FE0928C019E
+:10737000F0928D0100938E0110938F012197209739
+:1073800009F0BECF19C180908C0190908D01A09022
+:107390008E01B0908F0196E4691609F05DC083E01C
+:1073A000F40180935700E89507B600FCFDCF54C068
+:1073B000F6E46F1661F5772031F1E0908C01F090E2
+:1073C0008D0100918E0110918F0193DED82ECC2477
+:1073D000852D90E08C299D29F7010C0140925700E2
+:1073E000E895112482E090E0A0E0B0E0E80EF91EFC
+:1073F0000A1F1B1FE0928C01F0928D0100938E01F9
+:1074000010938F0102C075DE582E742423C0E090C3
+:107410008C01F0908D0100918E0110918F011695D5
+:107420000795F794E79465DE682FC7019FD4809194
+:107430008C0190918D01A0918E01B0918F010296E7
+:10744000A11DB11D80938C0190938D01A0938E019D
+:10745000B0938F01219704C055247724442443948A
+:10746000209709F0A5CF96E4691609F093CE85E040
+:10747000F40180935700E89507B600FCFDCF8ACE53
+:10748000833471F400918C0110918D0132DE90E013
+:1074900021E0F8010C0120935700E89511247ACEE1
+:1074A000833619F5E0908C01F0908D0100918E01EA
+:1074B00010918F011EDEF701E16090E021E00C01E8
+:1074C00020935700E895112482E090E0A0E0B0E01E
+:1074D000E80EF91E0A1F1B1FE0928C01F0928D012D
+:1074E00000938E0110938F0155CE8D3661F4E0919B
+:1074F0008C01F0918D0185E080935700E89507B6E7
+:1075000000FCFDCF47CE823551F4E0918C01F09123
+:107510008D0105911491812F04DE802F4CC084349D
+:1075200021F5E0908C01F0908D0100918E01109179
+:107530008F0116950795F794E794DBDD682FC70157
+:1075400015D480918C0190918D01A0918E01B09104
+:107550008F010296A11DB11D80938C0190938D0126
+:10756000A0938E01B0938F0115CE843609F5E0907B
+:107570008C01F0908D0100918E0110918F01D80146
+:10758000C701B695A79597958795E8D3CADD82E0A0
+:1075900090E0A0E0B0E0E80EF91E0A1F1B1FE09289
+:1075A0008C01F0928D0100938E0110938F0104C025
+:1075B0008B3111F08FE3B5DD83E08093E90090918A
+:1075C000E8008091E8008E778093E80095FF04C082
+:1075D00010C08EB38823C9F08091E80080FFF9CFF6
+:1075E0008091E8008E778093E80003C08EB38823F3
+:1075F00061F08091E80080FFF9CF84E08093E9009A
+:107600008091E8008B778093E800DF91CF911F9104
+:107610000F91FF90EF90DF90CF90BF90AF909F9031
+:107620008F907F906F905F904F900895909192010E
+:10763000892F8F77813249F5809193018032A1F0B3
+:10764000813219F5913A09F58091E800877F80939E
+:10765000E80089E091E067E070E0B7D18091E80050
+:107660008B778093E8000895913279F48091E80057
+:10767000877F8093E80089E091E067E070E009D2BD
+:107680008091E8008E778093E800089582E061ECB5
+:1076900042E061D083E061E842E15DD084E060E8EF
+:1076A00042E159C084B7877F84BF88E10FB6F89460
+:1076B00080936000109260000FBE80E090E020E8B0
+:1076C0000FB6F89420936100809361000FBE81E0B3
+:1076D00085BF82E085BFB0C088E10FB6F894809383
+:1076E0006000109260000FBEDDDF789402C031DDD3
+:1076F00023D3809108018823D1F78091E000816035
+:107700008093E000EFDC80E090E00895FA01923091
+:1077100071F0933089F0913029F480E191E022E119
+:1077200030E015C080E090E020E030E010C082E260
+:1077300091E02EE330E00BC0882329F480E691E04D
+:1077400024E030E004C084E691E026E230E091835A
+:107750008083C90108958093E9008091EB008160E6
+:107760008093EB001092ED006093EC004093ED00ED
+:107770008091EE00881F8827881F089580919201CC
+:1077800088238CF403C08EB38823B1F08091E80085
+:1077900082FFF9CF8091E8008B778093E80008950D
+:1077A0008EB3882349F08091E80080FFF9CF809163
+:1077B000E8008E778093E8000895EF92FF920F9390
+:1077C0001F9345D04CD008ED10E0F80180818F77F1
+:1077D000808380818068808380818F7D808319BCD5
+:1077E0001EBA1092900180EEE82EF12CF7018081F4
+:1077F0008B7F8083F80180818160808380E060E0FE
+:1078000042E0A9DFE1EEF0E080818E7F8083E2EE4E
+:10781000F0E0808181608083808188608083F701CF
+:1078200080818E7F8083F8018081806180831F91B9
+:107830000F91FF90EF900895E7EDF0E08081816077
+:1078400080838AE482BF81E080939101B6CFE8ED26
+:10785000F0E080818E7F80831092E2000895109284
+:10786000DA001092E10008951F920F920FB60F9266
+:1078700011242F933F934F935F936F937F938F9335
+:107880009F93AF93BF93EF93FF938091DA0080FFB4
+:107890001BC08091D80080FF17C08091DA008E7FD6
+:1078A0008093DA008091D90080FF0BC080E189BD10
+:1078B00082E189BD09B400FEFDCF81E08EBB3BD2E1
+:1078C00003C019BC1EBA37D28091E10080FF17C0F7
+:1078D0008091E20080FF13C08091E2008E7F809350
+:1078E000E2008091E20080618093E2008091D80004
+:1078F00080628093D80019BC85E08EBB1CD2809139
+:10790000E10084FF2CC08091E20084FF28C080E168
+:1079100089BD82E189BD09B400FEFDCF8091D80008
+:107920008F7D8093D8008091E1008F7E8093E1006D
+:107930008091E2008F7E8093E2008091E20081607E
+:107940008093E20080919001882331F48091E300DC
+:1079500087FD02C081E001C084E08EBBECD1809144
+:10796000E10083FF21C08091E20083FF1DC0809170
+:10797000E100877F8093E10082E08EBB109290014E
+:107980008091E1008E7F8093E1008091E2008E7F04
+:107990008093E2008091E20080618093E20080E0C9
+:1079A00060E042E0D8DEC7D1FF91EF91BF91AF9187
+:1079B0009F918F917F916F915F914F913F912F9107
+:1079C0000F900FBE0F901F9018959C014091980149
+:1079D000509199014617570718F4F90190E044C0F7
+:1079E0006115710511F0AB01F8CF8091E8008E7739
+:1079F0008093E80040E050E0F0CF8EB3882309F494
+:107A000044C0853009F443C08091E80083FF02C080
+:107A100081E008958091E80082FD31C08091E80006
+:107A200080FF22C08091F3009091F200782F60E0F7
+:107A3000292F30E0262B372B07C081918093F1004E
+:107A4000415050402F5F3F4F4115510519F02830EC
+:107A5000310598F390E02830310509F491E08091E8
+:107A6000E8008E778093E8004115510531F699239F
+:107A700021F605C08EB3882341F0853041F0809116
+:107A8000E80082FFF7CF80E0089582E0089583E068
+:107A900008959C016115710529F48091E8008B77A8
+:107AA0008093E800F90126C08EB3882391F18530D8
+:107AB00091F18091E80083FF02C081E008958091F8
+:107AC000E80082FFF1CF06C08091F1008193615000
+:107AD000704059F02091F3008091F200322F20E0A5
+:107AE00090E0822B932B892B79F78091E8008B779C
+:107AF0008093E80061157105B9F605C08EB388233F
+:107B000041F0853041F08091E80080FFF7CF80E0C0
+:107B1000089582E0089583E008950F931F93DF9303
+:107B2000CF9300D0CDB7DEB7E2E9F1E08091F1006C
+:107B3000819381E0EA39F807C9F778DD8091E800A0
+:107B400083FFE4C08091920190919301953009F4F4
+:107B50006DC0963040F4913081F1913070F09330E7
+:107B600009F0D4C02AC0983009F4A3C0993009F4B0
+:107B7000B2C0963009F0CAC07CC0803809F4C6C0D3
+:107B8000823809F0C3C08091960187708093E90024
+:107B90008091EB001092E9002091E800277F20936C
+:107BA000E80090E025E0969587952A95E1F78170A9
+:107BB0008093F1001092F10087C0882319F0823081
+:107BC00009F0A4C08F71823009F0A0C080919401A7
+:107BD000882331F520919601277009F497C02093EE
+:107BE000E9008091EB0080FF1BC0933021F480916D
+:107BF000EB00806213C08091EB0080618093EB000A
+:107C000081E090E002C0880F991F2A95E2F78093E7
+:107C1000EA001092EA008091EB0088608093EB000C
+:107C20001092E9008091E800877F51C0882309F015
+:107C30006DC0109194011F770FB7F8948091E80000
+:107C4000877F8093E8009ADD8091E80080FFFCCF79
+:107C50008091E3008078812B8093E300806880939B
+:107C6000E300112311F482E001C083E08EBB0FBF5B
+:107C70004DC08058823008F049C0809194019091A5
+:107C8000950160919601AE014F5F5F4F3FDDBC01F2
+:107C9000009709F43BC08091E800877F8093E8005B
+:107CA00089819A8192DE8091E8008B778093E80049
+:107CB0002DC0803859F58091E800877F8093E800D7
+:107CC000809190018093F1008091E8008E778093FD
+:107CD000E80054DD1BC08823C9F4909194019230D0
+:107CE000A8F48091E800877F8093E800909390014A
+:107CF00045DD80919001882331F48091E30087FD78
+:107D000002C081E001C084E08EBBC0DC8091E8004D
+:107D100083FF0AC08091EB0080628093EB0080912A
+:107D2000E800877F8093E8000F900F90CF91DF915C
+:107D30001F910F91089508951F938EB3882361F0CA
+:107D40001091E9001092E9008091E80083FF01C0E2
+:107D5000E4DE17701093E9001F910895F999FECFA2
+:107D600092BD81BDF89A992780B50895262FF9997B
+:107D7000FECF1FBA92BD81BD20BD0FB6F894FA9A0E
+:0C7D8000F99A0FBE01960895F894FFCF09
+:107D8C004C554641434443000100000000000008EC
+:107D9C001201100102000008EB034A20010000014F
+:107DAC00000109023E0002010080320904000001BA
+:107DBC00020201000524001001042402040524061B
+:107DCC000001070582030800FF09040100020A00F4
+:107DDC0000000705040210000107058302100001D2
+:107DEC0004030904260341005600520020004300FE
+:107DFC0044004300200042006F006F0074006C00D0
+:0C7E0C006F00610064006500720000005F
+:040000030000700089
+:00000001FF
diff --git a/bootloaders/caterina_LUFA/Descriptors.c b/bootloaders/caterina_LUFA/Descriptors.c
new file mode 100755
index 0000000..a3ca700
--- /dev/null
+++ b/bootloaders/caterina_LUFA/Descriptors.c
@@ -0,0 +1,243 @@
+/*
+ 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 = 0x03EB,
+ .ProductID = 0x204A,
+ .ReleaseNumber = VERSION_BCD(00.01),
+
+ .ManufacturerStrIndex = NO_DESCRIPTOR,
+ .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(18), .Type = DTYPE_String},
+
+ .UnicodeString = L"AVR CDC Bootloader"
+};
+
+/** 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
+ {
+ Address = &ProductString;
+ Size = ProductString.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..a647af0
--- /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
+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
+