Minor update.

This commit is contained in:
opendous
2011-11-06 07:02:51 +00:00
parent 76eef74ec7
commit f3b7dcfe3d
21 changed files with 224 additions and 4548 deletions

View File

@@ -7,9 +7,48 @@ PROJECT = DiskLoader
TARGET = DiskLoader.elf
CC = avr-gcc
# BOARD2
MCU = atmega32u4
AVR_FREQ = 16000000L
# Select MCU name and bootloader start address - uncomment _ONE_ of the following pairs
#
# Starting byte address of the bootloader, as a byte address - computed via the formula
# BOOT_START = ((TOTAL_FLASH_BYTES - BOOTLOADER_SECTION_SIZE_BYTES) * 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.
# MCU name and Bootloader Start address - uncomment one of the following pairs
#MCU = at90usb162
#BOOT_START = 0x3000
#MCU = atmega32u2
#BOOT_START = 0x7000
#MCU = atmega32u4
#BOOT_START = 0x7000
#MCU = at90usb646
#BOOT_START = 0xF000
#MCU = at90usb647
#BOOT_START = 0xF000
#MCU = at90usb1286
#BOOT_START = 0x1E000
MCU = at90usb1287
BOOT_START = 0x1E000
# Processor frequency.
# This will define a symbol, F_CPU, in all source code files equal to the
# processor frequency. 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.
# Typical values are:
# F_CPU = 8000000L
# F_CPU = 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
@@ -20,13 +59,14 @@ ARDUINO_MODEL_PID = 0x0034
# Change if your programmer is different
AVRDUDE_PROGRAMMER = avrispmkII
AVRDUDE_PORT = usb
AVRDUDE_PORT = usb
# program name should not be changed...
PROGRAM = DiskLoader
AVRDUDE = avrdude
AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) -p $(MCU)
#AVRDUDE_FLAGS = -vvv -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) -p $(MCU) -B 5 -u
AVRDUDE_FLAGS = -vvv -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) -p $(MCU)
## Options common to compile, link and assembly rules
COMMON = -mmcu=$(MCU)
@@ -40,8 +80,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 += -nodefaultlibs -nostartfiles
LDFLAGS += -Wl,-gc-sections,-Map=DiskLoader.map,--section-start=.text=$(BOOT_START),--relax
#Note: do not use custom start functions for compatibility across USB AVR lineup
#LDFLAGS += -nodefaultlibs -nostartfiles
## Intel Hex file production flags
@@ -75,11 +116,12 @@ $(BUILD_DIR):
@mkdir -p $@
clean:
@rm -rf build/
@rm -f *.hex
@rm -f *.elf
@rm -f *.lss
@rm -f *.map
rm -rf build/
rm -f DiskLoader.hex
rm -f DiskLoader.elf.hex
rm -f *.elf
rm -f *.lss
rm -f *.map
define make-goal
$1/%.o: %.cpp
@@ -92,14 +134,15 @@ $(TARGET): $(OBJ)
$(CC) $(LDFLAGS) $(LINKONLYOBJECTS) $(LIBDIRS) $(LIBS) $^ -o $@
%.hex: $(TARGET)
avr-objcopy -O ihex $(HEX_FLASH_FLAGS) $< $@
avr-objcopy -O ihex -R .eeprom -R .fuse -R .lock $< $@
%.lss: $(TARGET)
avr-objdump -h -S $< > $@
size: $(TARGET)
@echo
avr-size --mcu=$(MCU) --format=avr $(TARGET)
# @avr-size -C --mcu=${MCU} ${TARGET}.elf
program: $(TARGET).hex
$(AVRDUDE) $(AVRDUDE_FLAGS) -B 5 -u -U flash:w:$(TARGET).hex
$(AVRDUDE) $(AVRDUDE_FLAGS) -U flash:w:$(TARGET).hex

View File

