removed old version of Leonardo's caterina bootloader, replaced with LUFA-based caterina

This commit is contained in:
Zach Eveland 2012-03-08 13:47:42 -05:00
parent 177746aa7f
commit 33116711b0
15 changed files with 718 additions and 2144 deletions

View File

@ -154,7 +154,7 @@ leonardo.upload.disable_flushing=true
leonardo.bootloader.low_fuses=0xff
leonardo.bootloader.high_fuses=0xd8
leonardo.bootloader.extended_fuses=0xcb
leonardo.bootloader.path=caterina_LUFA
leonardo.bootloader.path=caterina
leonardo.bootloader.file=Caterina.hex
leonardo.bootloader.unlock_bits=0x3F
leonardo.bootloader.lock_bits=0x2F

View File

@ -1,120 +0,0 @@
:1078000011241FBECFEFDAE0DEBFCDBF0BC14101B7
:1078100042144505560455026403740300001E9586
:1078200087020110030000C18081C106C0FF0A0069
:107830000CA10185037508150026FF00954009017C
:107840008102954009029102C0040309041A033021
:1078500000300030003000300030003000300031A7
:1078600000370030003100380341007200640075B9
:107870000069006E006F0020004C0065006F006E14
:10788000006100720064006F00200062006F006FF2
:107890000074006C006F00610064006500720018E5
:1078A00003410072006400750069006E006F0020E3
:1078B000004C004C00430012010002020000404155
:1078C0002334000001000203011201000200000045
:1078D0004041233400000100020301090264000357
:1078E00001008032080B00020202010009040000BE
:1078F0000102020000052400100105240101010419
:107900002402020524060001070581031000400936
:10791000040100020A0000000705020240000007FF
:107920000583024000000904020001030000000971
:107930002101010001221E000705840340004000D0
:1079400020918A0130918B012C5F3F4F30938B0146
:1079500020938A01C901892F99278695982F803411
:1079600018F08FE7891B982F990F921710F44798FA
:107970000895479A08955D9A289A81E08093E000DF
:107980001092E200EE27FF270994089528E088E18D
:1079900090E00FB6F894A895809360000FBE2093F6
:1079A0006000FFCF0F931F93CF93DF93982FEB01CE
:1079B000042F10E088E76030780730F411E083E0AE
:1079C000FB0180935700E895892F68E071E0402F14
:1079D00006D1112311F107B600FCFDCF402F4695CB
:1079E000FE01A8E0B1E020E031E009C08D919D9159
:1079F0000C0130935700E895112432962F5F24171D
:107A0000A8F385E0FE0180935700E89507B600FCD7
:107A1000FDCF81E180935700E895DF91CF911F91D1
:107A20000F91089584B794B7977F94BF98E10FB6EC
:107A3000F89490936000109260000FBE5D9A289AAF
:107A4000479883FF08C0E0E0F0E0859194918F5F54
:107A50009F4F09F090DF3F9A209A559A90E89093B3
:107A600061001092610081E885BF95BF9FD084E1DD
:107A70008093880180E180938901E0E0F0E08591C6
:107A800094918F5F9F4F19F081E080938F01EE24D6
:107A9000FF24BB24B39454EFC52E51E0D52E1FD242
:107AA000082F8EE098E7FC012491319602964491CC
:107AB000201711F02223B9F7109291011092900132
:107AC00082E068E071E08BD0013479F460910801C4
:107AD0006058633028F0683111F064E001C063E061
:107AE000C62FD0E0CF5DD7480EC0063571F4809127
:107AF0000801803311F011E022C080910A01C82FE3
:107B0000D0E0C25ED74811E022C0053721F413E06F
:107B1000CEE1D8E71CC0053539F4E0900801F090BB
:107B20000901EE0CFF1C0AC0043631F482E0B701F3
:107B30004091090137DF02C0043721F010E0C5E2AF
:107B4000D8E705C010910901E701E10EF11CC7D18A
:107B50008097B1F483E068E871E041E050E059D0EB
:107B6000112329F0412F50E083E8BE0152D083E475
:107B700069E871E041E050E04CD0013509F08FCF69
:107B8000D0929101C0929001B0928F01EE24FF2417
:107B900086CFFC01289884E680938D0104C08091F3
:107BA000F100819361506623D1F7089510929101FD
:107BB0001092900110928E0110928F0181E08093BB
:107BC000D70080EA8093D80082E189BD09B400FE25
:107BD000FDCF80E98093D8001092E0000895FB016A
:107BE0008093E90024E69BE611C08091E80085FFC0
:107BF000FCCF289820938D018091F1008193809192
:107C0000E80085FD02C09093E8004150442369F7E5
:107C10000895982FFB01282F207287708093E90028
:107C200064E63AE317C08091E80085FFFCCF97FF38
:107C300002C0849101C080813196211180E05D985D
:107C400060938C018093F1008091E80085FD02C073
:107C50003093E800415050408FEF4F3F580719F7DD
:107C600096FF03C08AE38093E80008958091930112
:107C7000813299F45D9884E680938C0120E030E0B5
:107C800003C080818093F100F901E050FF4F2F5F26
:107C90003F4F28303105A9F714C0803261F480913C
:107CA000E80082FFFCCF80E091E067E072DF8BEFBD
:107CB0008093E80006C0823221F480919401809381
:107CC000070181E0089520919501223291F1213040
:107CD00081F48091980190919901089711F4209373
:107CE0009A0180919A01882309F059C029EC38E75C
:107CF00058C0223029F484E690E02BED38E71DC00F
:107D0000233009F04AC080919401882319F429E4B2
:107D100038E747C0823019F427E638E742C083309D
:107D200019F42DE438E73DC08130B9F52FE938E783
:107D300038C082E090E02BE238E740919801509102
:107D40009901BC014817590708F4BA0190918C01B8
:107D500040E050E0AEEF8091E8008570E1F3809163
:107D6000E80082FD16C0F901E40FF51F4F5F5F4F79
:107D7000E4915D98E093F100842F8F7311F4A09348
:107D8000E80094E64617570730F390938C0181E0A2
:107D9000089590938C0180E0089580E0089527EB8A
:107DA00038E7F901849190E0C8CF1092E900809102
:107DB000E80083FF61C082E991E068E0EADE82EFDB
:107DC0008093E8008091920187FF05C08091E800D0
:107DD00080FFFCCF03C08EEF8093E8008091930179
:107DE000853051F48091E80080FFFCCF80919401B0
:107DF00080688093E30039C08930E1F48091940178
:107E000080938E01E7E2F8E791E031E026E390937A
:107E1000E9003093EB0084918093EC002093ED0017
:107E20009F5F3196953099F78EE78093EA00109224
:107E3000EA001BC0883049F490918E015D9884E679
:107E400080938C019093F10010C0882339F45D98E1
:107E500084E680938C011092F10007C0863011F403
:107E600032DF01C003DF882321F08EEF8093E8002A
:107E7000089581E28093EB0008958091E1001092D3
:107E8000E100282F83FF0CC01092E90081E080936D
:107E9000EB001092EC0082E38093ED0010928E01D3
:107EA00022FF1CC080918C01882331F08150809387
:107EB0008C01882309F45D9A80918D01882331F02B
:107EC000815080938D01882309F4289A80918F0135
:107ED000882321F4109291011092900108951F932C
:107EE000CF93DF9312E0C0E9D1E05FDFC6DF1093EC
:107EF000E9008091E80085FF13C0289884E680930C
:107F00008D019091F1008091E80085FD03C08BE622
:107F10008093E800892F90E0DF91CF911F91089521
:107F2000809190019091910101979093910180939C
:107F300090018091900190919101892B09F426DDA7
:0A7F4000CE010197F1F7FCDCD0CF71
:087F4A0000E10000000000004E
:040000030000780081
:00000001FF

822
hardware/arduino/bootloaders/caterina/Makefile Normal file → Executable file
View File

