Commits

Trammell Hudson committed 8aaee28 Draft

move patch-panel code into subdir

Comments (0)

Files changed (14)

Makefile

-# 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".
-#----------------------------------------------------------------------------
-
-
-# Target file name (without extension).
-TARGET = patch-console
-
-
-# List C source files here. (C dependencies are automatically generated.)
-SRC =	$(TARGET).c \
-	bits.c \
-	usb_serial.c \
-
-
-# MCU name, you MUST set this to match the board you are using
-# type "make clean" after changing this, so all files will be rebuilt
-#
-#MCU = at90usb162       # Teensy 1.0
-#MCU = atmega32u4        # Teensy 2.0
-#MCU = at90usb646       # Teensy++ 1.0
-MCU = at90usb1286      # Teensy++ 2.0
-
-
-# Processor frequency.
-#   Normally the first thing your program should do is set the clock prescaler,
-#   so your program will run at the correct speed.  You should also set this
-#   variable to same clock speed.  The _delay_ms() macro uses this, and many
-#   examples use this variable to calculate timings.  Do not add a "UL" here.
-F_CPU = 16000000
-
-
-# Output format. (can be srec, ihex, binary)
-FORMAT = ihex
-
-
-# Object files directory
-#     To put object files in current directory, use a dot (.), do NOT make
-#     this an empty or blank macro!
-OBJDIR = .
-
-
-# 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 = 
-
-
-# Compiler flag to set the C Standard level.
-#     c89   = "ANSI" C
-#     gnu89 = c89 plus GCC extensions
-#     c99   = ISO C99 standard (not yet fully implemented)
-#     gnu99 = c99 plus GCC extensions
-CSTANDARD = -std=gnu99
-
-
-# Place -D or -U options here for C sources
-CDEFS = -DF_CPU=$(F_CPU)UL
-
-
-# Place -D or -U options here for ASM sources
-ADEFS = -DF_CPU=$(F_CPU)
-
-
-# Place -D or -U options here for C++ sources
-CPPDEFS = -DF_CPU=$(F_CPU)UL
-#CPPDEFS += -D__STDC_LIMIT_MACROS
-#CPPDEFS += -D__STDC_CONSTANT_MACROS
-
-
-
-#---------------- Compiler Options C ----------------
-#  -g*:          generate debugging information
-#  -O*:          optimization level
-#  -f...:        tuning, see GCC manual and avr-libc documentation
-#  -Wall...:     warning level
-#  -Wa,...:      tell GCC to pass this to the assembler.
-#    -adhlns...: create assembler listing
-CFLAGS = -g$(DEBUG)
-CFLAGS += $(CDEFS)
-CFLAGS += -O$(OPT)
-CFLAGS += -funsigned-char
-CFLAGS += -funsigned-bitfields
-CFLAGS += -ffunction-sections
-CFLAGS += -fpack-struct
-CFLAGS += -fshort-enums
-CFLAGS += -Wall
-CFLAGS += -Wstrict-prototypes
-#CFLAGS += -mshort-calls
-#CFLAGS += -fno-unit-at-a-time
-#CFLAGS += -Wundef
-#CFLAGS += -Wunreachable-code
-#CFLAGS += -Wsign-compare
-CFLAGS += -Wa,-adhlns=$(<:%.c=$(OBJDIR)/%.lst)
-CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS))
-CFLAGS += $(CSTANDARD)
-
-
-#---------------- Compiler Options C++ ----------------
-#  -g*:          generate debugging information
-#  -O*:          optimization level
-#  -f...:        tuning, see GCC manual and avr-libc documentation
-#  -Wall...:     warning level
-#  -Wa,...:      tell GCC to pass this to the assembler.
-#    -adhlns...: create assembler listing
-CPPFLAGS = -g$(DEBUG)
-CPPFLAGS += $(CPPDEFS)
-CPPFLAGS += -O$(OPT)
-CPPFLAGS += -funsigned-char
-CPPFLAGS += -funsigned-bitfields
-CPPFLAGS += -fpack-struct
-CPPFLAGS += -fshort-enums
-CPPFLAGS += -fno-exceptions
-CPPFLAGS += -Wall
-CPPFLAGS += -Wundef
-#CPPFLAGS += -mshort-calls
-#CPPFLAGS += -fno-unit-at-a-time
-#CPPFLAGS += -Wstrict-prototypes
-#CPPFLAGS += -Wunreachable-code
-#CPPFLAGS += -Wsign-compare
-CPPFLAGS += -Wa,-adhlns=$(<:%.cpp=$(OBJDIR)/%.lst)
-CPPFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS))
-#CPPFLAGS += $(CSTANDARD)
-
-
-#---------------- Assembler Options ----------------
-#  -Wa,...:   tell GCC to pass this to the assembler.
-#  -adhlns:   create listing
-#  -gstabs:   have the assembler create line number information; note that
-#             for use in COFF files, additional information about filenames
-#             and function names needs to be present in the assembler source
-#             files -- see avr-libc docs [FIXME: not yet described there]
-#  -listing-cont-lines: Sets the maximum number of continuation lines of hex 
-#       dump that will be displayed for a given single line of source input.
-ASFLAGS = $(ADEFS) -Wa,-adhlns=$(<:%.S=$(OBJDIR)/%.lst),-gstabs,--listing-cont-lines=100
-
-
-#---------------- Library Options ----------------
-# Minimalistic printf version
-PRINTF_LIB_MIN = -Wl,-u,vfprintf -lprintf_min
-
-# Floating point printf version (requires MATH_LIB = -lm below)
-PRINTF_LIB_FLOAT = -Wl,-u,vfprintf -lprintf_flt
-
-# If this is left blank, then it will use the Standard printf version.
-PRINTF_LIB = 
-#PRINTF_LIB = $(PRINTF_LIB_MIN)
-#PRINTF_LIB = $(PRINTF_LIB_FLOAT)
-
-
-# Minimalistic scanf version
-SCANF_LIB_MIN = -Wl,-u,vfscanf -lscanf_min
-
-# Floating point + %[ scanf version (requires MATH_LIB = -lm below)
-SCANF_LIB_FLOAT = -Wl,-u,vfscanf -lscanf_flt
-
-# If this is left blank, then it will use the Standard scanf version.
-SCANF_LIB = 
-#SCANF_LIB = $(SCANF_LIB_MIN)
-#SCANF_LIB = $(SCANF_LIB_FLOAT)
-
-
-MATH_LIB = -lm
-
-
-# List any extra directories to look for libraries here.
-#     Each directory must be seperated by a space.
-#     Use forward slashes for directory separators.
-#     For a directory that has spaces, enclose it in quotes.
-EXTRALIBDIRS = 
-
-
-
-#---------------- External Memory Options ----------------
-
-# 64 KB of external RAM, starting after internal RAM (ATmega128!),
-# used for variables (.data/.bss) and heap (malloc()).
-#EXTMEMOPTS = -Wl,-Tdata=0x801100,--defsym=__heap_end=0x80ffff
-
-# 64 KB of external RAM, starting after internal RAM (ATmega128!),
-# only used for heap (malloc()).
-#EXTMEMOPTS = -Wl,--section-start,.data=0x801100,--defsym=__heap_end=0x80ffff
-
-EXTMEMOPTS =
-
-
-
-#---------------- Linker Options ----------------
-#  -Wl,...:     tell GCC to pass this to linker.
-#    -Map:      create map file
-#    --cref:    add cross reference to  map file
-LDFLAGS = -Wl,-Map=$(TARGET).map,--cref
-LDFLAGS += -Wl,--relax
-LDFLAGS += -Wl,--gc-sections
-LDFLAGS += $(EXTMEMOPTS)
-LDFLAGS += $(patsubst %,-L%,$(EXTRALIBDIRS))
-LDFLAGS += $(PRINTF_LIB) $(SCANF_LIB) $(MATH_LIB)
-#LDFLAGS += -T linker_script.x
-
-#---------------- Platform detection -------------
-UNAME := $(shell uname)
-
-#---------------- Programming Options (avrdude) ----------------
-
-# Programming hardware
-# Type: avrdude -c ?
-# to get a full listing.
-#
-AVRDUDE_PROGRAMMER = stk500v2
-
-# com1 = serial port. Use lpt1 to connect to parallel port.
-ifeq ($(UNAME), Linux)
-	AVRDUDE_PORT = /dev/ttyACM0    # programmer connected to serial device
-else
-	AVRDUDE_PORT = com1
-endif
-
-AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex
-#AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep
-
-
-# Uncomment the following if you want avrdude's erase cycle counter.
-# Note that this counter needs to be initialized first using -Yn,
-# see avrdude manual.
-#AVRDUDE_ERASE_COUNTER = -y
-
-# Uncomment the following if you do /not/ wish a verification to be
-# performed after programming the device.
-#AVRDUDE_NO_VERIFY = -V
-
-# Increase verbosity level.  Please use this when submitting bug
-# reports about avrdude. See <http://savannah.nongnu.org/projects/avrdude> 
-# to submit bug reports.
-#AVRDUDE_VERBOSE = -v -v
-
-AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER)
-AVRDUDE_FLAGS += $(AVRDUDE_NO_VERIFY)
-AVRDUDE_FLAGS += $(AVRDUDE_VERBOSE)
-AVRDUDE_FLAGS += $(AVRDUDE_ERASE_COUNTER)
-
-
-
-#---------------- Debugging Options ----------------
-
-# For simulavr only - target MCU frequency.
-DEBUG_MFREQ = $(F_CPU)
-
-# Set the DEBUG_UI to either gdb or insight.
-# DEBUG_UI = gdb
-DEBUG_UI = insight
-
-# Set the debugging back-end to either avarice, simulavr.
-DEBUG_BACKEND = avarice
-#DEBUG_BACKEND = simulavr
-
-# GDB Init Filename.
-GDBINIT_FILE = __avr_gdbinit
-
-# When using avarice settings for the JTAG
-JTAG_DEV = /dev/com1
-
-# Debugging port used to communicate between GDB / avarice / simulavr.
-DEBUG_PORT = 4242
-
-# Debugging host used to communicate between GDB / avarice / simulavr, normally
-#     just set to localhost unless doing some sort of crazy debugging when 
-#     avarice is running on a different computer.
-DEBUG_HOST = localhost
-
-
-
-#============================================================================
-
-
-# Define programs and commands.
-SHELL = sh
-ifeq ($(UNAME), Linux)
-	AVR_PATH = /usr
-else
-	AVR_PATH = /Applications/Arduino.app/Contents//Resources/Java/hardware/tools/avr
-endif
-
-CC = $(AVR_PATH)/bin/avr-gcc
-OBJCOPY = $(AVR_PATH)/bin/avr-objcopy
-OBJDUMP = $(AVR_PATH)/bin/avr-objdump
-SIZE = $(AVR_PATH)/bin/avr-size
-AR = $(AVR_PATH)/bin/avr-ar rcs
-NM = $(AVR_PATH)/bin/avr-nm
-AVRDUDE = $(AVR_PATH)/bin/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
-
-## Include the files from avr/include/
-#CFLAGS += -I$(AVR_PATH)/include
-
-# Combine all necessary flags and optional flags.
-# Add target processor to flags.
-ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) $(GENDEPFLAGS)
-ALL_CPPFLAGS = -mmcu=$(MCU) -I. -x c++ $(CPPFLAGS) $(GENDEPFLAGS)
-ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS)
-
-
-
-
-
-# Default target.
-all: begin gccversion sizebefore build sizeafter end
-
-# Change the build target to build a HEX file or a library.
-build: elf hex eep lss sym
-#build: lib
-
-
-elf: $(TARGET).elf
-hex: $(TARGET).hex
-eep: $(TARGET).eep
-lss: $(TARGET).lss
-sym: $(TARGET).sym
-LIBNAME=lib$(TARGET).a
-lib: $(LIBNAME)
-
-
-
-# Eye candy.
-# AVR Studio 3.x does not check make's exit code but relies on
-# the following magic strings to be generated by the compile job.
-begin:
-	@echo
-	@echo $(MSG_BEGIN)
-
-end:
-	@echo $(MSG_END)
-	@echo
-
-
-# Display size of file.
-HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex
-#ELFSIZE = $(SIZE) --mcu=$(MCU) --format=avr $(TARGET).elf
-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.  
-ifeq ($(UNAME), Linux)
-program: $(TARGET).hex $(TARGET).eep
-	~/opt/teensy_loader_cli/teensy_loader_cli -mmcu=$(MCU) -w $(TARGET).hex
-else
-program: $(TARGET).hex $(TARGET).eep
-	$(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM)
-endif
-
-
-
-# Generate avr-gdb config/init file which does the following:
-#     define the reset signal, load the target file, connect to target, and set 
-#     a breakpoint at main().
-gdb-config: 
-	@$(REMOVE) $(GDBINIT_FILE)
-	@echo define reset >> $(GDBINIT_FILE)
-	@echo SIGNAL SIGHUP >> $(GDBINIT_FILE)
-	@echo end >> $(GDBINIT_FILE)
-	@echo file $(TARGET).elf >> $(GDBINIT_FILE)
-	@echo target remote $(DEBUG_HOST):$(DEBUG_PORT)  >> $(GDBINIT_FILE)
-ifeq ($(DEBUG_BACKEND),simulavr)
-	@echo load  >> $(GDBINIT_FILE)
-endif
-	@echo break main >> $(GDBINIT_FILE)
-
-debug: gdb-config $(TARGET).elf
-ifeq ($(DEBUG_BACKEND), avarice)
-	@echo Starting AVaRICE - Press enter when "waiting to connect" message displays.
-	@$(WINSHELL) /c start avarice --jtag $(JTAG_DEV) --erase --program --file \
-	$(TARGET).elf $(DEBUG_HOST):$(DEBUG_PORT)
-	@$(WINSHELL) /c pause
-
-else
-	@$(WINSHELL) /c start simulavr --gdbserver --device $(MCU) --clock-freq \
-	$(DEBUG_MFREQ) --port $(DEBUG_PORT)
-endif
-	@$(WINSHELL) /c start avr-$(DEBUG_UI) --command=$(GDBINIT_FILE)
-
-
-
-
-# Convert ELF to COFF for use in debugging / simulating in AVR Studio or VMLAB.
-COFFCONVERT = $(OBJCOPY) --debugging
-COFFCONVERT += --change-section-address .data-0x800000
-COFFCONVERT += --change-section-address .bss-0x800000
-COFFCONVERT += --change-section-address .noinit-0x800000
-COFFCONVERT += --change-section-address .eeprom-0x810000
-
-
-
-coff: $(TARGET).elf
-	@echo
-	@echo $(MSG_COFF) $(TARGET).cof
-	$(COFFCONVERT) -O coff-avr $< $(TARGET).cof
-
-
-extcoff: $(TARGET).elf
-	@echo
-	@echo $(MSG_EXTENDED_COFF) $(TARGET).cof
-	$(COFFCONVERT) -O coff-ext-avr $< $(TARGET).cof
-
-
-
-# Create final output files (.hex, .eep) from ELF output file.
-%.hex: %.elf
-	@echo
-	@echo $(MSG_FLASH) $@
-	$(OBJCOPY) -O $(FORMAT) -R .eeprom -R .fuse -R .lock -R .signature $< $@
-
-%.eep: %.elf
-	@echo
-	@echo $(MSG_EEPROM) $@
-	-$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \
-	--change-section-lma .eeprom=0 --no-change-warnings -O $(FORMAT) $< $@ || exit 0
-
-# Create extended listing file from ELF output file.
-%.lss: %.elf
-	@echo
-	@echo $(MSG_EXTENDED_LISTING) $@
-	$(OBJDUMP) -h -S -z $< > $@
-
-# Create a symbol table from ELF output file.
-%.sym: %.elf
-	@echo
-	@echo $(MSG_SYMBOL_TABLE) $@
-	$(NM) -n $< > $@
-
-
-
-# Create library from object files.
-.SECONDARY : $(TARGET).a
-.PRECIOUS : $(OBJ)
-%.a: $(OBJ)
-	@echo
-	@echo $(MSG_CREATING_LIBRARY) $@
-	$(AR) $@ $(OBJ)
-
-
-# Link: create ELF output file from object files.
-.SECONDARY : $(TARGET).elf
-.PRECIOUS : $(OBJ)
-%.elf: $(OBJ)
-	@echo
-	@echo $(MSG_LINKING) $@
-	$(CC) $(ALL_CFLAGS) $^ --output $@ $(LDFLAGS)
-
-
-# Compile: create object files from C source files.
-$(OBJDIR)/%.o : %.c
-	@echo
-	@echo $(MSG_COMPILING) $<
-	$(CC) -c $(ALL_CFLAGS) $< -o $@ 
-
-
-# Compile: create object files from C++ source files.
-$(OBJDIR)/%.o : %.cpp
-	@echo
-	@echo $(MSG_COMPILING_CPP) $<
-	$(CC) -c $(ALL_CPPFLAGS) $< -o $@ 
-
-
-# Compile: create assembler files from C source files.
-%.s : %.c
-	$(CC) -S $(ALL_CFLAGS) $< -o $@
-
-
-# Compile: create assembler files from C++ source files.
-%.s : %.cpp
-	$(CC) -S $(ALL_CPPFLAGS) $< -o $@
-
-
-# Assemble: create object files from assembler source files.
-$(OBJDIR)/%.o : %.S
-	@echo
-	@echo $(MSG_ASSEMBLING) $<
-	$(CC) -c $(ALL_ASFLAGS) $< -o $@
-
-
-# Create preprocessed source for use in sending a bug report.
-%.i : %.c
-	$(CC) -E -mmcu=$(MCU) -I. $(CFLAGS) $< -o $@ 
-
-
-# Target: clean project.
-clean: begin clean_list end
-
-clean_list :
-	@echo
-	@echo $(MSG_CLEANING)
-	$(REMOVE) $(TARGET).hex
-	$(REMOVE) $(TARGET).eep
-	$(REMOVE) $(TARGET).cof
-	$(REMOVE) $(TARGET).elf
-	$(REMOVE) $(TARGET).map
-	$(REMOVE) $(TARGET).sym
-	$(REMOVE) $(TARGET).lss
-	$(REMOVE) $(SRC:%.c=$(OBJDIR)/%.o)
-	$(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 eep lss sym coff extcoff \
-clean clean_list program debug gdb-config

bits.c

-/** \file Access to AVR pins via constants.
- *
- * ddr(0xA3, 1) == enable DDRA |= (1 << 3)
- * out(0xA3, 1) == PORTA |= (1 << 3)
- * in(0xA3) == PINA & (1 << 3)
- */
-#include <avr/io.h>
-#include <avr/pgmspace.h>
-#include "bits.h"
-
-#define set_bit(PORT, PIN, VALUE) do { \
-		if (VALUE) \
-			sbi(PORT, PIN); \
-		else \
-			cbi(PORT, PIN); \
-	} while (0)
-
-#define get_bit(PORT, PIN) \
-	((PORT) & (1 << PIN))
-
-
-void
-ddr(
-	const uint8_t id,
-	const uint8_t value
-)
-{
-	const uint8_t port = (id >> 4) & 0xF;
-	const uint8_t pin = (id >> 0) & 0xF;
-
-	switch (port)
-	{
-	case 0xA:
-		set_bit(DDRA, pin, value);
-		return;
-	case 0xB:
-		set_bit(DDRB, pin, value);
-		return;
-	case 0xC:
-		set_bit(DDRC, pin, value);
-		return;
-	case 0xD:
-		set_bit(DDRD, pin, value);
-		return;
-	case 0xE:
-		set_bit(DDRE, pin, value);
-		return;
-	case 0xF:
-		set_bit(DDRF, pin, value);
-		return;
-	}
-}
-
-
-void
-out(
-	const uint8_t id,
-	const uint8_t value
-)
-{
-	const uint8_t port = (id >> 4) & 0xF;
-	const uint8_t pin = (id >> 0) & 0xF;
-
-	switch (port)
-	{
-	case 0xA:
-		set_bit(PORTA, pin, value);
-		return;
-	case 0xB:
-		set_bit(PORTB, pin, value);
-		return;
-	case 0xC:
-		set_bit(PORTC, pin, value);
-		return;
-	case 0xD:
-		set_bit(PORTD, pin, value);
-		return;
-	case 0xE:
-		set_bit(PORTE, pin, value);
-		return;
-	case 0xF:
-		set_bit(PORTF, pin, value);
-		return;
-	}
-}
-
-
-uint8_t
-in(
-	const uint8_t id
-)
-{
-	const uint8_t port = (id >> 4) & 0xF;
-	const uint8_t pin = (id >> 0) & 0xF;
-
-	switch (port)
-	{
-	case 0xA:
-		return get_bit(PINA, pin);
-	case 0xB:
-		return get_bit(PINB, pin);
-	case 0xC:
-		return get_bit(PINC, pin);
-	case 0xD:
-		return get_bit(PIND, pin);
-	case 0xE:
-		return get_bit(PINE, pin);
-	case 0xF:
-		return get_bit(PINF, pin);
-	}
-
-	return 0;
-}