@@ -1,4 +1,20 @@
/* Copyright (c) 2010, Peter Barrett
**
** Additional porting to the AT90USB1287 by Opendous Inc. 2011-10-31
**
** Permission to use, copy, modify, and/or distribute this software for
** any purpose with or without fee is hereby granted, provided that the
** above copyright notice and this permission notice appear in all copies.
**
** THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS 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, DIRECT, 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.
*/
#include "Platform.h"
@@ -11,6 +27,7 @@
//
// The tweakier code is to keep the bootloader below 2k (no interrupt table, for example)
/* // do not tweak code
extern "C"
void entrypoint(void) __attribute__ ((naked)) __attribute__ ((section (".vectors")));
void entrypoint(void)
@@ -25,6 +42,8 @@ void entrypoint(void)
"rjmp main" // Stack is all set up, start the main code
::);
}
*/
u8 _flashbuf[128];
u8 _inSync;
@@ -34,7 +53,19 @@ extern volatile u16 _timeout;
void Program(u8 ep, u16 page, u8 count)
{
u8 write = page < 30*1024; // Don't write over firmware please
// Don't write over firmware please
#if (defined(__AVR_AT90USB162__) || defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega16U4__))
u8 write = page < 12*1024; // 4kbyte default bootloader size
#elif (defined(__AVR_ATmega32U2__) || defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega32U6__))
u8 write = page < 28*1024; // 4kbyte default bootloader size
#elif (defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB647__))
u8 write = page < 56*1024; // 8kbyte default bootloader size
#elif (defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1287__))
u8 write = page < 120*1024; // 8kbyte default bootloader size
#else
#error Selected device not supported by this bootloader
#endif
if (write)
boot_page_erase(page);
@@ -106,23 +137,31 @@ const u8 _consts[] =
void USBInit(void);
int main(void) __attribute__ ((naked));
// STK500v1 main loop, very similar to optiboot in protocol and implementation
int main()
{
MCUSR &= ~(1 << WDRF);
wdt_disable();
TXLED0;
RXLED0;
LED0;
LED1;
BOARD_INIT();
USBInit();
_inSync = STK_INSYNC;
_ok = STK_OK;
if (pgm_read_word(0) != -1)
#if (FLASHEND > 0xFFFF)
if (((int16_t)pgm_read_word_far(0)) != ((int16_t)(-1)))
_ejected = 1;
#else
if (((int16_t)pgm_read_word(0)) != ((int16_t)(-1)))
_ejected = 1;
#endif
for(;;)
{
@@ -137,8 +176,14 @@ int main()
const u8* rs = _readSize;
for(;;)
{
#if (FLASHEND > 0xFFFF)
u8 c = pgm_read_byte_far(rs++);
len = pgm_read_byte_far(rs++);
#else
u8 c = pgm_read_byte(rs++);
len = pgm_read_byte(rs++);
#endif
if (c == cmd || c == 0)
break;
}
@@ -149,7 +194,8 @@ int main()
// Send a response
u8 send = 0;
const u8* pgm = _consts+7; // 0
if (STK_GET_PARAMETER == cmd)
if (STK_GET_PARAMETER == cmd) // 'A'
{
u8 i = packet[0] - 0x80;
if (i > 2)
@@ -158,7 +204,7 @@ int main()
send = 1;
}
else if (STK_UNIVERSAL == cmd)
else if (STK_UNIVERSAL == cmd) // 'V'
{
if (packet[0] == 0x30)
pgm = _consts + packet[2]; // read signature
@@ -166,24 +212,24 @@ int main()
}
// Read signature bytes
else if (STK_READ_SIGN == cmd)
else if (STK_READ_SIGN == cmd) // 'u'
{
pgm = _consts;
send = 3;
}
else if (STK_LOAD_ADDRESS == cmd)
else if (STK_LOAD_ADDRESS == cmd) // 'U'
{
address = *((u16*)packet); // word addresses
address = *((u16*)packet); // word addresses
address += address;
}
else if (STK_PROG_PAGE == cmd)
else if (STK_PROG_PAGE == cmd) // 'd'
{
Program(CDC_RX,address,packet[1]);
}
else if (STK_READ_PAGE == cmd)
else if (STK_READ_PAGE == cmd) // 't'
{
send = packet[1];
pgm = (const u8*)address;
@@ -199,7 +245,7 @@ int main()
if (send)
Transfer(CDC_TX|TRANSFER_PGM,pgm,send); // All from pgm memory
// Send ok
// Send ok
Transfer(CDC_TX|TRANSFER_RELEASE,&_ok,1);
if (cmd == 'Q')
@@ -227,6 +273,7 @@ void LEDPulse()
void Reboot()
{
TXLED0; // switch off the RX and TX LEDs before starting the user sketch
RXLED0;
UDCON = 1; // Detatch USB
@@ -236,4 +283,5 @@ void Reboot()
"clr r31\n"
"ijmp\n"
::);
}

View File

@@ -15,6 +15,7 @@ typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned long u32;
#define NOP() do { __asm__ __volatile__ ("nop"); } while (0)
#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);
@@ -24,14 +25,31 @@ typedef unsigned long u32;
#define USB_VID 0x2341 // arduino LLC vid
#define USB_PID ARDUINO_MODEL_PID // passed in by Makefile - 0x0034 for Leonardo, 0x0035 for MIcro
#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)
// the following have been changed for compatibility with the Micropendous
#if (defined(__AVR_AT90USB162__) || defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega32U2__))
// TODO
#elif (defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__))
#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)
#elif (defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1287__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB647__) || defined(__AVR_ATmega32U6__))
#define SELECT_USB_B PORTE |= (1 << PE7); DDRE |= (1 << PE7);
#define DISABLE_VOLTAGE_TXRX PORTE &= ~(1 << PE3); DDRE |= (1 << PE3);
#define BOARD_INIT() DDRB |= (1<<1); DDRB |= (1<<0); CPU_PRESCALE(0); DISABLE_JTAG(); DISABLE_VOLTAGE_TXRX; SELECT_USB_B;
#define LED0 PORTB &= ~(1<<1)
#define LED1 PORTB |= (1<<1)
#define TXLED0 NOP()
#define TXLED1 NOP()
#define RXLED0 NOP()
#define RXLED1 NOP()
#else
#error Selected device not supported by this bootloader
#endif
#define TRANSFER_PGM 0x80
#define TRANSFER_RELEASE 0x40

View File

@@ -1,6 +1,6 @@
/* Copyright (c) 2010, Peter Barrett
/* Copyright (c) 2010, Peter Barrett
**
** Additional porting to the AT90USB1287 by Opendous Inc. 2011-10-31
**
** Permission to use, copy, modify, and/or distribute this software for
** any purpose with or without fee is hereby granted, provided that the
@@ -120,6 +120,7 @@ static inline void Send8(u8 d)
static inline void SetEP(u8 ep)
{
UENUM = ep;
UECONX |= (1 << EPEN); // TODO: is this needed?
}
static inline u8 FifoByteCount()
@@ -181,7 +182,7 @@ static inline u8 FrameNumber()
static void InitEP(u8 index, u8 type, u8 size)
{
UENUM = index;
UECONX = 1;
UECONX |= (1 << EPEN);
UECFG0X = type;
UECFG1X = size;
}
@@ -192,14 +193,54 @@ void USBInit(void)
_timeout = 0;
_usbConfiguration = 0;
_ejected = 0;
UHWCON = 0x01; // power internal reg (don't need this?)
USBCON = (1<<USBE)|(1<<FRZCLK); // clock frozen, usb enabled
PLLCSR = 0x12; // Need 16 MHz xtal
while (!(PLLCSR & (1<<PLOCK))) // wait for lock pll
UDCON = (1 << DETACH);
// TODO: correctly check for other boards
#if (defined(__AVR_AT90USB1287__) || defined(__AVR_AT90USB647__))
DDRE |= (1 << PE7); PORTE &= ~(1 << PE7); // enable the USB signal switch to the USB-B connector
#endif
// power on internal regulator
#if (defined(__AVR_AT90USB162__) || defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega32U2__))
REGCR = (0 << REGDIS); // there is no UHWCON on the U2 USB AVR devices
#elif (defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__))
UHWCON = (1 << UVREGE);
#elif (defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1287__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB647__) || defined(__AVR_ATmega32U6__))
UHWCON = ((1 << UIMOD) | (1 << UVREGE));
#else
#error Selected device not supported by this bootloader
#endif
USBCON = ((1<<USBE) | (1<<FRZCLK)); // usb enabled, clock frozen
#if (defined(__AVR_AT90USB162__) || defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega32U2__))
PLLCSR = ((1 << PLLE) | (1 << PINDIV)); // enable PLL with a 16MHz XTAL
#elif (defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__))
PLLCSR = ((1 << PLLE) | (1 << PINDIV)); // enable PLL with a 16MHz XTAL
#elif (defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB647__) || defined(__AVR_ATmega32U6__))
PLLCSR = ((1 << PLLE) | (1 << PLLP2) | (1 << PLLP1)); // enable PLL with a 16MHz XTAL
#elif (defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1287__))
PLLCSR = ((1 << PLLE) | (1 << PLLP2) | (1 << PLLP0)); // enable PLL with a 16MHz XTAL
#else
#error Selected device not supported by this bootloader
#endif
while (!(PLLCSR & (1 << PLOCK))) // wait for PLL to lock
;
USBCON = ((1<<USBE)|(1<<OTGPADE)); // start USB clock
UDCON = 0; // enable attach resistor
// start USB
#if (defined(__AVR_AT90USB162__) || defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega32U2__))
USBCON = ((1 << USBE) | (0 << FRZCLK));
#else
USBCON = ((1 << USBE) | (1 << OTGPADE) | (0 << FRZCLK));
#endif
// enable attach resistor by disabling USB line detach
UDCON = (0 << DETACH);
}
u8 USBGetConfiguration(void)
@@ -237,7 +278,12 @@ void Transfer(u8 ep, const u8* data, int len)
while (!ReadWriteAllowed())
; // TODO Check for STALL etc
#if (FLASHEND > 0xFFFF)
u8 d = (ep & TRANSFER_PGM) ? pgm_read_byte_far(data) : data[0];
#else
u8 d = (ep & TRANSFER_PGM) ? pgm_read_byte(data) : data[0];
#endif
data++;
if (zero)
d = 0;
@@ -269,11 +315,23 @@ static void InitEndpoints()
for (u8 i = 1; i < sizeof(_initEndpoints); i++)
{
UENUM = i;
UECONX = 1;
UECONX |= (1 << EPEN);
#if (FLASHEND > 0xFFFF)
UECFG0X = pgm_read_byte_far(_initEndpoints+i);
#else
UECFG0X = pgm_read_byte(_initEndpoints+i);
#endif
UECFG1X = EP_DOUBLE_64;
}
UERST = 0x7E; // And reset them
// Reset all endpoints except EP0
#if (defined(__AVR_AT90USB162__) || defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega32U2__))
UERST = ((1<<EPRST4) | (1<<EPRST3) | (1<<EPRST2) | (1<<EPRST1));
#else // all other USB AVRs
UERST = ((1<<EPRST6) | (1<<EPRST5) | (1<<EPRST4) | (1<<EPRST3) | (1<<EPRST2) | (1<<EPRST1));
#endif
UERST = 0;
}
@@ -384,7 +442,11 @@ bool SendDescriptor()
return false;
if (desc_length == 0)
#if (FLASHEND > 0xFFFF)
desc_length = pgm_read_byte_far(desc_addr);
#else
desc_length = pgm_read_byte(desc_addr);
#endif
if ((u8)setup.wLength < desc_length) // bit of a cheat limiting to 255 bytes TODO (saved 8 bytes)
desc_length = (u8)setup.wLength;
@@ -396,7 +458,11 @@ bool SendDescriptor()
{
if (!WaitForINOrOUT())
return false;
#if (FLASHEND > 0xFFFF)
Send8(pgm_read_byte_far(&desc_addr[n++]));
#else
Send8(pgm_read_byte(&desc_addr[n++]));
#endif
u8 clr = n & 0x3F;
if (!clr)
ClearIN(); // Fifo is full, release this packet

View File

@@ -1,148 +0,0 @@
###############################################################################
# Makefile for DiskLoader
###############################################################################
## General Flags
PROJECT = DiskLoader
TARGET = DiskLoader.elf
CC = avr-gcc
# Select MCU name and bootloader start address - uncomment _ONE_ of the following pairs
#
# Starting byte address of the bootloader, as a byte address - computed via the formula
# BOOT_START = ((TOTAL_FLASH_BYTES - BOOTLOADER_SECTION_SIZE_BYTES) * 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.
# MCU name and Bootloader Start address - uncomment one of the following pairs
#MCU = at90usb162
#BOOT_START = 0x3000
#MCU = atmega32u2
#BOOT_START = 0x7000
#MCU = atmega32u4
#BOOT_START = 0x7000
#MCU = at90usb646
#BOOT_START = 0xF000
#MCU = at90usb647
#BOOT_START = 0xF000
#MCU = at90usb1286
#BOOT_START = 0x1E000
MCU = at90usb1287
BOOT_START = 0x1E000
# Processor frequency.
# This will define a symbol, F_CPU, in all source code files equal to the
# processor frequency. 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.
# Typical values are:
# F_CPU = 8000000L
# F_CPU = 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
#ARDUINO_MODEL_PID = 0x0035
# Change if your programmer is different
AVRDUDE_PROGRAMMER = avrispmkII
AVRDUDE_PORT = usb
# program name should not be changed...
PROGRAM = DiskLoader
AVRDUDE = avrdude
#AVRDUDE_FLAGS = -vvv -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) -p $(MCU) -B 5 -u
AVRDUDE_FLAGS = -vvv -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) -p $(MCU)
## Options common to compile, link and assembly rules
COMMON = -mmcu=$(MCU)
override CFLAGS = -g -Wall -Os -mmcu=$(MCU) -DF_CPU=$(AVR_FREQ) -DARDUINO_MODEL_PID=$(ARDUINO_MODEL_PID) $(DEFS) -ffunction-sections -gdwarf-2 -fdata-sections -fno-split-wide-types
## Assembly specific flags
ASMFLAGS = $(COMMON)
ASMFLAGS += $(CFLAGS)
ASMFLAGS += -x assembler-with-cpp -Wa,-gdwarf2
## Linker flags
LDFLAGS = $(COMMON)
LDFLAGS += -Wl,-gc-sections,-Map=DiskLoader.map,--section-start=.text=$(BOOT_START),--relax
#Note: do not use custom start functions for compatibility across USB AVR lineup
#LDFLAGS += -nodefaultlibs -nostartfiles
## Intel Hex file production flags
HEX_EEPROM_FLAGS = -j .eeprom
HEX_EEPROM_FLAGS += --set-section-flags=.eeprom="alloc,load"
HEX_EEPROM_FLAGS += --change-section-lma .eeprom=0 --no-change-warnings
## Objects explicitly added by the user
LINKONLYOBJECTS =
MODULES := .
SRC_DIR := $(addprefix src/,$(MODULES))
BUILD_DIR := $(addprefix build/,$(MODULES))
SRC := $(foreach sdir,$(SRC_DIR),$(wildcard $(sdir)/*.cpp))
OBJ := $(patsubst src/%.cpp,build/%.o,$(SRC))
DEP := $(OBJ:%.o=%.d)
INCLUDES := $(addprefix -I,$(SRC_DIR))
vpath %.cpp $(SRC_DIR)
.PHONY: all checkdirs clean
all: checkdirs $(TARGET) DiskLoader.hex DiskLoader.lss size
-include $(DEP)
checkdirs: $(BUILD_DIR)
$(BUILD_DIR):
@mkdir -p $@
clean:
rm -rf build/
rm -f DiskLoader.hex
rm -f DiskLoader.elf.hex
rm -f *.elf
rm -f *.lss
rm -f *.map
define make-goal
$1/%.o: %.cpp
$(CC) $(INCLUDES) $(CFLAGS) -c $$< -MD -o $$@
endef
$(foreach bdir,$(BUILD_DIR),$(eval $(call make-goal,$(bdir))))
$(TARGET): $(OBJ)
$(CC) $(LDFLAGS) $(LINKONLYOBJECTS) $(LIBDIRS) $(LIBS) $^ -o $@
%.hex: $(TARGET)
avr-objcopy -O ihex -R .eeprom -R .fuse -R .lock $< $@
%.lss: $(TARGET)
avr-objdump -h -S $< > $@
size: $(TARGET)
@echo
avr-size --mcu=$(MCU) --format=avr $(TARGET)
# @avr-size -C --mcu=${MCU} ${TARGET}.elf
program: $(TARGET).hex
$(AVRDUDE) $(AVRDUDE_FLAGS) -U flash:w:$(TARGET).hex

View File

@@ -1,287 +0,0 @@
/* Copyright (c) 2010, Peter Barrett
**
** Additional porting to the AT90USB1287 by Opendous Inc. 2011-10-31
**
** Permission to use, copy, modify, and/or distribute this software for
** any purpose with or without fee is hereby granted, provided that the
** above copyright notice and this permission notice appear in all copies.
**
** THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS 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, DIRECT, 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.
*/
#include "Platform.h"
// This bootloader creates a composite Serial device
//
// The serial interface supports a STK500v1 protocol that is very similar to optiboot
//
// The bootloader will timeout and start the firmware after a few hundred milliseconds
// if a usb connection is not detected.
//
// The tweakier code is to keep the bootloader below 2k (no interrupt table, for example)
/* // do not tweak code
extern "C"
void entrypoint(void) __attribute__ ((naked)) __attribute__ ((section (".vectors")));
void entrypoint(void)
{
asm volatile (
"eor r1, r1\n" // Zero register
"out 0x3F, r1\n" // SREG
"ldi r28, 0xFF\n"
"ldi r29, 0x0A\n"
"out 0x3E, r29\n" // SPH
"out 0x3D, r28\n" // SPL
"rjmp main" // Stack is all set up, start the main code
::);
}
*/
u8 _flashbuf[128];
u8 _inSync;
u8 _ok;
extern volatile u8 _ejected;
extern volatile u16 _timeout;
void Program(u8 ep, u16 page, u8 count)
{
// Don't write over firmware please
#if (defined(__AVR_AT90USB162__) || defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega16U4__))
u8 write = page < 12*1024; // 4kbyte default bootloader size
#elif (defined(__AVR_ATmega32U2__) || defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega32U6__))
u8 write = page < 28*1024; // 4kbyte default bootloader size
#elif (defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB647__))
u8 write = page < 56*1024; // 8kbyte default bootloader size
#elif (defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1287__))
u8 write = page < 120*1024; // 8kbyte default bootloader size
#else
#error Selected device not supported by this bootloader
#endif
if (write)
boot_page_erase(page);
Recv(ep,_flashbuf,count); // Read while page is erasing
if (!write)
return;
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++)
boot_page_fill(p++, b[i]);
boot_page_write(page);
boot_spm_busy_wait();
boot_rww_enable ();
}
int USBGetChar();
#define getch USBGetChar
#define HW_VER 0x02
#define SW_MAJOR 0x01
#define SW_MINOR 0x10
#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'
extern const u8 _readSize[] PROGMEM;
const u8 _readSize[] =
{
STK_GET_PARAMETER, 1,
STK_SET_DEVICE, 20,
STK_SET_DEVICE_EXT, 5,
STK_UNIVERSAL, 4,
STK_LOAD_ADDRESS, 2,
STK_PROG_PAGE, 3,
STK_READ_PAGE, 3,
0,0
};
extern const u8 _consts[] PROGMEM;
const u8 _consts[] =
{
SIGNATURE_0,
SIGNATURE_1,
SIGNATURE_2,
HW_VER, // Hardware version
SW_MAJOR, // Software major version
SW_MINOR, // Software minor version
0x03, // Unknown but seems to be required by avr studio 3.56
0x00, //
};
void USBInit(void);
// STK500v1 main loop, very similar to optiboot in protocol and implementation
int main()
{
MCUSR &= ~(1 << WDRF);
wdt_disable();
TXLED0;
RXLED0;
LED1;
BOARD_INIT();
USBInit();
_inSync = STK_INSYNC;
_ok = STK_OK;
#if (FLASHEND > 0xFFFF)
if (((int16_t)pgm_read_word_far(0)) != ((int16_t)(-1)))
_ejected = 1;
#else
if (((int16_t)pgm_read_word(0)) != ((int16_t)(-1)))
_ejected = 1;
#endif
for(;;)
{
u8* packet = _flashbuf;
u16 address = 0;
for (;;)
{
u8 cmd = getch();
// Read packet contents
u8 len;
const u8* rs = _readSize;
for(;;)
{
#if (FLASHEND > 0xFFFF)
u8 c = pgm_read_byte_far(rs++);
len = pgm_read_byte_far(rs++);
#else
u8 c = pgm_read_byte(rs++);
len = pgm_read_byte(rs++);
#endif
if (c == cmd || c == 0)
break;
}
_timeout = 0;
// Read params
Recv(CDC_RX,packet,len);
// Send a response
u8 send = 0;
const u8* pgm = _consts+7; // 0
if (STK_GET_PARAMETER == cmd) // 'A'
{
u8 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;
send = 1;
}
else if (STK_UNIVERSAL == cmd) // 'V'
{
if (packet[0] == 0x30)
pgm = _consts + packet[2]; // read signature
send = 1;
}
// Read signature bytes
else if (STK_READ_SIGN == cmd) // 'u'
{
pgm = _consts;
send = 3;
}
else if (STK_LOAD_ADDRESS == cmd) // 'U'
{
address = *((u16*)packet); // word addresses
address += address;
}
else if (STK_PROG_PAGE == cmd) // 'd'
{
Program(CDC_RX,address,packet[1]);
}
else if (STK_READ_PAGE == cmd) // 't'
{
send = packet[1];
pgm = (const u8*)address;
address += send; // not sure of this is required
}
// Check sync
if (getch() != ' ')
break;
Transfer(CDC_TX,&_inSync,1);
// Send result
if (send)
Transfer(CDC_TX|TRANSFER_PGM,pgm,send); // All from pgm memory
// Send ok
Transfer(CDC_TX|TRANSFER_RELEASE,&_ok,1);
if (cmd == 'Q')
break;
}
_timeout = 500; // wait a moment before exiting the bootloader - may need to finish responding to 'Q' for example
_ejected = 1;
}
}
// Nice breathing LED indicates we are in the firmware
u16 _pulse;
void LEDPulse()
{
_pulse += 4;
u8 p = _pulse >> 9;
if (p > 63)
p = 127-p;
p += p;
if (((u8)_pulse) > p)
LED0;
else
LED1;
}
void Reboot()
{
TXLED0; // switch off the RX and TX LEDs before starting the user sketch
RXLED0;
UDCON = 1; // Detatch USB
UDIEN = 0;
asm volatile ( // Reset vector to run firmware
"clr r30\n"
"clr r31\n"
"ijmp\n"
::);
}

View File

@@ -1,67 +0,0 @@
#include <inttypes.h>
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <avr/boot.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <avr/wdt.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned long u32;
#define NOP() do { __asm__ __volatile__ ("nop"); } while (0)
#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_VID 0x2341 // arduino LLC vid
#define USB_PID ARDUINO_MODEL_PID // passed in by Makefile - 0x0034 for Leonardo, 0x0035 for MIcro
// the following have been changed for compatibility with the Micropendous
#if (defined(__AVR_AT90USB162__) || defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega32U2__))
// TODO
#elif (defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__))
#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)
#elif (defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1287__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB647__) || defined(__AVR_ATmega32U6__))
#define SELECT_USB_B PORTE |= (1 << PE7); DDRE |= (1 << PE7);
#define DISABLE_VOLTAGE_TXRX PORTE &= ~(1 << PE3); DDRE |= (1 << PE3);
#define BOARD_INIT() DDRB |= (1<<1); DDRB |= (1<<0); CPU_PRESCALE(0); DISABLE_JTAG(); DISABLE_VOLTAGE_TXRX; SELECT_USB_B;
#define LED0 PORTB &= ~(1<<1)
#define LED1 PORTB |= (1<<1)
#define TXLED0 NOP()
#define TXLED1 NOP()
#define RXLED0 NOP()
#define RXLED1 NOP()
#else
#error Selected device not supported by this bootloader
#endif
#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);
#define CDC_ENABLED
#include "USBCore.h"
#include "USBDesc.h"

View File

@@ -1,574 +0,0 @@
/* Copyright (c) 2010, Peter Barrett
**
** Additional porting to the AT90USB1287 by Opendous Inc. 2011-10-31
**
** Permission to use, copy, modify, and/or distribute this software for
** any purpose with or without fee is hereby granted, provided that the
** above copyright notice and this permission notice appear in all copies.
**
** THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS 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, DIRECT, 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.
*/
#include "Platform.h"
#define CDC_TX CDC_ENDPOINT_IN
#define CDC_RX CDC_ENDPOINT_OUT
#define EP_TYPE_CONTROL 0x00
#define EP_TYPE_BULK_IN 0x81
#define EP_TYPE_BULK_OUT 0x80
#define EP_TYPE_INTERRUPT_IN 0xC1
#define EP_TYPE_INTERRUPT_OUT 0xC0
#define EP_TYPE_ISOCHRONOUS_IN 0x41
#define EP_TYPE_ISOCHRONOUS_OUT 0x40
/** 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 */
void Reboot();
//==================================================================
//==================================================================
typedef struct
{
u32 dwDTERate;
u8 bCharFormat;
u8 bParityType;
u8 bDataBits;
u8 lineState;
} LineInfo;
static volatile LineInfo _usbLineInfo = { 57600, 0x00, 0x00, 0x00, 0x00 };
//==================================================================
//==================================================================
// 4 bytes of RAM
volatile u8 _usbConfiguration;
volatile u8 _ejected;
volatile u16 _timeout;
static inline void WaitIN(void)
{
while (!(UEINTX & (1<<TXINI)));
}
static inline void ClearIN(void)
{
UEINTX = ~(1<<TXINI);
}
static inline void WaitOUT(void)
{
while (!(UEINTX & (1<<RXOUTI)))
;
}
static inline u8 WaitForINOrOUT()
{
while (!(UEINTX & ((1<<TXINI)|(1<<RXOUTI))))
;
return (UEINTX & (1<<RXOUTI)) == 0;
}
static inline void ClearOUT(void)
{
UEINTX = ~(1<<RXOUTI);
}
static
void Send(volatile const u8* data, u8 count)
{
TXLED1; // light the TX LED
TxLEDPulse = TX_RX_LED_PULSE_MS;
while (count--)
UEDATX = *data++;
}
void Recv(volatile u8* data, u8 count)
{
RXLED1; // light the RX LED
RxLEDPulse = TX_RX_LED_PULSE_MS;
while (count--)
*data++ = UEDATX;
}
static inline u8 Recv8()
{
RXLED1; // light the RX LED
RxLEDPulse = TX_RX_LED_PULSE_MS;
return UEDATX;
}
static inline void Send8(u8 d)
{
TXLED1; // light the TX LED
TxLEDPulse = TX_RX_LED_PULSE_MS;
UEDATX = d;
}
static inline void SetEP(u8 ep)
{
UENUM = ep;
UECONX |= (1 << EPEN); // TODO: is this needed?
}
static inline u8 FifoByteCount()
{
return UEBCLX;
}
static inline u8 ReceivedSetupInt()
{
return UEINTX & (1<<RXSTPI);
}
static inline void ClearSetupInt()
{
UEINTX = ~((1<<RXSTPI) | (1<<RXOUTI) | (1<<TXINI));
}
static inline void Stall()
{
UECONX = (1<<STALLRQ) | (1<<EPEN);
}
static inline u8 ReadWriteAllowed()
{
return UEINTX & (1<<RWAL);
}
static inline u8 Stalled()
{
return UEINTX & (1<<STALLEDI);
}
static inline u8 FifoFree()
{
return UEINTX & (1<<FIFOCON);
}
static inline void ReleaseRX()
{
UEINTX = 0x6B; // FIFOCON=0 NAKINI=1 RWAL=1 NAKOUTI=0 RXSTPI=1 RXOUTI=0 STALLEDI=1 TXINI=1
}
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()
{
return UDFNUML;
}
//==================================================================
//==================================================================
#define EP_SINGLE_64 0x32 // EP0
#define EP_DOUBLE_64 0x36 // Other endpoints
static void InitEP(u8 index, u8 type, u8 size)
{
UENUM = index;
UECONX |= (1 << EPEN);
UECFG0X = type;
UECFG1X = size;
}
// API
void USBInit(void)
{
_timeout = 0;
_usbConfiguration = 0;
_ejected = 0;
UDCON = (1 << DETACH);
// TODO: correctly check for other boards
#if (defined(__AVR_AT90USB1287__) || defined(__AVR_AT90USB647__))
DDRE |= (1 << PE7); PORTE &= ~(1 << PE7); // enable the USB signal switch to the USB-B connector
#endif
// power on internal regulator
#if (defined(__AVR_AT90USB162__) || defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega32U2__))
REGCR = (0 << REGDIS); // there is no UHWCON on the U2 USB AVR devices
#elif (defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__))
UHWCON = (1 << UVREGE);
#elif (defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1287__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB647__) || defined(__AVR_ATmega32U6__))
UHWCON = ((1 << UIMOD) | (1 << UVREGE));
#else
#error Selected device not supported by this bootloader
#endif
USBCON = ((1<<USBE) | (1<<FRZCLK)); // usb enabled, clock frozen
#if (defined(__AVR_AT90USB162__) || defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega32U2__))
PLLCSR = ((1 << PLLE) | (1 << PINDIV)); // enable PLL with a 16MHz XTAL
#elif (defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__))
PLLCSR = ((1 << PLLE) | (1 << PINDIV)); // enable PLL with a 16MHz XTAL
#elif (defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB647__) || defined(__AVR_ATmega32U6__))
PLLCSR = ((1 << PLLE) | (1 << PLLP2) | (1 << PLLP1)); // enable PLL with a 16MHz XTAL
#elif (defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1287__))
PLLCSR = ((1 << PLLE) | (1 << PLLP2) | (1 << PLLP0)); // enable PLL with a 16MHz XTAL
#else
#error Selected device not supported by this bootloader
#endif
while (!(PLLCSR & (1 << PLOCK))) // wait for PLL to lock
;
// start USB
#if (defined(__AVR_AT90USB162__) || defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega32U2__))
USBCON = ((1 << USBE) | (0 << FRZCLK));
#else
USBCON = ((1 << USBE) | (1 << OTGPADE) | (0 << FRZCLK));
#endif
// enable attach resistor by disabling USB line detach
UDCON = (0 << DETACH);
}
u8 USBGetConfiguration(void)
{
return _usbConfiguration;
}
u8 HasData(u8 ep)
{
SetEP(ep);
return ReadWriteAllowed(); // count in fifo
}
int USBGetChar();
void Recv(u8 ep, u8* dst, u8 len)
{
SetEP(ep);
while (len--)
{
while (!ReadWriteAllowed())
;
*dst++ = Recv8();
if (!ReadWriteAllowed()) // release empty buffer
ReleaseRX();
}
}
// Transmit a packet to endpoint
void Transfer(u8 ep, const u8* data, int len)
{
u8 zero = ep & TRANSFER_ZERO;
SetEP(ep & 7);
while (len--)
{
while (!ReadWriteAllowed())
; // TODO Check for STALL etc
#if (FLASHEND > 0xFFFF)
u8 d = (ep & TRANSFER_PGM) ? pgm_read_byte_far(data) : data[0];
#else
u8 d = (ep & TRANSFER_PGM) ? pgm_read_byte(data) : data[0];
#endif
data++;
if (zero)
d = 0;
Send8(d);
if (!ReadWriteAllowed())
ReleaseTX();
}
if (ep & TRANSFER_RELEASE)
ReleaseTX();
}
extern const u8 _initEndpoints[] PROGMEM;
const u8 _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
EP_TYPE_INTERRUPT_IN, // HID_ENDPOINT_INT
};
static void InitEndpoints()
{
for (u8 i = 1; i < sizeof(_initEndpoints); i++)
{
UENUM = i;
UECONX |= (1 << EPEN);
#if (FLASHEND > 0xFFFF)
UECFG0X = pgm_read_byte_far(_initEndpoints+i);
#else
UECFG0X = pgm_read_byte(_initEndpoints+i);
#endif
UECFG1X = EP_DOUBLE_64;
}
// Reset all endpoints except EP0
#if (defined(__AVR_AT90USB162__) || defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega32U2__))
UERST = ((1<<EPRST4) | (1<<EPRST3) | (1<<EPRST2) | (1<<EPRST1));
#else // all other USB AVRs
UERST = ((1<<EPRST6) | (1<<EPRST5) | (1<<EPRST4) | (1<<EPRST3) | (1<<EPRST2) | (1<<EPRST1));
#endif
UERST = 0;
}
typedef struct
{
u8 bmRequestType;
u8 bRequest;
u8 wValueL;
u8 wValueH;
u16 wIndex;
u16 wLength;
} Setup;
Setup _setup;
//bool USBHook(Setup& setup)
bool USBHook()
{
Setup& setup = _setup;
u8 r = setup.bRequest;
// CDC Requests
if (CDC_GET_LINE_CODING == r)
{
Send((const volatile u8*)&_usbLineInfo,7);
}
else if (CDC_SET_LINE_CODING == r)
{
WaitOUT();
Recv((volatile u8*)&_usbLineInfo,7);
ClearOUT();
}
else if (CDC_SET_CONTROL_LINE_STATE == r)
{
_usbLineInfo.lineState = setup.wValueL;
}
return true;
}
extern const u8 _rawHID[] PROGMEM;
#define LSB(_x) ((_x) & 0xFF)
#define MSB(_x) ((_x) >> 8)
#define RAWHID_USAGE_PAGE 0xFFC0
#define RAWHID_USAGE 0x0C00
#define RAWHID_TX_SIZE 64
#define RAWHID_RX_SIZE 64
const u8 _rawHID[] =
{
// RAW HID
0x06, LSB(RAWHID_USAGE_PAGE), MSB(RAWHID_USAGE_PAGE), // 30
0x0A, LSB(RAWHID_USAGE), MSB(RAWHID_USAGE),
0xA1, 0x01, // Collection 0x01
0x85, 0x03, // REPORT_ID (3)
0x75, 0x08, // report size = 8 bits
0x15, 0x00, // logical minimum = 0
0x26, 0xFF, 0x00, // logical maximum = 255
0x95, 64, // report count TX
0x09, 0x01, // usage
0x81, 0x02, // Input (array)
0x95, 64, // report count RX
0x09, 0x02, // usage
0x91, 0x02, // Output (array)
0xC0 // end collection
};
u8 _cdcComposite = 0;
bool SendDescriptor()
{
Setup& setup = _setup;
u8 desc_length = 0;
const u8* desc_addr = 0;
u8 t = setup.wValueH;
if (0x22 == t)
{
desc_addr = _rawHID;
desc_length = sizeof(desc_length);
} else if (USB_DEVICE_DESCRIPTOR_TYPE == t)
{
if (setup.wLength == 8)
_cdcComposite = 1;
desc_addr = _cdcComposite ? (const u8*)&USB_DeviceDescriptorA : (const u8*)&USB_DeviceDescriptor;
}
else if (USB_CONFIGURATION_DESCRIPTOR_TYPE == t)
{
desc_addr = (const u8*)&USB_ConfigDescriptor;
desc_length = sizeof(USB_ConfigDescriptor);
}
else if (USB_STRING_DESCRIPTOR_TYPE == t)
{
if (setup.wValueL == 0)
desc_addr = (const u8*)&STRING_LANGUAGE;
else if (setup.wValueL == IPRODUCT)
desc_addr = (const u8*)&STRING_IPRODUCT;
else if (setup.wValueL == IMANUFACTURER)
desc_addr = (const u8*)&STRING_IMANUFACTURER;
else
return false;
} else
return false;
if (desc_length == 0)
#if (FLASHEND > 0xFFFF)
desc_length = pgm_read_byte_far(desc_addr);
#else
desc_length = pgm_read_byte(desc_addr);
#endif
if ((u8)setup.wLength < desc_length) // bit of a cheat limiting to 255 bytes TODO (saved 8 bytes)
desc_length = (u8)setup.wLength;
// Send descriptor
// EP0 is 64 bytes long
// RWAL and FIFOCON don't work on EP0
u8 n = 0;
do
{
if (!WaitForINOrOUT())
return false;
#if (FLASHEND > 0xFFFF)
Send8(pgm_read_byte_far(&desc_addr[n++]));
#else
Send8(pgm_read_byte(&desc_addr[n++]));
#endif
u8 clr = n & 0x3F;
if (!clr)
ClearIN(); // Fifo is full, release this packet
} while (n < desc_length);
return true;
}
void USBSetupInterrupt()
{
SetEP(0);
if (!ReceivedSetupInt())
return;
Setup& setup = _setup; // global saves ~30 bytes
Recv((u8*)&setup,8);
ClearSetupInt();
if (setup.bmRequestType & DEVICETOHOST)
WaitIN();
else
ClearIN();
bool ok = true;
u8 r = setup.bRequest;
if (SET_ADDRESS == r)
{
WaitIN();
UDADDR = setup.wValueL | (1<<ADDEN);
}
else if (SET_CONFIGURATION == r)
{
_usbConfiguration = setup.wValueL;
InitEndpoints();
}
else if (GET_CONFIGURATION == r)
{
Send8(_usbConfiguration);
}
else if (GET_STATUS == r)
{
Send8(0); // All good as far as I know
}
else if (GET_DESCRIPTOR == r)
{
ok = SendDescriptor();
}
else
{
ok = USBHook();
}
if (ok)
ClearIN();
else
Stall();
}
void USBGeneralInterrupt()
{
u8 udint = UDINT;
UDINT = 0;
// End of Reset
if (udint & (1<<EORSTI))
{
InitEP(0,EP_TYPE_CONTROL,EP_SINGLE_64); // init ep0
_usbConfiguration = 0; // not configured yet
}
// Start of Frame - happens every millisecond so we use it for TX and RX LED one-shot timing, too
if (udint & (1<<SOFI))
{
// check whether the one-shot period has elapsed. if so, turn off the LED
if (TxLEDPulse && !(--TxLEDPulse))
TXLED0;
if (RxLEDPulse && !(--RxLEDPulse))
RXLED0;
if (!_ejected)
_timeout = 0;
}
}
void LEDPulse();
int USBGetChar()
{
for(;;)
{
USBSetupInterrupt();
USBGeneralInterrupt();
// Read a char
if (HasData(CDC_RX))
{
u8 c = Recv8();
if (!ReadWriteAllowed())
ReleaseRX();
return c;
}
if (!--_timeout) {
Reboot(); // USB not connected, run firmware
}
_delay_us(100); // stretch out the bootloader period to about 5 seconds after enumeration
LEDPulse();
}
return -1;
}

View File

@@ -1,246 +0,0 @@
// Copyright (c) 2010, Peter Barrett
/*
** Permission to use, copy, modify, and/or distribute this software for
** any purpose with or without fee is hereby granted, provided that the
** above copyright notice and this permission notice appear in all copies.
**
** THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS 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, DIRECT, 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.
*/
#ifndef __USBCORE_H__
#define __USBCORE_H__
#define GET_STATUS 0
#define CLEAR_FEATURE 1
#define SET_FEATURE 3
#define SET_ADDRESS 5
#define GET_DESCRIPTOR 6
#define GET_CONFIGURATION 8
#define SET_CONFIGURATION 9
#define GET_INTERFACE 10
#define SET_INTERFACE 11
// bmRequestType
#define HOSTTODEVICE 0x00
#define DEVICETOHOST 0x80
#define STANDARD 0x00
#define CLASS 0x20
#define VENDOR 0x40
#define DEVICE 0x00
#define INTERFACE 0x01
#define ENDPOINT 0x02
#define OTHER 0x03
#define CDC_SET_LINE_CODING 0x20
#define CDC_GET_LINE_CODING 0x21
#define CDC_SET_CONTROL_LINE_STATE 0x22
// Descriptors
#define USB_DEVICE_DESC_SIZE 18
#define USB_CONFIGUARTION_DESC_SIZE 9
#define USB_INTERFACE_DESC_SIZE 9
#define USB_ENDPOINT_DESC_SIZE 7
#define USB_DEVICE_DESCRIPTOR_TYPE 1
#define USB_CONFIGURATION_DESCRIPTOR_TYPE 2
#define USB_STRING_DESCRIPTOR_TYPE 3
#define USB_INTERFACE_DESCRIPTOR_TYPE 4
#define USB_ENDPOINT_DESCRIPTOR_TYPE 5
#define USB_DEVICE_CLASS_COMMUNICATIONS 0x02
#define USB_DEVICE_CLASS_HUMAN_INTERFACE 0x03
#define USB_DEVICE_CLASS_STORAGE 0x08
#define USB_DEVICE_CLASS_VENDOR_SPECIFIC 0xFF
#define USB_CONFIG_POWERED_MASK 0x40
#define USB_CONFIG_BUS_POWERED 0x80
#define USB_CONFIG_SELF_POWERED 0xC0
#define USB_CONFIG_REMOTE_WAKEUP 0x20
// bMaxPower in Configuration Descriptor
#define USB_CONFIG_POWER_MA(mA) ((mA)/2)
// bEndpointAddress in Endpoint Descriptor
#define USB_ENDPOINT_DIRECTION_MASK 0x80
#define USB_ENDPOINT_OUT(addr) ((addr) | 0x00)
#define USB_ENDPOINT_IN(addr) ((addr) | 0x80)
#define USB_ENDPOINT_TYPE_MASK 0x03
#define USB_ENDPOINT_TYPE_CONTROL 0x00
#define USB_ENDPOINT_TYPE_ISOCHRONOUS 0x01
#define USB_ENDPOINT_TYPE_BULK 0x02
#define USB_ENDPOINT_TYPE_INTERRUPT 0x03
#define TOBYTES(x) ((x) & 0xFF),(((x) >> 8) & 0xFF)
#define CDC_V1_10 0x0110
#define CDC_COMMUNICATION_INTERFACE_CLASS 0x02
#define CDC_CALL_MANAGEMENT 0x01
#define CDC_ABSTRACT_CONTROL_MODEL 0x02
#define CDC_HEADER 0x00
#define CDC_ABSTRACT_CONTROL_MANAGEMENT 0x02
#define CDC_UNION 0x06
#define CDC_CS_INTERFACE 0x24
#define CDC_CS_ENDPOINT 0x25
#define CDC_DATA_INTERFACE_CLASS 0x0A
// 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;
} DeviceDescriptor;
// Config
typedef struct {
u8 len; // 9
u8 dtype; // 2
u16 clen; // total length
u8 numInterfaces;
u8 config;
u8 iconfig;
u8 attributes;
u8 maxPower;
} ConfigDescriptor;
// String
// Interface
typedef struct
{
u8 len; // 9
u8 dtype; // 4
u8 number;
u8 alternate;
u8 numEndpoints;
u8 interfaceClass;
u8 interfaceSubClass;
u8 protocol;
u8 iInterface;
} InterfaceDescriptor;
// Endpoint
typedef struct
{
u8 len; // 7
u8 dtype; // 5
u8 addr;
u8 attr;
u16 packetSize;
u8 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;
} IADDescriptor;
// CDC CS interface descriptor
typedef struct
{
u8 len; // 5
u8 dtype; // 0x24
u8 subtype;
u8 d0;
u8 d1;
} CDCCSInterfaceDescriptor;
typedef struct
{
u8 len; // 4
u8 dtype; // 0x24
u8 subtype;
u8 d0;
} CDCCSInterfaceDescriptor4;
typedef struct
{
IADDescriptor iad; // Only needed on compound device
// Control
InterfaceDescriptor cif; //
CDCCSInterfaceDescriptor header;
CDCCSInterfaceDescriptor callManagement;
CDCCSInterfaceDescriptor4 controlManagement;
CDCCSInterfaceDescriptor functionalDescriptor;
EndpointDescriptor cifin;
// Data
InterfaceDescriptor dif;
EndpointDescriptor in;
EndpointDescriptor out;
} CDCDescriptor;
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;
} HIDDescDescriptor;
typedef struct
{
InterfaceDescriptor hid;
HIDDescDescriptor desc;
EndpointDescriptor in;
} HIDDescriptor;
#define D_DEVICE(_class,_subClass,_proto,_packetSize0,_vid,_pid,_version,_im,_ip,_is,_configs) \
{ 18, 1, 0x200, _class,_subClass,_proto,_packetSize0,_vid,_pid,_version,_im,_ip,_is,_configs }
#define D_CONFIG(_totalLength,_interfaces) \
{ 9, 2, _totalLength,_interfaces, 1, 0, USB_CONFIG_BUS_POWERED, USB_CONFIG_POWER_MA(100) }
#define D_INTERFACE(_n,_numEndpoints,_class,_subClass,_protocol) \
{ 9, 4, _n, 0, _numEndpoints, _class,_subClass, _protocol, 0 }
#define D_ENDPOINT(_addr,_attr,_packetSize, _interval) \
{ 7, 5, _addr,_attr,_packetSize, _interval }
#define D_IAD(_firstInterface, _count, _class, _subClass, _protocol) \
{ 8, 11, _firstInterface, _count, _class, _subClass, _protocol, 0 }
#define D_HIDREPORT(_descriptorLength) \
{ 9, 0x21, 0x1, 0x1, 0, 1, 0x22, _descriptorLength, 0 }
#define D_CDCCS(_subtype,_d0,_d1) { 5, 0x24, _subtype, _d0, _d1 }
#define D_CDCCS4(_subtype,_d0) { 4, 0x24, _subtype, _d0 }
#endif