@ -1,105 +1,717 @@
###############################################################################
# Makefile for Caterina (formerly DiskLoader)
###############################################################################
## General Flags
PROJECT = Caterina
TARGET = Caterina.elf
CC = avr-gcc
# BOARD2
MCU = atmega32u4
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 bootloader PID
ARDUINO_MODEL_PID = 0x0034
# Arduino Micro bootloader PID
#ARDUINO_MODEL_PID = 0x0035
# Change if your programmer is different
AVRDUDE_PROGRAMMER = avrispmkII
AVRDUDE_PORT = usb
# program name should not be changed...
PROGRAM = Caterina
AVRDUDE = avrdude
AVRDUDE_FLAGS = -p $(MCU) -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=Caterina.map,--section-start=.text=0x7800,--relax
LDFLAGS += -nodefaultlibs -nostartfiles
## Intel Hex file production flags
HEX_EEPROM_FLAGS = -j .eeprom
HEX_EEPROM_FLAGS += --set-section-flags=.eeprom="alloc,load"
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) Caterina.hex Caterina.lss size
-include $(DEP)
checkdirs: $(BUILD_DIR)
$(BUILD_DIR):
@mkdir -p $@
clean:
@rm -rf build/
@rm -f *.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 $(HEX_FLASH_FLAGS) $< $@
%.lss: $(TARGET)
avr-objdump -h -S $< > $@
size: $(TARGET)
@echo
# @avr-size -C --mcu=${MCU} ${TARGET}.elf
program: $(TARGET).hex
$(AVRDUDE) $(AVRDUDE_FLAGS) -B 1 -u -U flash:w:$(TARGET).hex
# Hey Emacs, this is a -*- makefile -*-
#----------------------------------------------------------------------------
# WinAVR Makefile Template written by Eric B. Weddington, Jörg Wunsch, et al.
# >> Modified for use with the LUFA project. <<
#
# Released to the Public Domain
#
# Additional material for this makefile was written by:
# Peter Fleury
# Tim Henigan
# Colin O'Flynn
# Reiner Patommel
# Markus Pfaff
# Sander Pool
# Frederik Rouleau
# Carlos Lamas
# Dean Camera
# Opendous Inc.
# Denver Gingerich
#
#----------------------------------------------------------------------------
# On command line:
#
# make all = Make software.
#
# make clean = Clean out built project files.
#
# make coff = Convert ELF to AVR COFF.
#
# make extcoff = Convert ELF to AVR Extended COFF.
#
# make program = Download the hex file to the device, using avrdude.
# Please customize the avrdude settings below first!
#
# make doxygen = Generate DoxyGen documentation for the project (must have
# DoxyGen installed)
#
# make debug = Start either simulavr or avarice as specified for debugging,
# with avr-gdb or avr-insight as the front end for debugging.
#
# make filename.s = Just compile filename.c into the assembler code only.
#
# make filename.i = Create a preprocessed source file for use in submitting
# bug reports to the GCC project.
#
# To rebuild project do "make clean" then "make all".
#----------------------------------------------------------------------------
# MCU name
MCU = atmega32u4
# Target architecture (see library "Board Types" documentation).
ARCH = AVR8
# Target board (see library "Board Types" documentation, NONE for projects not requiring
# LUFA board drivers). If USER is selected, put custom board drivers in a directory called
# "Board" inside the application directory.
BOARD = USER
# Processor frequency.
# This will define a symbol, F_CPU, in all source code files equal to the
# processor frequency in Hz. You can then use this symbol in your source code to
# calculate timings. Do NOT tack on a 'UL' at the end, this will be done
# automatically to create a 32-bit value in your source code.
#
# This will be an integer division of F_USB below, as it is sourced by
# F_USB after it has run through any CPU prescalers. Note that this value
# does not *change* the processor frequency - it should merely be updated to
# reflect the processor speed set externally so that the code can use accurate
# software delays.
F_CPU = 16000000
# Input clock frequency.
# This will define a symbol, F_USB, in all source code files equal to the
# input clock frequency (before any prescaling is performed) in Hz. This value may
# differ from F_CPU if prescaling is used on the latter, and is required as the
# raw input clock is fed directly to the PLL sections of the AVR for high speed
# clock generation for the USB and other AVR subsections. Do NOT tack on a 'UL'
# at the end, this will be done automatically to create a 32-bit value in your
# source code.
#
# If no clock division is performed on the input clock inside the AVR (via the
# CPU clock adjust registers or the clock division fuses), this will be equal to F_CPU.
F_USB = $(F_CPU)
# Starting byte address of the bootloader, as a byte address - computed via the formula
# BOOT_START = ((FLASH_SIZE_KB - BOOT_SECTION_SIZE_KB) * 1024)
#
# Note that the bootloader size and start address given in AVRStudio is in words and not
# bytes, and so will need to be doubled to obtain the byte address needed by AVR-GCC.
FLASH_SIZE_KB = 32
BOOT_SECTION_SIZE_KB = 4
BOOT_START = 0x$(shell echo "obase=16; ($(FLASH_SIZE_KB) - $(BOOT_SECTION_SIZE_KB)) * 1024" | bc)
# Output format. (can be srec, ihex, binary)
FORMAT = ihex
# Target file name (without extension).
TARGET = Caterina
# Object files directory
# To put object files in current directory, use a dot (.), do NOT make
# this an empty or blank macro!
OBJDIR = .
# Path to the LUFA library
LUFA_PATH = ../../../../../LUFA-111009
# LUFA library compile-time options and predefined tokens
LUFA_OPTS = -D USB_DEVICE_ONLY
LUFA_OPTS += -D DEVICE_STATE_AS_GPIOR=0
LUFA_OPTS += -D ORDERED_EP_CONFIG
LUFA_OPTS += -D FIXED_CONTROL_ENDPOINT_SIZE=8
LUFA_OPTS += -D FIXED_NUM_CONFIGURATIONS=1
LUFA_OPTS += -D USE_RAM_DESCRIPTORS
LUFA_OPTS += -D USE_STATIC_OPTIONS="(USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL)"
LUFA_OPTS += -D NO_INTERNAL_SERIAL
LUFA_OPTS += -D NO_DEVICE_SELF_POWER
LUFA_OPTS += -D NO_DEVICE_REMOTE_WAKEUP
LUFA_OPTS += -D NO_SOF_EVENTS
#LUFA_OPTS += -D NO_BLOCK_SUPPORT
#LUFA_OPTS += -D NO_EEPROM_BYTE_SUPPORT
#LUFA_OPTS += -D NO_FLASH_BYTE_SUPPORT
#LUFA_OPTS += -D NO_LOCK_BYTE_WRITE_SUPPORT
# Create the LUFA source path variables by including the LUFA root makefile
include $(LUFA_PATH)/LUFA/makefile
# List C source files here. (C dependencies are automatically generated.)
SRC = $(TARGET).c \
Descriptors.c \
$(LUFA_SRC_USB) \
# List C++ source files here. (C dependencies are automatically generated.)
CPPSRC =
# List Assembler source files here.
# Make them always end in a capital .S. Files ending in a lowercase .s
# will not be considered source files but generated files (assembler
# output from the compiler), and will be deleted upon "make clean"!
# Even though the DOS/Win* filesystem matches both .s and .S the same,
# it will preserve the spelling of the filenames, and gcc itself does
# care about how the name is spelled on its command-line.
ASRC =
# Optimization level, can be [0, 1, 2, 3, s].
# 0 = turn off optimization. s = optimize for size.
# (Note: 3 is not always the best optimization level. See avr-libc FAQ.)
OPT = s
# Debugging format.
# Native formats for AVR-GCC's -g are dwarf-2 [default] or stabs.
# AVR Studio 4.10 requires dwarf-2.
# AVR [Extended] COFF format requires stabs, plus an avr-objcopy run.
DEBUG = dwarf-2
# List any extra directories to look for include files here.
# Each directory must be seperated by a space.
# Use forward slashes for directory separators.
# For a directory that has spaces, enclose it in quotes.
EXTRAINCDIRS = $(LUFA_PATH)/
# Compiler flag to set the C Standard level.
# c89 = "ANSI" C
# gnu89 = c89 plus GCC extensions
# c99 = ISO C99 standard (not yet fully implemented)
# gnu99 = c99 plus GCC extensions
CSTANDARD = -std=c99
# Place -D or -U options here for C sources
CDEFS = -DF_CPU=$(F_CPU)UL
CDEFS += -DF_USB=$(F_USB)UL
CDEFS += -DBOARD=BOARD_$(BOARD) -DARCH=ARCH_$(ARCH)
CDEFS += -DBOOT_START_ADDR=$(BOOT_START)UL
CDEFS += $(LUFA_OPTS)
# Place -D or -U options here for ASM sources
ADEFS = -DF_CPU=$(F_CPU)
ADEFS += -DF_USB=$(F_USB)UL
ADEFS += -DBOARD=BOARD_$(BOARD)
ADEFS += -DBOOT_START_ADDR=$(BOOT_START)UL
ADEFS += $(LUFA_OPTS)
# Place -D or -U options here for C++ sources
CPPDEFS = -DF_CPU=$(F_CPU)UL
CPPDEFS += -DF_USB=$(F_USB)UL
CPPDEFS += -DBOARD=BOARD_$(BOARD)
CPPDEFS += -DBOOT_START_ADDR=$(BOOT_START)UL
CPPDEFS += $(LUFA_OPTS)
#CPPDEFS += -D__STDC_LIMIT_MACROS
#CPPDEFS += -D__STDC_CONSTANT_MACROS
#---------------- Compiler Options C ----------------
# -g*: generate debugging information
# -O*: optimization level
# -f...: tuning, see GCC manual and avr-libc documentation
# -Wall...: warning level
# -Wa,...: tell GCC to pass this to the assembler.
# -adhlns...: create assembler listing
CFLAGS = -g$(DEBUG)
CFLAGS += $(CDEFS)
CFLAGS += -O$(OPT)
CFLAGS += -funsigned-char
CFLAGS += -funsigned-bitfields
CFLAGS += -ffunction-sections
CFLAGS += -fno-inline-small-functions
CFLAGS += -fpack-struct
CFLAGS += -fshort-enums
CFLAGS += -fno-strict-aliasing
CFLAGS += -Wall
CFLAGS += -Wstrict-prototypes
#CFLAGS += -mshort-calls
#CFLAGS += -fno-unit-at-a-time
#CFLAGS += -Wundef
#CFLAGS += -Wunreachable-code
#CFLAGS += -Wsign-compare
CFLAGS += -Wa,-adhlns=$(<:%.c=$(OBJDIR)/%.lst)
CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS))
CFLAGS += $(CSTANDARD)
#---------------- Compiler Options C++ ----------------
# -g*: generate debugging information
# -O*: optimization level
# -f...: tuning, see GCC manual and avr-libc documentation
# -Wall...: warning level
# -Wa,...: tell GCC to pass this to the assembler.
# -adhlns...: create assembler listing
CPPFLAGS = -g$(DEBUG)
CPPFLAGS += $(CPPDEFS)
CPPFLAGS += -O$(OPT)
CPPFLAGS += -funsigned-char
CPPFLAGS += -funsigned-bitfields
CPPFLAGS += -fpack-struct
CPPFLAGS += -fshort-enums
CPPFLAGS += -fno-exceptions
CPPFLAGS += -Wall
CPPFLAGS += -Wundef
#CPPFLAGS += -mshort-calls
#CPPFLAGS += -fno-unit-at-a-time
#CPPFLAGS += -Wstrict-prototypes
#CPPFLAGS += -Wunreachable-code
#CPPFLAGS += -Wsign-compare
CPPFLAGS += -Wa,-adhlns=$(<:%.cpp=$(OBJDIR)/%.lst)
CPPFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS))
#CPPFLAGS += $(CSTANDARD)
#---------------- Assembler Options ----------------
# -Wa,...: tell GCC to pass this to the assembler.
# -adhlns: create listing
# -gstabs: have the assembler create line number information; note that
# for use in COFF files, additional information about filenames
# and function names needs to be present in the assembler source
# files -- see avr-libc docs [FIXME: not yet described there]
# -listing-cont-lines: Sets the maximum number of continuation lines of hex
# dump that will be displayed for a given single line of source input.
ASFLAGS = $(ADEFS) -Wa,-adhlns=$(<:%.S=$(OBJDIR)/%.lst),-gstabs,--listing-cont-lines=100
#---------------- Library Options ----------------
# Minimalistic printf version
PRINTF_LIB_MIN = -Wl,-u,vfprintf -lprintf_min
# Floating point printf version (requires MATH_LIB = -lm below)
PRINTF_LIB_FLOAT = -Wl,-u,vfprintf -lprintf_flt
# If this is left blank, then it will use the Standard printf version.
PRINTF_LIB =
#PRINTF_LIB = $(PRINTF_LIB_MIN)
#PRINTF_LIB = $(PRINTF_LIB_FLOAT)
# Minimalistic scanf version
SCANF_LIB_MIN = -Wl,-u,vfscanf -lscanf_min
# Floating point + %[ scanf version (requires MATH_LIB = -lm below)
SCANF_LIB_FLOAT = -Wl,-u,vfscanf -lscanf_flt
# If this is left blank, then it will use the Standard scanf version.
SCANF_LIB =
#SCANF_LIB = $(SCANF_LIB_MIN)
#SCANF_LIB = $(SCANF_LIB_FLOAT)
MATH_LIB = -lm
# List any extra directories to look for libraries here.
# Each directory must be seperated by a space.
# Use forward slashes for directory separators.
# For a directory that has spaces, enclose it in quotes.
EXTRALIBDIRS =
#---------------- External Memory Options ----------------
# 64 KB of external RAM, starting after internal RAM (ATmega128!),
# used for variables (.data/.bss) and heap (malloc()).
#EXTMEMOPTS = -Wl,-Tdata=0x801100,--defsym=__heap_end=0x80ffff
# 64 KB of external RAM, starting after internal RAM (ATmega128!),
# only used for heap (malloc()).
#EXTMEMOPTS = -Wl,--section-start,.data=0x801100,--defsym=__heap_end=0x80ffff
EXTMEMOPTS =
#---------------- Linker Options ----------------
# -Wl,...: tell GCC to pass this to linker.
# -Map: create map file
# --cref: add cross reference to map file
LDFLAGS = -Wl,-Map=$(TARGET).map,--cref
LDFLAGS += -Wl,--section-start=.text=$(BOOT_START)
LDFLAGS += -Wl,--relax
LDFLAGS += -Wl,--gc-sections
LDFLAGS += $(EXTMEMOPTS)
LDFLAGS += $(patsubst %,-L%,$(EXTRALIBDIRS))
LDFLAGS += $(PRINTF_LIB) $(SCANF_LIB) $(MATH_LIB)
#LDFLAGS += -T linker_script.x
#---------------- Programming Options (avrdude) ----------------
# Programming hardware
# Type: avrdude -c ?
# to get a full listing.
#
AVRDUDE_PROGRAMMER = avrispmkII
# com1 = serial port. Use lpt1 to connect to parallel port.
AVRDUDE_PORT = usb
AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex
#AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep
# Uncomment the following if you want avrdude's erase cycle counter.
# Note that this counter needs to be initialized first using -Yn,
# see avrdude manual.
#AVRDUDE_ERASE_COUNTER = -y
# Uncomment the following if you do /not/ wish a verification to be
# performed after programming the device.
#AVRDUDE_NO_VERIFY = -V
# Increase verbosity level. Please use this when submitting bug
# reports about avrdude. See <http://savannah.nongnu.org/projects/avrdude>
# to submit bug reports.
#AVRDUDE_VERBOSE = -v -v
AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER)
AVRDUDE_FLAGS += $(AVRDUDE_NO_VERIFY)
AVRDUDE_FLAGS += $(AVRDUDE_VERBOSE)
AVRDUDE_FLAGS += $(AVRDUDE_ERASE_COUNTER)
#---------------- Debugging Options ----------------
# For simulavr only - target MCU frequency.
DEBUG_MFREQ = $(F_CPU)
# Set the DEBUG_UI to either gdb or insight.
# DEBUG_UI = gdb
DEBUG_UI = insight
# Set the debugging back-end to either avarice, simulavr.
DEBUG_BACKEND = avarice
#DEBUG_BACKEND = simulavr
# GDB Init Filename.
GDBINIT_FILE = __avr_gdbinit
# When using avarice settings for the JTAG
JTAG_DEV = /dev/com1
# Debugging port used to communicate between GDB / avarice / simulavr.
DEBUG_PORT = 4242
# Debugging host used to communicate between GDB / avarice / simulavr, normally
# just set to localhost unless doing some sort of crazy debugging when
# avarice is running on a different computer.
DEBUG_HOST = localhost
#============================================================================
# Define programs and commands.
SHELL = sh
CC = avr-gcc
OBJCOPY = avr-objcopy
OBJDUMP = avr-objdump
SIZE = avr-size
AR = avr-ar rcs
NM = avr-nm
AVRDUDE = /Applications/avrdude -C /Applications/avrdude.conf -B 1
REMOVE = rm -f
REMOVEDIR = rm -rf
COPY = cp
WINSHELL = cmd
# Define Messages
# English
MSG_ERRORS_NONE = Errors: none
MSG_BEGIN = -------- begin --------
MSG_END = -------- end --------
MSG_SIZE_BEFORE = Size before:
MSG_SIZE_AFTER = Size after:
MSG_COFF = Converting to AVR COFF:
MSG_EXTENDED_COFF = Converting to AVR Extended COFF:
MSG_FLASH = Creating load file for Flash:
MSG_EEPROM = Creating load file for EEPROM:
MSG_EXTENDED_LISTING = Creating Extended Listing:
MSG_SYMBOL_TABLE = Creating Symbol Table:
MSG_LINKING = Linking:
MSG_COMPILING = Compiling C:
MSG_COMPILING_CPP = Compiling C++:
MSG_ASSEMBLING = Assembling:
MSG_CLEANING = Cleaning project:
MSG_CREATING_LIBRARY = Creating library:
# Define all object files.
OBJ = $(SRC:%.c=$(OBJDIR)/%.o) $(CPPSRC:%.cpp=$(OBJDIR)/%.o) $(ASRC:%.S=$(OBJDIR)/%.o)
# Define all listing files.
LST = $(SRC:%.c=$(OBJDIR)/%.lst) $(CPPSRC:%.cpp=$(OBJDIR)/%.lst) $(ASRC:%.S=$(OBJDIR)/%.lst)
# Compiler flags to generate dependency files.
GENDEPFLAGS = -MMD -MP -MF .dep/$(@F).d
# Combine all necessary flags and optional flags.
# Add target processor to flags.
ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) $(GENDEPFLAGS)
ALL_CPPFLAGS = -mmcu=$(MCU) -I. -x c++ $(CPPFLAGS) $(GENDEPFLAGS)
ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS)
# Default target.
all: begin gccversion sizebefore build sizeafter end
# Change the build target to build a HEX file or a library.
build: elf hex eep lss sym
#build: lib
elf: $(TARGET).elf
hex: $(TARGET).hex
eep: $(TARGET).eep
lss: $(TARGET).lss
sym: $(TARGET).sym
LIBNAME=lib$(TARGET).a
lib: $(LIBNAME)
# Eye candy.
# AVR Studio 3.x does not check make's exit code but relies on
# the following magic strings to be generated by the compile job.
begin:
@echo
@echo $(MSG_BEGIN)
end:
@echo $(MSG_END)
@echo
# Display size of file.
HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex
ELFSIZE = $(SIZE) $(MCU_FLAG) $(FORMAT_FLAG) $(TARGET).elf
MCU_FLAG = $(shell $(SIZE) --help | grep -- --mcu > /dev/null && echo --mcu=$(MCU) )
FORMAT_FLAG = $(shell $(SIZE) --help | grep -- --format=.*avr > /dev/null && echo --format=avr )
sizebefore:
@if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); \
2>/dev/null; echo; fi
sizeafter:
@if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); \
2>/dev/null; echo; fi
# Display compiler version information.
gccversion :
@$(CC) --version
# Program the device.
program: $(TARGET).hex $(TARGET).eep
$(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM)
# Generate avr-gdb config/init file which does the following:
# define the reset signal, load the target file, connect to target, and set
# a breakpoint at main().
gdb-config:
@$(REMOVE) $(GDBINIT_FILE)
@echo define reset >> $(GDBINIT_FILE)
@echo SIGNAL SIGHUP >> $(GDBINIT_FILE)
@echo end >> $(GDBINIT_FILE)
@echo file $(TARGET).elf >> $(GDBINIT_FILE)
@echo target remote $(DEBUG_HOST):$(DEBUG_PORT) >> $(GDBINIT_FILE)
ifeq ($(DEBUG_BACKEND),simulavr)
@echo load >> $(GDBINIT_FILE)
endif
@echo break main >> $(GDBINIT_FILE)
debug: gdb-config $(TARGET).elf
ifeq ($(DEBUG_BACKEND), avarice)
@echo Starting AVaRICE - Press enter when "waiting to connect" message displays.
@$(WINSHELL) /c start avarice --jtag $(JTAG_DEV) --erase --program --file \
$(TARGET).elf $(DEBUG_HOST):$(DEBUG_PORT)
@$(WINSHELL) /c pause
else
@$(WINSHELL) /c start simulavr --gdbserver --device $(MCU) --clock-freq \
$(DEBUG_MFREQ) --port $(DEBUG_PORT)
endif
@$(WINSHELL) /c start avr-$(DEBUG_UI) --command=$(GDBINIT_FILE)
# Convert ELF to COFF for use in debugging / simulating in AVR Studio or VMLAB.
COFFCONVERT = $(OBJCOPY) --debugging
COFFCONVERT += --change-section-address .data-0x800000
COFFCONVERT += --change-section-address .bss-0x800000
COFFCONVERT += --change-section-address .noinit-0x800000
COFFCONVERT += --change-section-address .eeprom-0x810000
coff: $(TARGET).elf
@echo
@echo $(MSG_COFF) $(TARGET).cof
$(COFFCONVERT) -O coff-avr $< $(TARGET).cof
extcoff: $(TARGET).elf
@echo
@echo $(MSG_EXTENDED_COFF) $(TARGET).cof
$(COFFCONVERT) -O coff-ext-avr $< $(TARGET).cof
# Create final output files (.hex, .eep) from ELF output file.
%.hex: %.elf
@echo
@echo $(MSG_FLASH) $@
$(OBJCOPY) -O $(FORMAT) -R .eeprom -R .fuse -R .lock $< $@
%.eep: %.elf
@echo
@echo $(MSG_EEPROM) $@
-$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \
--change-section-lma .eeprom=0 --no-change-warnings -O $(FORMAT) $< $@ || exit 0
# Create extended listing file from ELF output file.
%.lss: %.elf
@echo
@echo $(MSG_EXTENDED_LISTING) $@
$(OBJDUMP) -h -S -z $< > $@
# Create a symbol table from ELF output file.
%.sym: %.elf
@echo
@echo $(MSG_SYMBOL_TABLE) $@
$(NM) -n $< > $@
# Create library from object files.
.SECONDARY : $(TARGET).a
.PRECIOUS : $(OBJ)
%.a: $(OBJ)
@echo
@echo $(MSG_CREATING_LIBRARY) $@
$(AR) $@ $(OBJ)
# Link: create ELF output file from object files.
.SECONDARY : $(TARGET).elf
.PRECIOUS : $(OBJ)
%.elf: $(OBJ)
@echo
@echo $(MSG_LINKING) $@
$(CC) $(ALL_CFLAGS) $^ --output $@ $(LDFLAGS)
# Compile: create object files from C source files.
$(OBJDIR)/%.o : %.c
@echo
@echo $(MSG_COMPILING) $<
$(CC) -c $(ALL_CFLAGS) $< -o $@
# Compile: create object files from C++ source files.
$(OBJDIR)/%.o : %.cpp
@echo
@echo $(MSG_COMPILING_CPP) $<
$(CC) -c $(ALL_CPPFLAGS) $< -o $@
# Compile: create assembler files from C source files.
%.s : %.c
$(CC) -S $(ALL_CFLAGS) $< -o $@
# Compile: create assembler files from C++ source files.
%.s : %.cpp
$(CC) -S $(ALL_CPPFLAGS) $< -o $@
# Assemble: create object files from assembler source files.
$(OBJDIR)/%.o : %.S
@echo
@echo $(MSG_ASSEMBLING) $<
$(CC) -c $(ALL_ASFLAGS) $< -o $@
# Create preprocessed source for use in sending a bug report.
%.i : %.c
$(CC) -E -mmcu=$(MCU) -I. $(CFLAGS) $< -o $@
# Target: clean project.
clean: begin clean_list end
clean_list :
@echo
@echo $(MSG_CLEANING)
$(REMOVE) $(TARGET).hex
$(REMOVE) $(TARGET).eep
$(REMOVE) $(TARGET).cof
$(REMOVE) $(TARGET).elf
$(REMOVE) $(TARGET).map
$(REMOVE) $(TARGET).sym
$(REMOVE) $(TARGET).lss
$(REMOVE) $(SRC:%.c=$(OBJDIR)/%.o) $(CPPSRC:%.cpp=$(OBJDIR)/%.o) $(ASRC:%.S=$(OBJDIR)/%.o)
$(REMOVE) $(SRC:%.c=$(OBJDIR)/%.lst) $(CPPSRC:%.cpp=$(OBJDIR)/%.lst) $(ASRC:%.S=$(OBJDIR)/%.lst)
$(REMOVE) $(SRC:.c=.s)
$(REMOVE) $(SRC:.c=.d)
$(REMOVE) $(SRC:.c=.i)
$(REMOVEDIR) .dep
doxygen:
@echo Generating Project Documentation \($(TARGET)\)...
@doxygen Doxygen.conf
@echo Documentation Generation Complete.
clean_doxygen:
rm -rf Documentation
checksource:
@for f in $(SRC) $(CPPSRC) $(ASRC); do \
if [ -f $$f ]; then \
echo "Found Source File: $$f" ; \
else \
echo "Source File Not Found: $$f" ; \
fi; done
# Create object files directory
$(shell mkdir $(OBJDIR) 2>/dev/null)
# Include the dependency files.
-include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*)
# Listing of phony targets.
.PHONY : all begin finish end sizebefore sizeafter gccversion \
build elf hex eep lss sym coff extcoff doxygen clean \
clean_list clean_doxygen program debug gdb-config checksource