bits.h

-#ifndef _prom_bits_h_
-#define _prom_bits_h_
-
-#include <stdint.h>
-
-#define sbi(PORT, PIN) ((PORT) |=  (1 << (PIN)))
-#define cbi(PORT, PIN) ((PORT) &= ~(1 << (PIN)))
-#define array_count(ARRAY) (sizeof(ARRAY) / sizeof(*(ARRAY)))
-#define _STR(X) #X
-#define STR(X) _STR(X)
-
-
-extern void
-ddr(
-	const uint8_t port,
-	const uint8_t value
-);
-
-
-extern void
-out(
-	const uint8_t port,
-	uint8_t value
-);
-
-
-extern uint8_t
-in(
-	uint8_t port
-);
-
-#endif

patch-console.c

-/**
- * \file Future crew patch panel
- *
- * Figure out which ports on the patch panel are cross connected
- */
-
-#include <avr/io.h>
-#include <avr/pgmspace.h>
-#include <avr/interrupt.h>
-#include <stdint.h>
-#include <string.h>
-#include <util/delay.h>
-#include "usb_serial.h"
-#include "bits.h"
-
-void send_mem_str(const char *s);
-uint8_t recv_str(char *buf, uint8_t size);
-void parse_and_execute_command(const char *buf, uint8_t num);
-
-static uint8_t
-hexdigit(
-	uint8_t x
-)
-{
-	x &= 0xF;
-	if (x < 0xA)
-		return x + '0' - 0x0;
-	else
-		return x + 'A' - 0xA;
-}
-
-
-static const uint8_t ports[] = {
-	0xB6,
-	0xB5,
-	0xB4,
-	0xB3,
-	0xB2,
-	0xB1,
-	0xB0,
-	0xE7,
-	0xE6,
-	0xF0,
-	0xF1,
-	0xF2,
-	0xF3,
-	0xF4,
-	0xF5,
-	0xF6,
-	0xF7,
-
-	0xC7,
-	0xC6,
-	0xC5,
-	0xC4,
-	0xC3,
-	0xC2,
-	0xC1,
-	0xC0,
-	0xE1,
-	0xE0,
-	0xD7,
-	0xD5,
-	0xD4,
-	0xD3,
-	0xD2,
-	0xD1,
-	0xD0,
-	0xB7,
-
-/*
-	0xA0,
-	0xA1,
-	0xA2,
-	0xA3,
-	0xA4,
-	0xA5,
-	0xA6,
-	0xA7,
-*/
-};
-
-#define INPUT_COUNT (sizeof(ports) / sizeof(*ports))
-//#define INPUT_COUNT 28
-
-
-int main(void)
-{
-	// set for 16 MHz clock
-#define CPU_PRESCALE(n) (CLKPR = 0x80, CLKPR = (n))
-	CPU_PRESCALE(0);
-
-	// Disable the ADC
-	ADMUX = 0;
-
-	// initialize the USB, and then wait for the host
-	// to set configuration.  If the Teensy is powered
-	// without a PC connected to the USB port, this 
-	// will wait forever.
-	usb_init();
-	while (!usb_configured()) /* wait */ ;
-	_delay_ms(1000);
-
-	// wait for the user to run their terminal emulator program
-	// which sets DTR to indicate it is ready to receive.
-	while (!(usb_serial_get_control() & USB_SERIAL_DTR))
-		continue;
-
-	// discard anything that was received prior.  Sometimes the
-	// operating system or other software will send a modem
-	// "AT command", which can still be buffered.
-	usb_serial_flush_input();
-
-	// Activate pull ups on every port
-	for (int i = 0 ; i < INPUT_COUNT ; i++)
-	{
-		ddr(ports[i], 0);
-		out(ports[i], 1);
-	}
-
-	char line[128];
-
-	while (1)
-	{
-		unsigned off = 0;
-		uint8_t sw = PINA;
-		line[off++] = hexdigit(sw >> 4);
-		line[off++] = hexdigit(sw >> 0);
-
-		// for each pin, set it low and then see which other
-		// pins are pulled low
-		for (int i = 0 ; i < INPUT_COUNT-1 ; i++)
-		{
-			out(ports[i], 0);
-			ddr(ports[i], 1);
-
-			for (int j = i + 1 ; j < INPUT_COUNT ; j++)
-			{
-				if (in(ports[j]))
-					continue;
-				line[off++] = ' ';
-				line[off++] = hexdigit(i >> 4);
-				line[off++] = hexdigit(i >> 0);
-				line[off++] = ':';
-				line[off++] = hexdigit(j >> 4);
-				line[off++] = hexdigit(j >> 0);
-			}
-
-			ddr(ports[i], 0);
-			out(ports[i], 1);
-		}
-		
-		if (off == 0)
-			continue;
-
-		line[off++] = '\r';
-		line[off++] = '\n';
-		usb_serial_write(line, off);
-
-		_delay_ms(250);
-	}
-}