View File

@@ -1,82 +0,0 @@
/* Copyright (c) 2011, Peter Barrett
**
** Permission to use, copy, modify, and/or distribute this software for
** any purpose with or without fee is hereby granted, provided that the
** above copyright notice and this permission notice appear in all copies.
**
** THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS 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, DIRECT, 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.
*/
#include "Platform.h"
//====================================================================================================
//====================================================================================================
// Actual device descriptors
const u16 STRING_LANGUAGE[2] = {
(3<<8) | (2+2),
0x0409 // English
};
const u16 STRING_IPRODUCT[28] = {
(3<<8) | (2+2*27),
#if USB_PID == USB_PID_LEONARDO
'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
'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] = {
(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,IMANUFACTURER,IPRODUCT,0,1);
//#else
DeviceDescriptor USB_DeviceDescriptor = D_DEVICE(0x00,0x00,0x00,64,USB_VID,USB_PID,0x100,IMANUFACTURER,IPRODUCT,0,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),
// CDC communication interface
D_INTERFACE(CDC_ACM_INTERFACE,1,CDC_COMMUNICATION_INTERFACE_CLASS,CDC_ABSTRACT_CONTROL_MODEL,0),
D_CDCCS(CDC_HEADER,0x10,0x01), // Header (1.10 bcd)
D_CDCCS(CDC_CALL_MANAGEMENT,1,1), // Device handles call management
D_CDCCS4(CDC_ABSTRACT_CONTROL_MANAGEMENT,2), // SET_LINE_CODING, GET_LINE_CODING, SET_CONTROL_LINE_STATE supported
D_CDCCS(CDC_UNION,CDC_ACM_INTERFACE,CDC_DATA_INTERFACE), // Communication interface is master, data interface is slave 0
D_ENDPOINT(USB_ENDPOINT_IN (CDC_ENDPOINT_ACM),USB_ENDPOINT_TYPE_INTERRUPT,0x10,0x40),
// CDC data interface
D_INTERFACE(CDC_DATA_INTERFACE,2,CDC_DATA_INTERFACE_CLASS,0,0),
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
// 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)
}
};