View File

@ -1,251 +0,0 @@
#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)
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
::);
}
uint8_t _flashbuf[128];
uint8_t _inSync;
uint8_t _ok;
extern volatile uint8_t _ejected;
extern volatile uint16_t _timeout;
void Program(uint8_t ep, uint16_t page, uint8_t count)
{
uint8_t write = page < 30*1024; // Don't write over firmware please
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;
uint16_t* p = (uint16_t*)page;
uint16_t* b = (uint16_t*)_flashbuf;
for (uint8_t i = 0; i < count; i++)
boot_page_fill(p++, b[i]);
boot_page_write(page);
boot_spm_busy_wait();
boot_rww_enable ();
}
void StartSketch();
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 uint8_t _readSize[] PROGMEM;
const uint8_t _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 uint8_t _consts[] PROGMEM;
const uint8_t _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);
int main(void) __attribute__ ((naked));
// STK500v1 main loop, very similar to optiboot in protocol and implementation
int main()
{
uint8_t MCUSR_state = MCUSR; // store the reason for the reset
MCUSR &= ~(1 << WDRF); // must clear the watchdog reset flag before disabling and reenabling WDT
wdt_disable();
TX_LED_OFF();
RX_LED_OFF();
L_LED_OFF();
if (MCUSR_state & (1<<WDRF) && (pgm_read_word(0) != 0xFFFF)) {
StartSketch(); // if the reset was caused by WDT and if a sketch is already present then run the sketch instead of the bootloader
}
BOARD_INIT();
USBInit();
_inSync = STK_INSYNC;
_ok = STK_OK;
if (pgm_read_word(0) != 0xFFFF)
_ejected = 1;
for(;;)
{
uint8_t* packet = _flashbuf;
uint16_t address = 0;
for (;;)
{
uint8_t cmd = getch();
// Read packet contents
uint8_t len;
const uint8_t* rs = _readSize;
for(;;)
{
uint8_t c = pgm_read_byte(rs++);
len = pgm_read_byte(rs++);
if (c == cmd || c == 0)
break;
}
_timeout = 0;
// Read params
Recv(CDC_RX,packet,len);
// Send a response
uint8_t send = 0;
const uint8_t* pgm = _consts+7; // 0
if (STK_GET_PARAMETER == cmd)
{
uint8_t i = packet[0] - 0x80;
if (i > 2)
i = (i == 0x18) ? 3 : 4; // 0x80:HW_VER,0x81:SW_MAJOR,0x82:SW_MINOR,0x18:3 or 0
pgm = _consts + i + 3;
send = 1;
}
else if (STK_UNIVERSAL == cmd)
{
if (packet[0] == 0x30)
pgm = _consts + packet[2]; // read signature
send = 1;
}
// Read signature bytes
else if (STK_READ_SIGN == cmd)
{
pgm = _consts;
send = 3;
}
else if (STK_LOAD_ADDRESS == cmd)
{
address = *((uint16_t*)packet); // word addresses
address += address;
}
else if (STK_PROG_PAGE == cmd)
{
Program(CDC_RX,address,packet[1]);
}
else if (STK_READ_PAGE == cmd)
{
send = packet[1];
pgm = (const uint8_t*)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
uint16_t _pulse;
void LEDPulse()
{
_pulse += 4;
uint8_t p = _pulse >> 9;
if (p > 63)
p = 127-p;
p += p;
if (((uint8_t)_pulse) > p)
L_LED_OFF();
else
L_LED_ON();
}
void StartSketch()
{
TX_LED_OFF(); // switch off the RX and TX LEDs before starting the user sketch
RX_LED_OFF();
UDCON = 1; // Detach USB
UDIEN = 0;
asm volatile ( // Reset vector to run firmware
"clr r30\n"
"clr r31\n"
"ijmp\n"
::);
}
void Reset()
{
wdt_enable(WDTO_15MS); // reset the microcontroller to reinitialize all IO and other registers
for (;;)
;
}

View File

@ -1,49 +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>
#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_BOOTLOADER 0x0034
#define USB_PID_MICRO_BOOTLOADER 0x0035
#define USB_VID 0x2341 // arduino LLC vid
#define USB_PID ARDUINO_MODEL_PID // passed in by Makefile - 0x0034 for Leonardo, 0x0035 for MIcro
#define USB_SERIAL_STRING '0','0','0','0','0','0','0','0','1','7','0','1'
#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 L_LED_OFF() PORTC &= ~(1<<7)
#define L_LED_ON() PORTC |= (1<<7)
#define TX_LED_OFF() PORTD |= (1<<5)
#define TX_LED_ON() PORTD &= ~(1<<5)
#define RX_LED_OFF() PORTB |= (1<<0)
#define RX_LED_ON() PORTB &= ~(1<<0)
#define TRANSFER_PGM 0x80
#define TRANSFER_RELEASE 0x40
#define TRANSFER_ZERO 0x20
void Transfer(uint8_t ep, const uint8_t* data, int len);
void Recv(uint8_t ep, uint8_t* dst, uint8_t len);
void Program(uint8_t ep, uint16_t page, uint8_t count);
/* HID is not fully-supported in the bootloader - can be enabled
for testing, but note the descriptor report and other parts are
not complete */
#define HID_ENABLED
#include "USBCore.h"
#include "USBDesc.h"

View File

@ -1,512 +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.
*/
#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
uint8_t TxLEDPulse; /**< Milliseconds remaining for data Tx LED pulse */
uint8_t RxLEDPulse; /**< Milliseconds remaining for data Rx LED pulse */
void Reset();
//==================================================================
//==================================================================
typedef struct
{
uint32_t dwDTERate;
uint8_t bCharFormat;
uint8_t bParityType;
uint8_t bDataBits;
uint8_t lineState;
} LineInfo;
static volatile LineInfo _usbLineInfo = { 57600, 0x00, 0x00, 0x00, 0x00 };
//==================================================================
//==================================================================
// 4 bytes of RAM
volatile uint8_t _usbConfiguration;
volatile uint8_t _ejected;
volatile uint16_t _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 uint8_t 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 uint8_t* data, uint8_t count)
{
TX_LED_ON(); // light the TX LED
TxLEDPulse = TX_RX_LED_PULSE_MS;
while (count--)
UEDATX = *data++;
}
void Recv(volatile uint8_t* data, uint8_t count)
{
RX_LED_ON(); // light the RX LED
RxLEDPulse = TX_RX_LED_PULSE_MS;
while (count--)
*data++ = UEDATX;
}
static inline uint8_t Recv8()
{
RX_LED_ON(); // light the RX LED
RxLEDPulse = TX_RX_LED_PULSE_MS;
return UEDATX;
}
static inline void Send8(uint8_t d)
{
TX_LED_ON(); // light the TX LED
TxLEDPulse = TX_RX_LED_PULSE_MS;
UEDATX = d;
}
static inline void SetEP(uint8_t ep)
{
UENUM = ep;
}
static inline uint8_t FifoByteCount()
{
return UEBCLX;
}
static inline uint8_t 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 uint8_t ReadWriteAllowed()
{
return UEINTX & (1<<RWAL);
}
static inline uint8_t Stalled()
{
return UEINTX & (1<<STALLEDI);
}
static inline uint8_t 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 uint8_t FrameNumber()
{
return UDFNUML;
}
//==================================================================
//==================================================================
#define EP_SINGLE_64 0x32 // EP0
#define EP_DOUBLE_64 0x36 // Other endpoints
static void InitEP(uint8_t index, uint8_t type, uint8_t size)
{
UENUM = index;
UECONX = 1;
UECFG0X = type;
UECFG1X = size;
}
// API
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
;
USBCON = ((1<<USBE)|(1<<OTGPADE)); // start USB clock
UDCON = 0; // enable attach resistor
}
uint8_t USBGetConfiguration(void)
{
return _usbConfiguration;
}
uint8_t HasData(uint8_t ep)
{
SetEP(ep);
return ReadWriteAllowed(); // count in fifo
}
int USBGetChar();
void Recv(uint8_t ep, uint8_t* dst, uint8_t len)
{
SetEP(ep);
while (len--)
{
while (!ReadWriteAllowed())
;
*dst++ = Recv8();
if (!ReadWriteAllowed()) // release empty buffer
ReleaseRX();
}
}
// Transmit a packet to endpoint
void Transfer(uint8_t ep, const uint8_t* data, int len)
{
uint8_t zero = ep & TRANSFER_ZERO;
SetEP(ep & 7);
while (len--)
{
while (!ReadWriteAllowed())
; // TODO Check for STALL etc
uint8_t d = (ep & TRANSFER_PGM) ? pgm_read_byte(data) : data[0];
data++;
if (zero)
d = 0;
Send8(d);
if (!ReadWriteAllowed())
ReleaseTX();
}
if (ep & TRANSFER_RELEASE)
ReleaseTX();
}
extern const uint8_t _initEndpoints[] PROGMEM;
const uint8_t _initEndpoints[] =
{
0,
EP_TYPE_INTERRUPT_IN, // CDC_ENDPOINT_ACM
EP_TYPE_BULK_OUT, // CDC_ENDPOINT_OUT
EP_TYPE_BULK_IN, // CDC_ENDPOINT_IN
#ifdef HID_ENABLED
EP_TYPE_INTERRUPT_IN, // HID_ENDPOINT_INT
#endif
};
static void InitEndpoints()
{
for (uint8_t i = 1; i < sizeof(_initEndpoints); i++)
{
UENUM = i;
UECONX = 1;
UECFG0X = pgm_read_byte(_initEndpoints+i);
UECFG1X = EP_DOUBLE_64;
}
UERST = 0x7E; // And reset them
UERST = 0;
}
typedef struct
{
uint8_t bmRequestType;
uint8_t bRequest;
uint8_t wValueL;
uint8_t wValueH;
uint16_t wIndex;
uint16_t wLength;
} Setup;
Setup _setup;
//bool USBHook(Setup& setup)
bool USBHook()
{
Setup& setup = _setup;
uint8_t r = setup.bRequest;
// CDC Requests
if (CDC_GET_LINE_CODING == r)
{
Send((const volatile uint8_t*)&_usbLineInfo,7);
}
else if (CDC_SET_LINE_CODING == r)
{
WaitOUT();
Recv((volatile uint8_t*)&_usbLineInfo,7);
ClearOUT();
}
else if (CDC_SET_CONTROL_LINE_STATE == r)
{
_usbLineInfo.lineState = setup.wValueL;
}
return true;
}
extern const uint8_t _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 uint8_t _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
};
uint8_t _cdcComposite = 0;
bool SendDescriptor()
{
Setup& setup = _setup;
uint16_t desc_length = 0;
const uint8_t* desc_addr = 0;
uint8_t t = setup.wValueH;
if (0x22 == t)
{
#ifdef HID_ENABLED
desc_addr = _rawHID;
desc_length = sizeof(desc_length);
#endif
} else if (USB_DEVICE_DESCRIPTOR_TYPE == t)
{
if (setup.wLength == 8)
_cdcComposite = 1;
desc_addr = _cdcComposite ? (const uint8_t*)&USB_DeviceDescriptorA : (const uint8_t*)&USB_DeviceDescriptor;
}
else if (USB_CONFIGURATION_DESCRIPTOR_TYPE == t)
{
desc_addr = (const uint8_t*)&USB_ConfigDescriptor;
desc_length = sizeof(USB_ConfigDescriptor);
}
else if (USB_STRING_DESCRIPTOR_TYPE == t)
{
if (setup.wValueL == 0)
desc_addr = (const uint8_t*)&STRING_LANGUAGE;
else if (setup.wValueL == IPRODUCT)
desc_addr = (const uint8_t*)&STRING_IPRODUCT;
else if (setup.wValueL == ISERIAL)
desc_addr = (const uint8_t*)&STRING_SERIAL;
else if (setup.wValueL == IMANUFACTURER)
desc_addr = (const uint8_t*)&STRING_IMANUFACTURER;
else
return false;
} else
return false;
if (desc_length == 0)
desc_length = pgm_read_byte(desc_addr);
if (setup.wLength < desc_length)
desc_length = setup.wLength;
// Send descriptor
// EP0 is 64 bytes long
// RWAL and FIFOCON don't work on EP0
uint16_t n = 0;
do
{
if (!WaitForINOrOUT())
return false;
Send8(pgm_read_byte(&desc_addr[n++]));
uint8_t 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((uint8_t*)&setup,8);
ClearSetupInt();
if (setup.bmRequestType & DEVICETOHOST)
WaitIN();
else
ClearIN();
bool ok = true;
uint8_t 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()
{
uint8_t 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))
TX_LED_OFF();
if (RxLEDPulse && !(--RxLEDPulse))
RX_LED_OFF();
if (!_ejected)
_timeout = 0;
}
}
void LEDPulse();
int USBGetChar()
{
for(;;)
{
USBSetupInterrupt();
USBGeneralInterrupt();
// Read a char
if (HasData(CDC_RX))
{
uint8_t c = Recv8();
if (!ReadWriteAllowed())
ReleaseRX();
return c;
}
if (!--_timeout) {
Reset();
}
_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 {
uint8_t len; // 18
uint8_t dtype; // 1 USB_DEVICE_DESCRIPTOR_TYPE
uint16_t usbVersion; // 0x200
uint8_t deviceClass;
uint8_t deviceSubClass;
uint8_t deviceProtocol;
uint8_t packetSize0; // Packet 0
uint16_t idVendor;
uint16_t idProduct;
uint16_t deviceVersion; // 0x100
uint8_t iManufacturer;
uint8_t iProduct;
uint8_t iSerialNumber;
uint8_t bNumConfigurations;
} DeviceDescriptor;
// Config
typedef struct {
uint8_t len; // 9
uint8_t dtype; // 2
uint16_t clen; // total length
uint8_t numInterfaces;
uint8_t config;
uint8_t iconfig;
uint8_t attributes;
uint8_t maxPower;
} ConfigDescriptor;
// String
// Interface
typedef struct
{
uint8_t len; // 9
uint8_t dtype; // 4
uint8_t number;
uint8_t alternate;
uint8_t numEndpoints;
uint8_t interfaceClass;
uint8_t interfaceSubClass;
uint8_t protocol;
uint8_t iInterface;
} InterfaceDescriptor;
// Endpoint
typedef struct
{
uint8_t len; // 7
uint8_t dtype; // 5
uint8_t addr;
uint8_t attr;
uint16_t packetSize;
uint8_t interval;
} EndpointDescriptor;
// Interface Association Descriptor
// Used to bind 2 interfaces together in CDC compostite device
typedef struct
{
uint8_t len; // 8
uint8_t dtype; // 11
uint8_t firstInterface;
uint8_t interfaceCount;
uint8_t functionClass;
uint8_t funtionSubClass;
uint8_t functionProtocol;
uint8_t iInterface;
} IADDescriptor;
// CDC CS interface descriptor
typedef struct
{
uint8_t len; // 5
uint8_t dtype; // 0x24
uint8_t subtype;
uint8_t d0;
uint8_t d1;
} CDCCSInterfaceDescriptor;
typedef struct
{
uint8_t len; // 4
uint8_t dtype; // 0x24
uint8_t subtype;
uint8_t 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
{
uint8_t len; // 9
uint8_t dtype; // 0x21
uint8_t addr;
uint8_t versionL; // 0x101
uint8_t versionH; // 0x101
uint8_t country;
uint8_t desctype; // 0x22 report
uint8_t descLenL;
uint8_t descLenH;
} HIDDescDescriptor;
typedef struct
{
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,83 +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 uint16_t STRING_LANGUAGE[2] = {
(3<<8) | (2+2),
0x0409 // English
};
const uint16_t STRING_SERIAL[13] = {
(3<<8) | (2+2*12),
USB_SERIAL_STRING
};
const uint16_t STRING_IPRODUCT[28] = {
(3<<8) | (2+2*27),
#if USB_PID == USB_PID_LEONARDO_BOOTLOADER
'A','r','d','u','i','n','o',' ','L','e','o','n','a','r','d','o',' ','b','o','o','t','l','o','a','d','e','r'
#elif USB_PID == USB_PID_MICRO_BOOTLOADER
'A','r','d','u','i','n','o',' ','M','i','c','r','o',' ','b','o','o','t','l','o','a','d','e','r',' ',' ',' '
#endif
};
const uint16_t STRING_IMANUFACTURER[12] = {
(3<<8) | (2+2*11),
'A','r','d','u','i','n','o',' ','L','L','C'
};
DeviceDescriptor USB_DeviceDescriptorA = D_DEVICE(0X02,0X00,0X00,64,USB_VID,USB_PID,0x100,0,IPRODUCT,ISERIAL,1);
DeviceDescriptor USB_DeviceDescriptor = D_DEVICE(0x00,0x00,0x00,64,USB_VID,USB_PID,0x100,0,IPRODUCT,ISERIAL,1);
Config USB_ConfigDescriptor =
{
D_CONFIG(sizeof(Config),INTERFACE_COUNT),
// 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)
},
#ifdef HID_ENABLED
// HID
{
D_INTERFACE(HID_INTERFACE,1,3,0,0),
D_HIDREPORT(30),
D_ENDPOINT(USB_ENDPOINT_IN (HID_ENDPOINT_INT),USB_ENDPOINT_TYPE_INTERRUPT,0x40,0x40)
}
#endif
};

View File

@ -1,60 +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.
*/
#ifndef HID_ENABLED // HID is NOT enabled
#define CDC_ACM_INTERFACE 0 // CDC ACM
#define CDC_DATA_INTERFACE 1 // CDC Data
#define CDC_ENDPOINT_ACM 1
#define CDC_ENDPOINT_OUT 2
#define CDC_ENDPOINT_IN 3
#define INTERFACE_COUNT 2 // 2 for CDC
#else // HID is enabled
#define CDC_ACM_INTERFACE 0 // CDC ACM
#define CDC_DATA_INTERFACE 1 // CDC Data
#define CDC_ENDPOINT_ACM 1
#define CDC_ENDPOINT_OUT 2
#define CDC_ENDPOINT_IN 3
#define HID_INTERFACE 2 // HID Interface
#define HID_ENDPOINT_INT 4
#define INTERFACE_COUNT 3 // 2 for CDC + 1 for hid
#endif
typedef struct
{
ConfigDescriptor config;
CDCDescriptor cdc;
#ifdef HID_ENABLED
HIDDescriptor hid;
#endif
} Config;
extern Config USB_ConfigDescriptor PROGMEM;
extern DeviceDescriptor USB_DeviceDescriptor PROGMEM;
extern DeviceDescriptor USB_DeviceDescriptorA PROGMEM;
extern const uint16_t STRING_LANGUAGE[2] PROGMEM;
extern const uint16_t STRING_IPRODUCT[28] PROGMEM;
extern const uint16_t STRING_IMANUFACTURER[12] PROGMEM;
extern const uint16_t STRING_SERIAL[13] PROGMEM;
#define IMANUFACTURER 1
#define IPRODUCT 2
#define ISERIAL 3
#define CDC_TX CDC_ENDPOINT_IN
#define CDC_RX CDC_ENDPOINT_OUT

View File

@ -1,717 +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 doxygen = Generate DoxyGen documentation for the project (must have
# DoxyGen installed)
#
# make debug = Start either simulavr or avarice as specified for debugging,
# with avr-gdb or avr-insight as the front end for debugging.
#
# make filename.s = Just compile filename.c into the assembler code only.
#
# make filename.i = Create a preprocessed source file for use in submitting
# bug reports to the GCC project.
#
# To rebuild project do "make clean" then "make all".
#----------------------------------------------------------------------------
# MCU name
MCU = atmega32u4
# Target architecture (see library "Board Types" documentation).
ARCH = AVR8
# Target board (see library "Board Types" documentation, NONE for projects not requiring
# LUFA board drivers). If USER is selected, put custom board drivers in a directory called
# "Board" inside the application directory.
BOARD = USER
# Processor frequency.
# This will define a symbol, F_CPU, in all source code files equal to the
# processor frequency in Hz. You can then use this symbol in your source code to
# calculate timings. Do NOT tack on a 'UL' at the end, this will be done
# automatically to create a 32-bit value in your source code.
#
# This will be an integer division of F_USB below, as it is sourced by
# F_USB after it has run through any CPU prescalers. Note that this value
# does not *change* the processor frequency - it should merely be updated to
# reflect the processor speed set externally so that the code can use accurate
# software delays.
F_CPU = 16000000
# Input clock frequency.
# This will define a symbol, F_USB, in all source code files equal to the
# input clock frequency (before any prescaling is performed) in Hz. This value may
# differ from F_CPU if prescaling is used on the latter, and is required as the
# raw input clock is fed directly to the PLL sections of the AVR for high speed
# clock generation for the USB and other AVR subsections. Do NOT tack on a 'UL'
# at the end, this will be done automatically to create a 32-bit value in your
# source code.
#
# If no clock division is performed on the input clock inside the AVR (via the
# CPU clock adjust registers or the clock division fuses), this will be equal to F_CPU.
F_USB = $(F_CPU)
# Starting byte address of the bootloader, as a byte address - computed via the formula
# BOOT_START = ((FLASH_SIZE_KB - BOOT_SECTION_SIZE_KB) * 1024)
#
# Note that the bootloader size and start address given in AVRStudio is in words and not
# bytes, and so will need to be doubled to obtain the byte address needed by AVR-GCC.
FLASH_SIZE_KB = 32
BOOT_SECTION_SIZE_KB = 4
BOOT_START = 0x$(shell echo "obase=16; ($(FLASH_SIZE_KB) - $(BOOT_SECTION_SIZE_KB)) * 1024" | bc)
# Output format. (can be srec, ihex, binary)
FORMAT = ihex
# Target file name (without extension).
TARGET = Caterina
# Object files directory
# To put object files in current directory, use a dot (.), do NOT make
# this an empty or blank macro!
OBJDIR = .
# Path to the LUFA library
LUFA_PATH = ../../../../../LUFA-111009
# LUFA library compile-time options and predefined tokens
LUFA_OPTS = -D USB_DEVICE_ONLY
LUFA_OPTS += -D DEVICE_STATE_AS_GPIOR=0
LUFA_OPTS += -D ORDERED_EP_CONFIG
LUFA_OPTS += -D FIXED_CONTROL_ENDPOINT_SIZE=8
LUFA_OPTS += -D FIXED_NUM_CONFIGURATIONS=1
LUFA_OPTS += -D USE_RAM_DESCRIPTORS
LUFA_OPTS += -D USE_STATIC_OPTIONS="(USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL)"
LUFA_OPTS += -D NO_INTERNAL_SERIAL
LUFA_OPTS += -D NO_DEVICE_SELF_POWER
LUFA_OPTS += -D NO_DEVICE_REMOTE_WAKEUP
LUFA_OPTS += -D NO_SOF_EVENTS
#LUFA_OPTS += -D NO_BLOCK_SUPPORT
#LUFA_OPTS += -D NO_EEPROM_BYTE_SUPPORT
#LUFA_OPTS += -D NO_FLASH_BYTE_SUPPORT
#LUFA_OPTS += -D NO_LOCK_BYTE_WRITE_SUPPORT
# Create the LUFA source path variables by including the LUFA root makefile
include $(LUFA_PATH)/LUFA/makefile
# List C source files here. (C dependencies are automatically generated.)
SRC = $(TARGET).c \
Descriptors.c \
$(LUFA_SRC_USB) \
# List C++ source files here. (C dependencies are automatically generated.)
CPPSRC =
# List Assembler source files here.
# Make them always end in a capital .S. Files ending in a lowercase .s
# will not be considered source files but generated files (assembler
# output from the compiler), and will be deleted upon "make clean"!
# Even though the DOS/Win* filesystem matches both .s and .S the same,
# it will preserve the spelling of the filenames, and gcc itself does
# care about how the name is spelled on its command-line.
ASRC =
# Optimization level, can be [0, 1, 2, 3, s].
# 0 = turn off optimization. s = optimize for size.
# (Note: 3 is not always the best optimization level. See avr-libc FAQ.)
OPT = s
# Debugging format.
# Native formats for AVR-GCC's -g are dwarf-2 [default] or stabs.
# AVR Studio 4.10 requires dwarf-2.
# AVR [Extended] COFF format requires stabs, plus an avr-objcopy run.
DEBUG = dwarf-2
# List any extra directories to look for include files here.
# Each directory must be seperated by a space.
# Use forward slashes for directory separators.
# For a directory that has spaces, enclose it in quotes.
EXTRAINCDIRS = $(LUFA_PATH)/
# Compiler flag to set the C Standard level.
# c89 = "ANSI" C
# gnu89 = c89 plus GCC extensions
# c99 = ISO C99 standard (not yet fully implemented)
# gnu99 = c99 plus GCC extensions
CSTANDARD = -std=c99
# Place -D or -U options here for C sources
CDEFS = -DF_CPU=$(F_CPU)UL
CDEFS += -DF_USB=$(F_USB)UL
CDEFS += -DBOARD=BOARD_$(BOARD) -DARCH=ARCH_$(ARCH)
CDEFS += -DBOOT_START_ADDR=$(BOOT_START)UL
CDEFS += $(LUFA_OPTS)
# Place -D or -U options here for ASM sources
ADEFS = -DF_CPU=$(F_CPU)
ADEFS += -DF_USB=$(F_USB)UL
ADEFS += -DBOARD=BOARD_$(BOARD)
ADEFS += -DBOOT_START_ADDR=$(BOOT_START)UL
ADEFS += $(LUFA_OPTS)
# Place -D or -U options here for C++ sources
CPPDEFS = -DF_CPU=$(F_CPU)UL
CPPDEFS += -DF_USB=$(F_USB)UL
CPPDEFS += -DBOARD=BOARD_$(BOARD)
CPPDEFS += -DBOOT_START_ADDR=$(BOOT_START)UL
CPPDEFS += $(LUFA_OPTS)
#CPPDEFS += -D__STDC_LIMIT_MACROS
#CPPDEFS += -D__STDC_CONSTANT_MACROS
#---------------- Compiler Options C ----------------
# -g*: generate debugging information
# -O*: optimization level
# -f...: tuning, see GCC manual and avr-libc documentation
# -Wall...: warning level
# -Wa,...: tell GCC to pass this to the assembler.
# -adhlns...: create assembler listing
CFLAGS = -g$(DEBUG)
CFLAGS += $(CDEFS)
CFLAGS += -O$(OPT)
CFLAGS += -funsigned-char
CFLAGS += -funsigned-bitfields
CFLAGS += -ffunction-sections
CFLAGS += -fno-inline-small-functions
CFLAGS += -fpack-struct
CFLAGS += -fshort-enums
CFLAGS += -fno-strict-aliasing
CFLAGS += -Wall
CFLAGS += -Wstrict-prototypes
#CFLAGS += -mshort-calls
#CFLAGS += -fno-unit-at-a-time
#CFLAGS += -Wundef
#CFLAGS += -Wunreachable-code
#CFLAGS += -Wsign-compare
CFLAGS += -Wa,-adhlns=$(<:%.c=$(OBJDIR)/%.lst)
CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS))
CFLAGS += $(CSTANDARD)
#---------------- Compiler Options C++ ----------------
# -g*: generate debugging information
# -O*: optimization level
# -f...: tuning, see GCC manual and avr-libc documentation
# -Wall...: warning level
# -Wa,...: tell GCC to pass this to the assembler.
# -adhlns...: create assembler listing
CPPFLAGS = -g$(DEBUG)
CPPFLAGS += $(CPPDEFS)
CPPFLAGS += -O$(OPT)
CPPFLAGS += -funsigned-char
CPPFLAGS += -funsigned-bitfields
CPPFLAGS += -fpack-struct
CPPFLAGS += -fshort-enums
CPPFLAGS += -fno-exceptions
CPPFLAGS += -Wall
CPPFLAGS += -Wundef
#CPPFLAGS += -mshort-calls
#CPPFLAGS += -fno-unit-at-a-time
#CPPFLAGS += -Wstrict-prototypes
#CPPFLAGS += -Wunreachable-code
#CPPFLAGS += -Wsign-compare
CPPFLAGS += -Wa,-adhlns=$(<:%.cpp=$(OBJDIR)/%.lst)
CPPFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS))
#CPPFLAGS += $(CSTANDARD)
#---------------- Assembler Options ----------------
# -Wa,...: tell GCC to pass this to the assembler.
# -adhlns: create listing
# -gstabs: have the assembler create line number information; note that
# for use in COFF files, additional information about filenames
# and function names needs to be present in the assembler source
# files -- see avr-libc docs [FIXME: not yet described there]
# -listing-cont-lines: Sets the maximum number of continuation lines of hex
# dump that will be displayed for a given single line of source input.
ASFLAGS = $(ADEFS) -Wa,-adhlns=$(<:%.S=$(OBJDIR)/%.lst),-gstabs,--listing-cont-lines=100
#---------------- Library Options ----------------
# Minimalistic printf version
PRINTF_LIB_MIN = -Wl,-u,vfprintf -lprintf_min
# Floating point printf version (requires MATH_LIB = -lm below)
PRINTF_LIB_FLOAT = -Wl,-u,vfprintf -lprintf_flt
# If this is left blank, then it will use the Standard printf version.
PRINTF_LIB =
#PRINTF_LIB = $(PRINTF_LIB_MIN)
#PRINTF_LIB = $(PRINTF_LIB_FLOAT)
# Minimalistic scanf version
SCANF_LIB_MIN = -Wl,-u,vfscanf -lscanf_min
# Floating point + %[ scanf version (requires MATH_LIB = -lm below)
SCANF_LIB_FLOAT = -Wl,-u,vfscanf -lscanf_flt
# If this is left blank, then it will use the Standard scanf version.
SCANF_LIB =
#SCANF_LIB = $(SCANF_LIB_MIN)
#SCANF_LIB = $(SCANF_LIB_FLOAT)
MATH_LIB = -lm
# List any extra directories to look for libraries here.
# Each directory must be seperated by a space.
# Use forward slashes for directory separators.
# For a directory that has spaces, enclose it in quotes.
EXTRALIBDIRS =
#---------------- External Memory Options ----------------
# 64 KB of external RAM, starting after internal RAM (ATmega128!),
# used for variables (.data/.bss) and heap (malloc()).
#EXTMEMOPTS = -Wl,-Tdata=0x801100,--defsym=__heap_end=0x80ffff
# 64 KB of external RAM, starting after internal RAM (ATmega128!),
# only used for heap (malloc()).
#EXTMEMOPTS = -Wl,--section-start,.data=0x801100,--defsym=__heap_end=0x80ffff
EXTMEMOPTS =
#---------------- Linker Options ----------------
# -Wl,...: tell GCC to pass this to linker.
# -Map: create map file
# --cref: add cross reference to map file
LDFLAGS = -Wl,-Map=$(TARGET).map,--cref
LDFLAGS += -Wl,--section-start=.text=$(BOOT_START)
LDFLAGS += -Wl,--relax
LDFLAGS += -Wl,--gc-sections
LDFLAGS += $(EXTMEMOPTS)
LDFLAGS += $(patsubst %,-L%,$(EXTRALIBDIRS))
LDFLAGS += $(PRINTF_LIB) $(SCANF_LIB) $(MATH_LIB)
#LDFLAGS += -T linker_script.x
#---------------- Programming Options (avrdude) ----------------
# Programming hardware
# Type: avrdude -c ?
# to get a full listing.
#
AVRDUDE_PROGRAMMER = avrispmkII
# com1 = serial port. Use lpt1 to connect to parallel port.
AVRDUDE_PORT = usb
AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex
#AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep
# Uncomment the following if you want avrdude's erase cycle counter.
# Note that this counter needs to be initialized first using -Yn,
# see avrdude manual.
#AVRDUDE_ERASE_COUNTER = -y
# Uncomment the following if you do /not/ wish a verification to be
# performed after programming the device.
#AVRDUDE_NO_VERIFY = -V
# Increase verbosity level. Please use this when submitting bug
# reports about avrdude. See <http://savannah.nongnu.org/projects/avrdude>
# to submit bug reports.
#AVRDUDE_VERBOSE = -v -v
AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER)
AVRDUDE_FLAGS += $(AVRDUDE_NO_VERIFY)
AVRDUDE_FLAGS += $(AVRDUDE_VERBOSE)
AVRDUDE_FLAGS += $(AVRDUDE_ERASE_COUNTER)
#---------------- Debugging Options ----------------
# For simulavr only - target MCU frequency.
DEBUG_MFREQ = $(F_CPU)
# Set the DEBUG_UI to either gdb or insight.
# DEBUG_UI = gdb
DEBUG_UI = insight
# Set the debugging back-end to either avarice, simulavr.
DEBUG_BACKEND = avarice
#DEBUG_BACKEND = simulavr
# GDB Init Filename.
GDBINIT_FILE = __avr_gdbinit
# When using avarice settings for the JTAG
JTAG_DEV = /dev/com1
# Debugging port used to communicate between GDB / avarice / simulavr.
DEBUG_PORT = 4242
# Debugging host used to communicate between GDB / avarice / simulavr, normally
# just set to localhost unless doing some sort of crazy debugging when
# avarice is running on a different computer.
DEBUG_HOST = localhost
#============================================================================
# Define programs and commands.
SHELL = sh
CC = avr-gcc
OBJCOPY = avr-objcopy
OBJDUMP = avr-objdump
SIZE = avr-size
AR = avr-ar rcs
NM = avr-nm
AVRDUDE = /Applications/avrdude -C /Applications/avrdude.conf -B 1
REMOVE = rm -f
REMOVEDIR = rm -rf
COPY = cp
WINSHELL = cmd
# Define Messages
# English
MSG_ERRORS_NONE = Errors: none
MSG_BEGIN = -------- begin --------
MSG_END = -------- end --------
MSG_SIZE_BEFORE = Size before:
MSG_SIZE_AFTER = Size after:
MSG_COFF = Converting to AVR COFF:
MSG_EXTENDED_COFF = Converting to AVR Extended COFF:
MSG_FLASH = Creating load file for Flash:
MSG_EEPROM = Creating load file for EEPROM:
MSG_EXTENDED_LISTING = Creating Extended Listing:
MSG_SYMBOL_TABLE = Creating Symbol Table:
MSG_LINKING = Linking:
MSG_COMPILING = Compiling C:
MSG_COMPILING_CPP = Compiling C++:
MSG_ASSEMBLING = Assembling:
MSG_CLEANING = Cleaning project:
MSG_CREATING_LIBRARY = Creating library:
# Define all object files.
OBJ = $(SRC:%.c=$(OBJDIR)/%.o) $(CPPSRC:%.cpp=$(OBJDIR)/%.o) $(ASRC:%.S=$(OBJDIR)/%.o)
# Define all listing files.
LST = $(SRC:%.c=$(OBJDIR)/%.lst) $(CPPSRC:%.cpp=$(OBJDIR)/%.lst) $(ASRC:%.S=$(OBJDIR)/%.lst)
# Compiler flags to generate dependency files.
GENDEPFLAGS = -MMD -MP -MF .dep/$(@F).d
# Combine all necessary flags and optional flags.
# Add target processor to flags.
ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) $(GENDEPFLAGS)
ALL_CPPFLAGS = -mmcu=$(MCU) -I. -x c++ $(CPPFLAGS) $(GENDEPFLAGS)
ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS)
# Default target.
all: begin gccversion sizebefore build sizeafter end
# Change the build target to build a HEX file or a library.
build: elf hex eep lss sym
#build: lib
elf: $(TARGET).elf
hex: $(TARGET).hex
eep: $(TARGET).eep
lss: $(TARGET).lss
sym: $(TARGET).sym
LIBNAME=lib$(TARGET).a
lib: $(LIBNAME)
# Eye candy.
# AVR Studio 3.x does not check make's exit code but relies on
# the following magic strings to be generated by the compile job.
begin:
@echo
@echo $(MSG_BEGIN)
end:
@echo $(MSG_END)
@echo
# Display size of file.
HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex
ELFSIZE = $(SIZE) $(MCU_FLAG) $(FORMAT_FLAG) $(TARGET).elf
MCU_FLAG = $(shell $(SIZE) --help | grep -- --mcu > /dev/null && echo --mcu=$(MCU) )
FORMAT_FLAG = $(shell $(SIZE) --help | grep -- --format=.*avr > /dev/null && echo --format=avr )
sizebefore:
@if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); \
2>/dev/null; echo; fi
sizeafter:
@if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); \
2>/dev/null; echo; fi
# Display compiler version information.
gccversion :
@$(CC) --version
# Program the device.
program: $(TARGET).hex $(TARGET).eep
$(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM)
# Generate avr-gdb config/init file which does the following:
# define the reset signal, load the target file, connect to target, and set
# a breakpoint at main().
gdb-config:
@$(REMOVE) $(GDBINIT_FILE)
@echo define reset >> $(GDBINIT_FILE)
@echo SIGNAL SIGHUP >> $(GDBINIT_FILE)
@echo end >> $(GDBINIT_FILE)
@echo file $(TARGET).elf >> $(GDBINIT_FILE)
@echo target remote $(DEBUG_HOST):$(DEBUG_PORT) >> $(GDBINIT_FILE)
ifeq ($(DEBUG_BACKEND),simulavr)
@echo load >> $(GDBINIT_FILE)
endif
@echo break main >> $(GDBINIT_FILE)
debug: gdb-config $(TARGET).elf
ifeq ($(DEBUG_BACKEND), avarice)
@echo Starting AVaRICE - Press enter when "waiting to connect" message displays.
@$(WINSHELL) /c start avarice --jtag $(JTAG_DEV) --erase --program --file \
$(TARGET).elf $(DEBUG_HOST):$(DEBUG_PORT)
@$(WINSHELL) /c pause
else
@$(WINSHELL) /c start simulavr --gdbserver --device $(MCU) --clock-freq \
$(DEBUG_MFREQ) --port $(DEBUG_PORT)
endif
@$(WINSHELL) /c start avr-$(DEBUG_UI) --command=$(GDBINIT_FILE)
# Convert ELF to COFF for use in debugging / simulating in AVR Studio or VMLAB.
COFFCONVERT = $(OBJCOPY) --debugging
COFFCONVERT += --change-section-address .data-0x800000
COFFCONVERT += --change-section-address .bss-0x800000
COFFCONVERT += --change-section-address .noinit-0x800000
COFFCONVERT += --change-section-address .eeprom-0x810000
coff: $(TARGET).elf
@echo
@echo $(MSG_COFF) $(TARGET).cof
$(COFFCONVERT) -O coff-avr $< $(TARGET).cof
extcoff: $(TARGET).elf
@echo
@echo $(MSG_EXTENDED_COFF) $(TARGET).cof
$(COFFCONVERT) -O coff-ext-avr $< $(TARGET).cof
# Create final output files (.hex, .eep) from ELF output file.
%.hex: %.elf
@echo
@echo $(MSG_FLASH) $@
$(OBJCOPY) -O $(FORMAT) -R .eeprom -R .fuse -R .lock $< $@
%.eep: %.elf
@echo
@echo $(MSG_EEPROM) $@
-$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \
--change-section-lma .eeprom=0 --no-change-warnings -O $(FORMAT) $< $@ || exit 0
# Create extended listing file from ELF output file.
%.lss: %.elf
@echo
@echo $(MSG_EXTENDED_LISTING) $@
$(OBJDUMP) -h -S -z $< > $@
# Create a symbol table from ELF output file.
%.sym: %.elf
@echo
@echo $(MSG_SYMBOL_TABLE) $@
$(NM) -n $< > $@
# Create library from object files.
.SECONDARY : $(TARGET).a
.PRECIOUS : $(OBJ)
%.a: $(OBJ)
@echo
@echo $(MSG_CREATING_LIBRARY) $@
$(AR) $@ $(OBJ)
# Link: create ELF output file from object files.
.SECONDARY : $(TARGET).elf
.PRECIOUS : $(OBJ)
%.elf: $(OBJ)
@echo
@echo $(MSG_LINKING) $@
$(CC) $(ALL_CFLAGS) $^ --output $@ $(LDFLAGS)
# Compile: create object files from C source files.
$(OBJDIR)/%.o : %.c
@echo
@echo $(MSG_COMPILING) $<
$(CC) -c $(ALL_CFLAGS) $< -o $@
# Compile: create object files from C++ source files.
$(OBJDIR)/%.o : %.cpp
@echo
@echo $(MSG_COMPILING_CPP) $<
$(CC) -c $(ALL_CPPFLAGS) $< -o $@
# Compile: create assembler files from C source files.
%.s : %.c
$(CC) -S $(ALL_CFLAGS) $< -o $@
# Compile: create assembler files from C++ source files.
%.s : %.cpp
$(CC) -S $(ALL_CPPFLAGS) $< -o $@
# Assemble: create object files from assembler source files.
$(OBJDIR)/%.o : %.S
@echo
@echo $(MSG_ASSEMBLING) $<
$(CC) -c $(ALL_ASFLAGS) $< -o $@
# Create preprocessed source for use in sending a bug report.
%.i : %.c
$(CC) -E -mmcu=$(MCU) -I. $(CFLAGS) $< -o $@
# Target: clean project.
clean: begin clean_list end
clean_list :
@echo
@echo $(MSG_CLEANING)
$(REMOVE) $(TARGET).hex
$(REMOVE) $(TARGET).eep
$(REMOVE) $(TARGET).cof
$(REMOVE) $(TARGET).elf
$(REMOVE) $(TARGET).map
$(REMOVE) $(TARGET).sym
$(REMOVE) $(TARGET).lss
$(REMOVE) $(SRC:%.c=$(OBJDIR)/%.o) $(CPPSRC:%.cpp=$(OBJDIR)/%.o) $(ASRC:%.S=$(OBJDIR)/%.o)
$(REMOVE) $(SRC:%.c=$(OBJDIR)/%.lst) $(CPPSRC:%.cpp=$(OBJDIR)/%.lst) $(ASRC:%.S=$(OBJDIR)/%.lst)
$(REMOVE) $(SRC:.c=.s)
$(REMOVE) $(SRC:.c=.d)
$(REMOVE) $(SRC:.c=.i)
$(REMOVEDIR) .dep
doxygen:
@echo Generating Project Documentation \($(TARGET)\)...
@doxygen Doxygen.conf
@echo Documentation Generation Complete.
clean_doxygen:
rm -rf Documentation
checksource:
@for f in $(SRC) $(CPPSRC) $(ASRC); do \
if [ -f $$f ]; then \
echo "Found Source File: $$f" ; \
else \
echo "Source File Not Found: $$f" ; \
fi; done
# Create object files directory
$(shell mkdir $(OBJDIR) 2>/dev/null)
# Include the dependency files.
-include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*)
# Listing of phony targets.
.PHONY : all begin finish end sizebefore sizeafter gccversion \
build elf hex eep lss sym coff extcoff doxygen clean \
clean_list clean_doxygen program debug gdb-config checksource