patch-panel/Makefile

+# 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".
+#----------------------------------------------------------------------------
+
+
+# Target file name (without extension).
+TARGET = patch-console
+
+
+# List C source files here. (C dependencies are automatically generated.)
+SRC =	$(TARGET).c \
+	bits.c \
+	usb_serial.c \
+
+
+# MCU name, you MUST set this to match the board you are using
+# type "make clean" after changing this, so all files will be rebuilt
+#
+#MCU = at90usb162       # Teensy 1.0
+#MCU = atmega32u4        # Teensy 2.0
+#MCU = at90usb646       # Teensy++ 1.0
+MCU = at90usb1286      # Teensy++ 2.0
+
+
+# Processor frequency.
+#   Normally the first thing your program should do is set the clock prescaler,
+#   so your program will run at the correct speed.  You should also set this
+#   variable to same clock speed.  The _delay_ms() macro uses this, and many
+#   examples use this variable to calculate timings.  Do not add a "UL" here.
+F_CPU = 16000000
+
+
+# Output format. (can be srec, ihex, binary)
+FORMAT = ihex
+
+
+# Object files directory
+#     To put object files in current directory, use a dot (.), do NOT make
+#     this an empty or blank macro!
+OBJDIR = .
+
+
+# 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 = 
+
+
+# Compiler flag to set the C Standard level.
+#     c89   = "ANSI" C
+#     gnu89 = c89 plus GCC extensions
+#     c99   = ISO C99 standard (not yet fully implemented)
+#     gnu99 = c99 plus GCC extensions
+CSTANDARD = -std=gnu99
+
+
+# Place -D or -U options here for C sources
+CDEFS = -DF_CPU=$(F_CPU)UL
+
+
+# Place -D or -U options here for ASM sources
+ADEFS = -DF_CPU=$(F_CPU)
+
+
+# Place -D or -U options here for C++ sources
+CPPDEFS = -DF_CPU=$(F_CPU)UL
+#CPPDEFS += -D__STDC_LIMIT_MACROS
+#CPPDEFS += -D__STDC_CONSTANT_MACROS
+
+
+
+#---------------- Compiler Options C ----------------
+#  -g*:          generate debugging information
+#  -O*:          optimization level
+#  -f...:        tuning, see GCC manual and avr-libc documentation
+#  -Wall...:     warning level
+#  -Wa,...:      tell GCC to pass this to the assembler.
+#    -adhlns...: create assembler listing
+CFLAGS = -g$(DEBUG)
+CFLAGS += $(CDEFS)
+CFLAGS += -O$(OPT)
+CFLAGS += -funsigned-char
+CFLAGS += -funsigned-bitfields
+CFLAGS += -ffunction-sections
+CFLAGS += -fpack-struct
+CFLAGS += -fshort-enums
+CFLAGS += -Wall
+CFLAGS += -Wstrict-prototypes
+#CFLAGS += -mshort-calls
+#CFLAGS += -fno-unit-at-a-time
+#CFLAGS += -Wundef
+#CFLAGS += -Wunreachable-code
+#CFLAGS += -Wsign-compare
+CFLAGS += -Wa,-adhlns=$(<:%.c=$(OBJDIR)/%.lst)
+CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS))
+CFLAGS += $(CSTANDARD)
+
+
+#---------------- Compiler Options C++ ----------------
+#  -g*:          generate debugging information
+#  -O*:          optimization level
+#  -f...:        tuning, see GCC manual and avr-libc documentation
+#  -Wall...:     warning level
+#  -Wa,...:      tell GCC to pass this to the assembler.
+#    -adhlns...: create assembler listing
+CPPFLAGS = -g$(DEBUG)
+CPPFLAGS += $(CPPDEFS)
+CPPFLAGS += -O$(OPT)
+CPPFLAGS += -funsigned-char
+CPPFLAGS += -funsigned-bitfields
+CPPFLAGS += -fpack-struct
+CPPFLAGS += -fshort-enums
+CPPFLAGS += -fno-exceptions
+CPPFLAGS += -Wall
+CPPFLAGS += -Wundef
+#CPPFLAGS += -mshort-calls
+#CPPFLAGS += -fno-unit-at-a-time
+#CPPFLAGS += -Wstrict-prototypes
+#CPPFLAGS += -Wunreachable-code
+#CPPFLAGS += -Wsign-compare
+CPPFLAGS += -Wa,-adhlns=$(<:%.cpp=$(OBJDIR)/%.lst)
+CPPFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS))
+#CPPFLAGS += $(CSTANDARD)
+
+
+#---------------- Assembler Options ----------------
+#  -Wa,...:   tell GCC to pass this to the assembler.
+#  -adhlns:   create listing
+#  -gstabs:   have the assembler create line number information; note that
+#             for use in COFF files, additional information about filenames
+#             and function names needs to be present in the assembler source
+#             files -- see avr-libc docs [FIXME: not yet described there]
+#  -listing-cont-lines: Sets the maximum number of continuation lines of hex 
+#       dump that will be displayed for a given single line of source input.
+ASFLAGS = $(ADEFS) -Wa,-adhlns=$(<:%.S=$(OBJDIR)/%.lst),-gstabs,--listing-cont-lines=100
+
+
+#---------------- Library Options ----------------
+# Minimalistic printf version
+PRINTF_LIB_MIN = -Wl,-u,vfprintf -lprintf_min
+
+# Floating point printf version (requires MATH_LIB = -lm below)
+PRINTF_LIB_FLOAT = -Wl,-u,vfprintf -lprintf_flt
+
+# If this is left blank, then it will use the Standard printf version.
+PRINTF_LIB = 
+#PRINTF_LIB = $(PRINTF_LIB_MIN)
+#PRINTF_LIB = $(PRINTF_LIB_FLOAT)
+
+
+# Minimalistic scanf version
+SCANF_LIB_MIN = -Wl,-u,vfscanf -lscanf_min
+
+# Floating point + %[ scanf version (requires MATH_LIB = -lm below)
+SCANF_LIB_FLOAT = -Wl,-u,vfscanf -lscanf_flt
+
+# If this is left blank, then it will use the Standard scanf version.
+SCANF_LIB = 
+#SCANF_LIB = $(SCANF_LIB_MIN)
+#SCANF_LIB = $(SCANF_LIB_FLOAT)
+
+
+MATH_LIB = -lm
+
+
+# List any extra directories to look for libraries here.
+#     Each directory must be seperated by a space.
+#     Use forward slashes for directory separators.
+#     For a directory that has spaces, enclose it in quotes.
+EXTRALIBDIRS = 
+
+
+
+#---------------- External Memory Options ----------------
+
+# 64 KB of external RAM, starting after internal RAM (ATmega128!),
+# used for variables (.data/.bss) and heap (malloc()).
+#EXTMEMOPTS = -Wl,-Tdata=0x801100,--defsym=__heap_end=0x80ffff
+
+# 64 KB of external RAM, starting after internal RAM (ATmega128!),
+# only used for heap (malloc()).
+#EXTMEMOPTS = -Wl,--section-start,.data=0x801100,--defsym=__heap_end=0x80ffff
+
+EXTMEMOPTS =
+
+
+
+#---------------- Linker Options ----------------
+#  -Wl,...:     tell GCC to pass this to linker.
+#    -Map:      create map file
+#    --cref:    add cross reference to  map file
+LDFLAGS = -Wl,-Map=$(TARGET).map,--cref
+LDFLAGS += -Wl,--relax
+LDFLAGS += -Wl,--gc-sections
+LDFLAGS += $(EXTMEMOPTS)
+LDFLAGS += $(patsubst %,-L%,$(EXTRALIBDIRS))
+LDFLAGS += $(PRINTF_LIB) $(SCANF_LIB) $(MATH_LIB)
+#LDFLAGS += -T linker_script.x
+
+#---------------- Platform detection -------------
+UNAME := $(shell uname)
+
+#---------------- Programming Options (avrdude) ----------------
+
+# Programming hardware
+# Type: avrdude -c ?
+# to get a full listing.
+#
+AVRDUDE_PROGRAMMER = stk500v2
+
+# com1 = serial port. Use lpt1 to connect to parallel port.
+ifeq ($(UNAME), Linux)
+	AVRDUDE_PORT = /dev/ttyACM0    # programmer connected to serial device
+else
+	AVRDUDE_PORT = com1
+endif
+
+AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex
+#AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep
+
+
+# Uncomment the following if you want avrdude's erase cycle counter.
+# Note that this counter needs to be initialized first using -Yn,
+# see avrdude manual.
+#AVRDUDE_ERASE_COUNTER = -y
+
+# Uncomment the following if you do /not/ wish a verification to be
+# performed after programming the device.
+#AVRDUDE_NO_VERIFY = -V
+
+# Increase verbosity level.  Please use this when submitting bug
+# reports about avrdude. See <http://savannah.nongnu.org/projects/avrdude> 
+# to submit bug reports.
+#AVRDUDE_VERBOSE = -v -v
+
+AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER)
+AVRDUDE_FLAGS += $(AVRDUDE_NO_VERIFY)
+AVRDUDE_FLAGS += $(AVRDUDE_VERBOSE)
+AVRDUDE_FLAGS += $(AVRDUDE_ERASE_COUNTER)
+
+
+
+#---------------- Debugging Options ----------------
+
+# For simulavr only - target MCU frequency.
+DEBUG_MFREQ = $(F_CPU)
+
+# Set the DEBUG_UI to either gdb or insight.
+# DEBUG_UI = gdb
+DEBUG_UI = insight
+
+# Set the debugging back-end to either avarice, simulavr.
+DEBUG_BACKEND = avarice
+#DEBUG_BACKEND = simulavr
+
+# GDB Init Filename.
+GDBINIT_FILE = __avr_gdbinit
+
+# When using avarice settings for the JTAG
+JTAG_DEV = /dev/com1
+
+# Debugging port used to communicate between GDB / avarice / simulavr.
+DEBUG_PORT = 4242
+
+# Debugging host used to communicate between GDB / avarice / simulavr, normally
+#     just set to localhost unless doing some sort of crazy debugging when 
+#     avarice is running on a different computer.
+DEBUG_HOST = localhost
+
+
+
+#============================================================================
+
+
+# Define programs and commands.
+SHELL = sh
+ifeq ($(UNAME), Linux)
+	AVR_PATH = /usr
+else
+	AVR_PATH = /Applications/Arduino.app/Contents//Resources/Java/hardware/tools/avr
+endif
+
+CC = $(AVR_PATH)/bin/avr-gcc
+OBJCOPY = $(AVR_PATH)/bin/avr-objcopy
+OBJDUMP = $(AVR_PATH)/bin/avr-objdump
+SIZE = $(AVR_PATH)/bin/avr-size
+AR = $(AVR_PATH)/bin/avr-ar rcs
+NM = $(AVR_PATH)/bin/avr-nm
+AVRDUDE = $(AVR_PATH)/bin/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
+
+## Include the files from avr/include/
+#CFLAGS += -I$(AVR_PATH)/include
+
+# Combine all necessary flags and optional flags.
+# Add target processor to flags.
+ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) $(GENDEPFLAGS)
+ALL_CPPFLAGS = -mmcu=$(MCU) -I. -x c++ $(CPPFLAGS) $(GENDEPFLAGS)
+ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS)
+
+
+
+
+
+# Default target.
+all: begin gccversion sizebefore build sizeafter end
+
+# Change the build target to build a HEX file or a library.
+build: elf hex eep lss sym
+#build: lib
+
+
+elf: $(TARGET).elf
+hex: $(TARGET).hex
+eep: $(TARGET).eep
+lss: $(TARGET).lss
+sym: $(TARGET).sym
+LIBNAME=lib$(TARGET).a
+lib: $(LIBNAME)
+
+
+
+# Eye candy.
+# AVR Studio 3.x does not check make's exit code but relies on
+# the following magic strings to be generated by the compile job.
+begin:
+	@echo
+	@echo $(MSG_BEGIN)
+
+end:
+	@echo $(MSG_END)
+	@echo
+
+
+# Display size of file.
+HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex
+#ELFSIZE = $(SIZE) --mcu=$(MCU) --format=avr $(TARGET).elf
+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.  
+ifeq ($(UNAME), Linux)
+program: $(TARGET).hex $(TARGET).eep
+	~/opt/teensy_loader_cli/teensy_loader_cli -mmcu=$(MCU) -w $(TARGET).hex
+else
+program: $(TARGET).hex $(TARGET).eep
+	$(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM)
+endif
+
+
+
+# Generate avr-gdb config/init file which does the following:
+#     define the reset signal, load the target file, connect to target, and set 
+#     a breakpoint at main().
+gdb-config: 
+	@$(REMOVE) $(GDBINIT_FILE)
+	@echo define reset >> $(GDBINIT_FILE)
+	@echo SIGNAL SIGHUP >> $(GDBINIT_FILE)
+	@echo end >> $(GDBINIT_FILE)
+	@echo file $(TARGET).elf >> $(GDBINIT_FILE)
+	@echo target remote $(DEBUG_HOST):$(DEBUG_PORT)  >> $(GDBINIT_FILE)
+ifeq ($(DEBUG_BACKEND),simulavr)
+	@echo load  >> $(GDBINIT_FILE)
+endif
+	@echo break main >> $(GDBINIT_FILE)
+
+debug: gdb-config $(TARGET).elf
+ifeq ($(DEBUG_BACKEND), avarice)
+	@echo Starting AVaRICE - Press enter when "waiting to connect" message displays.
+	@$(WINSHELL) /c start avarice --jtag $(JTAG_DEV) --erase --program --file \
+	$(TARGET).elf $(DEBUG_HOST):$(DEBUG_PORT)
+	@$(WINSHELL) /c pause
+
+else
+	@$(WINSHELL) /c start simulavr --gdbserver --device $(MCU) --clock-freq \
+	$(DEBUG_MFREQ) --port $(DEBUG_PORT)
+endif
+	@$(WINSHELL) /c start avr-$(DEBUG_UI) --command=$(GDBINIT_FILE)
+
+
+
+
+# Convert ELF to COFF for use in debugging / simulating in AVR Studio or VMLAB.
+COFFCONVERT = $(OBJCOPY) --debugging
+COFFCONVERT += --change-section-address .data-0x800000
+COFFCONVERT += --change-section-address .bss-0x800000
+COFFCONVERT += --change-section-address .noinit-0x800000
+COFFCONVERT += --change-section-address .eeprom-0x810000
+
+
+
+coff: $(TARGET).elf
+	@echo
+	@echo $(MSG_COFF) $(TARGET).cof
+	$(COFFCONVERT) -O coff-avr $< $(TARGET).cof
+
+
+extcoff: $(TARGET).elf
+	@echo
+	@echo $(MSG_EXTENDED_COFF) $(TARGET).cof
+	$(COFFCONVERT) -O coff-ext-avr $< $(TARGET).cof
+
+
+
+# Create final output files (.hex, .eep) from ELF output file.
+%.hex: %.elf
+	@echo
+	@echo $(MSG_FLASH) $@
+	$(OBJCOPY) -O $(FORMAT) -R .eeprom -R .fuse -R .lock -R .signature $< $@
+
+%.eep: %.elf
+	@echo
+	@echo $(MSG_EEPROM) $@
+	-$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \
+	--change-section-lma .eeprom=0 --no-change-warnings -O $(FORMAT) $< $@ || exit 0
+
+# Create extended listing file from ELF output file.
+%.lss: %.elf
+	@echo
+	@echo $(MSG_EXTENDED_LISTING) $@
+	$(OBJDUMP) -h -S -z $< > $@
+
+# Create a symbol table from ELF output file.
+%.sym: %.elf
+	@echo
+	@echo $(MSG_SYMBOL_TABLE) $@
+	$(NM) -n $< > $@
+
+
+
+# Create library from object files.
+.SECONDARY : $(TARGET).a
+.PRECIOUS : $(OBJ)
+%.a: $(OBJ)
+	@echo
+	@echo $(MSG_CREATING_LIBRARY) $@
+	$(AR) $@ $(OBJ)
+
+
+# Link: create ELF output file from object files.
+.SECONDARY : $(TARGET).elf
+.PRECIOUS : $(OBJ)
+%.elf: $(OBJ)
+	@echo
+	@echo $(MSG_LINKING) $@
+	$(CC) $(ALL_CFLAGS) $^ --output $@ $(LDFLAGS)
+
+
+# Compile: create object files from C source files.
+$(OBJDIR)/%.o : %.c
+	@echo
+	@echo $(MSG_COMPILING) $<
+	$(CC) -c $(ALL_CFLAGS) $< -o $@ 
+
+
+# Compile: create object files from C++ source files.
+$(OBJDIR)/%.o : %.cpp
+	@echo
+	@echo $(MSG_COMPILING_CPP) $<
+	$(CC) -c $(ALL_CPPFLAGS) $< -o $@ 
+
+
+# Compile: create assembler files from C source files.
+%.s : %.c
+	$(CC) -S $(ALL_CFLAGS) $< -o $@
+
+
+# Compile: create assembler files from C++ source files.
+%.s : %.cpp
+	$(CC) -S $(ALL_CPPFLAGS) $< -o $@
+
+
+# Assemble: create object files from assembler source files.
+$(OBJDIR)/%.o : %.S
+	@echo
+	@echo $(MSG_ASSEMBLING) $<
+	$(CC) -c $(ALL_ASFLAGS) $< -o $@
+
+
+# Create preprocessed source for use in sending a bug report.
+%.i : %.c
+	$(CC) -E -mmcu=$(MCU) -I. $(CFLAGS) $< -o $@ 
+
+
+# Target: clean project.
+clean: begin clean_list end
+
+clean_list :
+	@echo
+	@echo $(MSG_CLEANING)
+	$(REMOVE) $(TARGET).hex
+	$(REMOVE) $(TARGET).eep
+	$(REMOVE) $(TARGET).cof
+	$(REMOVE) $(TARGET).elf
+	$(REMOVE) $(TARGET).map
+	$(REMOVE) $(TARGET).sym
+	$(REMOVE) $(TARGET).lss
+	$(REMOVE) $(SRC:%.c=$(OBJDIR)/%.o)
+	$(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 eep lss sym coff extcoff \
+clean clean_list program debug gdb-config

patch-panel/bits.c

+/** \file Access to AVR pins via constants.
+ *
+ * ddr(0xA3, 1) == enable DDRA |= (1 << 3)
+ * out(0xA3, 1) == PORTA |= (1 << 3)
+ * in(0xA3) == PINA & (1 << 3)
+ */
+#include <avr/io.h>
+#include <avr/pgmspace.h>
+#include "bits.h"
+
+#define set_bit(PORT, PIN, VALUE) do { \
+		if (VALUE) \
+			sbi(PORT, PIN); \
+		else \
+			cbi(PORT, PIN); \
+	} while (0)
+
+#define get_bit(PORT, PIN) \
+	((PORT) & (1 << PIN))
+
+
+void
+ddr(
+	const uint8_t id,
+	const uint8_t value
+)
+{
+	const uint8_t port = (id >> 4) & 0xF;
+	const uint8_t pin = (id >> 0) & 0xF;
+
+	switch (port)
+	{
+	case 0xA:
+		set_bit(DDRA, pin, value);
+		return;
+	case 0xB:
+		set_bit(DDRB, pin, value);
+		return;
+	case 0xC:
+		set_bit(DDRC, pin, value);
+		return;
+	case 0xD:
+		set_bit(DDRD, pin, value);
+		return;
+	case 0xE:
+		set_bit(DDRE, pin, value);
+		return;
+	case 0xF:
+		set_bit(DDRF, pin, value);
+		return;
+	}
+}
+
+
+void
+out(
+	const uint8_t id,
+	const uint8_t value
+)
+{
+	const uint8_t port = (id >> 4) & 0xF;
+	const uint8_t pin = (id >> 0) & 0xF;
+
+	switch (port)
+	{
+	case 0xA:
+		set_bit(PORTA, pin, value);
+		return;
+	case 0xB:
+		set_bit(PORTB, pin, value);
+		return;
+	case 0xC:
+		set_bit(PORTC, pin, value);
+		return;
+	case 0xD:
+		set_bit(PORTD, pin, value);
+		return;
+	case 0xE:
+		set_bit(PORTE, pin, value);
+		return;
+	case 0xF:
+		set_bit(PORTF, pin, value);
+		return;
+	}
+}
+
+
+uint8_t
+in(
+	const uint8_t id
+)
+{
+	const uint8_t port = (id >> 4) & 0xF;
+	const uint8_t pin = (id >> 0) & 0xF;
+
+	switch (port)
+	{
+	case 0xA:
+		return get_bit(PINA, pin);
+	case 0xB:
+		return get_bit(PINB, pin);
+	case 0xC:
+		return get_bit(PINC, pin);
+	case 0xD:
+		return get_bit(PIND, pin);
+	case 0xE:
+		return get_bit(PINE, pin);
+	case 0xF:
+		return get_bit(PINF, pin);
+	}
+
+	return 0;
+}