View File

@@ -1,63 +0,0 @@
/* Copyright (c) 2011, Peter Barrett
**
** Permission to use, copy, modify, and/or distribute this software for
** any purpose with or without fee is hereby granted, provided that the
** above copyright notice and this permission notice appear in all copies.
**
** THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS 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, DIRECT, 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.
*/
#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
typedef struct
{
ConfigDescriptor config;
#ifdef CDC_ENABLED
CDCDescriptor cdc;
#endif
HIDDescriptor hid;
} 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;
#define IMANUFACTURER 1
#define IPRODUCT 2
#define CDC_TX CDC_ENDPOINT_IN
#define CDC_RX CDC_ENDPOINT_OUT

View File

@@ -1,187 +0,0 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2009.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, and distribute this software
and its documentation for any purpose and without fee is hereby
granted, 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 FLASH 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.
*/
USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
{
.Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device},
.USBSpecification = VERSION_BCD(01.10),
.Class = 0x00,
.SubClass = 0x00,
.Protocol = 0x00,
.Endpoint0Size = 8,
.VendorID = 0x03EB,
.ProductID = 0x2040,
.ReleaseNumber = 0x0000,
.ManufacturerStrIndex = 0x01,
.ProductStrIndex = 0x02,
.SerialNumStrIndex = NO_DESCRIPTOR,
.NumberOfConfigurations = 1
};
/** Configuration descriptor structure. This descriptor, located in FLASH 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.
*/
USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
{
.Config =
{
.Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration},
.TotalConfigurationSize = ( sizeof(USB_Descriptor_Configuration_Header_t)
+ sizeof(USB_Descriptor_Interface_t) ),
.TotalInterfaces = 1,
.ConfigurationNumber = 1,
.ConfigurationStrIndex = NO_DESCRIPTOR,
.ConfigAttributes = (USB_CONFIG_ATTR_BUSPOWERED | USB_CONFIG_ATTR_SELFPOWERED),
.MaxPowerConsumption = USB_CONFIG_POWER_MA(100)
},
.Interface =
{
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
.InterfaceNumber = 1,
.AlternateSetting = 0,
.TotalEndpoints = 0,
.Class = 0xFF,
.SubClass = 0x00,
.Protocol = 0x00,
.InterfaceStrIndex = NO_DESCRIPTOR
},
};
/** Language descriptor structure. This descriptor, located in FLASH 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.
*/
USB_Descriptor_String_t PROGMEM LanguageString =
{
.Header = {.Size = USB_STRING_LEN(1), .Type = DTYPE_String},
.UnicodeString = {LANGUAGE_ID_ENG}
};
/** Manufacturer descriptor string. This is a Unicode string containing the manufacturer'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.
*/
USB_Descriptor_String_t PROGMEM ManufacturerString =
{
.Header = {.Size = USB_STRING_LEN(11), .Type = DTYPE_String},
.UnicodeString = L"Dean Camera"
};
/** 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.
*/
USB_Descriptor_String_t PROGMEM ProductString =
{
.Header = {.Size = USB_STRING_LEN(9), .Type = DTYPE_String},
.UnicodeString = L"LUFA Demo"
};
/** This function is called by the library when in device mode, and must be overridden (see 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, void** const DescriptorAddress)
{
const uint8_t DescriptorType = (wValue >> 8);
const uint8_t DescriptorNumber = (wValue & 0xFF);
void* Address = NULL;
uint16_t Size = NO_DESCRIPTOR;
switch (DescriptorType)
{
case DTYPE_Device:
Address = (void*)&DeviceDescriptor;
Size = sizeof(USB_Descriptor_Device_t);
break;
case DTYPE_Configuration:
Address = (void*)&ConfigurationDescriptor;
Size = sizeof(USB_Descriptor_Configuration_t);
break;
case DTYPE_String:
switch (DescriptorNumber)
{
case 0x00:
Address = (void*)&LanguageString;
Size = pgm_read_byte(&LanguageString.Header.Size);
break;
case 0x01:
Address = (void*)&ManufacturerString;
Size = pgm_read_byte(&ManufacturerString.Header.Size);
break;
case 0x02:
Address = (void*)&ProductString;
Size = pgm_read_byte(&ProductString.Header.Size);
break;
}
break;
}
*DescriptorAddress = Address;
return Size;
}

View File

@@ -1,59 +0,0 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2009.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, and distribute this software
and its documentation for any purpose and without fee is hereby
granted, 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>
#include <avr/pgmspace.h>
/* 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; /**< Configuration descriptor header structure */
USB_Descriptor_Interface_t Interface; /**< Interface descriptor, required for the device to enumerate */
} USB_Descriptor_Configuration_t;
/* Function Prototypes: */
uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex, void** const DescriptorAddress)
ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3);
#endif

