Adds support for USB device functionality for AT90USB and
ATU2/U4 series devices. Support tested on a PJRC TEENSY2++ board with AT90USB1286. Signed-off-by: Rob Lippert <roblip@gmail.com> git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@9487 35acf78f-673a-0410-8e92-d51de3d6d3f4
This commit is contained in:
parent
5928999fd5
commit
06f9534388
|
@ -0,0 +1,562 @@
|
||||||
|
# Hey Emacs, this is a -*- makefile -*-
|
||||||
|
#----------------------------------------------------------------------------
|
||||||
|
# WinAVR Makefile Template written by Eric B. Weddington, J<>rg Wunsch, et al.
|
||||||
|
#
|
||||||
|
# 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
|
||||||
|
#
|
||||||
|
#----------------------------------------------------------------------------
|
||||||
|
# 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 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 = at90usb1286
|
||||||
|
|
||||||
|
# Processor frequency.
|
||||||
|
F_CPU = 16000000
|
||||||
|
|
||||||
|
# Output format. (can be srec, ihex, binary)
|
||||||
|
FORMAT = ihex
|
||||||
|
|
||||||
|
# Target file name (without extension).
|
||||||
|
TARGET = ch
|
||||||
|
|
||||||
|
# Object files directory
|
||||||
|
# To put object files in current directory, use a dot (.), do NOT make
|
||||||
|
# this an empty or blank macro!
|
||||||
|
OBJDIR = .
|
||||||
|
|
||||||
|
# Imported source files
|
||||||
|
CHIBIOS = ../../..
|
||||||
|
include $(CHIBIOS)/os/hal/hal.mk
|
||||||
|
include $(CHIBIOS)/os/hal/boards/PJRC_TEENSY_2PLUSPLUS/board.mk
|
||||||
|
include $(CHIBIOS)/os/hal/ports/AVR/platform.mk
|
||||||
|
include $(CHIBIOS)/os/hal/osal/rt/osal.mk
|
||||||
|
include $(CHIBIOS)/os/rt/rt.mk
|
||||||
|
include $(CHIBIOS)/os/common/ports/AVR/compilers/GCC/mk/port.mk
|
||||||
|
include $(CHIBIOS)/os/hal/lib/streams/streams.mk
|
||||||
|
include $(CHIBIOS)/os/various/shell/shell.mk
|
||||||
|
|
||||||
|
# List C source files here. (C dependencies are automatically generated.)
|
||||||
|
SRC = $(KERNSRC) \
|
||||||
|
$(PORTSRC) \
|
||||||
|
$(OSALSRC) \
|
||||||
|
$(HALSRC) \
|
||||||
|
$(PLATFORMSRC) \
|
||||||
|
$(BOARDSRC) \
|
||||||
|
$(STREAMSSRC) \
|
||||||
|
$(SHELLSRC) \
|
||||||
|
usbcfg.c \
|
||||||
|
main.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 = $(CHIBIOS)/os/license $(PORTINC) $(KERNINC) $(TESTINC) \
|
||||||
|
$(HALINC) $(OSALINC) $(PLATFORMINC) \
|
||||||
|
$(BOARDINC) $(CHIBIOS)/os/various/shell \
|
||||||
|
$(STREAMSINC)
|
||||||
|
|
||||||
|
# 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=gnu11
|
||||||
|
|
||||||
|
# Place -D or -U options here for C sources
|
||||||
|
CDEFS = -DF_CPU=$(F_CPU)UL
|
||||||
|
|
||||||
|
# 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 += -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)
|
||||||
|
CFLAGS += -mrelax
|
||||||
|
|
||||||
|
#---------------- 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_MIN)
|
||||||
|
#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_MIN)
|
||||||
|
#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 += $(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 = arduino
|
||||||
|
|
||||||
|
# com1 = serial port. Use lpt1 to connect to parallel port.
|
||||||
|
AVRDUDE_PORT = /dev/tty.usbserial-A7004IPU
|
||||||
|
|
||||||
|
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)
|
||||||
|
AVRDUDE_FLAGS += -P $(AVRDUDE_PORT)
|
||||||
|
AVRDUDE_FLAGS += -b 57600
|
||||||
|
AVRDUDE_FLAGS += -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 sizeafter end
|
||||||
|
|
||||||
|
# Change the build target to build a HEX file or a library.
|
||||||
|
build: elf hex bin eep lss sym
|
||||||
|
#build: lib
|
||||||
|
|
||||||
|
elf: $(TARGET).elf
|
||||||
|
hex: $(TARGET).hex
|
||||||
|
bin: $(TARGET).bin
|
||||||
|
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) $(TARGET).elf
|
||||||
|
|
||||||
|
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 $< $@
|
||||||
|
|
||||||
|
%.bin: %.elf
|
||||||
|
@echo
|
||||||
|
@echo $(MSG_FLASH) $@
|
||||||
|
$(OBJCOPY) -O binary -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 -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 end
|
||||||
|
|
||||||
|
clean_list :
|
||||||
|
@echo
|
||||||
|
@echo $(MSG_CLEANING)
|
||||||
|
$(REMOVE) $(TARGET).hex
|
||||||
|
$(REMOVE) $(TARGET).bin
|
||||||
|
$(REMOVE) $(TARGET).eep
|
||||||
|
$(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)
|
||||||
|
$(REMOVEDIR) .dep
|
||||||
|
|
||||||
|
# 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 bin eep lss sym coff extcoff \
|
||||||
|
clean clean_list program debug gdb-config
|
|
@ -0,0 +1,549 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2015 Robert Lippert
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file templates/chconf.h
|
||||||
|
* @brief Configuration file template.
|
||||||
|
* @details A copy of this file must be placed in each project directory, it
|
||||||
|
* contains the application specific kernel settings.
|
||||||
|
*
|
||||||
|
* @addtogroup config
|
||||||
|
* @details Kernel related settings and hooks.
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CHCONF_H_
|
||||||
|
#define CHCONF_H_
|
||||||
|
|
||||||
|
#define _CHIBIOS_RT_CONF_
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/**
|
||||||
|
* @name System timers settings
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief System time counter resolution.
|
||||||
|
* @note Allowed values are 16 or 32 bits.
|
||||||
|
*/
|
||||||
|
#define CH_CFG_ST_RESOLUTION 16
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief System tick frequency.
|
||||||
|
* @details Frequency of the system timer that drives the system ticks. This
|
||||||
|
* setting also defines the system tick time unit.
|
||||||
|
*/
|
||||||
|
#define CH_CFG_ST_FREQUENCY 1000
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Time delta constant for the tick-less mode.
|
||||||
|
* @note If this value is zero then the system uses the classic
|
||||||
|
* periodic tick. This value represents the minimum number
|
||||||
|
* of ticks that is safe to specify in a timeout directive.
|
||||||
|
* The value one is not valid, timeouts are rounded up to
|
||||||
|
* this value.
|
||||||
|
*/
|
||||||
|
#define CH_CFG_ST_TIMEDELTA 0
|
||||||
|
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/**
|
||||||
|
* @name Kernel parameters and options
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Round robin interval.
|
||||||
|
* @details This constant is the number of system ticks allowed for the
|
||||||
|
* threads before preemption occurs. Setting this value to zero
|
||||||
|
* disables the preemption for threads with equal priority and the
|
||||||
|
* round robin becomes cooperative. Note that higher priority
|
||||||
|
* threads can still preempt, the kernel is always preemptive.
|
||||||
|
*
|
||||||
|
* @note Disabling the round robin preemption makes the kernel more compact
|
||||||
|
* and generally faster.
|
||||||
|
*/
|
||||||
|
#define CH_CFG_TIME_QUANTUM 20
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Managed RAM size.
|
||||||
|
* @details Size of the RAM area to be managed by the OS. If set to zero
|
||||||
|
* then the whole available RAM is used. The core memory is made
|
||||||
|
* available to the heap allocator and/or can be used directly through
|
||||||
|
* the simplified core memory allocator.
|
||||||
|
*
|
||||||
|
* @note In order to let the OS manage the whole RAM the linker script must
|
||||||
|
* provide the @p __heap_base__ and @p __heap_end__ symbols.
|
||||||
|
* @note Requires @p CH_CFG_USE_MEMCORE.
|
||||||
|
*/
|
||||||
|
#define CH_CFG_MEMCORE_SIZE 1536
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Idle thread automatic spawn suppression.
|
||||||
|
* @details When this option is activated the function @p chSysInit()
|
||||||
|
* does not spawn the idle thread automatically. The application has
|
||||||
|
* then the responsibility to do one of the following:
|
||||||
|
* - Spawn a custom idle thread at priority @p IDLEPRIO.
|
||||||
|
* - Change the main() thread priority to @p IDLEPRIO then enter
|
||||||
|
* an endless loop. In this scenario the @p main() thread acts as
|
||||||
|
* the idle thread.
|
||||||
|
* .
|
||||||
|
* @note Unless an idle thread is spawned the @p main() thread must not
|
||||||
|
* enter a sleep state.
|
||||||
|
*/
|
||||||
|
#define CH_CFG_NO_IDLE_THREAD FALSE
|
||||||
|
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/**
|
||||||
|
* @name Performance options
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief OS optimization.
|
||||||
|
* @details If enabled then time efficient rather than space efficient code
|
||||||
|
* is used when two possible implementations exist.
|
||||||
|
*
|
||||||
|
* @note This is not related to the compiler optimization options.
|
||||||
|
* @note The default is @p TRUE.
|
||||||
|
*/
|
||||||
|
#define CH_CFG_OPTIMIZE_SPEED TRUE
|
||||||
|
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/**
|
||||||
|
* @name Subsystem options
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Time Measurement APIs.
|
||||||
|
* @details If enabled then the time measurement APIs are included in
|
||||||
|
* the kernel.
|
||||||
|
*
|
||||||
|
* @note The default is @p TRUE.
|
||||||
|
*/
|
||||||
|
#define CH_CFG_USE_TM FALSE
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Threads registry APIs.
|
||||||
|
* @details If enabled then the registry APIs are included in the kernel.
|
||||||
|
*
|
||||||
|
* @note The default is @p TRUE.
|
||||||
|
*/
|
||||||
|
#define CH_CFG_USE_REGISTRY TRUE
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Threads synchronization APIs.
|
||||||
|
* @details If enabled then the @p chThdWait() function is included in
|
||||||
|
* the kernel.
|
||||||
|
*
|
||||||
|
* @note The default is @p TRUE.
|
||||||
|
*/
|
||||||
|
#define CH_CFG_USE_WAITEXIT TRUE
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Semaphores APIs.
|
||||||
|
* @details If enabled then the Semaphores APIs are included in the kernel.
|
||||||
|
*
|
||||||
|
* @note The default is @p TRUE.
|
||||||
|
*/
|
||||||
|
#define CH_CFG_USE_SEMAPHORES TRUE
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Semaphores queuing mode.
|
||||||
|
* @details If enabled then the threads are enqueued on semaphores by
|
||||||
|
* priority rather than in FIFO order.
|
||||||
|
*
|
||||||
|
* @note The default is @p FALSE. Enable this if you have special requirements.
|
||||||
|
* @note Requires @p CH_CFG_USE_SEMAPHORES.
|
||||||
|
*/
|
||||||
|
#define CH_CFG_USE_SEMAPHORES_PRIORITY FALSE
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Atomic semaphore API.
|
||||||
|
* @details If enabled then the semaphores the @p chSemSignalWait() API
|
||||||
|
* is included in the kernel.
|
||||||
|
*
|
||||||
|
* @note The default is @p TRUE.
|
||||||
|
* @note Requires @p CH_CFG_USE_SEMAPHORES.
|
||||||
|
*/
|
||||||
|
#define CH_USE_SEMSW TRUE
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Mutexes APIs.
|
||||||
|
* @details If enabled then the mutexes APIs are included in the kernel.
|
||||||
|
*
|
||||||
|
* @note The default is @p TRUE.
|
||||||
|
*/
|
||||||
|
#define CH_CFG_USE_MUTEXES TRUE
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enables recursive behavior on mutexes.
|
||||||
|
* @note Recursive mutexes are heavier and have an increased
|
||||||
|
* memory footprint.
|
||||||
|
*
|
||||||
|
* @note The default is @p FALSE.
|
||||||
|
* @note Requires @p CH_CFG_USE_MUTEXES.
|
||||||
|
*/
|
||||||
|
#define CH_CFG_USE_MUTEXES_RECURSIVE FALSE
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Conditional Variables APIs.
|
||||||
|
* @details If enabled then the conditional variables APIs are included
|
||||||
|
* in the kernel.
|
||||||
|
*
|
||||||
|
* @note The default is @p TRUE.
|
||||||
|
* @note Requires @p CH_CFG_USE_MUTEXES.
|
||||||
|
*/
|
||||||
|
#define CH_CFG_USE_CONDVARS TRUE
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Conditional Variables APIs with timeout.
|
||||||
|
* @details If enabled then the conditional variables APIs with timeout
|
||||||
|
* specification are included in the kernel.
|
||||||
|
*
|
||||||
|
* @note The default is @p TRUE.
|
||||||
|
* @note Requires @p CH_CFG_USE_CONDVARS.
|
||||||
|
*/
|
||||||
|
#define CH_CFG_USE_CONDVARS_TIMEOUT TRUE
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Events Flags APIs.
|
||||||
|
* @details If enabled then the event flags APIs are included in the kernel.
|
||||||
|
*
|
||||||
|
* @note The default is @p TRUE.
|
||||||
|
*/
|
||||||
|
#define CH_CFG_USE_EVENTS TRUE
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Events Flags APIs with timeout.
|
||||||
|
* @details If enabled then the events APIs with timeout specification
|
||||||
|
* are included in the kernel.
|
||||||
|
*
|
||||||
|
* @note The default is @p TRUE.
|
||||||
|
* @note Requires @p CH_CFG_USE_EVENTS.
|
||||||
|
*/
|
||||||
|
#define CH_CFG_USE_EVENTS_TIMEOUT TRUE
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Synchronous Messages APIs.
|
||||||
|
* @details If enabled then the synchronous messages APIs are included
|
||||||
|
* in the kernel.
|
||||||
|
*
|
||||||
|
* @note The default is @p TRUE.
|
||||||
|
*/
|
||||||
|
#define CH_CFG_USE_MESSAGES TRUE
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Synchronous Messages queuing mode.
|
||||||
|
* @details If enabled then messages are served by priority rather than in
|
||||||
|
* FIFO order.
|
||||||
|
*
|
||||||
|
* @note The default is @p FALSE. Enable this if you have special requirements.
|
||||||
|
* @note Requires @p CH_CFG_USE_MESSAGES.
|
||||||
|
*/
|
||||||
|
#define CH_CFG_USE_MESSAGES_PRIORITY FALSE
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Mailboxes APIs.
|
||||||
|
* @details If enabled then the asynchronous messages (mailboxes) APIs are
|
||||||
|
* included in the kernel.
|
||||||
|
*
|
||||||
|
* @note The default is @p TRUE.
|
||||||
|
* @note Requires @p CH_CFG_USE_SEMAPHORES.
|
||||||
|
*/
|
||||||
|
#define CH_CFG_USE_MAILBOXES TRUE
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief I/O Queues APIs.
|
||||||
|
* @details If enabled then the I/O queues APIs are included in the kernel.
|
||||||
|
*
|
||||||
|
* @note The default is @p TRUE.
|
||||||
|
*/
|
||||||
|
#define CH_CFG_USE_QUEUES TRUE
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Core Memory Manager APIs.
|
||||||
|
* @details If enabled then the core memory manager APIs are included
|
||||||
|
* in the kernel.
|
||||||
|
*
|
||||||
|
* @note The default is @p TRUE.
|
||||||
|
*/
|
||||||
|
#define CH_CFG_USE_MEMCORE TRUE
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Heap Allocator APIs.
|
||||||
|
* @details If enabled then the memory heap allocator APIs are included
|
||||||
|
* in the kernel.
|
||||||
|
*
|
||||||
|
* @note The default is @p TRUE.
|
||||||
|
* @note Requires @p CH_CFG_USE_MEMCORE and either @p CH_CFG_USE_MUTEXES or
|
||||||
|
* @p CH_CFG_USE_SEMAPHORES.
|
||||||
|
* @note Mutexes are recommended.
|
||||||
|
*/
|
||||||
|
#define CH_CFG_USE_HEAP TRUE
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief C-runtime allocator.
|
||||||
|
* @details If enabled the the heap allocator APIs just wrap the C-runtime
|
||||||
|
* @p malloc() and @p free() functions.
|
||||||
|
*
|
||||||
|
* @note The default is @p FALSE.
|
||||||
|
* @note Requires @p CH_CFG_USE_HEAP.
|
||||||
|
* @note The C-runtime may or may not require @p CH_CFG_USE_MEMCORE, see the
|
||||||
|
* appropriate documentation.
|
||||||
|
*/
|
||||||
|
#define CH_CFG_USE_MALLOC_HEAP FALSE
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Memory Pools Allocator APIs.
|
||||||
|
* @details If enabled then the memory pools allocator APIs are included
|
||||||
|
* in the kernel.
|
||||||
|
*
|
||||||
|
* @note The default is @p TRUE.
|
||||||
|
*/
|
||||||
|
#define CH_CFG_USE_MEMPOOLS FALSE
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Dynamic Threads APIs.
|
||||||
|
* @details If enabled then the dynamic threads creation APIs are included
|
||||||
|
* in the kernel.
|
||||||
|
*
|
||||||
|
* @note The default is @p TRUE.
|
||||||
|
* @note Requires @p CH_CFG_USE_WAITEXIT.
|
||||||
|
* @note Requires @p CH_CFG_USE_HEAP and/or @p CH_CFG_USE_MEMPOOLS.
|
||||||
|
*/
|
||||||
|
#define CH_CFG_USE_DYNAMIC TRUE
|
||||||
|
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/**
|
||||||
|
* @name Debug options
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Debug option, kernel statistics.
|
||||||
|
*
|
||||||
|
* @note The default is @p FALSE.
|
||||||
|
*/
|
||||||
|
#define CH_DBG_STATISTICS FALSE
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Debug option, system state check.
|
||||||
|
* @details If enabled the correct call protocol for system APIs is checked
|
||||||
|
* at runtime.
|
||||||
|
*
|
||||||
|
* @note The default is @p FALSE.
|
||||||
|
*/
|
||||||
|
#define CH_DBG_SYSTEM_STATE_CHECK FALSE
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Debug option, parameters checks.
|
||||||
|
* @details If enabled then the checks on the API functions input
|
||||||
|
* parameters are activated.
|
||||||
|
*
|
||||||
|
* @note The default is @p FALSE.
|
||||||
|
*/
|
||||||
|
#define CH_DBG_ENABLE_CHECKS FALSE
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Debug option, consistency checks.
|
||||||
|
* @details If enabled then all the assertions in the kernel code are
|
||||||
|
* activated. This includes consistency checks inside the kernel,
|
||||||
|
* runtime anomalies and port-defined checks.
|
||||||
|
*
|
||||||
|
* @note The default is @p FALSE.
|
||||||
|
*/
|
||||||
|
#define CH_DBG_ENABLE_ASSERTS FALSE
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Debug option, trace buffer.
|
||||||
|
* @details If enabled then the context switch circular trace buffer is
|
||||||
|
* activated.
|
||||||
|
*
|
||||||
|
* @note The default is @p FALSE.
|
||||||
|
*/
|
||||||
|
#define CH_DBG_ENABLE_TRACE FALSE
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Debug option, stack checks.
|
||||||
|
* @details If enabled then a runtime stack check is performed.
|
||||||
|
*
|
||||||
|
* @note The default is @p FALSE.
|
||||||
|
* @note The stack check is performed in a architecture/port dependent way.
|
||||||
|
* It may not be implemented or some ports.
|
||||||
|
* @note The default failure mode is to halt the system with the global
|
||||||
|
* @p panic_msg variable set to @p NULL.
|
||||||
|
*/
|
||||||
|
#define CH_DBG_ENABLE_STACK_CHECK FALSE
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Debug option, stacks initialization.
|
||||||
|
* @details If enabled then the threads working area is filled with a byte
|
||||||
|
* value when a thread is created. This can be useful for the
|
||||||
|
* runtime measurement of the used stack.
|
||||||
|
*
|
||||||
|
* @note The default is @p FALSE.
|
||||||
|
*/
|
||||||
|
#define CH_DBG_FILL_THREADS FALSE
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Debug option, threads profiling.
|
||||||
|
* @details If enabled then a field is added to the @p Thread structure that
|
||||||
|
* counts the system ticks occurred while executing the thread.
|
||||||
|
*
|
||||||
|
* @note The default is @p TRUE.
|
||||||
|
* @note This debug option is defaulted to TRUE because it is required by
|
||||||
|
* some test cases into the test suite.
|
||||||
|
*/
|
||||||
|
#define CH_DBG_THREADS_PROFILING FALSE
|
||||||
|
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/**
|
||||||
|
* @name Kernel hooks
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Threads descriptor structure extension.
|
||||||
|
* @details User fields added to the end of the @p thread_t structure.
|
||||||
|
*/
|
||||||
|
#define CH_CFG_THREAD_EXTRA_FIELDS \
|
||||||
|
/* Add threads custom fields here.*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Threads initialization hook.
|
||||||
|
* @details User initialization code added to the @p chThdInit() API.
|
||||||
|
*
|
||||||
|
* @note It is invoked from within @p chThdInit() and implicitly from all
|
||||||
|
* the threads creation APIs.
|
||||||
|
*/
|
||||||
|
#define CH_CFG_THREAD_INIT_HOOK(tp) { \
|
||||||
|
/* Add threads initialization code here.*/ \
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Threads finalization hook.
|
||||||
|
* @details User finalization code added to the @p chThdExit() API.
|
||||||
|
*/
|
||||||
|
#define CH_CFG_THREAD_EXIT_HOOK(tp) { \
|
||||||
|
/* Add threads finalization code here.*/ \
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Context switch hook.
|
||||||
|
* @details This hook is invoked just before switching between threads.
|
||||||
|
*/
|
||||||
|
#define CH_CFG_CONTEXT_SWITCH_HOOK(ntp, otp) { \
|
||||||
|
/* Context switch code here.*/ \
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ISR enter hook.
|
||||||
|
*/
|
||||||
|
#define CH_CFG_IRQ_PROLOGUE_HOOK() { \
|
||||||
|
/* IRQ prologue code here.*/ \
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ISR exit hook.
|
||||||
|
*/
|
||||||
|
#define CH_CFG_IRQ_EPILOGUE_HOOK() { \
|
||||||
|
/* IRQ epilogue code here.*/ \
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Idle thread enter hook.
|
||||||
|
* @note This hook is invoked within a critical zone, no OS functions
|
||||||
|
* should be invoked from here.
|
||||||
|
* @note This macro can be used to activate a power saving mode.
|
||||||
|
*/
|
||||||
|
#define CH_CFG_IDLE_ENTER_HOOK() { \
|
||||||
|
/* Idle-enter code here.*/ \
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Idle thread leave hook.
|
||||||
|
* @note This hook is invoked within a critical zone, no OS functions
|
||||||
|
* should be invoked from here.
|
||||||
|
* @note This macro can be used to deactivate a power saving mode.
|
||||||
|
*/
|
||||||
|
#define CH_CFG_IDLE_LEAVE_HOOK() { \
|
||||||
|
/* Idle-leave code here.*/ \
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Idle Loop hook.
|
||||||
|
* @details This hook is continuously invoked by the idle thread loop.
|
||||||
|
*/
|
||||||
|
#define CH_CFG_IDLE_LOOP_HOOK() { \
|
||||||
|
/* Idle loop code here.*/ \
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief System tick event hook.
|
||||||
|
* @details This hook is invoked in the system tick handler immediately
|
||||||
|
* after processing the virtual timers queue.
|
||||||
|
*/
|
||||||
|
#define CH_CFG_SYSTEM_TICK_HOOK() { \
|
||||||
|
/* System tick event code here.*/ \
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief System halt hook.
|
||||||
|
* @details This hook is invoked in case to a system halting error before
|
||||||
|
* the system is halted.
|
||||||
|
*/
|
||||||
|
#define CH_CFG_SYSTEM_HALT_HOOK(reason) { \
|
||||||
|
/* System halt code here.*/ \
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Trace hook.
|
||||||
|
* @details This hook is invoked each time a new record is written in the
|
||||||
|
* trace buffer.
|
||||||
|
*/
|
||||||
|
#define CH_CFG_TRACE_HOOK(tep) { \
|
||||||
|
/* Trace code here.*/ \
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Port-specific settings (override port settings defaulted in chcore.h). */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
#define SHELL_CMD_TEST_ENABLED FALSE
|
||||||
|
|
||||||
|
#endif /* CHCONF_H_ */
|
||||||
|
|
||||||
|
/** @} */
|
|
@ -0,0 +1,355 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2015 Robert Lippert
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file templates/halconf.h
|
||||||
|
* @brief HAL configuration header.
|
||||||
|
* @details HAL configuration file, this file allows to enable or disable the
|
||||||
|
* various device drivers from your application. You may also use
|
||||||
|
* this file in order to override the device drivers default settings.
|
||||||
|
*
|
||||||
|
* @addtogroup HAL_CONF
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef HALCONF_H_
|
||||||
|
#define HALCONF_H_
|
||||||
|
|
||||||
|
#include "mcuconf.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enables the TM subsystem.
|
||||||
|
*/
|
||||||
|
#if !defined(HAL_USE_TM) || defined(__DOXYGEN__)
|
||||||
|
#define HAL_USE_TM FALSE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enables the PAL subsystem.
|
||||||
|
*/
|
||||||
|
#if !defined(HAL_USE_PAL) || defined(__DOXYGEN__)
|
||||||
|
#define HAL_USE_PAL TRUE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enables the ADC subsystem.
|
||||||
|
*/
|
||||||
|
#if !defined(HAL_USE_ADC) || defined(__DOXYGEN__)
|
||||||
|
#define HAL_USE_ADC FALSE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enables the DAC subsystem.
|
||||||
|
*/
|
||||||
|
#if !defined(HAL_USE_DAC) || defined(__DOXYGEN__)
|
||||||
|
#define HAL_USE_DAC FALSE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enables the CAN subsystem.
|
||||||
|
*/
|
||||||
|
#if !defined(HAL_USE_CAN) || defined(__DOXYGEN__)
|
||||||
|
#define HAL_USE_CAN FALSE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enables the EXT subsystem.
|
||||||
|
*/
|
||||||
|
#if !defined(HAL_USE_EXT) || defined(__DOXYGEN__)
|
||||||
|
#define HAL_USE_EXT FALSE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enables the GPT subsystem.
|
||||||
|
*/
|
||||||
|
#if !defined(HAL_USE_GPT) || defined(__DOXYGEN__)
|
||||||
|
#define HAL_USE_GPT FALSE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enables the I2C subsystem.
|
||||||
|
*/
|
||||||
|
#if !defined(HAL_USE_I2C) || defined(__DOXYGEN__)
|
||||||
|
#define HAL_USE_I2C FALSE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enables the ICU subsystem.
|
||||||
|
*/
|
||||||
|
#if !defined(HAL_USE_ICU) || defined(__DOXYGEN__)
|
||||||
|
#define HAL_USE_ICU FALSE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enables the MAC subsystem.
|
||||||
|
*/
|
||||||
|
#if !defined(HAL_USE_MAC) || defined(__DOXYGEN__)
|
||||||
|
#define HAL_USE_MAC FALSE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enables the MMC_SPI subsystem.
|
||||||
|
*/
|
||||||
|
#if !defined(HAL_USE_MMC_SPI) || defined(__DOXYGEN__)
|
||||||
|
#define HAL_USE_MMC_SPI FALSE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enables the PWM subsystem.
|
||||||
|
*/
|
||||||
|
#if !defined(HAL_USE_PWM) || defined(__DOXYGEN__)
|
||||||
|
#define HAL_USE_PWM FALSE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enables the RTC subsystem.
|
||||||
|
*/
|
||||||
|
#if !defined(HAL_USE_RTC) || defined(__DOXYGEN__)
|
||||||
|
#define HAL_USE_RTC FALSE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enables the SDC subsystem.
|
||||||
|
*/
|
||||||
|
#if !defined(HAL_USE_SDC) || defined(__DOXYGEN__)
|
||||||
|
#define HAL_USE_SDC FALSE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enables the SERIAL subsystem.
|
||||||
|
*/
|
||||||
|
#if !defined(HAL_USE_SERIAL) || defined(__DOXYGEN__)
|
||||||
|
#define HAL_USE_SERIAL FALSE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enables the SERIAL over USB subsystem.
|
||||||
|
*/
|
||||||
|
#if !defined(HAL_USE_SERIAL_USB) || defined(__DOXYGEN__)
|
||||||
|
#define HAL_USE_SERIAL_USB TRUE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enables the SPI subsystem.
|
||||||
|
*/
|
||||||
|
#if !defined(HAL_USE_SPI) || defined(__DOXYGEN__)
|
||||||
|
#define HAL_USE_SPI FALSE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enables the UART subsystem.
|
||||||
|
*/
|
||||||
|
#if !defined(HAL_USE_UART) || defined(__DOXYGEN__)
|
||||||
|
#define HAL_USE_UART FALSE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enables the USB subsystem.
|
||||||
|
*/
|
||||||
|
#if !defined(HAL_USE_USB) || defined(__DOXYGEN__)
|
||||||
|
#define HAL_USE_USB TRUE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enables the I2S subsystem.
|
||||||
|
*/
|
||||||
|
#if !defined(HAL_USE_I2S) || defined(__DOXYGEN__)
|
||||||
|
#define HAL_USE_I2S FALSE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enables the WDG subsystem.
|
||||||
|
*/
|
||||||
|
#if !defined(HAL_USE_WDG) || defined(__DOXYGEN__)
|
||||||
|
#define HAL_USE_WDG FALSE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* ADC driver related settings. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enables synchronous APIs.
|
||||||
|
* @note Disabling this option saves both code and data space.
|
||||||
|
*/
|
||||||
|
#if !defined(ADC_USE_WAIT) || defined(__DOXYGEN__)
|
||||||
|
#define ADC_USE_WAIT TRUE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enables the @p adcAcquireBus() and @p adcReleaseBus() APIs.
|
||||||
|
* @note Disabling this option saves both code and data space.
|
||||||
|
*/
|
||||||
|
#if !defined(ADC_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
|
||||||
|
#define ADC_USE_MUTUAL_EXCLUSION TRUE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* CAN driver related settings. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sleep mode related APIs inclusion switch.
|
||||||
|
*/
|
||||||
|
#if !defined(CAN_USE_SLEEP_MODE) || defined(__DOXYGEN__)
|
||||||
|
#define CAN_USE_SLEEP_MODE TRUE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* I2C driver related settings. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enables the mutual exclusion APIs on the I2C bus.
|
||||||
|
*/
|
||||||
|
#if !defined(I2C_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
|
||||||
|
#define I2C_USE_MUTUAL_EXCLUSION TRUE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* MAC driver related settings. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enables an event sources for incoming packets.
|
||||||
|
*/
|
||||||
|
#if !defined(MAC_USE_ZERO_COPY) || defined(__DOXYGEN__)
|
||||||
|
#define MAC_USE_ZERO_COPY FALSE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enables an event sources for incoming packets.
|
||||||
|
*/
|
||||||
|
#if !defined(MAC_USE_EVENTS) || defined(__DOXYGEN__)
|
||||||
|
#define MAC_USE_EVENTS TRUE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* MMC_SPI driver related settings. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Delays insertions.
|
||||||
|
* @details If enabled this options inserts delays into the MMC waiting
|
||||||
|
* routines releasing some extra CPU time for the threads with
|
||||||
|
* lower priority, this may slow down the driver a bit however.
|
||||||
|
* This option is recommended also if the SPI driver does not
|
||||||
|
* use a DMA channel and heavily loads the CPU.
|
||||||
|
*/
|
||||||
|
#if !defined(MMC_NICE_WAITING) || defined(__DOXYGEN__)
|
||||||
|
#define MMC_NICE_WAITING TRUE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* SDC driver related settings. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Number of initialization attempts before rejecting the card.
|
||||||
|
* @note Attempts are performed at 10mS intervals.
|
||||||
|
*/
|
||||||
|
#if !defined(SDC_INIT_RETRY) || defined(__DOXYGEN__)
|
||||||
|
#define SDC_INIT_RETRY 100
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Include support for MMC cards.
|
||||||
|
* @note MMC support is not yet implemented so this option must be kept
|
||||||
|
* at @p FALSE.
|
||||||
|
*/
|
||||||
|
#if !defined(SDC_MMC_SUPPORT) || defined(__DOXYGEN__)
|
||||||
|
#define SDC_MMC_SUPPORT FALSE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Delays insertions.
|
||||||
|
* @details If enabled this options inserts delays into the MMC waiting
|
||||||
|
* routines releasing some extra CPU time for the threads with
|
||||||
|
* lower priority, this may slow down the driver a bit however.
|
||||||
|
*/
|
||||||
|
#if !defined(SDC_NICE_WAITING) || defined(__DOXYGEN__)
|
||||||
|
#define SDC_NICE_WAITING TRUE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* SERIAL driver related settings. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Default bit rate.
|
||||||
|
* @details Configuration parameter, this is the baud rate selected for the
|
||||||
|
* default configuration.
|
||||||
|
*/
|
||||||
|
#if !defined(SERIAL_DEFAULT_BITRATE) || defined(__DOXYGEN__)
|
||||||
|
#define SERIAL_DEFAULT_BITRATE 57600
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Serial buffers size.
|
||||||
|
* @details Configuration parameter, you can change the depth of the queue
|
||||||
|
* buffers depending on the requirements of your application.
|
||||||
|
* @note The default is 64 bytes for both the transmission and receive
|
||||||
|
* buffers.
|
||||||
|
*/
|
||||||
|
#if !defined(SERIAL_BUFFERS_SIZE) || defined(__DOXYGEN__)
|
||||||
|
#define SERIAL_BUFFERS_SIZE 16
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* SERIAL_USB driver related setting. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Serial over USB buffers size.
|
||||||
|
* @details Configuration parameter, the buffer size must be a multiple of
|
||||||
|
* the USB data endpoint maximum packet size.
|
||||||
|
* @note The default is 64 bytes for both the transmission and receive
|
||||||
|
* buffers.
|
||||||
|
*/
|
||||||
|
#if !defined(SERIAL_USB_BUFFERS_SIZE) || defined(__DOXYGEN__)
|
||||||
|
#define SERIAL_USB_BUFFERS_SIZE 64
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* SPI driver related settings. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enables synchronous APIs.
|
||||||
|
* @note Disabling this option saves both code and data space.
|
||||||
|
*/
|
||||||
|
#if !defined(SPI_USE_WAIT) || defined(__DOXYGEN__)
|
||||||
|
#define SPI_USE_WAIT FALSE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enables the @p spiAcquireBus() and @p spiReleaseBus() APIs.
|
||||||
|
* @note Disabling this option saves both code and data space.
|
||||||
|
*/
|
||||||
|
#if !defined(SPI_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
|
||||||
|
#define SPI_USE_MUTUAL_EXCLUSION TRUE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Turn off unused community HAL support */
|
||||||
|
#define HAL_USE_COMMUNITY FALSE
|
||||||
|
#define HAL_USE_CRC FALSE
|
||||||
|
#define HAL_USE_EICU FALSE
|
||||||
|
#define HAL_USE_NAND FALSE
|
||||||
|
#define HAL_USE_ONEWIRE FALSE
|
||||||
|
|
||||||
|
#endif /* HALCONF_H_ */
|
||||||
|
|
||||||
|
/** @} */
|
|
@ -0,0 +1,84 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2015 Robert Lippert
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "ch.h"
|
||||||
|
#include "hal.h"
|
||||||
|
#include "shell.h"
|
||||||
|
#include "usbcfg.h"
|
||||||
|
|
||||||
|
static THD_WORKING_AREA(waThread1, 128);
|
||||||
|
static THD_FUNCTION(Thread1, arg) {
|
||||||
|
(void)arg;
|
||||||
|
chRegSetThreadName("blinker");
|
||||||
|
while (true) {
|
||||||
|
palTogglePad(IOPORT4, BOARD_LED1);
|
||||||
|
chThdSleepMilliseconds(1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define SHELL_WA_SIZE THD_WORKING_AREA_SIZE(512)
|
||||||
|
|
||||||
|
static const ShellConfig shell_cfg1 = {
|
||||||
|
(BaseSequentialStream *)&SDU1,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Application entry point.
|
||||||
|
*/
|
||||||
|
int main(void) {
|
||||||
|
/*
|
||||||
|
* System initializations.
|
||||||
|
* - HAL initialization, this also initializes the configured device drivers
|
||||||
|
* and performs the board-specific initializations.
|
||||||
|
* - Kernel initialization, the main() function becomes a thread and the
|
||||||
|
* RTOS is active.
|
||||||
|
*/
|
||||||
|
halInit();
|
||||||
|
chSysInit();
|
||||||
|
|
||||||
|
palClearPad(IOPORT4, BOARD_LED1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Shell manager initialization.
|
||||||
|
*/
|
||||||
|
shellInit();
|
||||||
|
|
||||||
|
/* Initializes a serial-over-USB CDC driver. */
|
||||||
|
sduObjectInit(&SDU1);
|
||||||
|
sduStart(&SDU1, &serusbcfg);
|
||||||
|
|
||||||
|
/* Initialize USB */
|
||||||
|
usbStart(serusbcfg.usbp, &usbcfg);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Starts the LED blinker thread.
|
||||||
|
*/
|
||||||
|
chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO, Thread1, NULL);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Normal main() thread activity.
|
||||||
|
*/
|
||||||
|
while (true) {
|
||||||
|
if (SDU1.config->usbp->state == USB_ACTIVE) {
|
||||||
|
thread_t *shelltp = chThdCreateFromHeap(NULL, SHELL_WA_SIZE,
|
||||||
|
"shell", NORMALPRIO + 1,
|
||||||
|
shellThread, (void *)&shell_cfg1);
|
||||||
|
chThdWait(shelltp); /* Waiting termination. */
|
||||||
|
}
|
||||||
|
chThdSleepMilliseconds(1000);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,90 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2015 Robert Lippert
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MCUCONF_H_
|
||||||
|
#define MCUCONF_H_
|
||||||
|
|
||||||
|
/*
|
||||||
|
* AVR drivers configuration.
|
||||||
|
* The following settings override the default settings present in
|
||||||
|
* the various device driver implementation headers.
|
||||||
|
* Note that the settings for each driver only have effect if the driver
|
||||||
|
* is enabled in halconf.h.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ADC driver system settings.
|
||||||
|
*/
|
||||||
|
#define AVR_ADC_USE_ADC1 FALSE
|
||||||
|
|
||||||
|
/*
|
||||||
|
* CAN driver system settings.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MAC driver system settings.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PWM driver system settings.
|
||||||
|
*/
|
||||||
|
#define AVR_PWM_USE_TIM1 FALSE
|
||||||
|
#define AVR_PWM_USE_TIM2 FALSE
|
||||||
|
#define AVR_PWM_USE_TIM3 FALSE
|
||||||
|
#define AVR_PWM_USE_TIM4 FALSE
|
||||||
|
#define AVR_PWM_USE_TIM5 FALSE
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ICU driver system settings.
|
||||||
|
*/
|
||||||
|
#define AVR_ICU_USE_TIM1 FALSE
|
||||||
|
#define AVR_ICU_USE_TIM3 FALSE
|
||||||
|
#define AVR_ICU_USE_TIM4 FALSE
|
||||||
|
#define AVR_ICU_USE_TIM5 FALSE
|
||||||
|
|
||||||
|
/*
|
||||||
|
* GPT driver system settings.
|
||||||
|
*/
|
||||||
|
#define AVR_GPT_USE_TIM1 FALSE
|
||||||
|
#define AVR_GPT_USE_TIM2 FALSE
|
||||||
|
#define AVR_GPT_USE_TIM3 FALSE
|
||||||
|
#define AVR_GPT_USE_TIM4 FALSE
|
||||||
|
#define AVR_GPT_USE_TIM5 FALSE
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SERIAL driver system settings.
|
||||||
|
*/
|
||||||
|
#define AVR_SERIAL_USE_USART0 FALSE
|
||||||
|
#define AVR_SERIAL_USE_USART1 TRUE
|
||||||
|
|
||||||
|
/*
|
||||||
|
* I2C driver system settings.
|
||||||
|
*/
|
||||||
|
#define AVR_I2C_USE_I2C1 FALSE
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SPI driver system settings.
|
||||||
|
*/
|
||||||
|
#define AVR_SPI_USE_SPI1 FALSE
|
||||||
|
#define AVR_SPI_USE_16BIT_POLLED_EXCHANGE FALSE
|
||||||
|
|
||||||
|
/*
|
||||||
|
* USB driver system settings.
|
||||||
|
*/
|
||||||
|
#define AVR_USB_USE_USB1 TRUE
|
||||||
|
#define AVR_USB_USE_NAMED_ADDRESS_SPACES FALSE
|
||||||
|
|
||||||
|
#endif /* MCUCONF_H_ */
|
|
@ -0,0 +1,23 @@
|
||||||
|
*****************************************************************************
|
||||||
|
** ChibiOS/RT port for Atmel AVR AT90USB128. **
|
||||||
|
*****************************************************************************
|
||||||
|
|
||||||
|
** TARGET **
|
||||||
|
|
||||||
|
The demo runs on an PJRC Teensy 2++ board.
|
||||||
|
|
||||||
|
** The Demo **
|
||||||
|
|
||||||
|
The demo creates a standard serial-over-USB (CDC) slave device. The simple
|
||||||
|
ChibiOS shell is run on the USB serial connection and can be interacted
|
||||||
|
with by a standard serial port program (e.g. putty or screen).
|
||||||
|
|
||||||
|
** Build Procedure **
|
||||||
|
|
||||||
|
The demo was built using the GCC AVR toolchain. It should build with WinAVR too!
|
||||||
|
|
||||||
|
** Notes **
|
||||||
|
|
||||||
|
The USB driver itself is not that heavyweight but this demo requires a bit of
|
||||||
|
flash space and memory because of the nature of the ChibiOS shell code and
|
||||||
|
supporting functionality.
|
|
@ -0,0 +1,353 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2015 Robert Lippert
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "ch.h"
|
||||||
|
#include "hal.h"
|
||||||
|
#include "usbcfg.h"
|
||||||
|
|
||||||
|
/* Endpoints to be used. */
|
||||||
|
#define USBD_DATA_REQUEST_EP 1
|
||||||
|
#define USBD_DATA_AVAILABLE_EP 3
|
||||||
|
#define USBD_INTERRUPT_REQUEST_EP 2
|
||||||
|
|
||||||
|
#if (AVR_USB_USE_NAMED_ADDRESS_SPACES == TRUE) && defined(__FLASH)
|
||||||
|
# undef ROMCONST
|
||||||
|
# define ROMCONST const __flash
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Virtual serial port over USB.*/
|
||||||
|
SerialUSBDriver SDU1;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* USB Device Descriptor.
|
||||||
|
*/
|
||||||
|
static ROMCONST uint8_t vcom_device_descriptor_data[18] = {
|
||||||
|
USB_DESC_DEVICE (0x0110, /* bcdUSB (1.1). */
|
||||||
|
0x02, /* bDeviceClass (CDC). */
|
||||||
|
0x00, /* bDeviceSubClass. */
|
||||||
|
0x00, /* bDeviceProtocol. */
|
||||||
|
0x40, /* bMaxPacketSize. */
|
||||||
|
0x0483, /* idVendor (ST). */
|
||||||
|
0x5740, /* idProduct. */
|
||||||
|
0x0200, /* bcdDevice. */
|
||||||
|
1, /* iManufacturer. */
|
||||||
|
2, /* iProduct. */
|
||||||
|
3, /* iSerialNumber. */
|
||||||
|
1) /* bNumConfigurations. */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Configuration Descriptor tree for a CDC.*/
|
||||||
|
static ROMCONST uint8_t vcom_configuration_descriptor_data[67] = {
|
||||||
|
/* Configuration Descriptor.*/
|
||||||
|
USB_DESC_CONFIGURATION(67, /* wTotalLength. */
|
||||||
|
0x02, /* bNumInterfaces. */
|
||||||
|
0x01, /* bConfigurationValue. */
|
||||||
|
0, /* iConfiguration. */
|
||||||
|
0xC0, /* bmAttributes (self powered). */
|
||||||
|
50), /* bMaxPower (100mA). */
|
||||||
|
/* Interface Descriptor.*/
|
||||||
|
USB_DESC_INTERFACE (0x00, /* bInterfaceNumber. */
|
||||||
|
0x00, /* bAlternateSetting. */
|
||||||
|
0x01, /* bNumEndpoints. */
|
||||||
|
0x02, /* bInterfaceClass (Communications
|
||||||
|
Interface Class, CDC section
|
||||||
|
4.2). */
|
||||||
|
0x02, /* bInterfaceSubClass (Abstract
|
||||||
|
Control Model, CDC section 4.3). */
|
||||||
|
0x01, /* bInterfaceProtocol (AT commands,
|
||||||
|
CDC section 4.4). */
|
||||||
|
0), /* iInterface. */
|
||||||
|
/* Header Functional Descriptor (CDC section 5.2.3).*/
|
||||||
|
USB_DESC_BYTE (5), /* bLength. */
|
||||||
|
USB_DESC_BYTE (0x24), /* bDescriptorType (CS_INTERFACE). */
|
||||||
|
USB_DESC_BYTE (0x00), /* bDescriptorSubtype (Header
|
||||||
|
Functional Descriptor. */
|
||||||
|
USB_DESC_BCD (0x0110), /* bcdCDC. */
|
||||||
|
/* Call Management Functional Descriptor. */
|
||||||
|
USB_DESC_BYTE (5), /* bFunctionLength. */
|
||||||
|
USB_DESC_BYTE (0x24), /* bDescriptorType (CS_INTERFACE). */
|
||||||
|
USB_DESC_BYTE (0x01), /* bDescriptorSubtype (Call Management
|
||||||
|
Functional Descriptor). */
|
||||||
|
USB_DESC_BYTE (0x00), /* bmCapabilities (D0+D1). */
|
||||||
|
USB_DESC_BYTE (0x01), /* bDataInterface. */
|
||||||
|
/* ACM Functional Descriptor.*/
|
||||||
|
USB_DESC_BYTE (4), /* bFunctionLength. */
|
||||||
|
USB_DESC_BYTE (0x24), /* bDescriptorType (CS_INTERFACE). */
|
||||||
|
USB_DESC_BYTE (0x02), /* bDescriptorSubtype (Abstract
|
||||||
|
Control Management Descriptor). */
|
||||||
|
USB_DESC_BYTE (0x02), /* bmCapabilities. */
|
||||||
|
/* Union Functional Descriptor.*/
|
||||||
|
USB_DESC_BYTE (5), /* bFunctionLength. */
|
||||||
|
USB_DESC_BYTE (0x24), /* bDescriptorType (CS_INTERFACE). */
|
||||||
|
USB_DESC_BYTE (0x06), /* bDescriptorSubtype (Union
|
||||||
|
Functional Descriptor). */
|
||||||
|
USB_DESC_BYTE (0x00), /* bMasterInterface (Communication
|
||||||
|
Class Interface). */
|
||||||
|
USB_DESC_BYTE (0x01), /* bSlaveInterface0 (Data Class
|
||||||
|
Interface). */
|
||||||
|
/* Endpoint 2 Descriptor.*/
|
||||||
|
USB_DESC_ENDPOINT (USBD_INTERRUPT_REQUEST_EP|0x80,
|
||||||
|
0x03, /* bmAttributes (Interrupt). */
|
||||||
|
0x0008, /* wMaxPacketSize. */
|
||||||
|
0xFF), /* bInterval. */
|
||||||
|
/* Interface Descriptor.*/
|
||||||
|
USB_DESC_INTERFACE (0x01, /* bInterfaceNumber. */
|
||||||
|
0x00, /* bAlternateSetting. */
|
||||||
|
0x02, /* bNumEndpoints. */
|
||||||
|
0x0A, /* bInterfaceClass (Data Class
|
||||||
|
Interface, CDC section 4.5). */
|
||||||
|
0x00, /* bInterfaceSubClass (CDC section
|
||||||
|
4.6). */
|
||||||
|
0x00, /* bInterfaceProtocol (CDC section
|
||||||
|
4.7). */
|
||||||
|
0x00), /* iInterface. */
|
||||||
|
/* Endpoint 3 Descriptor.*/
|
||||||
|
USB_DESC_ENDPOINT (USBD_DATA_AVAILABLE_EP, /* bEndpointAddress.*/
|
||||||
|
0x02, /* bmAttributes (Bulk). */
|
||||||
|
0x0040, /* wMaxPacketSize. */
|
||||||
|
0x00), /* bInterval. */
|
||||||
|
/* Endpoint 1 Descriptor.*/
|
||||||
|
USB_DESC_ENDPOINT (USBD_DATA_REQUEST_EP|0x80, /* bEndpointAddress.*/
|
||||||
|
0x02, /* bmAttributes (Bulk). */
|
||||||
|
0x0040, /* wMaxPacketSize. */
|
||||||
|
0x00) /* bInterval. */
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* U.S. English language identifier.
|
||||||
|
*/
|
||||||
|
static ROMCONST uint8_t vcom_string0[] = {
|
||||||
|
USB_DESC_BYTE(4), /* bLength. */
|
||||||
|
USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType. */
|
||||||
|
USB_DESC_WORD(0x0409) /* wLANGID (U.S. English). */
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Vendor string.
|
||||||
|
*/
|
||||||
|
static ROMCONST uint8_t vcom_string1[] = {
|
||||||
|
USB_DESC_BYTE(38), /* bLength. */
|
||||||
|
USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType. */
|
||||||
|
'S', 0, 'T', 0, 'M', 0, 'i', 0, 'c', 0, 'r', 0, 'o', 0, 'e', 0,
|
||||||
|
'l', 0, 'e', 0, 'c', 0, 't', 0, 'r', 0, 'o', 0, 'n', 0, 'i', 0,
|
||||||
|
'c', 0, 's', 0
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Device Description string.
|
||||||
|
*/
|
||||||
|
static ROMCONST uint8_t vcom_string2[] = {
|
||||||
|
USB_DESC_BYTE(56), /* bLength. */
|
||||||
|
USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType. */
|
||||||
|
'C', 0, 'h', 0, 'i', 0, 'b', 0, 'i', 0, 'O', 0, 'S', 0, '/', 0,
|
||||||
|
'R', 0, 'T', 0, ' ', 0, 'V', 0, 'i', 0, 'r', 0, 't', 0, 'u', 0,
|
||||||
|
'a', 0, 'l', 0, ' ', 0, 'C', 0, 'O', 0, 'M', 0, ' ', 0, 'P', 0,
|
||||||
|
'o', 0, 'r', 0, 't', 0
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Serial Number string.
|
||||||
|
*/
|
||||||
|
static ROMCONST uint8_t vcom_string3[] = {
|
||||||
|
USB_DESC_BYTE(8), /* bLength. */
|
||||||
|
USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType. */
|
||||||
|
'0' + CH_KERNEL_MAJOR, 0,
|
||||||
|
'0' + CH_KERNEL_MINOR, 0,
|
||||||
|
'0' + CH_KERNEL_PATCH, 0
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Handles the GET_DESCRIPTOR callback.
|
||||||
|
*/
|
||||||
|
static const USBDescriptor *get_descriptor(USBDriver *usbp,
|
||||||
|
uint8_t dtype,
|
||||||
|
uint8_t dindex,
|
||||||
|
uint16_t lang) {
|
||||||
|
|
||||||
|
(void)usbp;
|
||||||
|
(void)lang;
|
||||||
|
(void)dtype;
|
||||||
|
(void)dindex;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief IN EP1 state.
|
||||||
|
*/
|
||||||
|
static USBInEndpointState ep1instate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief EP1 initialization structure
|
||||||
|
*/
|
||||||
|
static const USBEndpointConfig ep1config = {
|
||||||
|
USB_EP_MODE_TYPE_BULK,
|
||||||
|
NULL,
|
||||||
|
sduDataTransmitted,
|
||||||
|
NULL,
|
||||||
|
0x0040,
|
||||||
|
0,
|
||||||
|
&ep1instate,
|
||||||
|
NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief INTR EP3 state.
|
||||||
|
*/
|
||||||
|
static USBInEndpointState ep3instate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief EP3 initialization structure (IN only).
|
||||||
|
*/
|
||||||
|
static const USBEndpointConfig ep3config = {
|
||||||
|
USB_EP_MODE_TYPE_INTR,
|
||||||
|
NULL,
|
||||||
|
sduInterruptTransmitted,
|
||||||
|
NULL,
|
||||||
|
0x0010,
|
||||||
|
0x0000,
|
||||||
|
&ep3instate,
|
||||||
|
NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief OUT EP3 state.
|
||||||
|
*/
|
||||||
|
static USBOutEndpointState ep3state;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief EP2 initialization structure
|
||||||
|
*/
|
||||||
|
static const USBEndpointConfig ep2config = {
|
||||||
|
USB_EP_MODE_TYPE_BULK,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
sduDataReceived,
|
||||||
|
0,
|
||||||
|
0x0040,
|
||||||
|
NULL,
|
||||||
|
&ep3state,
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Handles the USB driver global events.
|
||||||
|
*/
|
||||||
|
static void usb_event(USBDriver *usbp, usbevent_t event) {
|
||||||
|
extern SerialUSBDriver SDU1;
|
||||||
|
|
||||||
|
switch (event) {
|
||||||
|
case USB_EVENT_RESET:
|
||||||
|
return;
|
||||||
|
case USB_EVENT_ADDRESS:
|
||||||
|
return;
|
||||||
|
case USB_EVENT_CONFIGURED:
|
||||||
|
chSysLockFromISR();
|
||||||
|
|
||||||
|
/* Enables the endpoints specified into the configuration.
|
||||||
|
Note, this callback is invoked from an ISR so I-Class functions
|
||||||
|
must be used.*/
|
||||||
|
usbInitEndpointI(usbp, USBD_DATA_REQUEST_EP, &ep1config);
|
||||||
|
usbInitEndpointI(usbp, USBD_DATA_AVAILABLE_EP, &ep2config);
|
||||||
|
usbInitEndpointI(usbp, USBD_INTERRUPT_REQUEST_EP, &ep3config);
|
||||||
|
|
||||||
|
/* Resetting the state of the CDC subsystem.*/
|
||||||
|
sduConfigureHookI(&SDU1);
|
||||||
|
|
||||||
|
chSysUnlockFromISR();
|
||||||
|
return;
|
||||||
|
case USB_EVENT_SUSPEND:
|
||||||
|
return;
|
||||||
|
case USB_EVENT_WAKEUP:
|
||||||
|
return;
|
||||||
|
case USB_EVENT_STALLED:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool usb_setup_hook(USBDriver *usbp) {
|
||||||
|
/* Override GET_DESCRIPTOR requests to return data from program memory */
|
||||||
|
if ((usbp->setup[0] & (USB_RTYPE_RECIPIENT_MASK | USB_RTYPE_TYPE_MASK)) ==
|
||||||
|
(USB_RTYPE_RECIPIENT_DEVICE | USB_RTYPE_TYPE_STD) &&
|
||||||
|
usbp->setup[1] == USB_REQ_GET_DESCRIPTOR) {
|
||||||
|
const uint8_t dtype = usbp->setup[3];
|
||||||
|
const uint8_t dindex = usbp->setup[2];
|
||||||
|
const AVR_USB_TX_BUF_ADDRESS_SPACE uint8_t *ddata = NULL;
|
||||||
|
size_t dsize = 0;
|
||||||
|
switch (dtype) {
|
||||||
|
case USB_DESCRIPTOR_DEVICE:
|
||||||
|
dsize = sizeof(vcom_device_descriptor_data);
|
||||||
|
ddata = vcom_device_descriptor_data;
|
||||||
|
break;
|
||||||
|
case USB_DESCRIPTOR_CONFIGURATION:
|
||||||
|
dsize = sizeof(vcom_configuration_descriptor_data);
|
||||||
|
ddata = vcom_configuration_descriptor_data;
|
||||||
|
break;
|
||||||
|
case USB_DESCRIPTOR_STRING:
|
||||||
|
if (dindex == 0) {
|
||||||
|
dsize = sizeof(vcom_string0);
|
||||||
|
ddata = vcom_string0;
|
||||||
|
} else if (dindex == 1) {
|
||||||
|
dsize = sizeof(vcom_string1);
|
||||||
|
ddata = vcom_string1;
|
||||||
|
} else if (dindex == 2) {
|
||||||
|
dsize = sizeof(vcom_string2);
|
||||||
|
ddata = vcom_string2;
|
||||||
|
} else if (dindex == 3) {
|
||||||
|
dsize = sizeof(vcom_string3);
|
||||||
|
ddata = vcom_string3;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (ddata == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
usbSetupTransfer(usbp, ddata, dsize, NULL);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return sduRequestsHook(usbp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Handles the USB driver start of frame event.
|
||||||
|
*/
|
||||||
|
static void sof_handler(USBDriver *usbp) {
|
||||||
|
(void)usbp;
|
||||||
|
|
||||||
|
osalSysLockFromISR();
|
||||||
|
sduSOFHookI(&SDU1);
|
||||||
|
osalSysUnlockFromISR();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* USB driver configuration.
|
||||||
|
*/
|
||||||
|
const USBConfig usbcfg = {
|
||||||
|
usb_event,
|
||||||
|
get_descriptor,
|
||||||
|
usb_setup_hook,
|
||||||
|
sof_handler
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Serial over USB driver configuration.
|
||||||
|
*/
|
||||||
|
const SerialUSBConfig serusbcfg = {
|
||||||
|
&USBD1,
|
||||||
|
USBD_DATA_REQUEST_EP,
|
||||||
|
USBD_DATA_AVAILABLE_EP,
|
||||||
|
USBD_INTERRUPT_REQUEST_EP
|
||||||
|
};
|
|
@ -0,0 +1,26 @@
|
||||||
|
/*
|
||||||
|
Copyright (C)2015 Robert Lippert
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef USBCFG_H_
|
||||||
|
#define USBCFG_H_
|
||||||
|
|
||||||
|
extern const USBConfig usbcfg;
|
||||||
|
extern const SerialUSBConfig serusbcfg;
|
||||||
|
|
||||||
|
/* Virtual serial port over USB.*/
|
||||||
|
extern SerialUSBDriver SDU1;
|
||||||
|
|
||||||
|
#endif /* USBCFG_H_ */
|
|
@ -0,0 +1,75 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2015 Robert Lippert
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "hal.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief PAL setup.
|
||||||
|
* @details Digital I/O ports static configuration as defined in @p board.h.
|
||||||
|
* This variable is used by the HAL when initializing the PAL driver.
|
||||||
|
*/
|
||||||
|
#if HAL_USE_PAL || defined(__DOXYGEN__)
|
||||||
|
const PALConfig pal_default_config =
|
||||||
|
{
|
||||||
|
#if defined(PORTA)
|
||||||
|
{VAL_PORTA, VAL_DDRA},
|
||||||
|
#endif
|
||||||
|
#if defined(PORTB)
|
||||||
|
{VAL_PORTB, VAL_DDRB},
|
||||||
|
#endif
|
||||||
|
#if defined(PORTC)
|
||||||
|
{VAL_PORTC, VAL_DDRC},
|
||||||
|
#endif
|
||||||
|
#if defined(PORTD)
|
||||||
|
{VAL_PORTD, VAL_DDRD},
|
||||||
|
#endif
|
||||||
|
#if defined(PORTE)
|
||||||
|
{VAL_PORTE, VAL_DDRE},
|
||||||
|
#endif
|
||||||
|
#if defined(PORTF)
|
||||||
|
{VAL_PORTF, VAL_DDRF},
|
||||||
|
#endif
|
||||||
|
#if defined(PORTG)
|
||||||
|
{VAL_PORTG, VAL_DDRG},
|
||||||
|
#endif
|
||||||
|
#if defined(PORTH)
|
||||||
|
{VAL_PORTH, VAL_DDRH},
|
||||||
|
#endif
|
||||||
|
#if defined(PORTJ)
|
||||||
|
{VAL_PORTJ, VAL_DDRJ},
|
||||||
|
#endif
|
||||||
|
#if defined(PORTK)
|
||||||
|
{VAL_PORTK, VAL_DDRK},
|
||||||
|
#endif
|
||||||
|
#if defined(PORTL)
|
||||||
|
{VAL_PORTL, VAL_DDRL},
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
#endif /* HAL_USE_PAL */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Board-specific initialization code.
|
||||||
|
*/
|
||||||
|
void boardInit(void) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* External interrupts setup, all disabled initially.
|
||||||
|
*/
|
||||||
|
EICRA = 0x00;
|
||||||
|
EICRB = 0x00;
|
||||||
|
EIMSK = 0x00;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,86 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2015 Robert Lippert
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef BOARD_H_
|
||||||
|
#define BOARD_H_
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Setup for the PJRC Teensy2++ board.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Board identifier.
|
||||||
|
*/
|
||||||
|
#define BOARD_TEENSY_2PLUSPLUS
|
||||||
|
#define BOARD_NAME "PJRC Teensy 2++"
|
||||||
|
|
||||||
|
/* All inputs with pull-ups */
|
||||||
|
#define VAL_DDRA 0x00
|
||||||
|
#define VAL_PORTA 0xFF
|
||||||
|
|
||||||
|
/* All inputs with pull-ups */
|
||||||
|
#define VAL_DDRB 0x00
|
||||||
|
#define VAL_PORTB 0xFF
|
||||||
|
|
||||||
|
/* All inputs with pull-ups */
|
||||||
|
#define VAL_DDRC 0x00
|
||||||
|
#define VAL_PORTC 0xFF
|
||||||
|
|
||||||
|
/* All inputs with pull-ups, LED on D6, serial TX1 on D3 */
|
||||||
|
#define VAL_DDRD 0x48
|
||||||
|
#define VAL_PORTD 0xFF
|
||||||
|
|
||||||
|
/* All inputs with pull-ups */
|
||||||
|
#define VAL_DDRE 0x00
|
||||||
|
#define VAL_PORTE 0xFF
|
||||||
|
|
||||||
|
/* All inputs with pull-ups */
|
||||||
|
#define VAL_DDRF 0x00
|
||||||
|
#define VAL_PORTF 0xFF
|
||||||
|
|
||||||
|
/* All inputs with pull-ups */
|
||||||
|
#define VAL_DDRG 0x00
|
||||||
|
#define VAL_PORTG 0xFF
|
||||||
|
|
||||||
|
/* All inputs with pull-ups */
|
||||||
|
#define VAL_DDRH 0x00
|
||||||
|
#define VAL_PORTH 0xFF
|
||||||
|
|
||||||
|
/* All inputs with pull-ups */
|
||||||
|
#define VAL_DDRJ 0x00
|
||||||
|
#define VAL_PORTJ 0xFF
|
||||||
|
|
||||||
|
/* All inputs with pull-ups */
|
||||||
|
#define VAL_DDRK 0x00
|
||||||
|
#define VAL_PORTK 0xFF
|
||||||
|
|
||||||
|
/* All inputs with pull-ups */
|
||||||
|
#define VAL_DDRL 0x00
|
||||||
|
#define VAL_PORTL 0xFF
|
||||||
|
|
||||||
|
#define BOARD_LED1 6
|
||||||
|
|
||||||
|
#if !defined(_FROM_ASM_)
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
void boardInit(void);
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif /* _FROM_ASM_ */
|
||||||
|
|
||||||
|
#endif /* BOARD_H_ */
|
|
@ -0,0 +1,5 @@
|
||||||
|
# List of all the board related files.
|
||||||
|
BOARDSRC = ${CHIBIOS}/os/hal/boards/PJRC_TEENSY_2PLUSPLUS/board.c
|
||||||
|
|
||||||
|
# Required include directories
|
||||||
|
BOARDINC = ${CHIBIOS}/os/hal/boards/PJRC_TEENSY_2PLUSPLUS
|
|
@ -0,0 +1,841 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2015 Robert Lippert
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file usb_lld.c
|
||||||
|
* @brief AVR USB subsystem low level driver source.
|
||||||
|
*
|
||||||
|
* @addtogroup USB
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "hal.h"
|
||||||
|
|
||||||
|
#if (HAL_USE_USB == TRUE) || defined(__DOXYGEN__)
|
||||||
|
|
||||||
|
#ifndef F_USB
|
||||||
|
#define F_USB F_CPU
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver local definitions. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver exported variables. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief USB1 driver identifier.
|
||||||
|
*/
|
||||||
|
#if (AVR_USB_USE_USB1 == TRUE) || defined(__DOXYGEN__)
|
||||||
|
USBDriver USBD1;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver local variables and types. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief EP0 state.
|
||||||
|
* @note It is an union because IN and OUT endpoints are never used at the
|
||||||
|
* same time for EP0.
|
||||||
|
*/
|
||||||
|
static union {
|
||||||
|
/**
|
||||||
|
* @brief IN EP0 state.
|
||||||
|
*/
|
||||||
|
USBInEndpointState in;
|
||||||
|
/**
|
||||||
|
* @brief OUT EP0 state.
|
||||||
|
*/
|
||||||
|
USBOutEndpointState out;
|
||||||
|
} ep0_state;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief EP0 initialization structure.
|
||||||
|
*/
|
||||||
|
static const USBEndpointConfig ep0config = {
|
||||||
|
USB_EP_MODE_TYPE_CTRL,
|
||||||
|
_usb_ep0setup,
|
||||||
|
_usb_ep0in,
|
||||||
|
_usb_ep0out,
|
||||||
|
0x40,
|
||||||
|
0x40,
|
||||||
|
&ep0_state.in,
|
||||||
|
&ep0_state.out
|
||||||
|
};
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver local variables and types. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver local functions. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
#ifdef AVR_USB_PLL_OFF_IN_SUSPEND
|
||||||
|
static __attribute__((unused)) void usb_pll_off(void) {
|
||||||
|
PLLCSR = 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void usb_pll_on(void) {
|
||||||
|
#if (F_USB == 8000000)
|
||||||
|
#if (defined(__AVR_AT90USB82__) || defined(__AVR_AT90USB162__) || \
|
||||||
|
defined(__AVR_ATmega8U2__) || defined(__AVR_ATmega16U2__) || \
|
||||||
|
defined(__AVR_ATmega32U2__))
|
||||||
|
#define PLL_VAL 0
|
||||||
|
#elif (defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__))
|
||||||
|
#define PLL_VAL 0
|
||||||
|
#elif (defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__))
|
||||||
|
#define PLL_VAL ((0 << PLLP2) | (1 << PLLP1) | (1 << PLLP0))
|
||||||
|
#elif (defined(__AVR_AT90USB647__) || defined(__AVR_AT90USB1287__))
|
||||||
|
#define PLL_VAL ((0 << PLLP2) | (1 << PLLP1) | (1 << PLLP0))
|
||||||
|
#endif
|
||||||
|
#elif (F_USB == 16000000)
|
||||||
|
#if (defined(__AVR_AT90USB82__) || defined(__AVR_AT90USB162__) || \
|
||||||
|
defined(__AVR_ATmega8U2__) || defined(__AVR_ATmega16U2__) || \
|
||||||
|
defined(__AVR_ATmega32U2__))
|
||||||
|
#define PLL_VAL ((0 << PLLP2) | (0 << PLLP1) | (1 << PLLP0))
|
||||||
|
#elif (defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__))
|
||||||
|
#define PLL_VAL (1 << PINDIV)
|
||||||
|
#elif (defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB647__))
|
||||||
|
#define PLL_VAL ((1 << PLLP2) | (1 << PLLP1) | (0 << PLLP0))
|
||||||
|
#elif (defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1287__))
|
||||||
|
#define PLL_VAL ((1 << PLLP2) | (0 << PLLP1) | (1 << PLLP0))
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef PLL_VAL
|
||||||
|
#error Could not determine PLL value, unsupported AVR USB model type
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef PLLFRQ
|
||||||
|
/* This initializes PLL on supported devices for USB 48MHz *only* */
|
||||||
|
PLLFRQ = (0 << PDIV3) | (1 << PDIV2) | (0 << PDIV1) | (0 << PDIV0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
PLLCSR = PLL_VAL;
|
||||||
|
PLLCSR = PLL_VAL | (1 << PLLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int usb_pll_is_locked(void) {
|
||||||
|
return !!(PLLCSR & (1 << PLOCK));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver interrupt handlers and threads. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief USB general/OTG/device management event interrupt handler.
|
||||||
|
*
|
||||||
|
* @isr
|
||||||
|
*/
|
||||||
|
OSAL_IRQ_HANDLER(USB_GEN_vect) {
|
||||||
|
uint8_t usbint, udint;
|
||||||
|
USBDriver * const usbp = &USBD1;
|
||||||
|
|
||||||
|
OSAL_IRQ_PROLOGUE();
|
||||||
|
|
||||||
|
usbint = USBINT;
|
||||||
|
udint = UDINT;
|
||||||
|
|
||||||
|
if (usbint & (1 << VBUSTI)) {
|
||||||
|
/* Connected. */
|
||||||
|
#ifdef AVR_USB_PLL_OFF_IN_SUSPEND
|
||||||
|
usb_pll_on();
|
||||||
|
while (!usb_pll_is_locked()) {}
|
||||||
|
#endif /* AVR_USB_PLL_OFF_IN_SUSPEND */
|
||||||
|
|
||||||
|
/* Attach to bus */
|
||||||
|
usb_lld_connect_bus(usbp);
|
||||||
|
USBINT &= ~(1 << VBUSTI);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* USB bus SUSPEND condition handling.*/
|
||||||
|
if (udint & (1 << SUSPI)) {
|
||||||
|
/* Disable suspend interrupt, enable WAKEUP interrupt */
|
||||||
|
UDIEN |= (1 << WAKEUPE);
|
||||||
|
UDINT &= ~(1 << WAKEUPI);
|
||||||
|
UDIEN &= ~(1 << SUSPE);
|
||||||
|
|
||||||
|
/* Freeze the clock to reduce power consumption */
|
||||||
|
USBCON |= (1 << FRZCLK);
|
||||||
|
#ifdef AVR_USB_PLL_OFF_IN_SUSPEND
|
||||||
|
usb_pll_off();
|
||||||
|
#endif /* AVR_USB_PLL_OFF_IN_SUSPEND */
|
||||||
|
|
||||||
|
/* Clear the interrupt */
|
||||||
|
UDINT &= ~(1 << SUSPI);
|
||||||
|
|
||||||
|
_usb_isr_invoke_event_cb(usbp, USB_EVENT_SUSPEND);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* USB bus WAKEUP condition handling.*/
|
||||||
|
if (udint & (1 << WAKEUPI)) {
|
||||||
|
#ifdef AVR_USB_PLL_OFF_IN_SUSPEND
|
||||||
|
usb_pll_on();
|
||||||
|
while (!usb_pll_is_locked()) {}
|
||||||
|
#endif /* AVR_USB_PLL_OFF_IN_SUSPEND */
|
||||||
|
|
||||||
|
/* Unfreeze the clock */
|
||||||
|
USBCON &= ~(1 << FRZCLK);
|
||||||
|
|
||||||
|
/* Clear & disable wakeup interrupt, enable suspend interrupt */
|
||||||
|
UDINT &= ~(1 << WAKEUPI);
|
||||||
|
UDIEN &= ~(1 << WAKEUPE);
|
||||||
|
UDIEN |= (1 << SUSPE);
|
||||||
|
|
||||||
|
_usb_isr_invoke_event_cb(usbp, USB_EVENT_WAKEUP);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* USB bus RESUME condition handling.*/
|
||||||
|
if (udint & (1 << EORSMI)) {
|
||||||
|
UDINT &= ~(1 << EORSMI);
|
||||||
|
UDIEN &= ~(1 << EORSME);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* USB bus reset condition handling.*/
|
||||||
|
if (udint & (1 << EORSTI)) {
|
||||||
|
UDINT &= ~(1 << EORSTI);
|
||||||
|
|
||||||
|
/* Clear & disable suspend interrupt, enable WAKEUP interrupt */
|
||||||
|
UDINT &= ~(1 << SUSPI);
|
||||||
|
UDIEN &= ~(1 << SUSPE);
|
||||||
|
UDIEN |= (1 << WAKEUPE);
|
||||||
|
|
||||||
|
/* Reinitialize EP0. This is not mentioned in the datasheet but
|
||||||
|
* apparently is required. */
|
||||||
|
usb_lld_init_endpoint(usbp, 0);
|
||||||
|
|
||||||
|
_usb_isr_invoke_event_cb(usbp, USB_EVENT_RESET);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Start-Of-Frame handling, only if enabled */
|
||||||
|
if ((UDIEN & (1 << SOFE)) && (udint & (1 << SOFI))) {
|
||||||
|
_usb_isr_invoke_sof_cb(usbp);
|
||||||
|
UDINT &= ~(1 << SOFI);
|
||||||
|
}
|
||||||
|
|
||||||
|
OSAL_IRQ_EPILOGUE();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void usb_fifo_write(USBDriver *usbp, usbep_t ep, size_t n) {
|
||||||
|
const USBEndpointConfig *epcp = usbp->epc[ep];
|
||||||
|
USBInEndpointState *isp = epcp->in_state;
|
||||||
|
syssts_t sts;
|
||||||
|
if (n == 0) {
|
||||||
|
isp->last_tx_size = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (n > epcp->in_maxsize)
|
||||||
|
n = epcp->in_maxsize;
|
||||||
|
/* i is number of bytes remaining to transmit minus 1 (to handle 256b case) */
|
||||||
|
uint8_t i = n - 1;
|
||||||
|
|
||||||
|
/* Must lock for entire operation to ensure nothing changes the ENUM value */
|
||||||
|
sts = osalSysGetStatusAndLockX();
|
||||||
|
UENUM = ep & 0xf;
|
||||||
|
do {
|
||||||
|
UEDATX = *isp->txbuf++;
|
||||||
|
} while (i--);
|
||||||
|
isp->last_tx_size = n;
|
||||||
|
osalSysRestoreStatusX(sts);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void usb_fifo_read(USBDriver *usbp, usbep_t ep, size_t n) {
|
||||||
|
const USBEndpointConfig *epcp = usbp->epc[ep];
|
||||||
|
USBOutEndpointState *osp = epcp->out_state;
|
||||||
|
syssts_t sts;
|
||||||
|
if (n == 0)
|
||||||
|
return;
|
||||||
|
if (n > epcp->out_maxsize)
|
||||||
|
n = epcp->out_maxsize;
|
||||||
|
// i is number of bytes remaining to receive minus 1 (to handle 256b case)
|
||||||
|
uint8_t i = n - 1;
|
||||||
|
|
||||||
|
/* Must lock for entire operation to ensure nothing changes the ENUM value */
|
||||||
|
sts = osalSysGetStatusAndLockX();
|
||||||
|
UENUM = ep & 0xf;
|
||||||
|
do {
|
||||||
|
*osp->rxbuf++ = UEDATX;
|
||||||
|
} while (i--);
|
||||||
|
osalSysRestoreStatusX(sts);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ep_isr(USBDriver *usbp, usbep_t ep) {
|
||||||
|
const USBEndpointConfig *epcp = usbp->epc[ep];
|
||||||
|
size_t n;
|
||||||
|
UENUM = ep & 0xf;
|
||||||
|
|
||||||
|
/* TODO: if stalling is needed/expected remove this check */
|
||||||
|
osalDbgAssert(!(UEINTX & (1 << STALLEDI)), "Endpoint stalled!");
|
||||||
|
|
||||||
|
if ((UEIENX & (1 << TXINE)) && (UEINTX & (1 << TXINI))) {
|
||||||
|
/* Ready to accept more IN data to transmit to host */
|
||||||
|
/* Update transaction counts to reflect newly transmitted bytes */
|
||||||
|
epcp->in_state->txcnt += epcp->in_state->last_tx_size;
|
||||||
|
n = epcp->in_state->txsize - epcp->in_state->txcnt;
|
||||||
|
if (n > 0) {
|
||||||
|
/* Transfer not completed, there are more packets to send. */
|
||||||
|
usb_fifo_write(usbp, ep, n);
|
||||||
|
|
||||||
|
/* Clear FIFOCON to send the data in the FIFO and switch bank */
|
||||||
|
UEINTX &= ~((1 << TXINI) | (1 << FIFOCON));
|
||||||
|
/* Enable the TX complete interrupt */
|
||||||
|
UEIENX |= (1 << TXINE);
|
||||||
|
} else {
|
||||||
|
/* Disable TXIN interrupt */
|
||||||
|
UEIENX &= ~(1 << TXINE);
|
||||||
|
/* Handshake interrupt status */
|
||||||
|
UEINTX &= ~(1 << TXINI);
|
||||||
|
_usb_isr_invoke_in_cb(usbp, ep);
|
||||||
|
}
|
||||||
|
} else if ((UEIENX & (1 << RXSTPE)) && (UEINTX & (1 << RXSTPI))) {
|
||||||
|
/* Received SETUP data */
|
||||||
|
/* Reset transaction state for endpoint */
|
||||||
|
epcp->in_state->txcnt = 0;
|
||||||
|
epcp->in_state->txsize = 0;
|
||||||
|
epcp->in_state->last_tx_size = 0;
|
||||||
|
/* Setup packets handling, setup packets are handled using a
|
||||||
|
specific callback.*/
|
||||||
|
_usb_isr_invoke_setup_cb(usbp, ep);
|
||||||
|
} else if ((UEIENX & (1 << RXOUTE)) && (UEINTX & (1 << RXOUTI))) {
|
||||||
|
/* Received OUT data from host */
|
||||||
|
if (ep == 0 && usbp->ep0state == USB_EP0_WAITING_STS) {
|
||||||
|
/* SETUP/control transaction complete, invoke the callback. */
|
||||||
|
UEIENX &= ~(1 << RXOUTE);
|
||||||
|
UEINTX &= ~((1 << RXOUTI) | (1 << FIFOCON));
|
||||||
|
_usb_isr_invoke_out_cb(usbp, ep);
|
||||||
|
} else {
|
||||||
|
/* Check the FIFO byte count to see how many bytes were received */
|
||||||
|
n = UEBCX;
|
||||||
|
|
||||||
|
usb_fifo_read(usbp, ep, n);
|
||||||
|
|
||||||
|
/* Transaction state update */
|
||||||
|
epcp->out_state->rxcnt += n;
|
||||||
|
epcp->out_state->rxsize -= n;
|
||||||
|
epcp->out_state->rxpkts -= 1;
|
||||||
|
if (n < epcp->out_maxsize || epcp->out_state->rxpkts == 0) {
|
||||||
|
/* Disable OUT interrupt */
|
||||||
|
UEIENX &= ~(1 << RXOUTE);
|
||||||
|
/* Mark OUT FIFO processed to allow more data to be received */
|
||||||
|
UEINTX &= ~((1 << RXOUTI) | (1 << FIFOCON));
|
||||||
|
/* Transfer complete, invokes the callback.*/
|
||||||
|
_usb_isr_invoke_out_cb(usbp, ep);
|
||||||
|
} else {
|
||||||
|
/* Mark OUT FIFO processed to allow more data to be received */
|
||||||
|
UEINTX &= ~((1 << RXOUTI) | (1 << FIFOCON));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief USB communication event interrupt handler.
|
||||||
|
*
|
||||||
|
* @isr
|
||||||
|
*/
|
||||||
|
OSAL_IRQ_HANDLER(USB_COM_vect) {
|
||||||
|
USBDriver *usbp = &USBD1;
|
||||||
|
const uint8_t epnum_orig = UENUM;
|
||||||
|
uint8_t i;
|
||||||
|
|
||||||
|
OSAL_IRQ_PROLOGUE();
|
||||||
|
|
||||||
|
/* Figure out which endpoint(s) are interrupting */
|
||||||
|
for (i = 0; i < USB_MAX_ENDPOINTS; ++i) {
|
||||||
|
if (UEINT & (1 << i)) {
|
||||||
|
ep_isr(usbp, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Restore endpoint selector to pre-interrupt state */
|
||||||
|
UENUM = epnum_orig;
|
||||||
|
|
||||||
|
OSAL_IRQ_EPILOGUE();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver exported functions. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Low level USB driver initialization.
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
void usb_lld_init(void) {
|
||||||
|
#if AVR_USB_USE_USB1 == TRUE
|
||||||
|
/* Driver initialization.*/
|
||||||
|
usbObjectInit(&USBD1);
|
||||||
|
|
||||||
|
/* Start and lock the USB 48MHz PLL (takes ~100ms) */
|
||||||
|
usb_pll_on();
|
||||||
|
while (!usb_pll_is_locked()) {}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Configures and activates the USB peripheral.
|
||||||
|
*
|
||||||
|
* @param[in] usbp pointer to the @p USBDriver object
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
void usb_lld_start(USBDriver *usbp) {
|
||||||
|
if (usbp->state == USB_STOP) {
|
||||||
|
/* Enables the peripheral.*/
|
||||||
|
#if AVR_USB_USE_USB1 == TRUE
|
||||||
|
if (&USBD1 == usbp) {
|
||||||
|
uint8_t i;
|
||||||
|
/*
|
||||||
|
* Workaround: disable pad drivers as first step in case bootloader left
|
||||||
|
* it on. Otherwise VBUS detection interrupt will not trigger later.
|
||||||
|
*/
|
||||||
|
USBCON &= ~(1 << OTGPADE);
|
||||||
|
|
||||||
|
/* Enable the internal 3.3V pad regulator */
|
||||||
|
UHWCON |= (1 << UVREGE);
|
||||||
|
|
||||||
|
/* Reset and disable all endpoints */
|
||||||
|
UERST = 0x7f;
|
||||||
|
UERST = 0;
|
||||||
|
for (i = 0; i < USB_MAX_ENDPOINTS; ++i){
|
||||||
|
UENUM = i;
|
||||||
|
UEIENX = 0;
|
||||||
|
UEINTX = 0;
|
||||||
|
UECFG1X = 0;
|
||||||
|
UECONX &= ~(1 << EPEN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/* Reset procedure enforced on driver start.*/
|
||||||
|
_usb_reset(usbp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Deactivates the USB peripheral.
|
||||||
|
*
|
||||||
|
* @param[in] usbp pointer to the @p USBDriver object
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
void usb_lld_stop(USBDriver *usbp) {
|
||||||
|
if (usbp->state == USB_READY) {
|
||||||
|
/* Disables the peripheral.*/
|
||||||
|
#if AVR_USB_USE_USB1 == TRUE
|
||||||
|
if (&USBD1 == usbp) {
|
||||||
|
/* Disable and clear transition interrupts */
|
||||||
|
USBCON &= ~((1 << VBUSTE) | (1 << IDTE));
|
||||||
|
USBINT = 0;
|
||||||
|
|
||||||
|
/* Disable and clear device interrupts */
|
||||||
|
UDIEN &= ~((1 << UPRSME) | (1 << EORSME) | (1 << WAKEUPE) | (1 << EORSTE)
|
||||||
|
| (1 << SOFE) | (1 << SUSPE));
|
||||||
|
UDINT = 0;
|
||||||
|
|
||||||
|
/* Freeze clock */
|
||||||
|
USBCON |= (1 << FRZCLK);
|
||||||
|
|
||||||
|
/* Disable USB logic */
|
||||||
|
USBCON &= ~(1 << USBE);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief USB low level reset routine.
|
||||||
|
*
|
||||||
|
* @param[in] usbp pointer to the @p USBDriver object
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
void usb_lld_reset(USBDriver *usbp) {
|
||||||
|
/* Post-reset initialization.*/
|
||||||
|
/* Reset and enable via toggling the USB macro logic overall enable bit */
|
||||||
|
USBCON &= ~(1 << USBE);
|
||||||
|
USBCON |= (1 << USBE);
|
||||||
|
|
||||||
|
/* Unfreeze clock */
|
||||||
|
USBCON &= ~(1 << FRZCLK);
|
||||||
|
|
||||||
|
/* Set Device mode */
|
||||||
|
/* TODO: Support HOST/OTG mode if needed */
|
||||||
|
UHWCON |= (1 << UIMOD);
|
||||||
|
|
||||||
|
/* Set FULL 12mbps speed */
|
||||||
|
UDCON &= ~(1 << LSM);
|
||||||
|
|
||||||
|
/* Enable device pin interrupt */
|
||||||
|
USBCON |= (1 << VBUSTE);
|
||||||
|
|
||||||
|
/* EP0 initialization.*/
|
||||||
|
UERST |= (1 << 0);
|
||||||
|
UERST &= ~(1 << 0);
|
||||||
|
usbp->epc[0] = &ep0config;
|
||||||
|
usb_lld_init_endpoint(usbp, 0);
|
||||||
|
|
||||||
|
/* Enable device-level event interrupts */
|
||||||
|
UDINT &= ~(1 << SUSPI);
|
||||||
|
UDIEN = (1 << UPRSME) | (1 << EORSME) | (1 << WAKEUPE) | (1 << EORSTE)
|
||||||
|
| (1 << SUSPE);
|
||||||
|
/* The SOF interrupt is only enabled if a callback is defined for
|
||||||
|
this service because it is a high rate source. */
|
||||||
|
if (usbp->config->sof_cb != NULL)
|
||||||
|
UDIEN |= (1 << SOFE);
|
||||||
|
|
||||||
|
/* Set OTG PAD to on which will trigger VBUS transition if plugged in. */
|
||||||
|
USBCON |= (1 << OTGPADE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sets the USB address.
|
||||||
|
*
|
||||||
|
* @param[in] usbp pointer to the @p USBDriver object
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
void usb_lld_set_address(USBDriver *usbp) {
|
||||||
|
UDADDR = (UDADDR & (1 << ADDEN)) | (usbp->address & 0x7F);
|
||||||
|
|
||||||
|
UDADDR |= (1 << ADDEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enables an endpoint.
|
||||||
|
*
|
||||||
|
* @param[in] usbp pointer to the @p USBDriver object
|
||||||
|
* @param[in] ep endpoint number
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
void usb_lld_init_endpoint(USBDriver *usbp, usbep_t ep) {
|
||||||
|
uint16_t size = 0;
|
||||||
|
const USBEndpointConfig *epcp = usbp->epc[ep];
|
||||||
|
|
||||||
|
/* Select this endpoint number for subsequent commands */
|
||||||
|
UENUM = ep & 0xf;
|
||||||
|
|
||||||
|
/* Enable endpoint to take out of reset */
|
||||||
|
UECONX |= (1 << EPEN);
|
||||||
|
|
||||||
|
UECFG1X = 0;
|
||||||
|
/* Set the endpoint type.*/
|
||||||
|
switch (epcp->ep_mode & USB_EP_MODE_TYPE) {
|
||||||
|
case USB_EP_MODE_TYPE_ISOC:
|
||||||
|
UECFG0X = (0 << EPTYPE1) | (1 << EPTYPE0);
|
||||||
|
break;
|
||||||
|
case USB_EP_MODE_TYPE_BULK:
|
||||||
|
UECFG0X = (1 << EPTYPE1) | (0 << EPTYPE0);
|
||||||
|
break;
|
||||||
|
case USB_EP_MODE_TYPE_INTR:
|
||||||
|
UECFG0X = (1 << EPTYPE1) | (1 << EPTYPE0);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
UECFG0X = (0 << EPTYPE1) | (0 << EPTYPE0);
|
||||||
|
}
|
||||||
|
if ((epcp->ep_mode & USB_EP_MODE_TYPE) == USB_EP_MODE_TYPE_CTRL) {
|
||||||
|
/* CTRL endpoint */
|
||||||
|
osalDbgCheck(epcp->in_maxsize == epcp->out_maxsize);
|
||||||
|
size = epcp->in_maxsize;
|
||||||
|
} else {
|
||||||
|
osalDbgAssert(!(epcp->in_cb != NULL && epcp->out_cb != NULL),
|
||||||
|
"On AVR each endpoint can be IN or OUT not both");
|
||||||
|
|
||||||
|
/* IN endpoint? */
|
||||||
|
if (epcp->in_cb != NULL) {
|
||||||
|
UECFG0X |= (1 << EPDIR);
|
||||||
|
size = epcp->in_maxsize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* OUT endpoint? */
|
||||||
|
if (epcp->out_cb != NULL) {
|
||||||
|
UECFG0X &= ~(1 << EPDIR);
|
||||||
|
size = epcp->out_maxsize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Endpoint size and address initialization. */
|
||||||
|
switch (size) {
|
||||||
|
case 8: UECFG1X = (0 << EPSIZE0) | (1 << ALLOC); break;
|
||||||
|
case 16: UECFG1X = (1 << EPSIZE0) | (1 << ALLOC); break;
|
||||||
|
case 32: UECFG1X = (2 << EPSIZE0) | (1 << ALLOC); break;
|
||||||
|
case 64: UECFG1X = (3 << EPSIZE0) | (1 << ALLOC); break;
|
||||||
|
case 128:
|
||||||
|
osalDbgAssert(ep == 1, "Endpoint size of 128 bytes only valid for EP#1");
|
||||||
|
UECFG1X = (4 << EPSIZE0) | (1 << ALLOC); break;
|
||||||
|
case 256:
|
||||||
|
osalDbgAssert(ep == 1, "Endpoint size of 256 bytes only valid for EP#1");
|
||||||
|
UECFG1X = (5 << EPSIZE0) | (1 << ALLOC); break;
|
||||||
|
default:
|
||||||
|
osalDbgAssert(false, "Invalid size for USB endpoint");
|
||||||
|
}
|
||||||
|
|
||||||
|
UEIENX |= (1 << RXSTPE)/* | (1 << RXOUTE)*/ | (1 << STALLEDE) ;
|
||||||
|
|
||||||
|
osalDbgAssert((UESTA0X & (1 << CFGOK)),
|
||||||
|
"Hardware reports endpoint config is INVALID");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Disables all the active endpoints except the endpoint zero.
|
||||||
|
*
|
||||||
|
* @param[in] usbp pointer to the @p USBDriver object
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
void usb_lld_disable_endpoints(USBDriver *usbp) {
|
||||||
|
uint8_t i;
|
||||||
|
for (i = 1; i <= USB_MAX_ENDPOINTS; ++i) {
|
||||||
|
UENUM = i;
|
||||||
|
UECFG1X &= ~(1 << ALLOC);
|
||||||
|
UECONX &= ~(1 << EPEN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns the status of an OUT endpoint.
|
||||||
|
*
|
||||||
|
* @param[in] usbp pointer to the @p USBDriver object
|
||||||
|
* @param[in] ep endpoint number
|
||||||
|
* @return The endpoint status.
|
||||||
|
* @retval EP_STATUS_DISABLED The endpoint is not active.
|
||||||
|
* @retval EP_STATUS_STALLED The endpoint is stalled.
|
||||||
|
* @retval EP_STATUS_ACTIVE The endpoint is active.
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
usbepstatus_t usb_lld_get_status_out(USBDriver *usbp, usbep_t ep) {
|
||||||
|
/* Select this endpoint number for subsequent commands */
|
||||||
|
UENUM = ep & 0xf;
|
||||||
|
|
||||||
|
if (!(UECONX & (1 << EPEN)))
|
||||||
|
return EP_STATUS_DISABLED;
|
||||||
|
if (UECONX & (1 << STALLRQ))
|
||||||
|
return EP_STATUS_STALLED;
|
||||||
|
return EP_STATUS_ACTIVE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns the status of an IN endpoint.
|
||||||
|
*
|
||||||
|
* @param[in] usbp pointer to the @p USBDriver object
|
||||||
|
* @param[in] ep endpoint number
|
||||||
|
* @return The endpoint status.
|
||||||
|
* @retval EP_STATUS_DISABLED The endpoint is not active.
|
||||||
|
* @retval EP_STATUS_STALLED The endpoint is stalled.
|
||||||
|
* @retval EP_STATUS_ACTIVE The endpoint is active.
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
usbepstatus_t usb_lld_get_status_in(USBDriver *usbp, usbep_t ep) {
|
||||||
|
return usb_lld_get_status_out(usbp, ep);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Reads a setup packet from the dedicated packet buffer.
|
||||||
|
* @details This function must be invoked in the context of the @p setup_cb
|
||||||
|
* callback in order to read the received setup packet.
|
||||||
|
* @pre In order to use this function the endpoint must have been
|
||||||
|
* initialized as a control endpoint.
|
||||||
|
* @post The endpoint is ready to accept another packet.
|
||||||
|
*
|
||||||
|
* @param[in] usbp pointer to the @p USBDriver object
|
||||||
|
* @param[in] ep endpoint number
|
||||||
|
* @param[out] buf buffer where to copy the packet data
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
void usb_lld_read_setup(USBDriver *usbp, usbep_t ep, uint8_t *buf) {
|
||||||
|
uint8_t i;
|
||||||
|
/* Select this endpoint number for subsequent commands */
|
||||||
|
UENUM = ep & 0xf;
|
||||||
|
|
||||||
|
for (i = 0; i < 8; ++i) {
|
||||||
|
*buf++ = UEDATX;
|
||||||
|
}
|
||||||
|
/* Clear FIFOCON and RXSTPI to drain the setup packet data from the FIFO */
|
||||||
|
UEINTX &= ~((1 << FIFOCON) | (1 << RXSTPI));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Ends a SETUP transaction
|
||||||
|
* @details This function must be invoked in the context of the @p setup_cb
|
||||||
|
* callback in order to finish an entire setup packet.
|
||||||
|
* @pre In order to use this function the endpoint must have been
|
||||||
|
* initialized as a control endpoint.
|
||||||
|
* @post The endpoint is ready to accept another packet.
|
||||||
|
*
|
||||||
|
* @param[in] usbp pointer to the @p USBDriver object
|
||||||
|
* @param[in] ep endpoint number
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
void usb_lld_end_setup(USBDriver *usbp, usbep_t ep) {
|
||||||
|
/* Select this endpoint number for subsequent commands */
|
||||||
|
UENUM = ep & 0xf;
|
||||||
|
|
||||||
|
if ((usbp->setup[0] & USB_RTYPE_DIR_MASK) == USB_RTYPE_DIR_DEV2HOST) {
|
||||||
|
/* Enable interrupt and wait for OUT packet */
|
||||||
|
usbp->epc[ep]->out_state->rxsize = 0;
|
||||||
|
usbp->epc[ep]->out_state->rxpkts = 1;
|
||||||
|
|
||||||
|
UEINTX &= ~((1 << FIFOCON) | (1 << RXOUTI));
|
||||||
|
UEIENX |= (1 << RXOUTE);
|
||||||
|
} else {
|
||||||
|
/* Enable interrupt and wait for IN packet */
|
||||||
|
usbp->epc[ep]->in_state->last_tx_size = 0;
|
||||||
|
usbp->epc[ep]->in_state->txcnt = 0;
|
||||||
|
usbp->epc[ep]->in_state->txsize = 0;
|
||||||
|
|
||||||
|
UEINTX &= ~((1 << FIFOCON) | (1 << TXINI));
|
||||||
|
UEIENX |= (1 << TXINE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Starts a receive operation on an OUT endpoint.
|
||||||
|
*
|
||||||
|
* @param[in] usbp pointer to the @p USBDriver object
|
||||||
|
* @param[in] ep endpoint number
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
void usb_lld_start_out(USBDriver *usbp, usbep_t ep) {
|
||||||
|
USBOutEndpointState *osp = usbp->epc[ep]->out_state;
|
||||||
|
syssts_t sts;
|
||||||
|
|
||||||
|
/* Initialize transfer by recording how many packets we expect to receive. */
|
||||||
|
if (osp->rxsize == 0) /* Special case for zero sized packets.*/
|
||||||
|
osp->rxpkts = 1;
|
||||||
|
else
|
||||||
|
osp->rxpkts = (uint8_t)((osp->rxsize + usbp->epc[ep]->out_maxsize - 1) /
|
||||||
|
usbp->epc[ep]->out_maxsize);
|
||||||
|
|
||||||
|
/* Select this endpoint number for subsequent commands */
|
||||||
|
/* Must lock for entire operation to ensure nothing changes the ENUM value */
|
||||||
|
sts = osalSysGetStatusAndLockX();
|
||||||
|
UENUM = ep & 0xf;
|
||||||
|
|
||||||
|
UEIENX |= (1 << RXOUTE);
|
||||||
|
osalSysRestoreStatusX(sts);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Starts a transmit operation on an IN endpoint.
|
||||||
|
*
|
||||||
|
* @param[in] usbp pointer to the @p USBDriver object
|
||||||
|
* @param[in] ep endpoint number
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
void usb_lld_start_in(USBDriver *usbp, usbep_t ep) {
|
||||||
|
USBInEndpointState *isp = usbp->epc[ep]->in_state;
|
||||||
|
syssts_t sts;
|
||||||
|
|
||||||
|
/* Initialize transfer by filling FIFO with passed data. */
|
||||||
|
usb_fifo_write(usbp, ep, isp->txsize);
|
||||||
|
|
||||||
|
/* Select this endpoint number for subsequent commands */
|
||||||
|
/* Must lock for entire operation to ensure nothing changes the ENUM value */
|
||||||
|
sts = osalSysGetStatusAndLockX();
|
||||||
|
UENUM = ep & 0xf;
|
||||||
|
|
||||||
|
/* Clear FIFOCON to send the data in the FIFO and switch bank */
|
||||||
|
UEINTX &= ~((1 << TXINI) | (1 << FIFOCON));
|
||||||
|
|
||||||
|
/* Enable the TX complete interrupt */
|
||||||
|
UEIENX |= (1 << TXINE);
|
||||||
|
|
||||||
|
osalSysRestoreStatusX(sts);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Brings an OUT endpoint in the stalled state.
|
||||||
|
*
|
||||||
|
* @param[in] usbp pointer to the @p USBDriver object
|
||||||
|
* @param[in] ep endpoint number
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
void usb_lld_stall_out(USBDriver *usbp, usbep_t ep) {
|
||||||
|
syssts_t sts;
|
||||||
|
(void)usbp;
|
||||||
|
|
||||||
|
/* Select this endpoint number for subsequent commands */
|
||||||
|
/* Must lock for entire operation to ensure nothing changes the ENUM value */
|
||||||
|
sts = osalSysGetStatusAndLockX();
|
||||||
|
UENUM = ep & 0xf;
|
||||||
|
|
||||||
|
UECONX |= (1 << STALLRQ);
|
||||||
|
osalSysRestoreStatusX(sts);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Brings an IN endpoint in the stalled state.
|
||||||
|
*
|
||||||
|
* @param[in] usbp pointer to the @p USBDriver object
|
||||||
|
* @param[in] ep endpoint number
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
void usb_lld_stall_in(USBDriver *usbp, usbep_t ep) {
|
||||||
|
usb_lld_stall_out(usbp, ep);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Brings an OUT endpoint in the active state.
|
||||||
|
*
|
||||||
|
* @param[in] usbp pointer to the @p USBDriver object
|
||||||
|
* @param[in] ep endpoint number
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
void usb_lld_clear_out(USBDriver *usbp, usbep_t ep) {
|
||||||
|
syssts_t sts;
|
||||||
|
(void)usbp;
|
||||||
|
|
||||||
|
/* Select this endpoint number for subsequent commands */
|
||||||
|
/* Must lock for entire operation to ensure nothing changes the ENUM value */
|
||||||
|
sts = osalSysGetStatusAndLockX();
|
||||||
|
UENUM = ep & 0xf;
|
||||||
|
|
||||||
|
UECONX |= (1 << STALLRQC);
|
||||||
|
osalSysRestoreStatusX(sts);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Brings an IN endpoint in the active state.
|
||||||
|
*
|
||||||
|
* @param[in] usbp pointer to the @p USBDriver object
|
||||||
|
* @param[in] ep endpoint number
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
void usb_lld_clear_in(USBDriver *usbp, usbep_t ep) {
|
||||||
|
usb_lld_clear_out(usbp, ep);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* HAL_USE_USB == TRUE */
|
||||||
|
|
||||||
|
/** @} */
|
|
@ -0,0 +1,398 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2015 Robert Lippert
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file usb_lld.h
|
||||||
|
* @brief AVR USB subsystem low level driver header.
|
||||||
|
*
|
||||||
|
* @addtogroup USB
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _USB_LLD_H_
|
||||||
|
#define _USB_LLD_H_
|
||||||
|
|
||||||
|
#if (HAL_USE_USB == TRUE) || defined(__DOXYGEN__)
|
||||||
|
|
||||||
|
#include "hal_usb.h"
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver constants. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Maximum endpoint address.
|
||||||
|
*/
|
||||||
|
#define USB_MAX_ENDPOINTS 7
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Status stage handling method.
|
||||||
|
*/
|
||||||
|
#define USB_EP0_STATUS_STAGE USB_EP0_STATUS_STAGE_HW
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The address is changed after IN packet is received.
|
||||||
|
*/
|
||||||
|
#define USB_SET_ADDRESS_MODE USB_LATE_SET_ADDRESS
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Method for set address acknowledge.
|
||||||
|
*/
|
||||||
|
#define USB_SET_ADDRESS_ACK_HANDLING USB_SET_ADDRESS_ACK_SW
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver pre-compile time settings. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name AVR configuration options
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @brief USB driver enable switch.
|
||||||
|
* @details If set to @p TRUE the support for USB1 is included.
|
||||||
|
* @note The default is @p FALSE.
|
||||||
|
*/
|
||||||
|
#if !defined(AVR_USB_USE_USB1) || defined(__DOXYGEN__)
|
||||||
|
#define AVR_USB_USE_USB1 FALSE
|
||||||
|
#endif
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If compiler supports named address spaces
|
||||||
|
* (see https://gcc.gnu.org/onlinedocs/gcc/Named-Address-Spaces.html)
|
||||||
|
* then mark our TX buf pointer as able to cover flash or SRAM to allow
|
||||||
|
* for storing/transmitting constants like USB descriptors in flash to save
|
||||||
|
* previous RAM space.
|
||||||
|
*/
|
||||||
|
#if !defined(AVR_USB_USE_NAMED_ADDRESS_SPACES) || defined(__DOXYGEN__)
|
||||||
|
#define AVR_USB_USE_NAMED_ADDRESS_SPACES FALSE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (AVR_USB_USE_NAMED_ADDRESS_SPACES == TRUE) && defined(__MEMX)
|
||||||
|
#define AVR_USB_TX_BUF_ADDRESS_SPACE volatile __memx
|
||||||
|
#else
|
||||||
|
#define AVR_USB_TX_BUF_ADDRESS_SPACE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Derived constants and error checks. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver data structures and types. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
typedef const AVR_USB_TX_BUF_ADDRESS_SPACE uint8_t *usbbufptr_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Type of an IN endpoint state structure.
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
/**
|
||||||
|
* @brief Requested transmit transfer size.
|
||||||
|
*/
|
||||||
|
size_t txsize;
|
||||||
|
/**
|
||||||
|
* @brief Transmitted bytes so far.
|
||||||
|
*/
|
||||||
|
size_t txcnt;
|
||||||
|
/**
|
||||||
|
* @brief Pointer to the transmission linear buffer.
|
||||||
|
*/
|
||||||
|
usbbufptr_t txbuf;
|
||||||
|
#if (USB_USE_WAIT == TRUE) || defined(__DOXYGEN__)
|
||||||
|
/**
|
||||||
|
* @brief Waiting thread.
|
||||||
|
*/
|
||||||
|
thread_reference_t thread;
|
||||||
|
#endif
|
||||||
|
/* End of the mandatory fields.*/
|
||||||
|
/**
|
||||||
|
* @brief Number of expected bytes in the most recent transmission.
|
||||||
|
*/
|
||||||
|
size_t last_tx_size;
|
||||||
|
} USBInEndpointState;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Type of an OUT endpoint state structure.
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
/**
|
||||||
|
* @brief Requested receive transfer size.
|
||||||
|
*/
|
||||||
|
size_t rxsize;
|
||||||
|
/**
|
||||||
|
* @brief Received bytes so far.
|
||||||
|
*/
|
||||||
|
size_t rxcnt;
|
||||||
|
/**
|
||||||
|
* @brief Pointer to the receive linear buffer.
|
||||||
|
*/
|
||||||
|
uint8_t *rxbuf;
|
||||||
|
#if (USB_USE_WAIT == TRUE) || defined(__DOXYGEN__)
|
||||||
|
/**
|
||||||
|
* @brief Waiting thread.
|
||||||
|
*/
|
||||||
|
thread_reference_t thread;
|
||||||
|
#endif
|
||||||
|
/* End of the mandatory fields.*/
|
||||||
|
uint8_t rxpkts;
|
||||||
|
} USBOutEndpointState;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Type of an USB endpoint configuration structure.
|
||||||
|
* @note Platform specific restrictions may apply to endpoints.
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
/**
|
||||||
|
* @brief Type and mode of the endpoint.
|
||||||
|
*/
|
||||||
|
uint32_t ep_mode;
|
||||||
|
/**
|
||||||
|
* @brief Setup packet notification callback.
|
||||||
|
* @details This callback is invoked when a setup packet has been
|
||||||
|
* received.
|
||||||
|
* @post The application must immediately call @p usbReadPacket() in
|
||||||
|
* order to access the received packet.
|
||||||
|
* @note This field is only valid for @p USB_EP_MODE_TYPE_CTRL
|
||||||
|
* endpoints, it should be set to @p NULL for other endpoint
|
||||||
|
* types.
|
||||||
|
*/
|
||||||
|
usbepcallback_t setup_cb;
|
||||||
|
/**
|
||||||
|
* @brief IN endpoint notification callback.
|
||||||
|
* @details This field must be set to @p NULL if the IN endpoint is not
|
||||||
|
* used.
|
||||||
|
*/
|
||||||
|
usbepcallback_t in_cb;
|
||||||
|
/**
|
||||||
|
* @brief OUT endpoint notification callback.
|
||||||
|
* @details This field must be set to @p NULL if the OUT endpoint is not
|
||||||
|
* used.
|
||||||
|
*/
|
||||||
|
usbepcallback_t out_cb;
|
||||||
|
/**
|
||||||
|
* @brief IN endpoint maximum packet size.
|
||||||
|
* @details This field must be set to zero if the IN endpoint is not
|
||||||
|
* used.
|
||||||
|
*/
|
||||||
|
uint16_t in_maxsize;
|
||||||
|
/**
|
||||||
|
* @brief OUT endpoint maximum packet size.
|
||||||
|
* @details This field must be set to zero if the OUT endpoint is not
|
||||||
|
* used.
|
||||||
|
*/
|
||||||
|
uint16_t out_maxsize;
|
||||||
|
/**
|
||||||
|
* @brief @p USBEndpointState associated to the IN endpoint.
|
||||||
|
* @details This structure maintains the state of the IN endpoint.
|
||||||
|
*/
|
||||||
|
USBInEndpointState *in_state;
|
||||||
|
/**
|
||||||
|
* @brief @p USBEndpointState associated to the OUT endpoint.
|
||||||
|
* @details This structure maintains the state of the OUT endpoint.
|
||||||
|
*/
|
||||||
|
USBOutEndpointState *out_state;
|
||||||
|
/* End of the mandatory fields.*/
|
||||||
|
} USBEndpointConfig;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Type of an USB driver configuration structure.
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
/**
|
||||||
|
* @brief USB events callback.
|
||||||
|
* @details This callback is invoked when an USB driver event is registered.
|
||||||
|
*/
|
||||||
|
usbeventcb_t event_cb;
|
||||||
|
/**
|
||||||
|
* @brief Device GET_DESCRIPTOR request callback.
|
||||||
|
* @note This callback is mandatory and cannot be set to @p NULL.
|
||||||
|
*/
|
||||||
|
usbgetdescriptor_t get_descriptor_cb;
|
||||||
|
/**
|
||||||
|
* @brief Requests hook callback.
|
||||||
|
* @details This hook allows to be notified of standard requests or to
|
||||||
|
* handle non standard requests.
|
||||||
|
*/
|
||||||
|
usbreqhandler_t requests_hook_cb;
|
||||||
|
/**
|
||||||
|
* @brief Start Of Frame callback.
|
||||||
|
*/
|
||||||
|
usbcallback_t sof_cb;
|
||||||
|
/* End of the mandatory fields.*/
|
||||||
|
} USBConfig;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Structure representing an USB driver.
|
||||||
|
*/
|
||||||
|
struct USBDriver {
|
||||||
|
/**
|
||||||
|
* @brief Driver state.
|
||||||
|
*/
|
||||||
|
usbstate_t state;
|
||||||
|
/**
|
||||||
|
* @brief Current configuration data.
|
||||||
|
*/
|
||||||
|
const USBConfig *config;
|
||||||
|
/**
|
||||||
|
* @brief Bit map of the transmitting IN endpoints.
|
||||||
|
*/
|
||||||
|
uint8_t transmitting;
|
||||||
|
/**
|
||||||
|
* @brief Bit map of the receiving OUT endpoints.
|
||||||
|
*/
|
||||||
|
uint8_t receiving;
|
||||||
|
/**
|
||||||
|
* @brief Active endpoints configurations.
|
||||||
|
*/
|
||||||
|
const USBEndpointConfig *epc[USB_MAX_ENDPOINTS + 1];
|
||||||
|
/**
|
||||||
|
* @brief Fields available to user, it can be used to associate an
|
||||||
|
* application-defined handler to an IN endpoint.
|
||||||
|
* @note The base index is one, the endpoint zero does not have a
|
||||||
|
* reserved element in this array.
|
||||||
|
*/
|
||||||
|
void *in_params[USB_MAX_ENDPOINTS];
|
||||||
|
/**
|
||||||
|
* @brief Fields available to user, it can be used to associate an
|
||||||
|
* application-defined handler to an OUT endpoint.
|
||||||
|
* @note The base index is one, the endpoint zero does not have a
|
||||||
|
* reserved element in this array.
|
||||||
|
*/
|
||||||
|
void *out_params[USB_MAX_ENDPOINTS];
|
||||||
|
/**
|
||||||
|
* @brief Endpoint 0 state.
|
||||||
|
*/
|
||||||
|
usbep0state_t ep0state;
|
||||||
|
/**
|
||||||
|
* @brief Next position in the buffer to be transferred through endpoint 0.
|
||||||
|
*/
|
||||||
|
const AVR_USB_TX_BUF_ADDRESS_SPACE uint8_t *ep0next;
|
||||||
|
/**
|
||||||
|
* @brief Number of bytes yet to be transferred through endpoint 0.
|
||||||
|
*/
|
||||||
|
size_t ep0n;
|
||||||
|
/**
|
||||||
|
* @brief Endpoint 0 end transaction callback.
|
||||||
|
*/
|
||||||
|
usbcallback_t ep0endcb;
|
||||||
|
/**
|
||||||
|
* @brief Setup packet buffer.
|
||||||
|
*/
|
||||||
|
uint8_t setup[8];
|
||||||
|
/**
|
||||||
|
* @brief Current USB device status.
|
||||||
|
*/
|
||||||
|
uint16_t status;
|
||||||
|
/**
|
||||||
|
* @brief Assigned USB address.
|
||||||
|
*/
|
||||||
|
uint8_t address;
|
||||||
|
/**
|
||||||
|
* @brief Current USB device configuration.
|
||||||
|
*/
|
||||||
|
uint8_t configuration;
|
||||||
|
#if defined(USB_DRIVER_EXT_FIELDS)
|
||||||
|
USB_DRIVER_EXT_FIELDS
|
||||||
|
#endif
|
||||||
|
/* End of the mandatory fields.*/
|
||||||
|
};
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver macros. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns the current frame number.
|
||||||
|
*
|
||||||
|
* @param[in] usbp pointer to the @p USBDriver object
|
||||||
|
* @return The current frame number.
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
#define usb_lld_get_frame_number(usbp) (UDFNUM)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns the exact size of a receive transaction.
|
||||||
|
* @details The received size can be different from the size specified in
|
||||||
|
* @p usbStartReceiveI() because the last packet could have a size
|
||||||
|
* different from the expected one.
|
||||||
|
* @pre The OUT endpoint must have been configured in transaction mode
|
||||||
|
* in order to use this function.
|
||||||
|
*
|
||||||
|
* @param[in] usbp pointer to the @p USBDriver object
|
||||||
|
* @param[in] ep endpoint number
|
||||||
|
* @return Received data size.
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
#define usb_lld_get_transaction_size(usbp, ep) \
|
||||||
|
((usbp)->epc[ep]->out_state->rxcnt)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Connects the USB device.
|
||||||
|
*
|
||||||
|
* @api
|
||||||
|
*/
|
||||||
|
#define usb_lld_connect_bus(usbp) (UDCON &= ~(1 << DETACH))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Disconnect the USB device.
|
||||||
|
*
|
||||||
|
* @api
|
||||||
|
*/
|
||||||
|
#define usb_lld_disconnect_bus(usbp) (UDCON |= (1 << DETACH))
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* External declarations. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
#if (AVR_USB_USE_USB1 == TRUE) && !defined(__DOXYGEN__)
|
||||||
|
extern USBDriver USBD1;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
void usb_lld_init(void);
|
||||||
|
void usb_lld_start(USBDriver *usbp);
|
||||||
|
void usb_lld_stop(USBDriver *usbp);
|
||||||
|
void usb_lld_reset(USBDriver *usbp);
|
||||||
|
void usb_lld_set_address(USBDriver *usbp);
|
||||||
|
void usb_lld_enable_address(USBDriver *usbp);
|
||||||
|
void usb_lld_init_endpoint(USBDriver *usbp, usbep_t ep);
|
||||||
|
void usb_lld_disable_endpoints(USBDriver *usbp);
|
||||||
|
usbepstatus_t usb_lld_get_status_in(USBDriver *usbp, usbep_t ep);
|
||||||
|
usbepstatus_t usb_lld_get_status_out(USBDriver *usbp, usbep_t ep);
|
||||||
|
void usb_lld_read_setup(USBDriver *usbp, usbep_t ep, uint8_t *buf);
|
||||||
|
void usb_lld_end_setup(USBDriver *usbp, usbep_t ep);
|
||||||
|
void usb_lld_start_out(USBDriver *usbp, usbep_t ep);
|
||||||
|
void usb_lld_start_in(USBDriver *usbp, usbep_t ep);
|
||||||
|
void usb_lld_stall_out(USBDriver *usbp, usbep_t ep);
|
||||||
|
void usb_lld_stall_in(USBDriver *usbp, usbep_t ep);
|
||||||
|
void usb_lld_clear_out(USBDriver *usbp, usbep_t ep);
|
||||||
|
void usb_lld_clear_in(USBDriver *usbp, usbep_t ep);
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* HAL_USE_USB == TRUE */
|
||||||
|
|
||||||
|
#endif /* _USB_LLD_H_ */
|
||||||
|
|
||||||
|
/** @} */
|
|
@ -8,6 +8,7 @@ PLATFORMSRC = ${CHIBIOS}/os/hal/ports/AVR/hal_lld.c \
|
||||||
${CHIBIOS}/os/hal/ports/AVR/hal_gpt_lld.c \
|
${CHIBIOS}/os/hal/ports/AVR/hal_gpt_lld.c \
|
||||||
${CHIBIOS}/os/hal/ports/AVR/hal_pwm_lld.c \
|
${CHIBIOS}/os/hal/ports/AVR/hal_pwm_lld.c \
|
||||||
${CHIBIOS}/os/hal/ports/AVR/hal_icu_lld.c \
|
${CHIBIOS}/os/hal/ports/AVR/hal_icu_lld.c \
|
||||||
|
${CHIBIOS}/os/hal/ports/AVR/hal_usb_lld.c \
|
||||||
${CHIBIOS}/os/hal/ports/AVR/hal_st_lld.c
|
${CHIBIOS}/os/hal/ports/AVR/hal_st_lld.c
|
||||||
|
|
||||||
# Required include directories
|
# Required include directories
|
||||||
|
|
Loading…
Reference in New Issue