patch-panel/bits.h

+#ifndef _prom_bits_h_
+#define _prom_bits_h_
+
+#include <stdint.h>
+
+#define sbi(PORT, PIN) ((PORT) |=  (1 << (PIN)))
+#define cbi(PORT, PIN) ((PORT) &= ~(1 << (PIN)))
+#define array_count(ARRAY) (sizeof(ARRAY) / sizeof(*(ARRAY)))
+#define _STR(X) #X
+#define STR(X) _STR(X)
+
+
+extern void
+ddr(
+	const uint8_t port,
+	const uint8_t value
+);
+
+
+extern void
+out(
+	const uint8_t port,
+	uint8_t value
+);
+
+
+extern uint8_t
+in(
+	uint8_t port
+);
+
+#endif

patch-panel/patch-console.c

+/**
+ * \file Future crew patch panel
+ *
+ * Figure out which ports on the patch panel are cross connected
+ */
+
+#include <avr/io.h>
+#include <avr/pgmspace.h>
+#include <avr/interrupt.h>
+#include <stdint.h>
+#include <string.h>
+#include <util/delay.h>
+#include "usb_serial.h"
+#include "bits.h"
+
+void send_mem_str(const char *s);
+uint8_t recv_str(char *buf, uint8_t size);
+void parse_and_execute_command(const char *buf, uint8_t num);
+
+static uint8_t
+hexdigit(
+	uint8_t x
+)
+{
+	x &= 0xF;
+	if (x < 0xA)
+		return x + '0' - 0x0;
+	else
+		return x + 'A' - 0xA;
+}
+
+
+static const uint8_t ports[] = {
+	0xB6,
+	0xB5,
+	0xB4,
+	0xB3,
+	0xB2,
+	0xB1,
+	0xB0,
+	0xE7,
+	0xE6,
+	0xF0,
+	0xF1,
+	0xF2,
+	0xF3,
+	0xF4,
+	0xF5,
+	0xF6,
+	0xF7,
+
+	0xC7,
+	0xC6,
+	0xC5,
+	0xC4,
+	0xC3,
+	0xC2,
+	0xC1,
+	0xC0,
+	0xE1,
+	0xE0,
+	0xD7,
+	0xD5,
+	0xD4,
+	0xD3,
+	0xD2,
+	0xD1,
+	0xD0,
+	0xB7,
+
+/*
+	0xA0,
+	0xA1,
+	0xA2,
+	0xA3,
+	0xA4,
+	0xA5,
+	0xA6,
+	0xA7,
+*/
+};
+
+#define INPUT_COUNT (sizeof(ports) / sizeof(*ports))
+//#define INPUT_COUNT 28
+
+
+int main(void)
+{
+	// set for 16 MHz clock
+#define CPU_PRESCALE(n) (CLKPR = 0x80, CLKPR = (n))
+	CPU_PRESCALE(0);
+
+	// Disable the ADC
+	ADMUX = 0;
+
+	// initialize the USB, and then wait for the host
+	// to set configuration.  If the Teensy is powered
+	// without a PC connected to the USB port, this 
+	// will wait forever.
+	usb_init();
+	while (!usb_configured()) /* wait */ ;
+	_delay_ms(1000);
+
+	// wait for the user to run their terminal emulator program
+	// which sets DTR to indicate it is ready to receive.
+	while (!(usb_serial_get_control() & USB_SERIAL_DTR))
+		continue;
+
+	// discard anything that was received prior.  Sometimes the
+	// operating system or other software will send a modem
+	// "AT command", which can still be buffered.
+	usb_serial_flush_input();
+
+	// Activate pull ups on every port
+	for (int i = 0 ; i < INPUT_COUNT ; i++)
+	{
+		ddr(ports[i], 0);
+		out(ports[i], 1);
+	}
+
+	char line[128];
+
+	while (1)
+	{
+		unsigned off = 0;
+		uint8_t sw = PINA;
+		line[off++] = hexdigit(sw >> 4);
+		line[off++] = hexdigit(sw >> 0);
+
+		// for each pin, set it low and then see which other
+		// pins are pulled low
+		for (int i = 0 ; i < INPUT_COUNT-1 ; i++)
+		{
+			out(ports[i], 0);
+			ddr(ports[i], 1);
+
+			for (int j = i + 1 ; j < INPUT_COUNT ; j++)
+			{
+				if (in(ports[j]))
+					continue;
+				line[off++] = ' ';
+				line[off++] = hexdigit(i >> 4);
+				line[off++] = hexdigit(i >> 0);
+				line[off++] = ':';
+				line[off++] = hexdigit(j >> 4);
+				line[off++] = hexdigit(j >> 0);
+			}
+
+			ddr(ports[i], 0);
+			out(ports[i], 1);
+		}
+		
+		if (off == 0)
+			continue;
+
+		line[off++] = '\r';
+		line[off++] = '\n';
+		usb_serial_write(line, off);
+
+		_delay_ms(250);
+	}
+}