View File

File diff suppressed because it is too large Load Diff

View File

@@ -1,166 +0,0 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2009.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, and distribute this software
and its documentation for any purpose and without fee is hereby
granted, 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 TestApp demo. This file contains the main tasks of the demo and
* is responsible for the initial application hardware configuration.
*/
#include "TestApp.h"
/** Main program entry point. This routine configures the hardware required by the application, then
* starts the scheduler to run the application tasks.
*/
int main(void)
{
SetupHardware();
puts_P(PSTR(ESC_FG_CYAN "LUFA Demo running.\r\n" ESC_FG_WHITE));
for (;;)
{
CheckJoystick();
CheckButton();
CheckTemperature();
/* Clear millisecond timer's Output Compare flag (logic 1 clears the flag) */
TIFR0 |= (1 << OCF0A);
USB_USBTask();
}
}
void SetupHardware(void)
{
/* Disable watchdog if enabled by bootloader/fuses */
MCUSR &= ~(1 << WDRF);
wdt_disable();
/* Disable clock division */
clock_prescale_set(clock_div_1);
/* Hardware initialization */
SerialStream_Init(9600, false);
ADC_Init(ADC_SINGLE_CONVERSION | ADC_PRESCALE_64);
Temperature_Init();
Joystick_Init();
LEDs_Init();
Buttons_Init();
/* Millisecond timer initialization */
OCR0A = 0x7D;
TCCR0A = (1 << WGM01);
TCCR0B = ((1 << CS01) | (1 << CS00));
}
/** Task responsible for checking the joystick position, and displaying the joystick position onto the
* board LEDs.
*/
void CheckJoystick(void)
{
uint8_t JoyStatus_LCL = Joystick_GetStatus();
uint8_t LEDMask = LEDS_NO_LEDS;
if (JoyStatus_LCL & JOY_UP)
LEDMask |= LEDS_LED1;
if (JoyStatus_LCL & JOY_DOWN)
LEDMask |= LEDS_LED2;
if (JoyStatus_LCL & JOY_LEFT)
LEDMask |= LEDS_LED3;
if (JoyStatus_LCL & JOY_RIGHT)
LEDMask |= LEDS_LED4;
if (JoyStatus_LCL & JOY_PRESS)
LEDMask = LEDS_ALL_LEDS;
LEDs_SetAllLEDs(LEDMask);
}
/** Task responsible for checking the current temperature via the temperature sensor mounted on the
* board, and displaying it through the serial USART.
*/
void CheckTemperature(void)
{
static uint16_t MSElapsed = 0;
/* Timer 0's compare flag is set every millisecond */
if (TIFR0 & (1 << OCF0A))
MSElapsed++;
/* Task runs every 10000 ticks, 10 seconds for this demo */
if (MSElapsed == 10000)
{
printf_P(PSTR("Current temperature: %d Degrees Celcius\r\n\r\n"),
(int8_t)Temperature_GetTemperature());
MSElapsed = 0;
}
}
/** Task responsible for checking the board's first button' position, and start-stopping other tasks and the USB
* interface in response to user joystick movements.
*/
void CheckButton(void)
{
static uint16_t DebounceMSElapsed = 0;
static bool IsPressed;
/* Timer 0's compare flag is set every millisecond */
if (TIFR0 & (1 << OCF0A))
DebounceMSElapsed++;
if (Buttons_GetStatus() & BUTTONS_BUTTON1)
{
if (!(IsPressed) && (DebounceMSElapsed == 100))
{
IsPressed = true;
if (USB_IsInitialized == true)
{
USB_ShutDown();
puts_P(PSTR(ESC_FG_YELLOW "USB Power Off.\r\n" ESC_FG_WHITE));
}
else
{
puts_P(PSTR(ESC_FG_YELLOW "USB Power On.\r\n" ESC_FG_WHITE));
USB_Init(USB_MODE_UID, USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL);
}
}
}
else
{
DebounceMSElapsed = 0;
IsPressed = false;
}
}