patch-panel/usb.h

+/*
+ * Prototypes, structure definitions and macros.
+ *
+ * Copyright (c) 2000-2003 Johannes Erdfelt <johannes@erdfelt.com>
+ *
+ * This library is covered by the LGPL, read LICENSE for details.
+ *
+ * This file (and only this file) may alternatively be licensed under the
+ * BSD license as well, read LICENSE for details.
+ */
+#ifndef __USB_H__
+#define __USB_H__
+
+#include <avr/io.h>
+#include <stdint.h>
+
+/*
+ * USB spec information
+ *
+ * This is all stuff grabbed from various USB specs and is pretty much
+ * not subject to change
+ */
+
+/*
+ * Device and/or Interface Class codes
+ */
+#define USB_CLASS_PER_INTERFACE		0	/* for DeviceClass */
+#define USB_CLASS_AUDIO			1
+#define USB_CLASS_COMM			2
+#define USB_CLASS_HID			3
+#define USB_CLASS_PRINTER		7
+#define USB_CLASS_PTP			6
+#define USB_CLASS_MASS_STORAGE		8
+#define USB_CLASS_HUB			9
+#define USB_CLASS_DATA			10
+#define USB_CLASS_VENDOR_SPEC		0xff
+
+/*
+ * Descriptor types
+ */
+#define USB_DT_DEVICE			0x01
+#define USB_DT_CONFIG			0x02
+#define USB_DT_STRING			0x03
+#define USB_DT_INTERFACE		0x04
+#define USB_DT_ENDPOINT			0x05
+
+#define USB_DT_HID			0x21
+#define USB_DT_REPORT			0x22
+#define USB_DT_PHYSICAL			0x23
+#define USB_DT_HUB			0x29
+
+/*
+ * Descriptor sizes per descriptor type
+ */
+#define USB_DT_DEVICE_SIZE		18
+#define USB_DT_CONFIG_SIZE		9
+#define USB_DT_INTERFACE_SIZE		9
+#define USB_DT_ENDPOINT_SIZE		7
+#define USB_DT_ENDPOINT_AUDIO_SIZE	9	/* Audio extension */
+#define USB_DT_HUB_NONVAR_SIZE		7
+
+/* All standard descriptors have these 2 fields in common */
+struct usb_descriptor_header {
+	uint8_t  bLength;
+	uint8_t  bDescriptorType;
+};
+
+/* String descriptor */
+struct usb_string_descriptor {
+	uint8_t  bLength;
+	uint8_t  bDescriptorType;
+	uint16_t wData[1];
+};
+
+/* HID descriptor */
+struct usb_hid_descriptor {
+	uint8_t  bLength;
+	uint8_t  bDescriptorType;
+	uint16_t bcdHID;
+	uint8_t  bCountryCode;
+	uint8_t  bNumDescriptors;
+	/* uint8_t  bReportDescriptorType; */
+	/* uint16_t wDescriptorLength; */
+	/* ... */
+};
+
+/* Endpoint descriptor */
+#define USB_MAXENDPOINTS	32
+struct usb_endpoint_descriptor {
+	uint8_t  bLength;
+	uint8_t  bDescriptorType;
+	uint8_t  bEndpointAddress;
+	uint8_t  bmAttributes;
+	uint16_t wMaxPacketSize;
+	uint8_t  bInterval;
+	uint8_t  bRefresh;
+	uint8_t  bSynchAddress;
+
+	unsigned char *extra;	/* Extra descriptors */
+	int extralen;
+};
+
+#define USB_ENDPOINT_ADDRESS_MASK	0x0f    /* in bEndpointAddress */
+#define USB_ENDPOINT_DIR_MASK		0x80
+
+#define USB_ENDPOINT_TYPE_MASK		0x03    /* in bmAttributes */
+#define USB_ENDPOINT_TYPE_CONTROL	0
+#define USB_ENDPOINT_TYPE_ISOCHRONOUS	1
+#define USB_ENDPOINT_TYPE_BULK		2
+#define USB_ENDPOINT_TYPE_INTERRUPT	3
+
+/* Interface descriptor */
+#define USB_MAXINTERFACES	32
+struct usb_interface_descriptor {
+	uint8_t  bLength;
+	uint8_t  bDescriptorType;
+	uint8_t  bInterfaceNumber;
+	uint8_t  bAlternateSetting;
+	uint8_t  bNumEndpoints;
+	uint8_t  bInterfaceClass;
+	uint8_t  bInterfaceSubClass;
+	uint8_t  bInterfaceProtocol;
+	uint8_t  iInterface;
+
+	struct usb_endpoint_descriptor endpoint;
+
+	unsigned char *extra;	/* Extra descriptors */
+	int extralen;
+};
+
+#define USB_MAXALTSETTING	128	/* Hard limit */
+struct usb_interface {
+	struct usb_interface_descriptor *altsetting;
+
+	int num_altsetting;
+};
+
+/* Configuration descriptor information.. */
+#define USB_MAXCONFIG		8
+struct usb_config_descriptor {
+	uint8_t  bLength;
+	uint8_t  bDescriptorType;
+	uint16_t wTotalLength;
+	uint8_t  bNumInterfaces;
+	uint8_t  bConfigurationValue;
+	uint8_t  iConfiguration;
+	uint8_t  bmAttributes;
+	uint8_t  MaxPower;
+
+	struct usb_interface interfaces[];
+
+#if 0
+	unsigned char *extra;	/* Extra descriptors */
+	int extralen;
+#endif
+};
+
+/* Device descriptor */
+struct usb_device_descriptor {
+	uint8_t  bLength;
+	uint8_t  bDescriptorType;
+	uint16_t bcdUSB;
+	uint8_t  bDeviceClass;
+	uint8_t  bDeviceSubClass;
+	uint8_t  bDeviceProtocol;
+	uint8_t  bMaxPacketSize0;
+	uint16_t idVendor;
+	uint16_t idProduct;
+	uint16_t bcdDevice;
+	uint8_t  iManufacturer;
+	uint8_t  iProduct;
+	uint8_t  iSerialNumber;
+	uint8_t  bNumConfigurations;
+};
+
+struct usb_ctrl_setup {
+	uint8_t  bRequestType;
+	uint8_t  bRequest;
+	uint16_t wValue;
+	uint16_t wIndex;
+	uint16_t wLength;
+};
+
+/*
+ * Standard requests
+ */
+#define USB_REQ_GET_STATUS		0x00
+#define USB_REQ_CLEAR_FEATURE		0x01
+/* 0x02 is reserved */
+#define USB_REQ_SET_FEATURE		0x03
+/* 0x04 is reserved */
+#define USB_REQ_SET_ADDRESS		0x05
+#define USB_REQ_GET_DESCRIPTOR		0x06
+#define USB_REQ_SET_DESCRIPTOR		0x07
+#define USB_REQ_GET_CONFIGURATION	0x08
+#define USB_REQ_SET_CONFIGURATION	0x09
+#define USB_REQ_GET_INTERFACE		0x0A
+#define USB_REQ_SET_INTERFACE		0x0B
+#define USB_REQ_SYNCH_FRAME		0x0C
+
+#define USB_TYPE_STANDARD		(0x00 << 5)
+#define USB_TYPE_CLASS			(0x01 << 5)
+#define USB_TYPE_VENDOR			(0x02 << 5)
+#define USB_TYPE_RESERVED		(0x03 << 5)
+
+#define USB_RECIP_DEVICE		0x00
+#define USB_RECIP_INTERFACE		0x01
+#define USB_RECIP_ENDPOINT		0x02
+#define USB_RECIP_OTHER			0x03
+
+/*
+ * Various libusb API related stuff
+ */
+
+#define USB_ENDPOINT_IN			0x80
+#define USB_ENDPOINT_OUT		0x00
+
+/* Error codes */
+#define USB_ERROR_BEGIN			500000
+
+/*
+ * This is supposed to look weird. This file is generated from autoconf
+ * and I didn't want to make this too complicated.
+ */
+#if 0
+#define USB_LE16_TO_CPU(x) do { x = ((x & 0xff) << 8) | ((x & 0xff00) >> 8); } while(0)
+#else
+#define USB_LE16_TO_CPU(x)
+#endif
+
+/* Data types */
+struct usb_device;
+struct usb_bus;
+
+
+struct usb_dev_handle;
+typedef struct usb_dev_handle usb_dev_handle;
+
+/* Variables */
+extern struct usb_bus *usb_busses;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Function prototypes */
+
+/* usb.c */
+usb_dev_handle *usb_open(struct usb_device *dev);
+int usb_close(usb_dev_handle *dev);
+int usb_get_string(usb_dev_handle *dev, int index, int langid, char *buf,
+	size_t buflen);
+int usb_get_string_simple(usb_dev_handle *dev, int index, char *buf,
+	size_t buflen);
+
+/* descriptors.c */
+int usb_get_descriptor_by_endpoint(usb_dev_handle *udev, int ep,
+	unsigned char type, unsigned char index, void *buf, int size);
+int usb_get_descriptor(usb_dev_handle *udev, unsigned char type,
+	unsigned char index, void *buf, int size);
+
+/* <arch>.c */
+int usb_bulk_write(usb_dev_handle *dev, int ep, char *bytes, int size,
+	int timeout);
+int usb_bulk_read(usb_dev_handle *dev, int ep, char *bytes, int size,
+	int timeout);
+int usb_interrupt_write(usb_dev_handle *dev, int ep, char *bytes, int size,
+        int timeout);
+int usb_interrupt_read(usb_dev_handle *dev, int ep, char *bytes, int size,
+        int timeout);
+int usb_control_msg(usb_dev_handle *dev, int requesttype, int request,
+	int value, int index, char *bytes, int size, int timeout);
+int usb_set_configuration(usb_dev_handle *dev, int configuration);
+int usb_claim_interface(usb_dev_handle *dev, int interface);
+int usb_release_interface(usb_dev_handle *dev, int interface);
+int usb_set_altinterface(usb_dev_handle *dev, int alternate);
+int usb_resetep(usb_dev_handle *dev, unsigned int ep);
+int usb_clear_halt(usb_dev_handle *dev, unsigned int ep);
+int usb_reset(usb_dev_handle *dev);
+
+#if 0
+#define LIBUSB_HAS_GET_DRIVER_NP 1
+int usb_get_driver_np(usb_dev_handle *dev, int interface, char *name,
+	unsigned int namelen);
+#define LIBUSB_HAS_DETACH_KERNEL_DRIVER_NP 1
+int usb_detach_kernel_driver_np(usb_dev_handle *dev, int interface);
+#endif
+
+char *usb_strerror(void);
+
+void usb_init(void);
+void usb_set_debug(int level);
+int usb_find_busses(void);
+int usb_find_devices(void);
+struct usb_device *usb_device(usb_dev_handle *dev);
+struct usb_bus *usb_get_busses(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __USB_H__ */
+

patch-panel/usb_serial.c

+/* USB Serial Example for Teensy USB Development Board
+ * http://www.pjrc.com/teensy/usb_serial.html
+ * Copyright (c) 2008,2010,2011 PJRC.COM, LLC
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+// Version 1.0: Initial Release
+// Version 1.1: support Teensy++
+// Version 1.2: fixed usb_serial_available
+// Version 1.3: added transmit bandwidth test
+// Version 1.4: added usb_serial_write
+// Version 1.5: add support for Teensy 2.0
+// Version 1.6: fix zero length packet bug
+// Version 1.7: fix usb_serial_set_control
+
+#define USB_SERIAL_PRIVATE_INCLUDE
+#include "usb_serial.h"
+
+#include <usb.h>
+
+
+/**************************************************************************
+ *
+ *  Configurable Options
+ *
+ **************************************************************************/
+
+// You can change these to give your code its own name.  On Windows,
+// these are only used before an INF file (driver install) is loaded.
+#define STR_MANUFACTURER	L"Your Name"
+#define STR_PRODUCT		L"USB Serial"
+
+// All USB serial devices are supposed to have a serial number
+// (according to Microsoft).  On windows, a new COM port is created
+// for every unique serial/vendor/product number combination.  If
+// you program 2 identical boards with 2 different serial numbers
+// and they are assigned COM7 and COM8, each will always get the
+// same COM port number because Windows remembers serial numbers.
+//
+// On Mac OS-X, a device file is created automatically which
+// incorperates the serial number, eg, /dev/cu-usbmodem12341
+//
+// Linux by default ignores the serial number, and creates device
+// files named /dev/ttyACM0, /dev/ttyACM1... in the order connected.
+// Udev rules (in /etc/udev/rules.d) can define persistent device
+// names linked to this serial number, as well as permissions, owner
+// and group settings.
+#define STR_SERIAL_NUMBER	L"12345"
+
+// Mac OS-X and Linux automatically load the correct drivers.  On
+// Windows, even though the driver is supplied by Microsoft, an
+// INF file is needed to load the driver.  These numbers need to
+// match the INF file.
+#define VENDOR_ID		0x16C0
+#define PRODUCT_ID		0x047A
+
+// When you write data, it goes into a USB endpoint buffer, which
+// is transmitted to the PC when it becomes full, or after a timeout
+// with no more writes.  Even if you write in exactly packet-size
+// increments, this timeout is used to send a "zero length packet"
+// that tells the PC no more data is expected and it should pass
+// any buffered data to the application that may be waiting.  If
+// you want data sent immediately, call usb_serial_flush_output().
+#define TRANSMIT_FLUSH_TIMEOUT	5   /* in milliseconds */
+
+// If the PC is connected but not "listening", this is the length
+// of time before usb_serial_getchar() returns with an error.  This
+// is roughly equivilant to a real UART simply transmitting the
+// bits on a wire where nobody is listening, except you get an error
+// code which you can ignore for serial-like discard of data, or
+// use to know your data wasn't sent.
+#define TRANSMIT_TIMEOUT	25   /* in milliseconds */
+
+// USB devices are supposed to implment a halt feature, which is
+// rarely (if ever) used.  If you comment this line out, the halt
+// code will be removed, saving 116 bytes of space (gcc 4.3.0).
+// This is not strictly USB compliant, but works with all major
+// operating systems.
+#define SUPPORT_ENDPOINT_HALT
+
+
+
+/**************************************************************************
+ *
+ *  Endpoint Buffer Configuration
+ *
+ **************************************************************************/
+
+// These buffer sizes are best for most applications, but perhaps if you
+// want more buffering on some endpoint at the expense of others, this
+// is where you can make such changes.  The AT90USB162 has only 176 bytes
+// of DPRAM (USB buffers) and only endpoints 3 & 4 can double buffer.
+
+#define ENDPOINT0_SIZE		16
+#define CDC_ACM_ENDPOINT	2
+#define CDC_RX_ENDPOINT		3