View File

@@ -1,62 +0,0 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2009.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, and distribute this software
and its documentation for any purpose and without fee is hereby
granted, 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 TestApp.c.
*/
#ifndef _TESTAPP_H_
#define _TESTAPP_H_
/* Includes: */
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/wdt.h>
#include <avr/power.h>
#include <LUFA/Version.h>
#include <LUFA/Drivers/USB/USB.h>
#include <LUFA/Drivers/Misc/TerminalCodes.h>
#include <LUFA/Drivers/Peripheral/ADC.h>
#include <LUFA/Drivers/Peripheral/SerialStream.h>
#include <LUFA/Drivers/Board/Joystick.h>
#include <LUFA/Drivers/Board/LEDs.h>
#include <LUFA/Drivers/Board/Buttons.h>
#include <LUFA/Drivers/Board/Temperature.h>
/* Function Prototypes: */
void SetupHardware(void);
void CheckJoystick(void);
void CheckButton(void);
void CheckTemperature(void);
#endif

View File

@@ -1,63 +0,0 @@
/** \file
*
* This file contains special DoxyGen information for the generation of the main page and other special
* documentation pages. It is not a project source file.
*/
/** \mainpage Test Application for the LUFA library
*
* \section SSec_Info USB Information:
*
* The following table gives a rundown of the USB utilization of this demo.
*
* <table>
* <tr>
* <td><b>USB Mode:</b></td>
* <td>Host/Device (Dual Role)</td>
* </tr>
* <tr>
* <td><b>USB Class:</b></td>
* <td>N/A</td>
* </tr>
* <tr>
* <td><b>USB Subclass:</b></td>
* <td>N/A</td>
* </tr>
* <tr>
* <td><b>Relevant Standards:</b></td>
* <td>N/A</td>
* </tr>
* <tr>
* <td><b>Usable Speeds:</b></td>
* <td>Low Speed Mode, Full Speed Mode</td>
* </tr>
* </table>
*
* \section SSec_Description Project Description:
*
* Test application. Demonstrates several aspects of the LUFA
* Library. On start-up the current temperature will be printed
* through the USART every 10 seconds, and the current joystick
* position will be indicated via the LEDs on the selected board.
* Pressing the HWB will initiate the USB subsystem, enumerating
* the device (which has <b>no actual functionality beyond
* enumeration as a device or as a host in this demo</b>, and serves
* only to demonstrate the USB portion of the library).
*
* Pressing the HWB a second time will turn off the USB system.
*
* When activated, the USB events will be printed through the
* serial USART.
*
* \section SSec_Options Project Options
*
* The following defines can be found in this demo, which can control the demo behaviour when defined, or changed in value.
*
* <table>
* <tr>
* <td>
* None
* </td>
* </tr>
* </table>
*/

View File

@@ -1,181 +0,0 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2009.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, and distribute this software
and its documentation for any purpose and without fee is hereby
granted, 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
*
* This file contains dummy handlers for all the possible USB events passed to the
* application by the library (see library documentation for more details on USB events).
*
* Each event is caught and printed to the USART so that they may be monitored.
*/
#define INCLUDE_FROM_TESTEVENTS_C
#include "TestEvents.h"
/** Simple routine which aborts the program execution when a fatal error occurs, and is passed to the
* application via an event. When run, this function shuts down the USB interface, indicates an error
* via the board LEDs, prints an error message to the USART and then enters an infinite loop, preventing
* any more application code (other than interrupts) from executing.
*/
static void Abort_Program(void)
{
USB_ShutDown();
LEDs_SetAllLEDs(LEDS_LED1 | LEDS_LED3);
puts_P(PSTR(ESC_FG_RED ESC_INVERSE_ON "\r\n**PROGRAM ABORT**" ESC_FG_WHITE));
for (;;);
}
/** Event handler for the USB_UIDChange event. When fired, the event is logged to the USART. */
void EVENT_USB_UIDChange(void)
{
char* ModeStrPtr;
puts_P(PSTR(ESC_FG_RED EVENT_PREFIX "UID Change\r\n"));
if (USB_CurrentMode == USB_MODE_DEVICE)
ModeStrPtr = PSTR("DEVICE");
else if (USB_CurrentMode == USB_MODE_HOST)
ModeStrPtr = PSTR("HOST");
else
ModeStrPtr = PSTR("N/A");
printf_P(PSTR(" -- New Mode %S\r\n" ESC_FG_WHITE), ModeStrPtr);
}
/**
* Event handler for the USB_InitFailure event. When fired, the event is logged to the USART and the program
* execution aborted.
*/
void EVENT_USB_InitFailure(const uint8_t ErrorCode)
{
char* ModeStrPtr;
puts_P(PSTR(ESC_FG_RED EVENT_PREFIX "Power On Fail\r\n"));
if (USB_CurrentMode == USB_MODE_DEVICE)
ModeStrPtr = PSTR("DEVICE");
else if (USB_CurrentMode == USB_MODE_HOST)
ModeStrPtr = PSTR("HOST");
else
ModeStrPtr = PSTR("N/A");
printf_P(PSTR(" -- Mode %S\r\n"
" -- Error Code %d\r\n" ESC_FG_WHITE), ModeStrPtr, ErrorCode);
Abort_Program();
}
/** Event handler for the USB_Device_Connect event. When fired, the event is logged to the USART. */
void EVENT_USB_Device_Connect(void)
{
puts_P(PSTR(ESC_FG_GREEN EVENT_PREFIX "USB Connect\r\n" ESC_FG_WHITE));
}
/** Event handler for the USB_Device_Disconnect event. When fired, the event is logged to the USART. */
void EVENT_USB_Device_Disconnect(void)
{
puts_P(PSTR(ESC_FG_GREEN EVENT_PREFIX "USB Disconnect\r\n" ESC_FG_WHITE));
}
/** Event handler for the USB_Device_Suspend event. When fired, the event is logged to the USART. */
void EVENT_USB_Device_Suspend(void)
{
puts_P(PSTR(ESC_FG_YELLOW EVENT_PREFIX "USB Sleep\r\n" ESC_FG_WHITE));
}
/** Event handler for the USB_Device_WakeUp event. When fired, the event is logged to the USART. */
void EVENT_USB_Device_WakeUp(void)
{
puts_P(PSTR(ESC_FG_YELLOW EVENT_PREFIX "USB Wakeup\r\n" ESC_FG_WHITE));
}
/** Event handler for the USB_Device_Reset event. When fired, the event is logged to the USART. */
void EVENT_USB_Device_Reset(void)
{
puts_P(PSTR(ESC_FG_YELLOW EVENT_PREFIX "USB Reset\r\n" ESC_FG_WHITE));
}
/** Event handler for the USB_Device_UnhandledControlRequest event. When fired, the event is logged to the USART. */
void EVENT_USB_Device_UnhandledControlRequest(void)
{
printf_P(PSTR(ESC_FG_YELLOW EVENT_PREFIX "Ctrl Request\r\n"
" -- Req Data %d\r\n"
" -- Req Type %d\r\n"
" -- Req Length %d\r\n" ESC_FG_WHITE), USB_ControlRequest.bRequest,
USB_ControlRequest.bmRequestType,
USB_ControlRequest.wLength);
}
/** Event handler for the USB_Device_ConfigurationChanged event. When fired, the event is logged to the USART. */
void EVENT_USB_Device_ConfigurationChanged(void)
{
puts_P(PSTR(ESC_FG_YELLOW EVENT_PREFIX "Configuration Number Changed\r\n" ESC_FG_WHITE));
}
/**
* Event handler for the USB_Host_HostError event. When fired, the event is logged to the USART and the program
* execution aborted.
*/
void EVENT_USB_Host_HostError(const uint8_t ErrorCode)
{
printf_P(PSTR(ESC_FG_RED EVENT_PREFIX "Host Mode Error\r\n"
" -- Error Code %d\r\n" ESC_FG_WHITE), ErrorCode);
Abort_Program();
}
/** Event handler for the USB_Host_DeviceEnumerationFailed event. When fired, the event is logged to the USART. */
void EVENT_USB_Host_DeviceEnumerationFailed(const uint8_t ErrorCode, const uint8_t SubErrorCode)
{
printf_P(PSTR(ESC_FG_RED EVENT_PREFIX "Dev Enum Error\r\n"
" -- Error Code %d\r\n"
" -- Sub Error Code %d\r\n"
" -- In State %d\r\n" ESC_FG_WHITE), ErrorCode, SubErrorCode, USB_HostState);
}
/** Event handler for the USB_Host_DeviceEnumerationComplete event. When fired, the event is logged to the USART. */
void EVENT_USB_Host_DeviceEnumerationComplete(void)
{
puts_P(PSTR(ESC_FG_YELLOW EVENT_PREFIX "Device Enumeration Complete\r\n" ESC_FG_WHITE));
}
/** Event handler for the USB_Host_DeviceAttached event. When fired, the event is logged to the USART. */
void EVENT_USB_Host_DeviceAttached(void)
{
puts_P(PSTR(ESC_FG_GREEN EVENT_PREFIX "Device Attached\r\n" ESC_FG_WHITE));
}
/** Event handler for the USB_Host_DeviceUnattached event. When fired, the event is logged to the USART. */
void EVENT_USB_Host_DeviceUnattached(void)
{
puts_P(PSTR(ESC_FG_GREEN EVENT_PREFIX "Device Unattached\r\n" ESC_FG_WHITE));
}

View File

@@ -1,72 +0,0 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2009.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, and distribute this software
and its documentation for any purpose and without fee is hereby
granted, 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 TestEvents.c.
*/
#ifndef _TESTEVENTS_H_
#define _TESTEVENTS_H_
/* Includes: */
#include <avr/io.h>
#include <LUFA/Common/Common.h>
#include <LUFA/Drivers/USB/USB.h>
#include <LUFA/Drivers/Board/LEDs.h>
#include <LUFA/Drivers/Peripheral/SerialStream.h>
#include <LUFA/Drivers/Misc/TerminalCodes.h>
/* Macros: */
/** Prefix sent through the USART when an even fires before the actual event message. */
#define EVENT_PREFIX ESC_INVERSE_ON "EVENT:" ESC_INVERSE_OFF " "
/* Function Prototypes: */
#if defined(INCLUDE_FROM_TESTEVENTS_C) || defined(__DOXYGEN__)
static void Abort_Program(void) ATTR_NO_RETURN;
#endif
void EVENT_USB_InitFailure(const uint8_t ErrorCode);
void EVENT_USB_UIDChange(void);
void EVENT_USB_Host_HostError(const uint8_t ErrorCode);
void EVENT_USB_Host_DeviceAttached(void);
void EVENT_USB_Host_DeviceUnattached(void);
void EVENT_USB_Host_DeviceEnumerationFailed(const uint8_t ErrorCode, const uint8_t SubErrorCode);
void EVENT_USB_Host_DeviceEnumerationComplete(void);
void EVENT_USB_Device_Connect(void);
void EVENT_USB_Device_Disconnect(void);
void EVENT_USB_Device_ConfigurationChanged(void);
void EVENT_USB_Device_ConfigurationChanged(void);
void EVENT_USB_Device_Suspend(void);
void EVENT_USB_Device_WakeUp(void);
void EVENT_USB_Device_Reset(void);
#endif

View File

@@ -1,736 +0,0 @@
# 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 dfu = Download the hex file to the device, using dfu-programmer (must
# have dfu-programmer installed).
#
# make flip = Download the hex file to the device, using Atmel FLIP (must
# have Atmel FLIP installed).
#
# make dfu-ee = Download the eeprom file to the device, using dfu-programmer
# (must have dfu-programmer installed).
#
# make flip-ee = Download the eeprom file to the device, using Atmel FLIP
# (must have Atmel FLIP installed).
#
# 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 = at90usb1287
# Target board (see library "Board Types" documentation, USER or blank 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 = USBKEY
# 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_CLOCK below, as it is sourced by
# F_CLOCK 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 = 8000000
# Input clock frequency.
# This will define a symbol, F_CLOCK, 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_CLOCK = $(F_CPU)
# Output format. (can be srec, ihex, binary)
FORMAT = ihex
# Target file name (without extension).
TARGET = TestApp
# 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 library compile-time options
LUFA_OPTS = -D USE_FLASH_DESCRIPTORS
# List C source files here. (C dependencies are automatically generated.)
SRC = $(TARGET).c \
TestEvents.c \
Descriptors.c \
$(LUFA_PATH)/LUFA/Drivers/Board/Temperature.c \
$(LUFA_PATH)/LUFA/Drivers/Peripheral/SerialStream.c \
$(LUFA_PATH)/LUFA/Drivers/Peripheral/Serial.c \
$(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/DevChapter9.c \
$(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/Endpoint.c \
$(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/Host.c \
$(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/HostChapter9.c \
$(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/LowLevel.c \
$(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/Pipe.c \
$(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/Events.c \
$(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/USBInterrupt.c \
$(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/USBTask.c \
$(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/ConfigDescriptor.c \
# 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=gnu99
# Place -D or -U options here for C sources
CDEFS = -DF_CPU=$(F_CPU)UL -DF_CLOCK=$(F_CLOCK)UL -DBOARD=BOARD_$(BOARD) $(LUFA_OPTS)
# Place -D or -U options here for ASM sources
ADEFS = -DF_CPU=$(F_CPU)
# Place -D or -U options here for C++ sources
CPPDEFS = -DF_CPU=$(F_CPU)UL
#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 += -fpack-struct
CFLAGS += -fshort-enums
CFLAGS += -Wall
CFLAGS += -Wstrict-prototypes
#CFLAGS += -mshort-calls
CFLAGS += -Wundef
#CFLAGS += -fno-unit-at-a-time
#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
CFLAGS += -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,--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: alf avr910 avrisp bascom bsd
# dt006 pavr picoweb pony-stk200 sp12 stk200 stk500
#
# Type: avrdude -c ?
# to get a full listing.
#
AVRDUDE_PROGRAMMER = jtagmkII
# 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 = avrdude
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 checkinvalidevents showliboptions showtarget 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
$(LUFA_PATH)/LUFA/LUFA_Events.lst:
@make -C $(LUFA_PATH)/LUFA/ LUFA_Events.lst
checkinvalidevents: $(LUFA_PATH)/LUFA/LUFA_Events.lst
@echo
@echo Checking for invalid events...
@$(shell) avr-nm $(TARGET).elf | sed -n -e 's/^.*EVENT_/EVENT_/p' | \
grep -F -v --file=$(LUFA_PATH)/LUFA/LUFA_Events.lst > InvalidEvents.tmp || true
@sed -n -e 's/^/ WARNING - INVALID EVENT NAME: /p' InvalidEvents.tmp
@if test -s InvalidEvents.tmp; then exit 1; fi
showliboptions:
@echo
@echo ---- Compile Time Library Options ----
@for i in $(LUFA_OPTS:-D%=%); do \
echo $$i; \
done
@echo --------------------------------------
showtarget:
@echo
@echo --------- Target Information ---------
@echo AVR Model: $(MCU)
@echo Board: $(BOARD)
@echo Clock: $(F_CPU)Hz CPU, $(F_CLOCK)Hz Master
@echo --------------------------------------
# Display compiler version information.
gccversion :
@$(CC) --version
# Program the device.
program: $(TARGET).hex $(TARGET).eep
$(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM)
flip: $(TARGET).hex
batchisp -hardware usb -device $(MCU) -operation erase f
batchisp -hardware usb -device $(MCU) -operation loadbuffer $(TARGET).hex program
batchisp -hardware usb -device $(MCU) -operation start reset 0
dfu: $(TARGET).hex
dfu-programmer $(MCU) erase
dfu-programmer $(MCU) flash --debug 1 $(TARGET).hex
dfu-programmer $(MCU) reset
flip-ee: $(TARGET).hex $(TARGET).eep
$(COPY) $(TARGET).eep $(TARGET)eep.hex
batchisp -hardware usb -device $(MCU) -operation memory EEPROM erase
batchisp -hardware usb -device $(MCU) -operation memory EEPROM loadbuffer $(TARGET)eep.hex program
batchisp -hardware usb -device $(MCU) -operation start reset 0
$(REMOVE) $(TARGET)eep.hex
dfu-ee: $(TARGET).hex $(TARGET).eep
dfu-programmer $(MCU) flash-eeprom --debug 1 --suppress-bootloader-mem $(TARGET).eep
dfu-programmer $(MCU) reset
# 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 $< $@
%.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 -z -S $< > $@
# 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 clean_binary end
clean_binary:
$(REMOVE) $(TARGET).hex
clean_list:
@echo $(MSG_CLEANING)
$(REMOVE) $(TARGET).eep
$(REMOVE) $(TARGET)eep.hex
$(REMOVE) $(TARGET).cof
$(REMOVE) $(TARGET).elf
$(REMOVE) $(TARGET).map
$(REMOVE) $(TARGET).sym
$(REMOVE) $(TARGET).lss
$(REMOVE) $(SRC:%.c=$(OBJDIR)/%.o)
$(REMOVE) $(SRC:%.c=$(OBJDIR)/%.lst)
$(REMOVE) $(SRC:.c=.s)
$(REMOVE) $(SRC:.c=.d)
$(REMOVE) $(SRC:.c=.i)
$(REMOVE) InvalidEvents.tmp
$(REMOVEDIR) .dep
doxygen:
@echo Generating Project Documentation...
@doxygen Doxygen.conf
@echo Documentation Generation Complete.
clean_doxygen:
rm -rf Documentation
# 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 checkinvalidevents showliboptions \
showtarget begin finish end sizebefore sizeafter \
gccversion build elf hex eep lss sym coff extcoff \
program dfu flip flip-ee dfu-ee clean debug \
clean_list clean_binary gdb-config doxygen

View File

@@ -1,21 +0,0 @@
#
# LUFA Library
# Copyright (C) Dean Camera, 2009.
#
# dean [at] fourwalledcubicle [dot] com
# www.fourwalledcubicle.com
#
# Makefile to build all the LUFA OTG Demos. Call with "make all" to
# rebuild all OTG demos.
# Projects are pre-cleaned before each one is built, to ensure any
# custom LUFA library build options are reflected in the compiled
# code.
all:
make -C TestApp clean
make -C TestApp all
%:
make -C TestApp $@