From 6570e7ae39948ac4db23bd995af7a276440cfed1 Mon Sep 17 00:00:00 2001 From: Ben Blazak Date: Sun, 11 Mar 2012 18:52:31 -0700 Subject: [PATCH 01/22] added src files - not much there yet though --- src/ergodox-firmware.c | 13 + src/lib/teensy-makefile | 617 ++++++++++++++++++++++++++++++++++++++++ src/makefile | 17 ++ 3 files changed, 647 insertions(+) create mode 100644 src/ergodox-firmware.c create mode 100644 src/lib/teensy-makefile create mode 100644 src/makefile diff --git a/src/ergodox-firmware.c b/src/ergodox-firmware.c new file mode 100644 index 0000000..0835479 --- /dev/null +++ b/src/ergodox-firmware.c @@ -0,0 +1,13 @@ +/* ---------------------------------------------------------------------------- + * Firmware for the ergoDOX keyboard + * ---------------------------------------------------------------------------- + * Copyright (c) 2012 Ben Blazak + * Released under The MIT License (MIT) (see "license.md") at + * + * ------------------------------------------------------------------------- */ + +// todo: set clock prescaler + +void main() { +} + diff --git a/src/lib/teensy-makefile b/src/lib/teensy-makefile new file mode 100644 index 0000000..5c7d3ea --- /dev/null +++ b/src/lib/teensy-makefile @@ -0,0 +1,617 @@ +# Hey Emacs, this is a -*- makefile -*- +#---------------------------------------------------------------------------- +#---------------------------------------------------------------------------- +# Copied from . Modified slightly to work +# with . +#---------------------------------------------------------------------------- +#---------------------------------------------------------------------------- +# 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 = ergodox-firmware + + +# List C source files here. (C dependencies are automatically generated.) +SRC = $(TARGET).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 + + + +#---------------- 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. +AVRDUDE_PORT = com1 # programmer connected to serial device + +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 +# to submit bug reports. +#AVRDUDE_VERBOSE = -v -v + +AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) +AVRDUDE_FLAGS += $(AVRDUDE_NO_VERIFY) +AVRDUDE_FLAGS += $(AVRDUDE_VERBOSE) +AVRDUDE_FLAGS += $(AVRDUDE_ERASE_COUNTER) + + + +#---------------- Debugging Options ---------------- + +# For simulavr only - target MCU frequency. +DEBUG_MFREQ = $(F_CPU) + +# Set the DEBUG_UI to either gdb or insight. +# DEBUG_UI = gdb +DEBUG_UI = insight + +# Set the debugging back-end to either avarice, simulavr. +DEBUG_BACKEND = avarice +#DEBUG_BACKEND = simulavr + +# GDB Init Filename. +GDBINIT_FILE = __avr_gdbinit + +# When using avarice settings for the JTAG +JTAG_DEV = /dev/com1 + +# Debugging port used to communicate between GDB / avarice / simulavr. +DEBUG_PORT = 4242 + +# Debugging host used to communicate between GDB / avarice / simulavr, normally +# just set to localhost unless doing some sort of crazy debugging when +# avarice is running on a different computer. +DEBUG_HOST = localhost + + + +#============================================================================ + + +# Define programs and commands. +SHELL = sh +CC = avr-gcc +OBJCOPY = avr-objcopy +OBJDUMP = avr-objdump +SIZE = avr-size +AR = avr-ar rcs +NM = avr-nm +AVRDUDE = avrdude +REMOVE = rm -f +REMOVEDIR = rm -rf +COPY = cp +WINSHELL = cmd + + +# Define Messages +# English +MSG_ERRORS_NONE = Errors: none +MSG_BEGIN = -------- begin -------- +MSG_END = -------- end -------- +MSG_SIZE_BEFORE = Size before: +MSG_SIZE_AFTER = Size after: +MSG_COFF = Converting to AVR COFF: +MSG_EXTENDED_COFF = Converting to AVR Extended COFF: +MSG_FLASH = Creating load file for Flash: +MSG_EEPROM = Creating load file for EEPROM: +MSG_EXTENDED_LISTING = Creating Extended Listing: +MSG_SYMBOL_TABLE = Creating Symbol Table: +MSG_LINKING = Linking: +MSG_COMPILING = Compiling C: +MSG_COMPILING_CPP = Compiling C++: +MSG_ASSEMBLING = Assembling: +MSG_CLEANING = Cleaning project: +MSG_CREATING_LIBRARY = Creating library: + + + + +# Define all object files. +OBJ = $(SRC:%.c=$(OBJDIR)/%.o) $(CPPSRC:%.cpp=$(OBJDIR)/%.o) $(ASRC:%.S=$(OBJDIR)/%.o) + +# Define all listing files. +LST = $(SRC:%.c=$(OBJDIR)/%.lst) $(CPPSRC:%.cpp=$(OBJDIR)/%.lst) $(ASRC:%.S=$(OBJDIR)/%.lst) + + +# Compiler flags to generate dependency files. +GENDEPFLAGS = -MMD -MP -MF .dep/$(@F).d + + +# Combine all necessary flags and optional flags. +# Add target processor to flags. +ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) $(GENDEPFLAGS) +ALL_CPPFLAGS = -mmcu=$(MCU) -I. -x c++ $(CPPFLAGS) $(GENDEPFLAGS) +ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS) + + + + + +# Default target. +all: begin gccversion sizebefore build 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. +program: $(TARGET).hex $(TARGET).eep + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM) + + +# Generate avr-gdb config/init file which does the following: +# define the reset signal, load the target file, connect to target, and set +# a breakpoint at main(). +gdb-config: + @$(REMOVE) $(GDBINIT_FILE) + @echo define reset >> $(GDBINIT_FILE) + @echo SIGNAL SIGHUP >> $(GDBINIT_FILE) + @echo end >> $(GDBINIT_FILE) + @echo file $(TARGET).elf >> $(GDBINIT_FILE) + @echo target remote $(DEBUG_HOST):$(DEBUG_PORT) >> $(GDBINIT_FILE) +ifeq ($(DEBUG_BACKEND),simulavr) + @echo load >> $(GDBINIT_FILE) +endif + @echo break main >> $(GDBINIT_FILE) + +debug: gdb-config $(TARGET).elf +ifeq ($(DEBUG_BACKEND), avarice) + @echo Starting AVaRICE - Press enter when "waiting to connect" message displays. + @$(WINSHELL) /c start avarice --jtag $(JTAG_DEV) --erase --program --file \ + $(TARGET).elf $(DEBUG_HOST):$(DEBUG_PORT) + @$(WINSHELL) /c pause + +else + @$(WINSHELL) /c start simulavr --gdbserver --device $(MCU) --clock-freq \ + $(DEBUG_MFREQ) --port $(DEBUG_PORT) +endif + @$(WINSHELL) /c start avr-$(DEBUG_UI) --command=$(GDBINIT_FILE) + + + + +# Convert ELF to COFF for use in debugging / simulating in AVR Studio or VMLAB. +COFFCONVERT = $(OBJCOPY) --debugging +COFFCONVERT += --change-section-address .data-0x800000 +COFFCONVERT += --change-section-address .bss-0x800000 +COFFCONVERT += --change-section-address .noinit-0x800000 +COFFCONVERT += --change-section-address .eeprom-0x810000 + + + +coff: $(TARGET).elf + @echo + @echo $(MSG_COFF) $(TARGET).cof + $(COFFCONVERT) -O coff-avr $< $(TARGET).cof + + +extcoff: $(TARGET).elf + @echo + @echo $(MSG_EXTENDED_COFF) $(TARGET).cof + $(COFFCONVERT) -O coff-ext-avr $< $(TARGET).cof + + + +# Create final output files (.hex, .eep) from ELF output file. +%.hex: %.elf + @echo + @echo $(MSG_FLASH) $@ + $(OBJCOPY) -O $(FORMAT) -R .eeprom -R .fuse -R .lock -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 diff --git a/src/makefile b/src/makefile new file mode 100644 index 0000000..339877c --- /dev/null +++ b/src/makefile @@ -0,0 +1,17 @@ +# ----------------------------------------------------------------------------- +# This is a stub at the moment, but I'm keeping it separate so I can mess with +# it later without changing the original +# ----------------------------------------------------------------------------- +# Copyright (c) 2012 Ben Blazak +# Released under The MIT License (MIT) (see "license.md") at +# +# ----------------------------------------------------------------------------- + +.PHONY: all clean + +all: + make -f lib/teensy-makefile all + +clean: + make -f lib/teensy-makefile clean + From 5f4b6c9e0936e419700fc86574ac3455cb6721d7 Mon Sep 17 00:00:00 2001 From: Ben Blazak Date: Sun, 11 Mar 2012 19:17:32 -0700 Subject: [PATCH 02/22] added some stuff in src/lib --- src/lib/print.c | 62 +++++ src/lib/print.h | 16 ++ src/lib/twi.c | 527 +++++++++++++++++++++++++++++++++++++ src/lib/twi.h | 53 ++++ src/lib/usb_debug_only.c | 549 +++++++++++++++++++++++++++++++++++++++ src/lib/usb_debug_only.h | 84 ++++++ 6 files changed, 1291 insertions(+) create mode 100644 src/lib/print.c create mode 100644 src/lib/print.h create mode 100644 src/lib/twi.c create mode 100644 src/lib/twi.h create mode 100644 src/lib/usb_debug_only.c create mode 100644 src/lib/usb_debug_only.h diff --git a/src/lib/print.c b/src/lib/print.c new file mode 100644 index 0000000..e6aa1fe --- /dev/null +++ b/src/lib/print.c @@ -0,0 +1,62 @@ +/* Very basic print functions, intended to be used with usb_debug_only.c + * http://www.pjrc.com/teensy/ + * Copyright (c) 2008 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 + +#include +#include + +#include "print.h" + +void print_P(const char *s) +{ + char c; + + while (1) { + c = pgm_read_byte(s++); + if (!c) break; + if (c == '\n') usb_debug_putchar('\r'); + usb_debug_putchar(c); + } +} + +void phex1(unsigned char c) +{ + usb_debug_putchar(c + ((c < 10) ? '0' : 'A' - 10)); +} + +void phex(unsigned char c) +{ + phex1(c >> 4); + phex1(c & 15); +} + +void phex16(unsigned int i) +{ + phex(i >> 8); + phex(i); +} + + + + diff --git a/src/lib/print.h b/src/lib/print.h new file mode 100644 index 0000000..be7ce8c --- /dev/null +++ b/src/lib/print.h @@ -0,0 +1,16 @@ +#ifndef print_h__ +#define print_h__ + +#include +#include "usb_debug_only.h" + +// this macro allows you to write print("some text") and +// the string is automatically placed into flash memory :) +#define print(s) print_P(PSTR(s)) +#define pchar(c) usb_debug_putchar(c) + +void print_P(const char *s); +void phex(unsigned char c); +void phex16(unsigned int i); + +#endif diff --git a/src/lib/twi.c b/src/lib/twi.c new file mode 100644 index 0000000..6b2db3c --- /dev/null +++ b/src/lib/twi.c @@ -0,0 +1,527 @@ +/* + twi.c - TWI/I2C library for Wiring & Arduino + Copyright (c) 2006 Nicholas Zambetti. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Modified 2012 by Todd Krein (todd@krein.org) to implement repeated starts +*/ + +#include +#include +#include +#include +#include +#include +#include "Arduino.h" // for digitalWrite + +#ifndef cbi +#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) +#endif + +#ifndef sbi +#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) +#endif + +#include "pins_arduino.h" +#include "twi.h" + +static volatile uint8_t twi_state; +static volatile uint8_t twi_slarw; +static volatile uint8_t twi_sendStop; // should the transaction end with a stop +static volatile uint8_t twi_inRepStart; // in the middle of a repeated start + +static void (*twi_onSlaveTransmit)(void); +static void (*twi_onSlaveReceive)(uint8_t*, int); + +static uint8_t twi_masterBuffer[TWI_BUFFER_LENGTH]; +static volatile uint8_t twi_masterBufferIndex; +static volatile uint8_t twi_masterBufferLength; + +static uint8_t twi_txBuffer[TWI_BUFFER_LENGTH]; +static volatile uint8_t twi_txBufferIndex; +static volatile uint8_t twi_txBufferLength; + +static uint8_t twi_rxBuffer[TWI_BUFFER_LENGTH]; +static volatile uint8_t twi_rxBufferIndex; + +static volatile uint8_t twi_error; + +/* + * Function twi_init + * Desc readys twi pins and sets twi bitrate + * Input none + * Output none + */ +void twi_init(void) +{ + // initialize state + twi_state = TWI_READY; + twi_sendStop = true; // default value + twi_inRepStart = false; + + // activate internal pullups for twi. + digitalWrite(SDA, 1); + digitalWrite(SCL, 1); + + // initialize twi prescaler and bit rate + cbi(TWSR, TWPS0); + cbi(TWSR, TWPS1); + TWBR = ((F_CPU / TWI_FREQ) - 16) / 2; + + /* twi bit rate formula from atmega128 manual pg 204 + SCL Frequency = CPU Clock Frequency / (16 + (2 * TWBR)) + note: TWBR should be 10 or higher for master mode + It is 72 for a 16mhz Wiring board with 100kHz TWI */ + + // enable twi module, acks, and twi interrupt + TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA); +} + +/* + * Function twi_slaveInit + * Desc sets slave address and enables interrupt + * Input none + * Output none + */ +void twi_setAddress(uint8_t address) +{ + // set twi slave address (skip over TWGCE bit) + TWAR = address << 1; +} + +/* + * Function twi_readFrom + * Desc attempts to become twi bus master and read a + * series of bytes from a device on the bus + * Input address: 7bit i2c device address + * data: pointer to byte array + * length: number of bytes to read into array + * sendStop: Boolean indicating whether to send a stop at the end + * Output number of bytes read + */ +uint8_t twi_readFrom(uint8_t address, uint8_t* data, uint8_t length, uint8_t sendStop) +{ + uint8_t i; + + // ensure data will fit into buffer + if(TWI_BUFFER_LENGTH < length){ + return 0; + } + + // wait until twi is ready, become master receiver + while(TWI_READY != twi_state){ + continue; + } + twi_state = TWI_MRX; + twi_sendStop = sendStop; + // reset error state (0xFF.. no error occured) + twi_error = 0xFF; + + // initialize buffer iteration vars + twi_masterBufferIndex = 0; + twi_masterBufferLength = length-1; // This is not intuitive, read on... + // On receive, the previously configured ACK/NACK setting is transmitted in + // response to the received byte before the interrupt is signalled. + // Therefor we must actually set NACK when the _next_ to last byte is + // received, causing that NACK to be sent in response to receiving the last + // expected byte of data. + + // build sla+w, slave device address + w bit + twi_slarw = TW_READ; + twi_slarw |= address << 1; + + if (true == twi_inRepStart) { + // if we're in the repeated start state, then we've already sent the start, + // (@@@ we hope), and the TWI statemachine is just waiting for the address byte. + // We need to remove ourselves from the repeated start state before we enable interrupts, + // since the ISR is ASYNC, and we could get confused if we hit the ISR before cleaning + // up. Also, don't enable the START interrupt. There may be one pending from the + // repeated start that we sent outselves, and that would really confuse things. + twi_inRepStart = false; // remember, we're dealing with an ASYNC ISR + TWDR = twi_slarw; + TWCR = _BV(TWINT) | _BV(TWEA) | _BV(TWEN) | _BV(TWIE); // enable INTs, but not START + } + else + // send start condition + TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTA); + + // wait for read operation to complete + while(TWI_MRX == twi_state){ + continue; + } + + if (twi_masterBufferIndex < length) + length = twi_masterBufferIndex; + + // copy twi buffer to data + for(i = 0; i < length; ++i){ + data[i] = twi_masterBuffer[i]; + } + + return length; +} + +/* + * Function twi_writeTo + * Desc attempts to become twi bus master and write a + * series of bytes to a device on the bus + * Input address: 7bit i2c device address + * data: pointer to byte array + * length: number of bytes in array + * wait: boolean indicating to wait for write or not + * sendStop: boolean indicating whether or not to send a stop at the end + * Output 0 .. success + * 1 .. length to long for buffer + * 2 .. address send, NACK received + * 3 .. data send, NACK received + * 4 .. other twi error (lost bus arbitration, bus error, ..) + */ +uint8_t twi_writeTo(uint8_t address, uint8_t* data, uint8_t length, uint8_t wait, uint8_t sendStop) +{ + uint8_t i; + + // ensure data will fit into buffer + if(TWI_BUFFER_LENGTH < length){ + return 1; + } + + // wait until twi is ready, become master transmitter + while(TWI_READY != twi_state){ + continue; + } + twi_state = TWI_MTX; + twi_sendStop = sendStop; + // reset error state (0xFF.. no error occured) + twi_error = 0xFF; + + // initialize buffer iteration vars + twi_masterBufferIndex = 0; + twi_masterBufferLength = length; + + // copy data to twi buffer + for(i = 0; i < length; ++i){ + twi_masterBuffer[i] = data[i]; + } + + // build sla+w, slave device address + w bit + twi_slarw = TW_WRITE; + twi_slarw |= address << 1; + + // if we're in a repeated start, then we've already sent the START + // in the ISR. Don't do it again. + // + if (true == twi_inRepStart) { + // if we're in the repeated start state, then we've already sent the start, + // (@@@ we hope), and the TWI statemachine is just waiting for the address byte. + // We need to remove ourselves from the repeated start state before we enable interrupts, + // since the ISR is ASYNC, and we could get confused if we hit the ISR before cleaning + // up. Also, don't enable the START interrupt. There may be one pending from the + // repeated start that we sent outselves, and that would really confuse things. + twi_inRepStart = false; // remember, we're dealing with an ASYNC ISR + TWDR = twi_slarw; + TWCR = _BV(TWINT) | _BV(TWEA) | _BV(TWEN) | _BV(TWIE); // enable INTs, but not START + } + else + // send start condition + TWCR = _BV(TWINT) | _BV(TWEA) | _BV(TWEN) | _BV(TWIE) | _BV(TWSTA); // enable INTs + + // wait for write operation to complete + while(wait && (TWI_MTX == twi_state)){ + continue; + } + + if (twi_error == 0xFF) + return 0; // success + else if (twi_error == TW_MT_SLA_NACK) + return 2; // error: address send, nack received + else if (twi_error == TW_MT_DATA_NACK) + return 3; // error: data send, nack received + else + return 4; // other twi error +} + +/* + * Function twi_transmit + * Desc fills slave tx buffer with data + * must be called in slave tx event callback + * Input data: pointer to byte array + * length: number of bytes in array + * Output 1 length too long for buffer + * 2 not slave transmitter + * 0 ok + */ +uint8_t twi_transmit(const uint8_t* data, uint8_t length) +{ + uint8_t i; + + // ensure data will fit into buffer + if(TWI_BUFFER_LENGTH < length){ + return 1; + } + + // ensure we are currently a slave transmitter + if(TWI_STX != twi_state){ + return 2; + } + + // set length and copy data into tx buffer + twi_txBufferLength = length; + for(i = 0; i < length; ++i){ + twi_txBuffer[i] = data[i]; + } + + return 0; +} + +/* + * Function twi_attachSlaveRxEvent + * Desc sets function called before a slave read operation + * Input function: callback function to use + * Output none + */ +void twi_attachSlaveRxEvent( void (*function)(uint8_t*, int) ) +{ + twi_onSlaveReceive = function; +} + +/* + * Function twi_attachSlaveTxEvent + * Desc sets function called before a slave write operation + * Input function: callback function to use + * Output none + */ +void twi_attachSlaveTxEvent( void (*function)(void) ) +{ + twi_onSlaveTransmit = function; +} + +/* + * Function twi_reply + * Desc sends byte or readys receive line + * Input ack: byte indicating to ack or to nack + * Output none + */ +void twi_reply(uint8_t ack) +{ + // transmit master read ready signal, with or without ack + if(ack){ + TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWINT) | _BV(TWEA); + }else{ + TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWINT); + } +} + +/* + * Function twi_stop + * Desc relinquishes bus master status + * Input none + * Output none + */ +void twi_stop(void) +{ + // send stop condition + TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTO); + + // wait for stop condition to be exectued on bus + // TWINT is not set after a stop condition! + while(TWCR & _BV(TWSTO)){ + continue; + } + + // update twi state + twi_state = TWI_READY; +} + +/* + * Function twi_releaseBus + * Desc releases bus control + * Input none + * Output none + */ +void twi_releaseBus(void) +{ + // release bus + TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT); + + // update twi state + twi_state = TWI_READY; +} + +SIGNAL(TWI_vect) +{ + switch(TW_STATUS){ + // All Master + case TW_START: // sent start condition + case TW_REP_START: // sent repeated start condition + // copy device address and r/w bit to output register and ack + TWDR = twi_slarw; + twi_reply(1); + break; + + // Master Transmitter + case TW_MT_SLA_ACK: // slave receiver acked address + case TW_MT_DATA_ACK: // slave receiver acked data + // if there is data to send, send it, otherwise stop + if(twi_masterBufferIndex < twi_masterBufferLength){ + // copy data to output register and ack + TWDR = twi_masterBuffer[twi_masterBufferIndex++]; + twi_reply(1); + }else{ + if (twi_sendStop) + twi_stop(); + else { + twi_inRepStart = true; // we're gonna send the START + // don't enable the interrupt. We'll generate the start, but we + // avoid handling the interrupt until we're in the next transaction, + // at the point where we would normally issue the start. + TWCR = _BV(TWINT) | _BV(TWSTA)| _BV(TWEN) ; + twi_state = TWI_READY; + } + } + break; + case TW_MT_SLA_NACK: // address sent, nack received + twi_error = TW_MT_SLA_NACK; + twi_stop(); + break; + case TW_MT_DATA_NACK: // data sent, nack received + twi_error = TW_MT_DATA_NACK; + twi_stop(); + break; + case TW_MT_ARB_LOST: // lost bus arbitration + twi_error = TW_MT_ARB_LOST; + twi_releaseBus(); + break; + + // Master Receiver + case TW_MR_DATA_ACK: // data received, ack sent + // put byte into buffer + twi_masterBuffer[twi_masterBufferIndex++] = TWDR; + case TW_MR_SLA_ACK: // address sent, ack received + // ack if more bytes are expected, otherwise nack + if(twi_masterBufferIndex < twi_masterBufferLength){ + twi_reply(1); + }else{ + twi_reply(0); + } + break; + case TW_MR_DATA_NACK: // data received, nack sent + // put final byte into buffer + twi_masterBuffer[twi_masterBufferIndex++] = TWDR; + if (twi_sendStop) + twi_stop(); + else { + twi_inRepStart = true; // we're gonna send the START + // don't enable the interrupt. We'll generate the start, but we + // avoid handling the interrupt until we're in the next transaction, + // at the point where we would normally issue the start. + TWCR = _BV(TWINT) | _BV(TWSTA)| _BV(TWEN) ; + twi_state = TWI_READY; + } + break; + case TW_MR_SLA_NACK: // address sent, nack received + twi_stop(); + break; + // TW_MR_ARB_LOST handled by TW_MT_ARB_LOST case + + // Slave Receiver + case TW_SR_SLA_ACK: // addressed, returned ack + case TW_SR_GCALL_ACK: // addressed generally, returned ack + case TW_SR_ARB_LOST_SLA_ACK: // lost arbitration, returned ack + case TW_SR_ARB_LOST_GCALL_ACK: // lost arbitration, returned ack + // enter slave receiver mode + twi_state = TWI_SRX; + // indicate that rx buffer can be overwritten and ack + twi_rxBufferIndex = 0; + twi_reply(1); + break; + case TW_SR_DATA_ACK: // data received, returned ack + case TW_SR_GCALL_DATA_ACK: // data received generally, returned ack + // if there is still room in the rx buffer + if(twi_rxBufferIndex < TWI_BUFFER_LENGTH){ + // put byte in buffer and ack + twi_rxBuffer[twi_rxBufferIndex++] = TWDR; + twi_reply(1); + }else{ + // otherwise nack + twi_reply(0); + } + break; + case TW_SR_STOP: // stop or repeated start condition received + // put a null char after data if there's room + if(twi_rxBufferIndex < TWI_BUFFER_LENGTH){ + twi_rxBuffer[twi_rxBufferIndex] = '\0'; + } + // sends ack and stops interface for clock stretching + twi_stop(); + // callback to user defined callback + twi_onSlaveReceive(twi_rxBuffer, twi_rxBufferIndex); + // since we submit rx buffer to "wire" library, we can reset it + twi_rxBufferIndex = 0; + // ack future responses and leave slave receiver state + twi_releaseBus(); + break; + case TW_SR_DATA_NACK: // data received, returned nack + case TW_SR_GCALL_DATA_NACK: // data received generally, returned nack + // nack back at master + twi_reply(0); + break; + + // Slave Transmitter + case TW_ST_SLA_ACK: // addressed, returned ack + case TW_ST_ARB_LOST_SLA_ACK: // arbitration lost, returned ack + // enter slave transmitter mode + twi_state = TWI_STX; + // ready the tx buffer index for iteration + twi_txBufferIndex = 0; + // set tx buffer length to be zero, to verify if user changes it + twi_txBufferLength = 0; + // request for txBuffer to be filled and length to be set + // note: user must call twi_transmit(bytes, length) to do this + twi_onSlaveTransmit(); + // if they didn't change buffer & length, initialize it + if(0 == twi_txBufferLength){ + twi_txBufferLength = 1; + twi_txBuffer[0] = 0x00; + } + // transmit first byte from buffer, fall + case TW_ST_DATA_ACK: // byte sent, ack returned + // copy data to output register + TWDR = twi_txBuffer[twi_txBufferIndex++]; + // if there is more to send, ack, otherwise nack + if(twi_txBufferIndex < twi_txBufferLength){ + twi_reply(1); + }else{ + twi_reply(0); + } + break; + case TW_ST_DATA_NACK: // received nack, we are done + case TW_ST_LAST_DATA: // received ack, but we are done already! + // ack future responses + twi_reply(1); + // leave slave receiver state + twi_state = TWI_READY; + break; + + // All + case TW_NO_INFO: // no state information + break; + case TW_BUS_ERROR: // bus error, illegal stop/start + twi_error = TW_BUS_ERROR; + twi_stop(); + break; + } +} + diff --git a/src/lib/twi.h b/src/lib/twi.h new file mode 100644 index 0000000..6526593 --- /dev/null +++ b/src/lib/twi.h @@ -0,0 +1,53 @@ +/* + twi.h - TWI/I2C library for Wiring & Arduino + Copyright (c) 2006 Nicholas Zambetti. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef twi_h +#define twi_h + + #include + + //#define ATMEGA8 + + #ifndef TWI_FREQ + #define TWI_FREQ 100000L + #endif + + #ifndef TWI_BUFFER_LENGTH + #define TWI_BUFFER_LENGTH 32 + #endif + + #define TWI_READY 0 + #define TWI_MRX 1 + #define TWI_MTX 2 + #define TWI_SRX 3 + #define TWI_STX 4 + + void twi_init(void); + void twi_setAddress(uint8_t); + uint8_t twi_readFrom(uint8_t, uint8_t*, uint8_t, uint8_t); + uint8_t twi_writeTo(uint8_t, uint8_t*, uint8_t, uint8_t, uint8_t); + uint8_t twi_transmit(const uint8_t*, uint8_t); + void twi_attachSlaveRxEvent( void (*)(uint8_t*, int) ); + void twi_attachSlaveTxEvent( void (*)(void) ); + void twi_reply(uint8_t); + void twi_stop(void); + void twi_releaseBus(void); + +#endif + diff --git a/src/lib/usb_debug_only.c b/src/lib/usb_debug_only.c new file mode 100644 index 0000000..b1e53a9 --- /dev/null +++ b/src/lib/usb_debug_only.c @@ -0,0 +1,549 @@ +/* USB Debug Channel Example for Teensy USB Development Board + * http://www.pjrc.com/teensy/ + * Copyright (c) 2008 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: Add support for Teensy 2.0 + +#define USB_SERIAL_PRIVATE_INCLUDE +#include "usb_debug_only.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"Your USB Device" + + +// 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 0x0479 + + +// 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 102 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 + * + **************************************************************************/ + +// you might want to change the buffer size, up to 64 bytes. +// The host reserves your bandwidth because this is an interrupt +// endpoint, so it won't be available to other interrupt or isync +// endpoints in other devices on the bus. + +#define ENDPOINT0_SIZE 32 +#define DEBUG_TX_ENDPOINT 3 +#define DEBUG_TX_SIZE 32 +#define DEBUG_TX_BUFFER EP_DOUBLE_BUFFER + +static const uint8_t PROGMEM endpoint_config_table[] = { + 0, + 0, + 1, EP_TYPE_INTERRUPT_IN, EP_SIZE(DEBUG_TX_SIZE) | DEBUG_TX_BUFFER, + 0 +}; + + +/************************************************************************** + * + * Descriptor Data + * + **************************************************************************/ + +// Descriptors are the data that your computer reads when it auto-detects +// this USB device (called "enumeration" in USB lingo). The most commonly +// changed items are editable at the top of this file. Changing things +// in here should only be done by those who've read chapter 9 of the USB +// spec and relevant portions of any USB class specifications! + + +static uint8_t PROGMEM device_descriptor[] = { + 18, // bLength + 1, // bDescriptorType + 0x00, 0x02, // bcdUSB + 0, // bDeviceClass + 0, // bDeviceSubClass + 0, // bDeviceProtocol + ENDPOINT0_SIZE, // bMaxPacketSize0 + LSB(VENDOR_ID), MSB(VENDOR_ID), // idVendor + LSB(PRODUCT_ID), MSB(PRODUCT_ID), // idProduct + 0x00, 0x01, // bcdDevice + 1, // iManufacturer + 2, // iProduct + 0, // iSerialNumber + 1 // bNumConfigurations +}; + +static uint8_t PROGMEM hid_report_descriptor[] = { + 0x06, 0x31, 0xFF, // Usage Page 0xFF31 (vendor defined) + 0x09, 0x74, // Usage 0x74 + 0xA1, 0x53, // Collection 0x53 + 0x75, 0x08, // report size = 8 bits + 0x15, 0x00, // logical minimum = 0 + 0x26, 0xFF, 0x00, // logical maximum = 255 + 0x95, DEBUG_TX_SIZE, // report count + 0x09, 0x75, // usage + 0x81, 0x02, // Input (array) + 0xC0 // end collection +}; + +#define CONFIG1_DESC_SIZE (9+9+9+7) +#define HID_DESC2_OFFSET (9+9) +static uint8_t PROGMEM config1_descriptor[CONFIG1_DESC_SIZE] = { + // configuration descriptor, USB spec 9.6.3, page 264-266, Table 9-10 + 9, // bLength; + 2, // bDescriptorType; + LSB(CONFIG1_DESC_SIZE), // wTotalLength + MSB(CONFIG1_DESC_SIZE), + 1, // bNumInterfaces + 1, // bConfigurationValue + 0, // iConfiguration + 0xC0, // bmAttributes + 50, // bMaxPower + // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12 + 9, // bLength + 4, // bDescriptorType + 0, // bInterfaceNumber + 0, // bAlternateSetting + 1, // bNumEndpoints + 0x03, // bInterfaceClass (0x03 = HID) + 0x00, // bInterfaceSubClass + 0x00, // bInterfaceProtocol + 0, // iInterface + // HID interface descriptor, HID 1.11 spec, section 6.2.1 + 9, // bLength + 0x21, // bDescriptorType + 0x11, 0x01, // bcdHID + 0, // bCountryCode + 1, // bNumDescriptors + 0x22, // bDescriptorType + sizeof(hid_report_descriptor), // wDescriptorLength + 0, + // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 + 7, // bLength + 5, // bDescriptorType + DEBUG_TX_ENDPOINT | 0x80, // bEndpointAddress + 0x03, // bmAttributes (0x03=intr) + DEBUG_TX_SIZE, 0, // wMaxPacketSize + 1 // bInterval +}; + +// If you're desperate for a little extra code memory, these strings +// can be completely removed if iManufacturer, iProduct, iSerialNumber +// in the device desciptor are changed to zeros. +struct usb_string_descriptor_struct { + uint8_t bLength; + uint8_t bDescriptorType; + int16_t wString[]; +}; +static struct usb_string_descriptor_struct PROGMEM string0 = { + 4, + 3, + {0x0409} +}; +static struct usb_string_descriptor_struct PROGMEM string1 = { + sizeof(STR_MANUFACTURER), + 3, + STR_MANUFACTURER +}; +static struct usb_string_descriptor_struct PROGMEM string2 = { + sizeof(STR_PRODUCT), + 3, + STR_PRODUCT +}; + +// This table defines which descriptor data is sent for each specific +// request from the host (in wValue and wIndex). +static struct descriptor_list_struct { + uint16_t wValue; + uint16_t wIndex; + const uint8_t *addr; + uint8_t length; +} PROGMEM descriptor_list[] = { + {0x0100, 0x0000, device_descriptor, sizeof(device_descriptor)}, + {0x0200, 0x0000, config1_descriptor, sizeof(config1_descriptor)}, + {0x2200, 0x0000, hid_report_descriptor, sizeof(hid_report_descriptor)}, + {0x2100, 0x0000, config1_descriptor+HID_DESC2_OFFSET, 9}, + {0x0300, 0x0000, (const uint8_t *)&string0, 4}, + {0x0301, 0x0409, (const uint8_t *)&string1, sizeof(STR_MANUFACTURER)}, + {0x0302, 0x0409, (const uint8_t *)&string2, sizeof(STR_PRODUCT)} +}; +#define NUM_DESC_LIST (sizeof(descriptor_list)/sizeof(struct descriptor_list_struct)) + + +/************************************************************************** + * + * Variables - these are the only non-stack RAM usage + * + **************************************************************************/ + +// zero when we are not configured, non-zero when enumerated +static volatile uint8_t usb_configuration=0; + +// the time remaining before we transmit any partially full +// packet, or send a zero length packet. +static volatile uint8_t debug_flush_timer=0; + + +/************************************************************************** + * + * Public Functions - these are the API intended for the user + * + **************************************************************************/ + + +// initialize USB +void usb_init(void) +{ + HW_CONFIG(); + USB_FREEZE(); // enable USB + PLL_CONFIG(); // config PLL + while (!(PLLCSR & (1<= NUM_DESC_LIST) { + UECONX = (1< desc_length) len = desc_length; + do { + // wait for host ready for IN packet + do { + i = UEINTX; + } while (!(i & ((1<= 1 && i <= MAX_ENDPOINT) { + usb_send_in(); + UENUM = i; + if (bRequest == SET_FEATURE) { + UECONX = (1< + +void usb_init(void); // initialize everything +uint8_t usb_configured(void); // is the USB port configured + +int8_t usb_debug_putchar(uint8_t c); // transmit a character +void usb_debug_flush_output(void); // immediately transmit any buffered output +#define USB_DEBUG_HID + + +// Everything below this point is only intended for usb_serial.c +#ifdef USB_SERIAL_PRIVATE_INCLUDE +#include +#include +#include + +#define EP_TYPE_CONTROL 0x00 +#define EP_TYPE_BULK_IN 0x81 +#define EP_TYPE_BULK_OUT 0x80 +#define EP_TYPE_INTERRUPT_IN 0xC1 +#define EP_TYPE_INTERRUPT_OUT 0xC0 +#define EP_TYPE_ISOCHRONOUS_IN 0x41 +#define EP_TYPE_ISOCHRONOUS_OUT 0x40 + +#define EP_SINGLE_BUFFER 0x02 +#define EP_DOUBLE_BUFFER 0x06 + +#define EP_SIZE(s) ((s) == 64 ? 0x30 : \ + ((s) == 32 ? 0x20 : \ + ((s) == 16 ? 0x10 : \ + 0x00))) + +#define MAX_ENDPOINT 4 + +#define LSB(n) (n & 255) +#define MSB(n) ((n >> 8) & 255) + +#if defined(__AVR_AT90USB162__) +#define HW_CONFIG() +#define PLL_CONFIG() (PLLCSR = ((1< Date: Tue, 13 Mar 2012 00:40:28 -0700 Subject: [PATCH 03/22] mostly comments documenting pin and matrix assignment --- doc/references.md | 1 + src/ergodox-firmware.c | 170 ++++++++++++++++++++++++++++++++++++++++- 2 files changed, 169 insertions(+), 2 deletions(-) diff --git a/doc/references.md b/doc/references.md index bd64aaf..3f7bb32 100644 --- a/doc/references.md +++ b/doc/references.md @@ -102,6 +102,7 @@ * github: [TWI library in C] (https://github.com/arduino/Arduino/tree/master/libraries/Wire/utility) + : (arduino / Arduino / libraries / Wire / utility) * zip: [PJRC: usb_keyboard] (http://pjrc.com/teensy/usb_keyboard.zip) diff --git a/src/ergodox-firmware.c b/src/ergodox-firmware.c index 0835479..604e55d 100644 --- a/src/ergodox-firmware.c +++ b/src/ergodox-firmware.c @@ -6,8 +6,174 @@ * * ------------------------------------------------------------------------- */ -// todo: set clock prescaler +/* ---------------------------------------------------------------------------- + * Matrix [row.column] assignments + * - row and column numbers are in hex + * - coordinates without brackets are unused + * - left and right hands are mirrored, with `row += 6` for left hand rows + * ---------------------------------------------------------------------------- + * ....... rows x columns = positions; assigned, unassigned ....... + * ....... per hand: 6 x 7 = 42; 38, 4 ....... + * ....... total: 12 x 7 = 84; 76, 8 ....... + * ---------------------------------------------------------------------------- + * [66][65][64][63][62][61][60] [00][01][02][03][04][05][06] + * [76][75][74][73][72][71][70] [10][11][12][13][14][15][16] + * [86][85][84][83][82][81] 80 20 [21][22][23][24][25][26] + * [96][95][94][93][92][91][90] [30][31][32][33][34][35][36] + * [A6][A5][A4][A3][A2] A1 A0 40 41 [42][43][44][45][46] + * [B1] B0 50 [51] + * [B3] [B2] [52] [53] + * [B6][B5][B4] [54][55][56] + * ------------------------------------------------------------------------- */ -void main() { +/* ---------------------------------------------------------------------------- + * Pinouts and Pin assignments + * =========================== + * - '+' indicates pin + * - 'o' indicates unused pin + * - '-'s inserted between some of the pin names for readability + * - 'OC**' pins enclosed in parenthesis had lines over them in the pinout + * ---------------------------------------------------------------------------- + * Teensy 2.0 + * ========== GND +---.....---+ VCC + * SS PB0 + + PF0 ADC0 + * SCLK PB1 + + PF1 ADC1 + * MOSI PB2 + + PF4 ADC4 + * MISO PB3 + + + + PF5 ADC5 + * RTS OC1C OC0A --------- PB7 + PE6 AREF + PF6 ADC6 + * OC0B INT0 SCL PD0 + AIN0 + PF7 ADC7 + * INT1 SDA PD1 + INT6 + PB6 ADC13 OC1B OC4B + * RXD1 ----------- INT2 --- PD2 + + PB5 ADC12 OC1A (OC4B) + * TXD1 ----------- INT3 --- PD3 + + PB4 ADC11 + * OC3A (OC4A) -------- PC6 + + PD7 ADC10 T0 -- OC4D + * ICP3 ----- OC4A --------- PC7 +-+-+-+-+-+-+ PD6 ADC9 T1 - (OC4D) onboardLED + * CTS XCK1 PD5 --/ | | | \-- PD4 ADC8 ------------ ICP1 + * VCC ------------------/ | \-------------- RST + * GND --------------------/ + * ---------------------------------------------------------------------------- + * MCP23018 + * ======== Vss(GND) +01---.---28+ NC + * GPNC +02 27+ GPAC + * GPB0 +03 26+ GPA6 + * GPB1 +04 25+ GPAC + * GPB2 +05 24+ GPAC + * GPB3 +06 23+ GPAC + * GPB4 +07 22+ GPAC + * GPB5 +08 21+ GPAC + * GPB6 +09 20+ GPAC + * GPB7 +10 19+ INTC + * Vdd(Vcc) +11 18+ INTC + * SCL +12 17+ NC + * SDA +13 16+ RESET + * NC +14-------15+ ADDR + * ---------------------------------------------------------------------------- + * ---------------------------------------------------------------------------- + * Teensy 2.0 Pin Assignments + * ========================== + * power_negative GND +---.....---+ Vcc power_positive + * column6 PB0 + + PF0 row0 + * o + PF1 row1 + * o + PF4 row2 + * o o o + PF5 row3 + * LED3 OC1C + + PF6 row4 + * I2C SCL + + PF7 row5 + * I2C SDA + + OC1B LED2 + * column3 PD2 + + OC1A LED1 + * column4 PD3 + + PB4 column0 + * column1 PC6 + + PD7 column5 + * column2 PC7 +-o-o-o-o-o-o + * ---------------------------------------------------------------------------- + * MCP32018 Pin Assignments + * ======================== + * power_negative Vss(GND) +01---.---28o + * o02 27o + * column0 GPB0 +03 26o + * column1 GPB1 +04 25+ GPA5 row5 + * column2 GPB2 +05 24+ GPA4 row4 + * column3 GPB3 +06 23+ GPA3 row3 + * column4 GPB4 +07 22+ GPA2 row2 + * column5 GPB5 +08 21+ GPA1 row1 + * column6 GPB6 +09 20+ GPA0 row0 + * o10 19+ INTA ?TODO + * power_positive Vdd(Vcc) +11 18+ INTB ?TODO + * I2C SCL +12 17o + * I2C SDA +13 16+ RESET ?TODO + * o14-------15+ ADDR ?TODO + * ------------------------------------------------------------------------- */ + + +#include "lib/twi.h" +#include "lib/print.h" + + +// processor frequency (from ) +#define CPU_PRESCALE(n) (CLKPR = 0x80, CLKPR = (n)) +#define CPU_16MHz 0x00 +#define CPU_8MHz 0x01 +#define CPU_4MHz 0x02 +#define CPU_2MHz 0x03 +#define CPU_1MHz 0x04 +#define CPU_500kHz 0x05 +#define CPU_250kHz 0x06 +#define CPU_125kHz 0x07 +#define CPU_62kHz 0x08 + +// pins +// TODO: write some pretty macros + + +// TODO: +// - initialize pins +void init() { + CPU_PRESCALE(CPU_16MHz); // speed should match F_CPU in makefile } + +#define KB_LAYERS 1 +#define KB_ROWS 12 // don't change +#define KB_COLUMNS 7 // don't change + +uint8_t is_pressed[KB_ROWS][KB_COLUMNS] = { +// --- right hand --- +// column 0 1 2 3 4 5 6 + 0, 0, 0, 0, 0, 0, 0, //row 0x0 + 0, 0, 0, 0, 0, 0, 0, //row 0x1 + 0, 0, 0, 0, 0, 0, 0, //row 0x2 + 0, 0, 0, 0, 0, 0, 0, //row 0x3 + 0, 0, 0, 0, 0, 0, 0, //row 0x4 + 0, 0, 0, 0, 0, 0, 0, //row 0x5 + +// --- left hand --- +// column 0 1 2 3 4 5 6 + 0, 0, 0, 0, 0, 0, 0, //row 0x6 + 0, 0, 0, 0, 0, 0, 0, //row 0x7 + 0, 0, 0, 0, 0, 0, 0, //row 0x8 + 0, 0, 0, 0, 0, 0, 0, //row 0x9 + 0, 0, 0, 0, 0, 0, 0, //row 0xA + 0, 0, 0, 0, 0, 0, 0, //row 0xB +} + +// TODO: this belongs in program space +uint8_t kb_maps[KB_LAYERS][KB_ROWS][KB_COLUMNS] = { +// --- layer: default --- +// column 0 1 2 3 4 5 6 + 0, 0, 0, 0, 0, 0, 0, //row 0x0 + 0, 0, 0, 0, 0, 0, 0, //row 0x1 + 0, 0, 0, 0, 0, 0, 0, //row 0x2 + 0, 0, 0, 0, 0, 0, 0, //row 0x3 + 0, 0, 0, 0, 0, 0, 0, //row 0x4 + 0, 0, 0, 0, 0, 0, 0, //row 0x5 + 0, 0, 0, 0, 0, 0, 0, //row 0x6 + 0, 0, 0, 0, 0, 0, 0, //row 0x7 + 0, 0, 0, 0, 0, 0, 0, //row 0x8 + 0, 0, 0, 0, 0, 0, 0, //row 0x9 + 0, 0, 0, 0, 0, 0, 0, //row 0xA + 0, 0, 0, 0, 0, 0, 0, //row 0xB +} + + +void main() { + init(); +} + + From f628b56812727bc87da4e3da98322fd4cd12b213 Mon Sep 17 00:00:00 2001 From: Ben Blazak Date: Tue, 13 Mar 2012 23:51:51 -0700 Subject: [PATCH 04/22] worked on pin assignments a little; and some other minor updates --- doc/references.md | 3 +++ src/ergodox-firmware.c | 22 ++++++++++++++++------ 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/doc/references.md b/doc/references.md index 3f7bb32..1b5e078 100644 --- a/doc/references.md +++ b/doc/references.md @@ -23,6 +23,9 @@ -> [powering LEDs] (http://wolfstone.halloweenhost.com/Lighting/litlpo_PoweringLEDs.html) +* [Vcc, Vdd, Vss, etc.] + (http://encyclobeamia.solarbotics.net/articles/vxx.html) + ## Noob C Stuff diff --git a/src/ergodox-firmware.c b/src/ergodox-firmware.c index 604e55d..9ca0081 100644 --- a/src/ergodox-firmware.c +++ b/src/ergodox-firmware.c @@ -28,12 +28,12 @@ /* ---------------------------------------------------------------------------- * Pinouts and Pin assignments - * =========================== * - '+' indicates pin * - 'o' indicates unused pin * - '-'s inserted between some of the pin names for readability * - 'OC**' pins enclosed in parenthesis had lines over them in the pinout * ---------------------------------------------------------------------------- + * ---------------------------------------------------------------------------- * Teensy 2.0 * ========== GND +---.....---+ VCC * SS PB0 + + PF0 ADC0 @@ -94,11 +94,22 @@ * column4 GPB4 +07 22+ GPA2 row2 * column5 GPB5 +08 21+ GPA1 row1 * column6 GPB6 +09 20+ GPA0 row0 - * o10 19+ INTA ?TODO - * power_positive Vdd(Vcc) +11 18+ INTB ?TODO + * o10 19o + * power_positive Vdd(Vcc) +11 18o * I2C SCL +12 17o - * I2C SDA +13 16+ RESET ?TODO - * o14-------15+ ADDR ?TODO + * I2C SDA +13 16+ RESET (see note) + * o14-------15+ ADDR (see note) + * + * notes: + * - ADDR (pin15): Set to 0b000 via + * Vdd(Vcc) -- R1 -- V2 (on ADDR) -- R2 -- Vss(GND) + * where + * Vdd = +5V + * R1 = ?TODO:\ + * V2 = ?TODO: | (see mcp23018 datasheet, pg 11) + * R2 = ?TODO:/ + * - RESET (pin16): Not used by software. Might want to have it available + * somewhere physically just in case though? * ------------------------------------------------------------------------- */ @@ -176,4 +187,3 @@ void main() { init(); } - From 4bcc0e5dc35f1f86e204b128f6e4a0e7971cd113 Mon Sep 17 00:00:00 2001 From: Ben Blazak Date: Wed, 14 Mar 2012 14:46:52 -0700 Subject: [PATCH 05/22] split the firmware into general/controller/keyboard files --- .../teensy-2-0.c} | 77 +------------------ src/controller/teensy-2-0.h | 0 src/firmware.c | 22 ++++++ src/keyboard/ergodox.c | 72 +++++++++++++++++ src/keyboard/ergodox.h | 0 src/makefile | 14 +++- 6 files changed, 106 insertions(+), 79 deletions(-) rename src/{ergodox-firmware.c => controller/teensy-2-0.c} (64%) create mode 100644 src/controller/teensy-2-0.h create mode 100644 src/firmware.c create mode 100644 src/keyboard/ergodox.c create mode 100644 src/keyboard/ergodox.h diff --git a/src/ergodox-firmware.c b/src/controller/teensy-2-0.c similarity index 64% rename from src/ergodox-firmware.c rename to src/controller/teensy-2-0.c index 9ca0081..c2643f6 100644 --- a/src/ergodox-firmware.c +++ b/src/controller/teensy-2-0.c @@ -1,31 +1,11 @@ /* ---------------------------------------------------------------------------- - * Firmware for the ergoDOX keyboard + * Teensy 2.0 specific stuff * ---------------------------------------------------------------------------- * Copyright (c) 2012 Ben Blazak * Released under The MIT License (MIT) (see "license.md") at * * ------------------------------------------------------------------------- */ -/* ---------------------------------------------------------------------------- - * Matrix [row.column] assignments - * - row and column numbers are in hex - * - coordinates without brackets are unused - * - left and right hands are mirrored, with `row += 6` for left hand rows - * ---------------------------------------------------------------------------- - * ....... rows x columns = positions; assigned, unassigned ....... - * ....... per hand: 6 x 7 = 42; 38, 4 ....... - * ....... total: 12 x 7 = 84; 76, 8 ....... - * ---------------------------------------------------------------------------- - * [66][65][64][63][62][61][60] [00][01][02][03][04][05][06] - * [76][75][74][73][72][71][70] [10][11][12][13][14][15][16] - * [86][85][84][83][82][81] 80 20 [21][22][23][24][25][26] - * [96][95][94][93][92][91][90] [30][31][32][33][34][35][36] - * [A6][A5][A4][A3][A2] A1 A0 40 41 [42][43][44][45][46] - * [B1] B0 50 [51] - * [B3] [B2] [52] [53] - * [B6][B5][B4] [54][55][56] - * ------------------------------------------------------------------------- */ - /* ---------------------------------------------------------------------------- * Pinouts and Pin assignments * - '+' indicates pin @@ -113,10 +93,6 @@ * ------------------------------------------------------------------------- */ -#include "lib/twi.h" -#include "lib/print.h" - - // processor frequency (from ) #define CPU_PRESCALE(n) (CLKPR = 0x80, CLKPR = (n)) #define CPU_16MHz 0x00 @@ -132,58 +108,9 @@ // pins // TODO: write some pretty macros - // TODO: // - initialize pins -void init() { +void controller_init() { CPU_PRESCALE(CPU_16MHz); // speed should match F_CPU in makefile } - -#define KB_LAYERS 1 -#define KB_ROWS 12 // don't change -#define KB_COLUMNS 7 // don't change - -uint8_t is_pressed[KB_ROWS][KB_COLUMNS] = { -// --- right hand --- -// column 0 1 2 3 4 5 6 - 0, 0, 0, 0, 0, 0, 0, //row 0x0 - 0, 0, 0, 0, 0, 0, 0, //row 0x1 - 0, 0, 0, 0, 0, 0, 0, //row 0x2 - 0, 0, 0, 0, 0, 0, 0, //row 0x3 - 0, 0, 0, 0, 0, 0, 0, //row 0x4 - 0, 0, 0, 0, 0, 0, 0, //row 0x5 - -// --- left hand --- -// column 0 1 2 3 4 5 6 - 0, 0, 0, 0, 0, 0, 0, //row 0x6 - 0, 0, 0, 0, 0, 0, 0, //row 0x7 - 0, 0, 0, 0, 0, 0, 0, //row 0x8 - 0, 0, 0, 0, 0, 0, 0, //row 0x9 - 0, 0, 0, 0, 0, 0, 0, //row 0xA - 0, 0, 0, 0, 0, 0, 0, //row 0xB -} - -// TODO: this belongs in program space -uint8_t kb_maps[KB_LAYERS][KB_ROWS][KB_COLUMNS] = { -// --- layer: default --- -// column 0 1 2 3 4 5 6 - 0, 0, 0, 0, 0, 0, 0, //row 0x0 - 0, 0, 0, 0, 0, 0, 0, //row 0x1 - 0, 0, 0, 0, 0, 0, 0, //row 0x2 - 0, 0, 0, 0, 0, 0, 0, //row 0x3 - 0, 0, 0, 0, 0, 0, 0, //row 0x4 - 0, 0, 0, 0, 0, 0, 0, //row 0x5 - 0, 0, 0, 0, 0, 0, 0, //row 0x6 - 0, 0, 0, 0, 0, 0, 0, //row 0x7 - 0, 0, 0, 0, 0, 0, 0, //row 0x8 - 0, 0, 0, 0, 0, 0, 0, //row 0x9 - 0, 0, 0, 0, 0, 0, 0, //row 0xA - 0, 0, 0, 0, 0, 0, 0, //row 0xB -} - - -void main() { - init(); -} - diff --git a/src/controller/teensy-2-0.h b/src/controller/teensy-2-0.h new file mode 100644 index 0000000..e69de29 diff --git a/src/firmware.c b/src/firmware.c new file mode 100644 index 0000000..f7998cb --- /dev/null +++ b/src/firmware.c @@ -0,0 +1,22 @@ +/* ---------------------------------------------------------------------------- + * Firmware for the ergoDOX keyboard + * ---------------------------------------------------------------------------- + * Copyright (c) 2012 Ben Blazak + * Released under The MIT License (MIT) (see "license.md") at + * + * ------------------------------------------------------------------------- */ + + +#include "keyboard/ergodox.h" +#include "controller/teensy-2-0.h" +#include "lib/twi.h" +#include "lib/print.h" + + +void main() { + init(); +} + +void init() { +} + diff --git a/src/keyboard/ergodox.c b/src/keyboard/ergodox.c new file mode 100644 index 0000000..e4b16a0 --- /dev/null +++ b/src/keyboard/ergodox.c @@ -0,0 +1,72 @@ +/* ---------------------------------------------------------------------------- + * ergoDOX specific stuff + * ---------------------------------------------------------------------------- + * Copyright (c) 2012 Ben Blazak + * Released under The MIT License (MIT) (see "license.md") at + * + * ------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------------- + * Matrix [row.column] assignments + * - row and column numbers are in hex + * - coordinates without brackets are unused + * - left and right hands are mirrored, with `row += 6` for left hand rows + * ---------------------------------------------------------------------------- + * ....... rows x columns = positions; assigned, unassigned ....... + * ....... per hand: 6 x 7 = 42; 38, 4 ....... + * ....... total: 12 x 7 = 84; 76, 8 ....... + * ---------------------------------------------------------------------------- + * [66][65][64][63][62][61][60] [00][01][02][03][04][05][06] + * [76][75][74][73][72][71][70] [10][11][12][13][14][15][16] + * [86][85][84][83][82][81] 80 20 [21][22][23][24][25][26] + * [96][95][94][93][92][91][90] [30][31][32][33][34][35][36] + * [A6][A5][A4][A3][A2] A1 A0 40 41 [42][43][44][45][46] + * [B1] B0 50 [51] + * [B3] [B2] [52] [53] + * [B6][B5][B4] [54][55][56] + * ------------------------------------------------------------------------- */ + + +#define KB_LAYERS 1 +#define KB_ROWS 12 // don't change +#define KB_COLUMNS 7 // don't change + + +uint8_t is_pressed[KB_ROWS][KB_COLUMNS] = { +// --- right hand --- +// column 0 1 2 3 4 5 6 + 0, 0, 0, 0, 0, 0, 0, //row 0x0 + 0, 0, 0, 0, 0, 0, 0, //row 0x1 + 0, 0, 0, 0, 0, 0, 0, //row 0x2 + 0, 0, 0, 0, 0, 0, 0, //row 0x3 + 0, 0, 0, 0, 0, 0, 0, //row 0x4 + 0, 0, 0, 0, 0, 0, 0, //row 0x5 + +// --- left hand --- +// column 0 1 2 3 4 5 6 + 0, 0, 0, 0, 0, 0, 0, //row 0x6 + 0, 0, 0, 0, 0, 0, 0, //row 0x7 + 0, 0, 0, 0, 0, 0, 0, //row 0x8 + 0, 0, 0, 0, 0, 0, 0, //row 0x9 + 0, 0, 0, 0, 0, 0, 0, //row 0xA + 0, 0, 0, 0, 0, 0, 0, //row 0xB +} + +// TODO: this belongs in program space +uint8_t kb_maps[KB_LAYERS][KB_ROWS][KB_COLUMNS] = { +// --- layer: default --- +// column 0 1 2 3 4 5 6 + 0, 0, 0, 0, 0, 0, 0, //row 0x0 + 0, 0, 0, 0, 0, 0, 0, //row 0x1 + 0, 0, 0, 0, 0, 0, 0, //row 0x2 + 0, 0, 0, 0, 0, 0, 0, //row 0x3 + 0, 0, 0, 0, 0, 0, 0, //row 0x4 + 0, 0, 0, 0, 0, 0, 0, //row 0x5 + 0, 0, 0, 0, 0, 0, 0, //row 0x6 + 0, 0, 0, 0, 0, 0, 0, //row 0x7 + 0, 0, 0, 0, 0, 0, 0, //row 0x8 + 0, 0, 0, 0, 0, 0, 0, //row 0x9 + 0, 0, 0, 0, 0, 0, 0, //row 0xA + 0, 0, 0, 0, 0, 0, 0, //row 0xB +} + diff --git a/src/keyboard/ergodox.h b/src/keyboard/ergodox.h new file mode 100644 index 0000000..e69de29 diff --git a/src/makefile b/src/makefile index 339877c..5ece25a 100644 --- a/src/makefile +++ b/src/makefile @@ -1,17 +1,23 @@ # ----------------------------------------------------------------------------- -# This is a stub at the moment, but I'm keeping it separate so I can mess with -# it later without changing the original +# This is mostly a stub at the moment, but I'm keeping it separate so I can +# mess with it later without changing the original # ----------------------------------------------------------------------------- # Copyright (c) 2012 Ben Blazak # Released under The MIT License (MIT) (see "license.md") at # # ----------------------------------------------------------------------------- + +SRC = firmware.c + +TEENSY_MAKE = $(MAKE) -f 'lib/teensy-makefile' SRC='$(SRC)' + + .PHONY: all clean all: - make -f lib/teensy-makefile all + $(TEENSY_MAKE) all clean: - make -f lib/teensy-makefile clean + $(TEENSY_MAKE) clean From 6fb3bf7a57895b7c06cc2c211e372dfd2285e8eb Mon Sep 17 00:00:00 2001 From: Ben Blazak Date: Thu, 15 Mar 2012 01:01:36 -0700 Subject: [PATCH 06/22] still working... - removed the comment about the RESET pin on the MCP23018: i think these chips reset on powerup - the partitioning of code into files is all wrong at the moment... i need to write some more and then fix that --- doc/references.md | 14 +- src/controller/teensy-2-0.h | 0 src/firmware.c | 8 +- .../ergodox--keyboard.c} | 44 +++++- .../ergodox--teensy-2-0--mcp23018.c} | 134 ++++++++++++++---- src/hardware/ergodox.h | 18 +++ src/keyboard/ergodox.h | 0 7 files changed, 179 insertions(+), 39 deletions(-) delete mode 100644 src/controller/teensy-2-0.h rename src/{keyboard/ergodox.c => hardware/ergodox--keyboard.c} (73%) rename src/{controller/teensy-2-0.c => hardware/ergodox--teensy-2-0--mcp23018.c} (56%) create mode 100644 src/hardware/ergodox.h delete mode 100644 src/keyboard/ergodox.h diff --git a/doc/references.md b/doc/references.md index 1b5e078..8610167 100644 --- a/doc/references.md +++ b/doc/references.md @@ -1,12 +1,20 @@ ## Noob Electronics Stuff -* [Resistor Color Codes (picture)] +* [Resistor Color Codes] (http://www.ladyada.net/wiki/lib/exe/fetch.php?hash=a2c6a9&w=501&h=785&media=http%3A%2F%2Fwww.ladyada.net%2Fimages%2Fmetertutorial%2Frescolorcode.jpg) + : image * from [the Multimeter Tutorial] (http://www.ladyada.net/learn/multimeter/resistance.html) (on ) +* [Schematic Symbols] + (http://img.docstoccdn.com/thumb/orig/28066054.png) + : image + +* [Vcc, Vdd, Vss, etc.] + (http://encyclobeamia.solarbotics.net/articles/vxx.html) + * [Very Basic Circuits] (http://www.seattlerobotics.org/encoder/mar97/basics.html) : column by Kevin Ross for Encoder @@ -23,8 +31,8 @@ -> [powering LEDs] (http://wolfstone.halloweenhost.com/Lighting/litlpo_PoweringLEDs.html) -* [Vcc, Vdd, Vss, etc.] - (http://encyclobeamia.solarbotics.net/articles/vxx.html) +* [All About Circuits : Reference] + (http://www.allaboutcircuits.com/vol_5/index.html) ## Noob C Stuff diff --git a/src/controller/teensy-2-0.h b/src/controller/teensy-2-0.h deleted file mode 100644 index e69de29..0000000 diff --git a/src/firmware.c b/src/firmware.c index f7998cb..ce80f70 100644 --- a/src/firmware.c +++ b/src/firmware.c @@ -7,8 +7,8 @@ * ------------------------------------------------------------------------- */ -#include "keyboard/ergodox.h" -#include "controller/teensy-2-0.h" +#include "hardware/ergodox.h" + #include "lib/twi.h" #include "lib/print.h" @@ -18,5 +18,9 @@ void main() { } void init() { + controller_init(); // must be first + kb_init(); // must be second + + // TODO: other stuff? } diff --git a/src/keyboard/ergodox.c b/src/hardware/ergodox--keyboard.c similarity index 73% rename from src/keyboard/ergodox.c rename to src/hardware/ergodox--keyboard.c index e4b16a0..eb5ea68 100644 --- a/src/keyboard/ergodox.c +++ b/src/hardware/ergodox--keyboard.c @@ -1,11 +1,17 @@ /* ---------------------------------------------------------------------------- - * ergoDOX specific stuff + * ergoDOX keyboard specific stuff + * - public things are prefixed by `kb_` or `KB_` * ---------------------------------------------------------------------------- * Copyright (c) 2012 Ben Blazak * Released under The MIT License (MIT) (see "license.md") at * * ------------------------------------------------------------------------- */ + +// ---------------------------------------------------------------------------- +// documentation +// ---------------------------------------------------------------------------- + /* ---------------------------------------------------------------------------- * Matrix [row.column] assignments * - row and column numbers are in hex @@ -27,12 +33,21 @@ * ------------------------------------------------------------------------- */ -#define KB_LAYERS 1 -#define KB_ROWS 12 // don't change -#define KB_COLUMNS 7 // don't change +#include "ergodox.h" -uint8_t is_pressed[KB_ROWS][KB_COLUMNS] = { +// ---------------------------------------------------------------------------- +// macros +// ---------------------------------------------------------------------------- + +// TODO + + +// ---------------------------------------------------------------------------- +// variables +// ---------------------------------------------------------------------------- + +uint8_t kb_is_pressed[KB_ROWS][KB_COLUMNS] = { // --- right hand --- // column 0 1 2 3 4 5 6 0, 0, 0, 0, 0, 0, 0, //row 0x0 @@ -41,7 +56,6 @@ uint8_t is_pressed[KB_ROWS][KB_COLUMNS] = { 0, 0, 0, 0, 0, 0, 0, //row 0x3 0, 0, 0, 0, 0, 0, 0, //row 0x4 0, 0, 0, 0, 0, 0, 0, //row 0x5 - // --- left hand --- // column 0 1 2 3 4 5 6 0, 0, 0, 0, 0, 0, 0, //row 0x6 @@ -54,7 +68,8 @@ uint8_t is_pressed[KB_ROWS][KB_COLUMNS] = { // TODO: this belongs in program space uint8_t kb_maps[KB_LAYERS][KB_ROWS][KB_COLUMNS] = { -// --- layer: default --- +// ------- layer: default ------- +// --- right hand --- // column 0 1 2 3 4 5 6 0, 0, 0, 0, 0, 0, 0, //row 0x0 0, 0, 0, 0, 0, 0, 0, //row 0x1 @@ -62,6 +77,8 @@ uint8_t kb_maps[KB_LAYERS][KB_ROWS][KB_COLUMNS] = { 0, 0, 0, 0, 0, 0, 0, //row 0x3 0, 0, 0, 0, 0, 0, 0, //row 0x4 0, 0, 0, 0, 0, 0, 0, //row 0x5 +// --- left hand --- +// column 0 1 2 3 4 5 6 0, 0, 0, 0, 0, 0, 0, //row 0x6 0, 0, 0, 0, 0, 0, 0, //row 0x7 0, 0, 0, 0, 0, 0, 0, //row 0x8 @@ -70,3 +87,16 @@ uint8_t kb_maps[KB_LAYERS][KB_ROWS][KB_COLUMNS] = { 0, 0, 0, 0, 0, 0, 0, //row 0xB } +// ---------------------------------------------------------------------------- +// functions +// ---------------------------------------------------------------------------- + +// TODO +void kb_init() { +} + +// TODO +// - cycle through row=HIGH and read each column +void kb_update() { +} + diff --git a/src/controller/teensy-2-0.c b/src/hardware/ergodox--teensy-2-0--mcp23018.c similarity index 56% rename from src/controller/teensy-2-0.c rename to src/hardware/ergodox--teensy-2-0--mcp23018.c index c2643f6..176b782 100644 --- a/src/controller/teensy-2-0.c +++ b/src/hardware/ergodox--teensy-2-0--mcp23018.c @@ -1,11 +1,17 @@ /* ---------------------------------------------------------------------------- - * Teensy 2.0 specific stuff + * ergodox controller (Teensy 2.0 and MCP23018) specific stuff + * - public things are prefixed by `controller_` or `CONTROLLER_` * ---------------------------------------------------------------------------- * Copyright (c) 2012 Ben Blazak * Released under The MIT License (MIT) (see "license.md") at * * ------------------------------------------------------------------------- */ + +// ---------------------------------------------------------------------------- +// documentation +// ---------------------------------------------------------------------------- + /* ---------------------------------------------------------------------------- * Pinouts and Pin assignments * - '+' indicates pin @@ -51,12 +57,12 @@ * Teensy 2.0 Pin Assignments * ========================== * power_negative GND +---.....---+ Vcc power_positive - * column6 PB0 + + PF0 row0 - * o + PF1 row1 - * o + PF4 row2 - * o o o + PF5 row3 - * LED3 OC1C + + PF6 row4 - * I2C SCL + + PF7 row5 + * column6 PB0 + + PF0 row6 + * o + PF1 row7 + * o + PF4 row8 + * o o o + PF5 row9 + * LED3 OC1C + + PF6 rowA + * I2C SCL + + PF7 rowB * I2C SDA + + OC1B LED2 * column3 PD2 + + OC1A LED1 * column4 PD3 + + PB4 column0 @@ -68,31 +74,28 @@ * power_negative Vss(GND) +01---.---28o * o02 27o * column0 GPB0 +03 26o - * column1 GPB1 +04 25+ GPA5 row5 - * column2 GPB2 +05 24+ GPA4 row4 - * column3 GPB3 +06 23+ GPA3 row3 - * column4 GPB4 +07 22+ GPA2 row2 - * column5 GPB5 +08 21+ GPA1 row1 - * column6 GPB6 +09 20+ GPA0 row0 + * column1 GPB1 +04 25+ GPA5 rowB + * column2 GPB2 +05 24+ GPA4 rowA + * column3 GPB3 +06 23+ GPA3 row9 + * column4 GPB4 +07 22+ GPA2 row8 + * column5 GPB5 +08 21+ GPA1 row7 + * column6 GPB6 +09 20+ GPA0 row6 * o10 19o * power_positive Vdd(Vcc) +11 18o * I2C SCL +12 17o - * I2C SDA +13 16+ RESET (see note) + * I2C SDA +13 16o * o14-------15+ ADDR (see note) * * notes: - * - ADDR (pin15): Set to 0b000 via - * Vdd(Vcc) -- R1 -- V2 (on ADDR) -- R2 -- Vss(GND) - * where - * Vdd = +5V - * R1 = ?TODO:\ - * V2 = ?TODO: | (see mcp23018 datasheet, pg 11) - * R2 = ?TODO:/ - * - RESET (pin16): Not used by software. Might want to have it available - * somewhere physically just in case though? + * - ADDR (pin15): Set slave address to 0b0100000 by connecting to Vss(GND) + * - note: The user-defined bits are the three least significant * ------------------------------------------------------------------------- */ +// ---------------------------------------------------------------------------- +// macros +// ---------------------------------------------------------------------------- + // processor frequency (from ) #define CPU_PRESCALE(n) (CLKPR = 0x80, CLKPR = (n)) #define CPU_16MHz 0x00 @@ -105,12 +108,89 @@ #define CPU_125kHz 0x07 #define CPU_62kHz 0x08 -// pins -// TODO: write some pretty macros +// teensy pins +// TODO +// I2C SCL PD0 +// I2C SDA PD1 +// LED1 OC1A PB5 +// LED2 OC1B PB6 +// LED3 OC1C PB7 +// COLUMN_0_RH PB4 +// COLUMN_1_RH PC6 +// COLUMN_2_RH PC7 +// COLUMN_3_RH PD2 +// COLUMN_4_RH PD3 +// COLUMN_5_RH PD7 +// COLUMN_6_RH PB0 +// ROW_0 PF0 +// ROW_1 PF1 +// ROW_2 PF4 +// ROW_3 PF5 +// ROW_4 PF6 +// ROW_5 PF7 -// TODO: -// - initialize pins +// mcp23018 pins +// TODO +// I2C SCL +// I2C SDA +// COLUMN_0_LH GPB0 +// COLUMN_1_LH GPB1 +// COLUMN_2_LH GPB2 +// COLUMN_3_LH GPB3 +// COLUMN_4_LH GPB4 +// COLUMN_5_LH GPB5 +// COLUMN_6_LH GPB6 +// ROW_6 GPA0 +// ROW_7 GPA1 +// ROW_8 GPA2 +// ROW_9 GPA3 +// ROW_A GPA4 +// ROW_B GPA5 + +// pins logically common to both +// TODO +// (i don't think we're going to use these this way...) +// COLUMN_0 GPB0 +// COLUMN_0 PB4 +// COLUMN_1 GPB1 +// COLUMN_1 PC6 +// COLUMN_2 GPB2 +// COLUMN_2 PC7 +// COLUMN_3 GPB3 +// COLUMN_3 PD2 +// COLUMN_4 GPB4 +// COLUMN_4 PD3 +// COLUMN_5 GPB5 +// COLUMN_5 PD7 +// COLUMN_6 GPB6 +// COLUMN_6 PB0 + + + +// ---------------------------------------------------------------------------- +// functions +// ---------------------------------------------------------------------------- + +// TODO +// - set internal brown-out detection circuit? void controller_init() { + // teensy + // --- processor frequency CPU_PRESCALE(CPU_16MHz); // speed should match F_CPU in makefile + + // --- pins + // --- --- unused: set as input with internal pullup enabled (see + // teensy 2.0 datasheet section 10.2.6) + DDRB &= ~0b00001110; // set B(1,2,3) as input + PORTB |= 0b00001110; // set B(1,2,3) internal pullup enabled + DDRD &= ~0b01110000; // set D(4,5,6) as input + PORTD |= 0b01110000; // set D(4,5,6) internal pullup enabled + DDRE &= ~0b01000000; // set E(6) as input + PORTE |= 0b01000000; // set E(6) internal pullup enabled + // --- --- [used] + // TODO + + // mcp32018 + // TODO } diff --git a/src/hardware/ergodox.h b/src/hardware/ergodox.h new file mode 100644 index 0000000..34dbdb6 --- /dev/null +++ b/src/hardware/ergodox.h @@ -0,0 +1,18 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) 2012 Ben Blazak + * Released under The MIT License (MIT) (see "license.md") at + * + * ------------------------------------------------------------------------- */ + + +#define KB_LAYERS 1 +#define KB_ROWS 12 // must match real life +#define KB_COLUMNS 7 // must match real life + + +void controller_init(); + +void kb_init(); + +// TODO + diff --git a/src/keyboard/ergodox.h b/src/keyboard/ergodox.h deleted file mode 100644 index e69de29..0000000 From 37b504adfed41374d5d7b6ffd237f0df8af93e33 Mon Sep 17 00:00:00 2001 From: Ben Blazak Date: Fri, 16 Mar 2012 03:15:47 -0700 Subject: [PATCH 07/22] mostly: figured out how to initialize the LEDs with PWM --- doc/references.md | 3 + readme.md | 7 +- src/hardware/ergodox--keyboard.c | 24 +-- src/hardware/ergodox--teensy-2-0--mcp23018.c | 151 +++++++++++++------ 4 files changed, 121 insertions(+), 64 deletions(-) diff --git a/doc/references.md b/doc/references.md index 8610167..a773443 100644 --- a/doc/references.md +++ b/doc/references.md @@ -73,6 +73,9 @@ (http://svn.savannah.nongnu.org/viewvc/trunk/avr-libc/include/avr/iom32u4.h?revision=2288&root=avr-libc&view=markup) : list of registers and associated bit numbers for ATmega32U4 +* [A Brief Tutorial on Programming the AVR without Arduino] by Chris Kuethe + (https://www.mainframe.cx/~ckuethe/avr-c-tutorial/) + ## Articles / Tutorials diff --git a/readme.md b/readme.md index 42d2190..f63c311 100644 --- a/readme.md +++ b/readme.md @@ -1,4 +1,5 @@ -# [ergodox-firmware][1]: Firmware for the [ergoDOX keyboard][2] -[1]: https://github.com/benblazak/ergodox-firmware -[2]: http://geekhack.org/showthread.php?22780-Interest-Check-Custom-split-ergo-keyboard +# [ergodox-firmware][]: Firmware for the [ergoDOX keyboard][] + +[ergodox-firmware]: https://github.com/benblazak/ergodox-firmware +[ergodox keyboard]: http://geekhack.org/showthread.php?22780-Interest-Check-Custom-split-ergo-keyboard diff --git a/src/hardware/ergodox--keyboard.c b/src/hardware/ergodox--keyboard.c index eb5ea68..53d1d15 100644 --- a/src/hardware/ergodox--keyboard.c +++ b/src/hardware/ergodox--keyboard.c @@ -8,9 +8,9 @@ * ------------------------------------------------------------------------- */ -// ---------------------------------------------------------------------------- -// documentation -// ---------------------------------------------------------------------------- +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * ~~~ documentation ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ /* ---------------------------------------------------------------------------- * Matrix [row.column] assignments @@ -36,16 +36,16 @@ #include "ergodox.h" -// ---------------------------------------------------------------------------- -// macros -// ---------------------------------------------------------------------------- +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * ~~~ macros ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ // TODO -// ---------------------------------------------------------------------------- -// variables -// ---------------------------------------------------------------------------- +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * ~~~ variables ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ uint8_t kb_is_pressed[KB_ROWS][KB_COLUMNS] = { // --- right hand --- @@ -87,9 +87,9 @@ uint8_t kb_maps[KB_LAYERS][KB_ROWS][KB_COLUMNS] = { 0, 0, 0, 0, 0, 0, 0, //row 0xB } -// ---------------------------------------------------------------------------- -// functions -// ---------------------------------------------------------------------------- +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * ~~~ functions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ // TODO void kb_init() { diff --git a/src/hardware/ergodox--teensy-2-0--mcp23018.c b/src/hardware/ergodox--teensy-2-0--mcp23018.c index 176b782..d26da51 100644 --- a/src/hardware/ergodox--teensy-2-0--mcp23018.c +++ b/src/hardware/ergodox--teensy-2-0--mcp23018.c @@ -8,9 +8,9 @@ * ------------------------------------------------------------------------- */ -// ---------------------------------------------------------------------------- -// documentation -// ---------------------------------------------------------------------------- +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * ~~~ documentation ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ /* ---------------------------------------------------------------------------- * Pinouts and Pin assignments @@ -68,6 +68,12 @@ * column4 PD3 + + PB4 column0 * column1 PC6 + + PD7 column5 * column2 PC7 +-o-o-o-o-o-o + * + * notes: + * - SCL and SDA: Need external pull-up resistors. Sometimes the internal + * pull-ups are enough (see datasheet section 20.5.1), but i think for this + * project we'll want external ones, in case people want to separate the + * halves very far. * ---------------------------------------------------------------------------- * MCP32018 Pin Assignments * ======================== @@ -91,10 +97,51 @@ * - note: The user-defined bits are the three least significant * ------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Registers + * ---------------------------------------------------------------------------- + * General I/O (see datasheet section 10.2.1) + * + * DDRxn function PINxn function + * 1 output 1 drive high + * 0 drive low + * 0 input 1 internal pull-up on + * 0 internal pull-up off + * + * notes: + * - Unused pins should be set as input with internal pullup enabled (see + * datasheet section 10.2.6). + * ---------------------------------------------------------------------------- + * PWM on ports OC1(A|B|C) (see datasheet section 14.10) + * + * notes: + * - PWM pins should be set as outputs. + * - we want Waveform Generation Mode 15 + * (fast PWM, TOP = OCRnA) + * (see table 14-5) + * - set (TCCRB[4,3],TCCRA[1,0]) to (1,1,1,1) + * - we want "Compare Output Mode, Fast PWM" to be 0b10 + * "Clear OCnA/OCnB/OCnC on compare match, set OCnA/OCnB/OCnC at TOP" + * (see table 14-3) + * this way higher values of OCR1(A|B|C) will mean longer 'on' times for the + * LEDs + * - when in a fast PWM mode, set (TCCR1A[7,6,5,4,3,2]) to (1,0,1,0,1,0) + * - we want "Clock Select Bit Description" to be 0b001 + * "clkI/O/1 (No prescaling)" + * (see table 14-6) + * - set (TCCR1B[2,1,0]) to (0,0,1) + * - LEDs will be at minimum brightness until OCR1(A|B|C) are changed (since + * the default value of all the bits in those registers is 0) + * + * abbreviations: + * - OC = Output Compare + * - TCCR = Timer/Counter Control Register + * ------------------------------------------------------------------------- */ -// ---------------------------------------------------------------------------- -// macros -// ---------------------------------------------------------------------------- + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * ~~~ macros ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ // processor frequency (from ) #define CPU_PRESCALE(n) (CLKPR = 0x80, CLKPR = (n)) @@ -108,6 +155,20 @@ #define CPU_125kHz 0x07 #define CPU_62kHz 0x08 +// pins +#define CONTROLLER_LED1_ON (OCR1A = 0xFFFF) +#define CONTROLLER_LED1_OFF (OCR1A = 0) +#define CONTROLLER_LED1_SET(n) (OCR1A = (n)) +#define CONTROLLER_LED1_SET_PERCENT(n) (OCR1A = (n) * 0xFFFF) +#define CONTROLLER_LED2_ON (OCR1B = 0xFFFF) +#define CONTROLLER_LED2_OFF (OCR1B = 0) +#define CONTROLLER_LED2_SET(n) (OCR1B = (n)) +#define CONTROLLER_LED2_SET_PERCENT(n) (OCR1B = (n) * 0xFFFF) +#define CONTROLLER_LED3_ON (OCR1C = 0xFFFF) +#define CONTROLLER_LED3_OFF (OCR1C = 0) +#define CONTROLLER_LED3_SET(n) (OCR1C = (n)) +#define CONTROLLER_LED3_SET_PERCENT(n) (OCR1C = (n) * 0xFFFF) + // teensy pins // TODO // I2C SCL PD0 @@ -115,6 +176,12 @@ // LED1 OC1A PB5 // LED2 OC1B PB6 // LED3 OC1C PB7 +// ROW_0 PF0 +// ROW_1 PF1 +// ROW_2 PF4 +// ROW_3 PF5 +// ROW_4 PF6 +// ROW_5 PF7 // COLUMN_0_RH PB4 // COLUMN_1_RH PC6 // COLUMN_2_RH PC7 @@ -122,17 +189,17 @@ // COLUMN_4_RH PD3 // COLUMN_5_RH PD7 // COLUMN_6_RH PB0 -// ROW_0 PF0 -// ROW_1 PF1 -// ROW_2 PF4 -// ROW_3 PF5 -// ROW_4 PF6 -// ROW_5 PF7 // mcp23018 pins // TODO // I2C SCL // I2C SDA +// ROW_6 GPA0 +// ROW_7 GPA1 +// ROW_8 GPA2 +// ROW_9 GPA3 +// ROW_A GPA4 +// ROW_B GPA5 // COLUMN_0_LH GPB0 // COLUMN_1_LH GPB1 // COLUMN_2_LH GPB2 @@ -140,57 +207,43 @@ // COLUMN_4_LH GPB4 // COLUMN_5_LH GPB5 // COLUMN_6_LH GPB6 -// ROW_6 GPA0 -// ROW_7 GPA1 -// ROW_8 GPA2 -// ROW_9 GPA3 -// ROW_A GPA4 -// ROW_B GPA5 - -// pins logically common to both -// TODO -// (i don't think we're going to use these this way...) -// COLUMN_0 GPB0 -// COLUMN_0 PB4 -// COLUMN_1 GPB1 -// COLUMN_1 PC6 -// COLUMN_2 GPB2 -// COLUMN_2 PC7 -// COLUMN_3 GPB3 -// COLUMN_3 PD2 -// COLUMN_4 GPB4 -// COLUMN_4 PD3 -// COLUMN_5 GPB5 -// COLUMN_5 PD7 -// COLUMN_6 GPB6 -// COLUMN_6 PB0 +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * ~~~ functions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -// ---------------------------------------------------------------------------- -// functions -// ---------------------------------------------------------------------------- +void controller_init() { + teensy_init(); + mcp23018_init(); +} // TODO // - set internal brown-out detection circuit? -void controller_init() { - // teensy - // --- processor frequency +void teensy_init() { CPU_PRESCALE(CPU_16MHz); // speed should match F_CPU in makefile - // --- pins - // --- --- unused: set as input with internal pullup enabled (see - // teensy 2.0 datasheet section 10.2.6) + // unused pins DDRB &= ~0b00001110; // set B(1,2,3) as input PORTB |= 0b00001110; // set B(1,2,3) internal pullup enabled DDRD &= ~0b01110000; // set D(4,5,6) as input PORTD |= 0b01110000; // set D(4,5,6) internal pullup enabled DDRE &= ~0b01000000; // set E(6) as input PORTE |= 0b01000000; // set E(6) internal pullup enabled - // --- --- [used] - // TODO - // mcp32018 - // TODO + // LEDs with PWM + DDRB |= 0b11100000; // set B(5,6,7) as output + TCCR1A = 0b10101011; // set and configure fast PWM + TCCR1B |= 0b00011001; // set and configure fast PWM + // --- --- rows + // TODO: set to high output + // --- --- columns + // TODO: set to input with pullup enabled + // --- --- I2C (TWI) + // TODO: use twi library +} + +// TODO +void mcp23018_init() { } From 4dd05f515b8d7da546082e24e43ec4a9a05a1646 Mon Sep 17 00:00:00 2001 From: Ben Blazak Date: Fri, 16 Mar 2012 18:31:36 -0700 Subject: [PATCH 08/22] working more on controller_init(), and file factoring --- doc/references.md | 7 ++ .../ergodox--keyboard.c => ergodox/layout.c} | 6 +- src/{hardware/ergodox.h => ergodox/layout.h} | 7 +- .../teensy-2-0--mcp23018.c} | 110 ++++++++---------- src/ergodox/teensy-2-0--mcp23018.h | 28 +++++ src/firmware.c | 7 -- 6 files changed, 89 insertions(+), 76 deletions(-) rename src/{hardware/ergodox--keyboard.c => ergodox/layout.c} (97%) rename src/{hardware/ergodox.h => ergodox/layout.h} (71%) rename src/{hardware/ergodox--teensy-2-0--mcp23018.c => ergodox/teensy-2-0--mcp23018.c} (78%) create mode 100644 src/ergodox/teensy-2-0--mcp23018.h diff --git a/doc/references.md b/doc/references.md index a773443..12a83b4 100644 --- a/doc/references.md +++ b/doc/references.md @@ -49,6 +49,9 @@ (http://www.cprogramming.com/tutorial/bitwise_operators.html) (on ) +* [AVR Tutorials - \[TUT\] \[C\] Bit manipulation (AKA "Programming 101")] + (http://www.avrfreaks.net/index.php?name=PNphpBB2&file=printview&t=37871&start=0) + * [In C++ is "const" after type ID acceptable?] (http://stackoverflow.com/questions/988069/in-c-is-const-after-type-id-acceptable) (on ) @@ -63,6 +66,10 @@ * [Markdown: Syntax] (http://daringfireball.net/projects/markdown/syntax) +* [Keyboard Scan Rates] + (http://geekhack.org/showwiki.php?title=Keyboard+scan+rates) + list (on ) + ## AVR C stuff diff --git a/src/hardware/ergodox--keyboard.c b/src/ergodox/layout.c similarity index 97% rename from src/hardware/ergodox--keyboard.c rename to src/ergodox/layout.c index 53d1d15..0939b76 100644 --- a/src/hardware/ergodox--keyboard.c +++ b/src/ergodox/layout.c @@ -1,6 +1,6 @@ /* ---------------------------------------------------------------------------- - * ergoDOX keyboard specific stuff - * - public things are prefixed by `kb_` or `KB_` + * ergoDOX layout specific stuff + * - public things are prefixed by `layout_` or `LAYOUT_` * ---------------------------------------------------------------------------- * Copyright (c) 2012 Ben Blazak * Released under The MIT License (MIT) (see "license.md") at @@ -33,7 +33,7 @@ * ------------------------------------------------------------------------- */ -#include "ergodox.h" +#include "layout.h" /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/src/hardware/ergodox.h b/src/ergodox/layout.h similarity index 71% rename from src/hardware/ergodox.h rename to src/ergodox/layout.h index 34dbdb6..60bbfce 100644 --- a/src/hardware/ergodox.h +++ b/src/ergodox/layout.h @@ -1,4 +1,7 @@ /* ---------------------------------------------------------------------------- + * ergoDOX layout specific stuff + * - public things are prefixed by `layout_` or `LAYOUT_` + * ---------------------------------------------------------------------------- * Copyright (c) 2012 Ben Blazak * Released under The MIT License (MIT) (see "license.md") at * @@ -10,9 +13,5 @@ #define KB_COLUMNS 7 // must match real life -void controller_init(); - -void kb_init(); - // TODO diff --git a/src/hardware/ergodox--teensy-2-0--mcp23018.c b/src/ergodox/teensy-2-0--mcp23018.c similarity index 78% rename from src/hardware/ergodox--teensy-2-0--mcp23018.c rename to src/ergodox/teensy-2-0--mcp23018.c index d26da51..421a4df 100644 --- a/src/hardware/ergodox--teensy-2-0--mcp23018.c +++ b/src/ergodox/teensy-2-0--mcp23018.c @@ -16,7 +16,7 @@ * Pinouts and Pin assignments * - '+' indicates pin * - 'o' indicates unused pin - * - '-'s inserted between some of the pin names for readability + * - '-'s inserted between some of the pin functions for readability * - 'OC**' pins enclosed in parenthesis had lines over them in the pinout * ---------------------------------------------------------------------------- * ---------------------------------------------------------------------------- @@ -39,16 +39,16 @@ * ---------------------------------------------------------------------------- * MCP23018 * ======== Vss(GND) +01---.---28+ NC - * GPNC +02 27+ GPAC + * NC +02 27+ GPA7 * GPB0 +03 26+ GPA6 - * GPB1 +04 25+ GPAC - * GPB2 +05 24+ GPAC - * GPB3 +06 23+ GPAC - * GPB4 +07 22+ GPAC - * GPB5 +08 21+ GPAC - * GPB6 +09 20+ GPAC - * GPB7 +10 19+ INTC - * Vdd(Vcc) +11 18+ INTC + * GPB1 +04 25+ GPA5 + * GPB2 +05 24+ GPA4 + * GPB3 +06 23+ GPA3 + * GPB4 +07 22+ GPA2 + * GPB5 +08 21+ GPA1 + * GPB6 +09 20+ GPA0 + * GPB7 +10 19+ INTA + * Vdd(Vcc) +11 18+ INTB * SCL +12 17+ NC * SDA +13 16+ RESET * NC +14-------15+ ADDR @@ -93,12 +93,12 @@ * o14-------15+ ADDR (see note) * * notes: - * - ADDR (pin15): Set slave address to 0b0100000 by connecting to Vss(GND) - * - note: The user-defined bits are the three least significant + * - ADDR (pin15): Set slave address to 0b0100000 by connecting to Vss(GND). + * (The user-defined bits are the three least significant). * ------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------------- - * Registers + * Notes about Registers * ---------------------------------------------------------------------------- * General I/O (see datasheet section 10.2.1) * @@ -134,11 +134,16 @@ * the default value of all the bits in those registers is 0) * * abbreviations: - * - OC = Output Compare + * - OCR = Output Compare Register * - TCCR = Timer/Counter Control Register * ------------------------------------------------------------------------- */ +#include "lib/twi.h" + +#include "teensy-2-0--mcp23018.h" + + /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * ~~~ macros ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ @@ -155,40 +160,13 @@ #define CPU_125kHz 0x07 #define CPU_62kHz 0x08 -// pins -#define CONTROLLER_LED1_ON (OCR1A = 0xFFFF) -#define CONTROLLER_LED1_OFF (OCR1A = 0) -#define CONTROLLER_LED1_SET(n) (OCR1A = (n)) -#define CONTROLLER_LED1_SET_PERCENT(n) (OCR1A = (n) * 0xFFFF) -#define CONTROLLER_LED2_ON (OCR1B = 0xFFFF) -#define CONTROLLER_LED2_OFF (OCR1B = 0) -#define CONTROLLER_LED2_SET(n) (OCR1B = (n)) -#define CONTROLLER_LED2_SET_PERCENT(n) (OCR1B = (n) * 0xFFFF) -#define CONTROLLER_LED3_ON (OCR1C = 0xFFFF) -#define CONTROLLER_LED3_OFF (OCR1C = 0) -#define CONTROLLER_LED3_SET(n) (OCR1C = (n)) -#define CONTROLLER_LED3_SET_PERCENT(n) (OCR1C = (n) * 0xFFFF) +// TWI frequency +#define TWI_FREQ 400000 // (see lib/twi.(h|c)) + +// pins +// --- rows ?TODO +// --- columns ?TODO -// teensy pins -// TODO -// I2C SCL PD0 -// I2C SDA PD1 -// LED1 OC1A PB5 -// LED2 OC1B PB6 -// LED3 OC1C PB7 -// ROW_0 PF0 -// ROW_1 PF1 -// ROW_2 PF4 -// ROW_3 PF5 -// ROW_4 PF6 -// ROW_5 PF7 -// COLUMN_0_RH PB4 -// COLUMN_1_RH PC6 -// COLUMN_2_RH PC7 -// COLUMN_3_RH PD2 -// COLUMN_4_RH PD3 -// COLUMN_5_RH PD7 -// COLUMN_6_RH PB0 // mcp23018 pins // TODO @@ -214,33 +192,41 @@ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ void controller_init() { - teensy_init(); - mcp23018_init(); + teensy_init(); // must be first + mcp23018_init(); // must be second } -// TODO -// - set internal brown-out detection circuit? void teensy_init() { CPU_PRESCALE(CPU_16MHz); // speed should match F_CPU in makefile // unused pins DDRB &= ~0b00001110; // set B(1,2,3) as input - PORTB |= 0b00001110; // set B(1,2,3) internal pullup enabled + PORTB |= 0b00001110; // set B(1,2,3) internal pull-up enabled DDRD &= ~0b01110000; // set D(4,5,6) as input - PORTD |= 0b01110000; // set D(4,5,6) internal pullup enabled + PORTD |= 0b01110000; // set D(4,5,6) internal pull-up enabled DDRE &= ~0b01000000; // set E(6) as input - PORTE |= 0b01000000; // set E(6) internal pullup enabled + PORTE |= 0b01000000; // set E(6) internal pull-up enabled - // LEDs with PWM + // LEDs DDRB |= 0b11100000; // set B(5,6,7) as output TCCR1A = 0b10101011; // set and configure fast PWM - TCCR1B |= 0b00011001; // set and configure fast PWM - // --- --- rows - // TODO: set to high output - // --- --- columns - // TODO: set to input with pullup enabled - // --- --- I2C (TWI) - // TODO: use twi library + TCCR1B = 0b00011001; // set and configure fast PWM + + // rows + DDRF |= 0b11110011; // set F(0,1,4,5,6,7) as output + PORTF |= 0b11110011; // set F(0,1,4,5,6,7) drive high + + // columns + DDRB &= ~0b00010001; // set B(0,4) as input + PORTB |= 0b00010001; // set B(0,4) internal pull-up enabled + DDRC &= ~0b11000000; // set C(6,7) as input + PORTC |= 0b11000000; // set C(6,7) internal pull-up enabled + DDRD &= ~0b10001100; // set D(2,3,7) as input + PORTD |= 0b10001100; // set D(2,3,7) internal pull-up enabled + + // I2C (TWI) + twi_init(); // (on pins D(0,1)) + twi_setAddress(0b0100000); } // TODO diff --git a/src/ergodox/teensy-2-0--mcp23018.h b/src/ergodox/teensy-2-0--mcp23018.h new file mode 100644 index 0000000..d57cd77 --- /dev/null +++ b/src/ergodox/teensy-2-0--mcp23018.h @@ -0,0 +1,28 @@ +/* ---------------------------------------------------------------------------- + * ergodox controller (Teensy 2.0 and MCP23018) specific stuff + * - public things are prefixed by `controller_` or `CONTROLLER_` + * ---------------------------------------------------------------------------- + * Copyright (c) 2012 Ben Blazak + * Released under The MIT License (MIT) (see "license.md") at + * + * ------------------------------------------------------------------------- */ + + +// LEDs +#define CONTROLLER_LED1_ON (OCR1A = 0xFFFF) +#define CONTROLLER_LED1_OFF (OCR1A = 0x0000) +#define CONTROLLER_LED1_SET(n) (OCR1A = (uint16_t)(n)) +#define CONTROLLER_LED1_SET_PERCENT(n) (OCR1A = (uint16_t)((n) * 0xFFFF)) +#define CONTROLLER_LED2_ON (OCR1B = 0xFFFF) +#define CONTROLLER_LED2_OFF (OCR1B = 0x0000) +#define CONTROLLER_LED2_SET(n) (OCR1B = (uint16_t)(n)) +#define CONTROLLER_LED2_SET_PERCENT(n) (OCR1B = (uint16_t)((n) * 0xFFFF)) +#define CONTROLLER_LED3_ON (OCR1C = 0xFFFF) +#define CONTROLLER_LED3_OFF (OCR1C = 0x0000) +#define CONTROLLER_LED3_SET(n) (OCR1C = (uint16_t)(n)) +#define CONTROLLER_LED3_SET_PERCENT(n) (OCR1C = (uint16_t)((n) * 0xFFFF)) + + +// init +void controller_init(); + diff --git a/src/firmware.c b/src/firmware.c index ce80f70..6f727a5 100644 --- a/src/firmware.c +++ b/src/firmware.c @@ -7,9 +7,6 @@ * ------------------------------------------------------------------------- */ -#include "hardware/ergodox.h" - -#include "lib/twi.h" #include "lib/print.h" @@ -18,9 +15,5 @@ void main() { } void init() { - controller_init(); // must be first - kb_init(); // must be second - - // TODO: other stuff? } From 19725eed4aac39e3f1b250a3c6fce3a2a5efb547 Mon Sep 17 00:00:00 2001 From: Ben Blazak Date: Mon, 19 Mar 2012 00:01:41 -0700 Subject: [PATCH 09/22] *lots* of stuff .. :) - got PWM working! also, i didn't make a note of it in the *.md file, but Waveform Generation Mode 15 for fast PWM wasn't working right (well.. wasn't working how i expected it to). i misinterpreted what the modes were doing, partially (haha, or all-ly?) because i didn't read the description of fast pwm thoroughly enough... in any case, all the information's in the datasheet, and it's actually not terribly long. i'm not sure how to correctly use Mode 15 yet, but i think i'll leave it alone for now, since Mode 5 works as expected, and i think what the datasheet says about *that* makes enough sense to me for me to be content for the moment. --- doc/references.md | 14 ++ readme.md | 6 + src/ergodox/teensy-2-0--mcp23018.c | 235 --------------------- src/ergodox/teensy-2-0--mcp23018.h | 28 --- src/firmware.c | 16 +- src/keyboard.h | 12 ++ src/keyboard/ergodox.h | 0 src/{ => keyboard}/ergodox/layout.c | 78 +++---- src/{ => keyboard}/ergodox/layout.h | 9 +- src/keyboard/ergodox/main.c | 25 +++ src/keyboard/ergodox/mcp23018.c | 61 ++++++ src/keyboard/ergodox/mcp23018.h | 21 ++ src/keyboard/ergodox/mcp23018.md | 127 +++++++++++ src/keyboard/ergodox/teensy-2-0.c | 65 ++++++ src/keyboard/ergodox/teensy-2-0.h | 36 ++++ src/keyboard/ergodox/teensy-2-0.md | 100 +++++++++ src/lib/{ => arduino}/twi.c | 97 ++------- src/lib/{ => arduino}/twi.h | 10 +- src/lib/{teensy-makefile => pjrc/Makefile} | 0 src/lib/{ => pjrc}/print.c | 0 src/lib/{ => pjrc}/print.h | 0 src/lib/{ => pjrc}/usb_debug_only.c | 0 src/lib/{ => pjrc}/usb_debug_only.h | 0 src/makefile | 7 +- 24 files changed, 543 insertions(+), 404 deletions(-) delete mode 100644 src/ergodox/teensy-2-0--mcp23018.c delete mode 100644 src/ergodox/teensy-2-0--mcp23018.h create mode 100644 src/keyboard.h create mode 100644 src/keyboard/ergodox.h rename src/{ => keyboard}/ergodox/layout.c (59%) rename src/{ => keyboard}/ergodox/layout.h (65%) create mode 100644 src/keyboard/ergodox/main.c create mode 100644 src/keyboard/ergodox/mcp23018.c create mode 100644 src/keyboard/ergodox/mcp23018.h create mode 100644 src/keyboard/ergodox/mcp23018.md create mode 100644 src/keyboard/ergodox/teensy-2-0.c create mode 100644 src/keyboard/ergodox/teensy-2-0.h create mode 100644 src/keyboard/ergodox/teensy-2-0.md rename src/lib/{ => arduino}/twi.c (78%) rename src/lib/{ => arduino}/twi.h (86%) rename src/lib/{teensy-makefile => pjrc/Makefile} (100%) rename src/lib/{ => pjrc}/print.c (100%) rename src/lib/{ => pjrc}/print.h (100%) rename src/lib/{ => pjrc}/usb_debug_only.c (100%) rename src/lib/{ => pjrc}/usb_debug_only.h (100%) diff --git a/doc/references.md b/doc/references.md index 12a83b4..c540434 100644 --- a/doc/references.md +++ b/doc/references.md @@ -125,6 +125,14 @@ (https://github.com/arduino/Arduino/tree/master/libraries/Wire/utility) : (arduino / Arduino / libraries / Wire / utility) +* forum: [Interfacing MCP23018 io expander via Arduino] + (http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1282150189) + : contains a quick MCP23017 library in C++ + +* github: [maniacbug / Arduino / libraries / MCP23018] + (https://github.com/maniacbug/Arduino/tree/master/libraries/MCP23018) + : library in C++ + * zip: [PJRC: usb_keyboard] (http://pjrc.com/teensy/usb_keyboard.zip) @@ -182,3 +190,9 @@ * from [the PJRC website] (http://pjrc.com/teensy/datasheets.html) +------------------------------------------------------------------------------- + +Copyright © 2012 Ben Blazak +Released under The MIT License (MIT) (see "license.md") at + + diff --git a/readme.md b/readme.md index f63c311..e1de6db 100644 --- a/readme.md +++ b/readme.md @@ -3,3 +3,9 @@ [ergodox-firmware]: https://github.com/benblazak/ergodox-firmware [ergodox keyboard]: http://geekhack.org/showthread.php?22780-Interest-Check-Custom-split-ergo-keyboard +------------------------------------------------------------------------------- + +Copyright © 2012 Ben Blazak +Released under The MIT License (MIT) (see "license.md") at + + diff --git a/src/ergodox/teensy-2-0--mcp23018.c b/src/ergodox/teensy-2-0--mcp23018.c deleted file mode 100644 index 421a4df..0000000 --- a/src/ergodox/teensy-2-0--mcp23018.c +++ /dev/null @@ -1,235 +0,0 @@ -/* ---------------------------------------------------------------------------- - * ergodox controller (Teensy 2.0 and MCP23018) specific stuff - * - public things are prefixed by `controller_` or `CONTROLLER_` - * ---------------------------------------------------------------------------- - * Copyright (c) 2012 Ben Blazak - * Released under The MIT License (MIT) (see "license.md") at - * - * ------------------------------------------------------------------------- */ - - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * ~~~ documentation ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - -/* ---------------------------------------------------------------------------- - * Pinouts and Pin assignments - * - '+' indicates pin - * - 'o' indicates unused pin - * - '-'s inserted between some of the pin functions for readability - * - 'OC**' pins enclosed in parenthesis had lines over them in the pinout - * ---------------------------------------------------------------------------- - * ---------------------------------------------------------------------------- - * Teensy 2.0 - * ========== GND +---.....---+ VCC - * SS PB0 + + PF0 ADC0 - * SCLK PB1 + + PF1 ADC1 - * MOSI PB2 + + PF4 ADC4 - * MISO PB3 + + + + PF5 ADC5 - * RTS OC1C OC0A --------- PB7 + PE6 AREF + PF6 ADC6 - * OC0B INT0 SCL PD0 + AIN0 + PF7 ADC7 - * INT1 SDA PD1 + INT6 + PB6 ADC13 OC1B OC4B - * RXD1 ----------- INT2 --- PD2 + + PB5 ADC12 OC1A (OC4B) - * TXD1 ----------- INT3 --- PD3 + + PB4 ADC11 - * OC3A (OC4A) -------- PC6 + + PD7 ADC10 T0 -- OC4D - * ICP3 ----- OC4A --------- PC7 +-+-+-+-+-+-+ PD6 ADC9 T1 - (OC4D) onboardLED - * CTS XCK1 PD5 --/ | | | \-- PD4 ADC8 ------------ ICP1 - * VCC ------------------/ | \-------------- RST - * GND --------------------/ - * ---------------------------------------------------------------------------- - * MCP23018 - * ======== Vss(GND) +01---.---28+ NC - * NC +02 27+ GPA7 - * GPB0 +03 26+ GPA6 - * GPB1 +04 25+ GPA5 - * GPB2 +05 24+ GPA4 - * GPB3 +06 23+ GPA3 - * GPB4 +07 22+ GPA2 - * GPB5 +08 21+ GPA1 - * GPB6 +09 20+ GPA0 - * GPB7 +10 19+ INTA - * Vdd(Vcc) +11 18+ INTB - * SCL +12 17+ NC - * SDA +13 16+ RESET - * NC +14-------15+ ADDR - * ---------------------------------------------------------------------------- - * ---------------------------------------------------------------------------- - * Teensy 2.0 Pin Assignments - * ========================== - * power_negative GND +---.....---+ Vcc power_positive - * column6 PB0 + + PF0 row6 - * o + PF1 row7 - * o + PF4 row8 - * o o o + PF5 row9 - * LED3 OC1C + + PF6 rowA - * I2C SCL + + PF7 rowB - * I2C SDA + + OC1B LED2 - * column3 PD2 + + OC1A LED1 - * column4 PD3 + + PB4 column0 - * column1 PC6 + + PD7 column5 - * column2 PC7 +-o-o-o-o-o-o - * - * notes: - * - SCL and SDA: Need external pull-up resistors. Sometimes the internal - * pull-ups are enough (see datasheet section 20.5.1), but i think for this - * project we'll want external ones, in case people want to separate the - * halves very far. - * ---------------------------------------------------------------------------- - * MCP32018 Pin Assignments - * ======================== - * power_negative Vss(GND) +01---.---28o - * o02 27o - * column0 GPB0 +03 26o - * column1 GPB1 +04 25+ GPA5 rowB - * column2 GPB2 +05 24+ GPA4 rowA - * column3 GPB3 +06 23+ GPA3 row9 - * column4 GPB4 +07 22+ GPA2 row8 - * column5 GPB5 +08 21+ GPA1 row7 - * column6 GPB6 +09 20+ GPA0 row6 - * o10 19o - * power_positive Vdd(Vcc) +11 18o - * I2C SCL +12 17o - * I2C SDA +13 16o - * o14-------15+ ADDR (see note) - * - * notes: - * - ADDR (pin15): Set slave address to 0b0100000 by connecting to Vss(GND). - * (The user-defined bits are the three least significant). - * ------------------------------------------------------------------------- */ - -/* ---------------------------------------------------------------------------- - * Notes about Registers - * ---------------------------------------------------------------------------- - * General I/O (see datasheet section 10.2.1) - * - * DDRxn function PINxn function - * 1 output 1 drive high - * 0 drive low - * 0 input 1 internal pull-up on - * 0 internal pull-up off - * - * notes: - * - Unused pins should be set as input with internal pullup enabled (see - * datasheet section 10.2.6). - * ---------------------------------------------------------------------------- - * PWM on ports OC1(A|B|C) (see datasheet section 14.10) - * - * notes: - * - PWM pins should be set as outputs. - * - we want Waveform Generation Mode 15 - * (fast PWM, TOP = OCRnA) - * (see table 14-5) - * - set (TCCRB[4,3],TCCRA[1,0]) to (1,1,1,1) - * - we want "Compare Output Mode, Fast PWM" to be 0b10 - * "Clear OCnA/OCnB/OCnC on compare match, set OCnA/OCnB/OCnC at TOP" - * (see table 14-3) - * this way higher values of OCR1(A|B|C) will mean longer 'on' times for the - * LEDs - * - when in a fast PWM mode, set (TCCR1A[7,6,5,4,3,2]) to (1,0,1,0,1,0) - * - we want "Clock Select Bit Description" to be 0b001 - * "clkI/O/1 (No prescaling)" - * (see table 14-6) - * - set (TCCR1B[2,1,0]) to (0,0,1) - * - LEDs will be at minimum brightness until OCR1(A|B|C) are changed (since - * the default value of all the bits in those registers is 0) - * - * abbreviations: - * - OCR = Output Compare Register - * - TCCR = Timer/Counter Control Register - * ------------------------------------------------------------------------- */ - - -#include "lib/twi.h" - -#include "teensy-2-0--mcp23018.h" - - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * ~~~ macros ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - -// processor frequency (from ) -#define CPU_PRESCALE(n) (CLKPR = 0x80, CLKPR = (n)) -#define CPU_16MHz 0x00 -#define CPU_8MHz 0x01 -#define CPU_4MHz 0x02 -#define CPU_2MHz 0x03 -#define CPU_1MHz 0x04 -#define CPU_500kHz 0x05 -#define CPU_250kHz 0x06 -#define CPU_125kHz 0x07 -#define CPU_62kHz 0x08 - -// TWI frequency -#define TWI_FREQ 400000 // (see lib/twi.(h|c)) - -// pins -// --- rows ?TODO -// --- columns ?TODO - - -// mcp23018 pins -// TODO -// I2C SCL -// I2C SDA -// ROW_6 GPA0 -// ROW_7 GPA1 -// ROW_8 GPA2 -// ROW_9 GPA3 -// ROW_A GPA4 -// ROW_B GPA5 -// COLUMN_0_LH GPB0 -// COLUMN_1_LH GPB1 -// COLUMN_2_LH GPB2 -// COLUMN_3_LH GPB3 -// COLUMN_4_LH GPB4 -// COLUMN_5_LH GPB5 -// COLUMN_6_LH GPB6 - - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * ~~~ functions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - -void controller_init() { - teensy_init(); // must be first - mcp23018_init(); // must be second -} - -void teensy_init() { - CPU_PRESCALE(CPU_16MHz); // speed should match F_CPU in makefile - - // unused pins - DDRB &= ~0b00001110; // set B(1,2,3) as input - PORTB |= 0b00001110; // set B(1,2,3) internal pull-up enabled - DDRD &= ~0b01110000; // set D(4,5,6) as input - PORTD |= 0b01110000; // set D(4,5,6) internal pull-up enabled - DDRE &= ~0b01000000; // set E(6) as input - PORTE |= 0b01000000; // set E(6) internal pull-up enabled - - // LEDs - DDRB |= 0b11100000; // set B(5,6,7) as output - TCCR1A = 0b10101011; // set and configure fast PWM - TCCR1B = 0b00011001; // set and configure fast PWM - - // rows - DDRF |= 0b11110011; // set F(0,1,4,5,6,7) as output - PORTF |= 0b11110011; // set F(0,1,4,5,6,7) drive high - - // columns - DDRB &= ~0b00010001; // set B(0,4) as input - PORTB |= 0b00010001; // set B(0,4) internal pull-up enabled - DDRC &= ~0b11000000; // set C(6,7) as input - PORTC |= 0b11000000; // set C(6,7) internal pull-up enabled - DDRD &= ~0b10001100; // set D(2,3,7) as input - PORTD |= 0b10001100; // set D(2,3,7) internal pull-up enabled - - // I2C (TWI) - twi_init(); // (on pins D(0,1)) - twi_setAddress(0b0100000); -} - -// TODO -void mcp23018_init() { -} - diff --git a/src/ergodox/teensy-2-0--mcp23018.h b/src/ergodox/teensy-2-0--mcp23018.h deleted file mode 100644 index d57cd77..0000000 --- a/src/ergodox/teensy-2-0--mcp23018.h +++ /dev/null @@ -1,28 +0,0 @@ -/* ---------------------------------------------------------------------------- - * ergodox controller (Teensy 2.0 and MCP23018) specific stuff - * - public things are prefixed by `controller_` or `CONTROLLER_` - * ---------------------------------------------------------------------------- - * Copyright (c) 2012 Ben Blazak - * Released under The MIT License (MIT) (see "license.md") at - * - * ------------------------------------------------------------------------- */ - - -// LEDs -#define CONTROLLER_LED1_ON (OCR1A = 0xFFFF) -#define CONTROLLER_LED1_OFF (OCR1A = 0x0000) -#define CONTROLLER_LED1_SET(n) (OCR1A = (uint16_t)(n)) -#define CONTROLLER_LED1_SET_PERCENT(n) (OCR1A = (uint16_t)((n) * 0xFFFF)) -#define CONTROLLER_LED2_ON (OCR1B = 0xFFFF) -#define CONTROLLER_LED2_OFF (OCR1B = 0x0000) -#define CONTROLLER_LED2_SET(n) (OCR1B = (uint16_t)(n)) -#define CONTROLLER_LED2_SET_PERCENT(n) (OCR1B = (uint16_t)((n) * 0xFFFF)) -#define CONTROLLER_LED3_ON (OCR1C = 0xFFFF) -#define CONTROLLER_LED3_OFF (OCR1C = 0x0000) -#define CONTROLLER_LED3_SET(n) (OCR1C = (uint16_t)(n)) -#define CONTROLLER_LED3_SET_PERCENT(n) (OCR1C = (uint16_t)((n) * 0xFFFF)) - - -// init -void controller_init(); - diff --git a/src/firmware.c b/src/firmware.c index 6f727a5..e40a0d1 100644 --- a/src/firmware.c +++ b/src/firmware.c @@ -1,5 +1,5 @@ /* ---------------------------------------------------------------------------- - * Firmware for the ergoDOX keyboard + * Firmware main file * ---------------------------------------------------------------------------- * Copyright (c) 2012 Ben Blazak * Released under The MIT License (MIT) (see "license.md") at @@ -7,13 +7,13 @@ * ------------------------------------------------------------------------- */ -#include "lib/print.h" +#include "lib/pjrc/print.h" + +#include "keyboard.h" -void main() { - init(); -} - -void init() { -} +// TODO +// int main(void) { +// return 0; +// } diff --git a/src/keyboard.h b/src/keyboard.h new file mode 100644 index 0000000..e6de53b --- /dev/null +++ b/src/keyboard.h @@ -0,0 +1,12 @@ +/* ---------------------------------------------------------------------------- + * Keyboard specific stuff + * - public things are prefixed by `kb_` or `KB_` + * ---------------------------------------------------------------------------- + * Copyright (c) 2012 Ben Blazak + * Released under The MIT License (MIT) (see "license.md") at + * + * ------------------------------------------------------------------------- */ + + +// TODO + diff --git a/src/keyboard/ergodox.h b/src/keyboard/ergodox.h new file mode 100644 index 0000000..e69de29 diff --git a/src/ergodox/layout.c b/src/keyboard/ergodox/layout.c similarity index 59% rename from src/ergodox/layout.c rename to src/keyboard/ergodox/layout.c index 0939b76..7a1717a 100644 --- a/src/ergodox/layout.c +++ b/src/keyboard/ergodox/layout.c @@ -36,67 +36,47 @@ #include "layout.h" -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * ~~~ macros ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - -// TODO - - /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * ~~~ variables ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -uint8_t kb_is_pressed[KB_ROWS][KB_COLUMNS] = { +// uint8_t kb_is_pressed[KB_ROWS][KB_COLUMNS] = { // --- right hand --- // column 0 1 2 3 4 5 6 - 0, 0, 0, 0, 0, 0, 0, //row 0x0 - 0, 0, 0, 0, 0, 0, 0, //row 0x1 - 0, 0, 0, 0, 0, 0, 0, //row 0x2 - 0, 0, 0, 0, 0, 0, 0, //row 0x3 - 0, 0, 0, 0, 0, 0, 0, //row 0x4 - 0, 0, 0, 0, 0, 0, 0, //row 0x5 +// 0, 0, 0, 0, 0, 0, 0, //row 0x0 +// 0, 0, 0, 0, 0, 0, 0, //row 0x1 +// 0, 0, 0, 0, 0, 0, 0, //row 0x2 +// 0, 0, 0, 0, 0, 0, 0, //row 0x3 +// 0, 0, 0, 0, 0, 0, 0, //row 0x4 +// 0, 0, 0, 0, 0, 0, 0, //row 0x5 // --- left hand --- // column 0 1 2 3 4 5 6 - 0, 0, 0, 0, 0, 0, 0, //row 0x6 - 0, 0, 0, 0, 0, 0, 0, //row 0x7 - 0, 0, 0, 0, 0, 0, 0, //row 0x8 - 0, 0, 0, 0, 0, 0, 0, //row 0x9 - 0, 0, 0, 0, 0, 0, 0, //row 0xA - 0, 0, 0, 0, 0, 0, 0, //row 0xB -} - +// 0, 0, 0, 0, 0, 0, 0, //row 0x6 +// 0, 0, 0, 0, 0, 0, 0, //row 0x7 +// 0, 0, 0, 0, 0, 0, 0, //row 0x8 +// 0, 0, 0, 0, 0, 0, 0, //row 0x9 +// 0, 0, 0, 0, 0, 0, 0, //row 0xA +// 0, 0, 0, 0, 0, 0, 0 //row 0xB +// }; +// // TODO: this belongs in program space -uint8_t kb_maps[KB_LAYERS][KB_ROWS][KB_COLUMNS] = { +// uint8_t layout_layers[LAYOUT_LAYERS][LAYOUT_ROWS][LAYOUT_COLUMNS] = { // ------- layer: default ------- // --- right hand --- // column 0 1 2 3 4 5 6 - 0, 0, 0, 0, 0, 0, 0, //row 0x0 - 0, 0, 0, 0, 0, 0, 0, //row 0x1 - 0, 0, 0, 0, 0, 0, 0, //row 0x2 - 0, 0, 0, 0, 0, 0, 0, //row 0x3 - 0, 0, 0, 0, 0, 0, 0, //row 0x4 - 0, 0, 0, 0, 0, 0, 0, //row 0x5 +// 0, 0, 0, 0, 0, 0, 0, //row 0x0 +// 0, 0, 0, 0, 0, 0, 0, //row 0x1 +// 0, 0, 0, 0, 0, 0, 0, //row 0x2 +// 0, 0, 0, 0, 0, 0, 0, //row 0x3 +// 0, 0, 0, 0, 0, 0, 0, //row 0x4 +// 0, 0, 0, 0, 0, 0, 0, //row 0x5 // --- left hand --- // column 0 1 2 3 4 5 6 - 0, 0, 0, 0, 0, 0, 0, //row 0x6 - 0, 0, 0, 0, 0, 0, 0, //row 0x7 - 0, 0, 0, 0, 0, 0, 0, //row 0x8 - 0, 0, 0, 0, 0, 0, 0, //row 0x9 - 0, 0, 0, 0, 0, 0, 0, //row 0xA - 0, 0, 0, 0, 0, 0, 0, //row 0xB -} - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * ~~~ functions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - -// TODO -void kb_init() { -} - -// TODO -// - cycle through row=HIGH and read each column -void kb_update() { -} +// 0, 0, 0, 0, 0, 0, 0, //row 0x6 +// 0, 0, 0, 0, 0, 0, 0, //row 0x7 +// 0, 0, 0, 0, 0, 0, 0, //row 0x8 +// 0, 0, 0, 0, 0, 0, 0, //row 0x9 +// 0, 0, 0, 0, 0, 0, 0, //row 0xA +// 0, 0, 0, 0, 0, 0, 0 //row 0xB +// }; diff --git a/src/ergodox/layout.h b/src/keyboard/ergodox/layout.h similarity index 65% rename from src/ergodox/layout.h rename to src/keyboard/ergodox/layout.h index 60bbfce..59069eb 100644 --- a/src/ergodox/layout.h +++ b/src/keyboard/ergodox/layout.h @@ -1,6 +1,5 @@ /* ---------------------------------------------------------------------------- - * ergoDOX layout specific stuff - * - public things are prefixed by `layout_` or `LAYOUT_` + * see "default.c" * ---------------------------------------------------------------------------- * Copyright (c) 2012 Ben Blazak * Released under The MIT License (MIT) (see "license.md") at @@ -8,9 +7,9 @@ * ------------------------------------------------------------------------- */ -#define KB_LAYERS 1 -#define KB_ROWS 12 // must match real life -#define KB_COLUMNS 7 // must match real life +#define LAYOUT_LAYERS 1 +#define LAYOUT_ROWS 12 // must match real life +#define LAYOUT_COLUMNS 7 // must match real life // TODO diff --git a/src/keyboard/ergodox/main.c b/src/keyboard/ergodox/main.c new file mode 100644 index 0000000..7e00c79 --- /dev/null +++ b/src/keyboard/ergodox/main.c @@ -0,0 +1,25 @@ +#include +#include "teensy-2-0.h" + +int main(void) { + teensy_init(); + + TEENSY_LED1_ON; + TEENSY_LED2_ON; + TEENSY_LED3_ON; + + for(uint8_t i=0;;i++) { + TEENSY_LED1_SET( (i+(3*0xFF/2/3)) % 0xFF/2 ); + TEENSY_LED2_SET( (i+(2*0xFF/2/3)) % 0xFF/2 ); + TEENSY_LED3_SET( (i+(1*0xFF/2/3)) % 0xFF/2 ); + +// counting_up +// ? (i == 0xFF ? counting_up = 0 : i++) +// : (i == 0x00 ? counting_up = 1 : i--); + + _delay_ms(10); + } + + return 0; +} + diff --git a/src/keyboard/ergodox/mcp23018.c b/src/keyboard/ergodox/mcp23018.c new file mode 100644 index 0000000..bd4bc07 --- /dev/null +++ b/src/keyboard/ergodox/mcp23018.c @@ -0,0 +1,61 @@ +/* ---------------------------------------------------------------------------- + * ergoDOX controller: MCP23018 specific code + * ---------------------------------------------------------------------------- + * Copyright (c) 2012 Ben Blazak + * Released under The MIT License (MIT) (see "license.md") at + * + * ------------------------------------------------------------------------- */ + + +#define TWI_ADDRESS MCP23018_TWI_ADDRESS // from header file + +#define True ((uint8_t)1) +#define False ((uint8_t)0) + +// register addresses (see "mcp23018.md") +#define IODIRA 0x00 // i/o direction register +#define IODIRB 0x01 +#define GPPUA 0x0C // GPIO pull-up resistor register +#define GPPUB 0x0D +#define GPIOA 0x12 // general purpose i/o port register +#define GPIOB 0x13 +#define OLATA 0x14 // output latch register +#define OLATB 0x15 + + +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +#include "lib/arduino/twi.h" + +#include "mcp23018.h" + + +void mcp23018_init(void) { + uint8_t data[3]; + + // set pin direction + // - unused : input : 1 + // - rows : output : 0 + // - columns : input : 1 + data[0] = IODIRA; // start register address + data[1] = 0b11000000; // IODIRA + data[2] = 0b11111111; // IODIRB + twi_writeTo(TWI_ADDRESS, data, 3, True); + + // set pull-up + // - unused : on : 1 + // - rows : off : 0 + // - columns : on : 1 + data[0] = GPPUA; // start register address + data[1] = 0b11000000; // GPPUA + data[2] = 0b11111111; // GPPUB + twi_writeTo(TWI_ADDRESS, data, 3, True); + + // set output pins high + // - rows : high : 1 + // - other : low : 0 (or ignored) + data[0] = OLATA; // start register address + data[1] = 0b00111111; // OLATA + twi_writeTo(TWI_ADDRESS, data, 2, True); +} + diff --git a/src/keyboard/ergodox/mcp23018.h b/src/keyboard/ergodox/mcp23018.h new file mode 100644 index 0000000..0006f27 --- /dev/null +++ b/src/keyboard/ergodox/mcp23018.h @@ -0,0 +1,21 @@ +/* ---------------------------------------------------------------------------- + * ergoDOX controller: MCP23018 specific exports + * ---------------------------------------------------------------------------- + * Copyright (c) 2012 Ben Blazak + * Released under The MIT License (MIT) (see "license.md") at + * + * ------------------------------------------------------------------------- */ + + +#ifndef MCP23018_h +#define MCP23018_h + + +#define MCP23018_TWI_ADDRESS 0b0100000 + + +void mcp23018_init(void); + + +#endif + diff --git a/src/keyboard/ergodox/mcp23018.md b/src/keyboard/ergodox/mcp23018.md new file mode 100644 index 0000000..8f11300 --- /dev/null +++ b/src/keyboard/ergodox/mcp23018.md @@ -0,0 +1,127 @@ +# Documentation : MCP23018 + +## Pinouts and Pin assignments + +* `+` indicates pin +* `o` indicates unused pin +* `-`s inserted between some of the pin functions for readability +* `OC**` pins enclosed in parenthesis had lines over them in the pinout + +### MCP23018 + Vss(GND) +01---.---28+ NC + NC +02 27+ GPA7 + GPB0 +03 26+ GPA6 + GPB1 +04 25+ GPA5 + GPB2 +05 24+ GPA4 + GPB3 +06 23+ GPA3 + GPB4 +07 22+ GPA2 + GPB5 +08 21+ GPA1 + GPB6 +09 20+ GPA0 + GPB7 +10 19+ INTA + Vdd(Vcc) +11 18+ INTB + SCL +12 17+ NC + SDA +13 16+ RESET + NC +14-------15+ ADDR + +### MCP32018 Pin Assignments + + power_negative Vss(GND) +01---.---28o + o02 27o + column0 GPB0 +03 26o + column1 GPB1 +04 25+ GPA5 rowB + column2 GPB2 +05 24+ GPA4 rowA + column3 GPB3 +06 23+ GPA3 row9 + column4 GPB4 +07 22+ GPA2 row8 + column5 GPB5 +08 21+ GPA1 row7 + column6 GPB6 +09 20+ GPA0 row6 + o10 19o + power_positive Vdd(Vcc) +11 18o + I2C SCL +12 17o + I2C SDA +13 16o + o14-------15+ ADDR (see note) + +* notes: + * ADDR (pin15): Set slave address to `0b0100000` by connecting to Vss(GND). + (The user-defined bits are the three least significant). + +## Notes about Registers + + register address function (for all bits) + -------- ------- ----------------------- + IODIRA 0x00 \ 1: set corresponding pin as input + IODIRB 0x01 / 0: set ................. as output + GPPUA 0x0C \ 1: set corresponding pin internal pull-up on + GPPUB 0x0D / 0: set .......................... pull-up off + GPIOA 0x12 \ read: returns the value on the port + GPIOB 0x13 / write: modifies the OLAT register + OLATA 0x14 \ read: returns the value of this register + OLATB 0x15 / write: modifies the output latches that control the + pins configured as output + +* IOCON (see datasheet section 1.6, table 1-5, register 1-8) + * BANK: bit 7; read/write; default = 0 + * 1: The registers associated with each port are separated into different + banks + * 0: The registers are in the same bank (addresses are sequential) + * SEQOP: bit 5; read/write; default = 0 + * 1: Sequential operation disabled, address pointer does not increment + * 0: Sequential operation enabled, address pointer increments + +* notes: + * All addresses given for IOCON.BANK = 0, since that's the default value of + the bit, and that's what we'll be using. + +* abbreviations: + * IODIR = I/O Direction Register + * IOCON = I/O Control Register + * GPPU = GPIO Pull-Up Resistor Register + * GPIO = General Purpose I/O Port Register + * OLAT = Output Latch Register + +## I²C Device Protocol (see datasheet section 1.3, figure 1-1) + + S : Start OP : Device opcode + SR : Restart ADDR : Device address + P : Stop Dout : Data out from MCP23018 + W : Write Din : Data in to MCP23018 + R : Read + + + S OP W ADDR ----> Din ... Din --> P + | + |--> SR OP R Dout ... Dout ---> P + |<-------------------------| + | + |--> SR OP W ADDR ... Din --> P + | + |--> P + + S OP R ----> Dout ... Dout --> P + | + |--> SR OP R Dout ... Dout ---> P + |<--------------------------| + | + |--> SR OP W ADDR Din ... Din --> P + | + |--> P + + Byte and Sequential Write + ------------------------- + Byte : S OP W ADDR --> Din --> P + Sequential : S OP W ADDR --> Din ... Din --> P + + Byte and Sequential Read + ------------------------ + Byte : S OP W ADDR --> SR OP R Dout --> P + Sequential : S OP W ADDR --> SR OP R Dout ... Dout --> P + +* notes: + * We'll be using sequential mode (ICON.SEQOP = 0; default) (see datasheet + section 1.3.1). + +------------------------------------------------------------------------------- + +Copyright © 2012 Ben Blazak +Released under The MIT License (MIT) (see "license.md") at + + diff --git a/src/keyboard/ergodox/teensy-2-0.c b/src/keyboard/ergodox/teensy-2-0.c new file mode 100644 index 0000000..da62913 --- /dev/null +++ b/src/keyboard/ergodox/teensy-2-0.c @@ -0,0 +1,65 @@ +/* ---------------------------------------------------------------------------- + * ergoDOX controller: Teensy 2.0 specific code + * ---------------------------------------------------------------------------- + * Copyright (c) 2012 Ben Blazak + * Released under The MIT License (MIT) (see "license.md") at + * + * ------------------------------------------------------------------------- */ + + +// processor frequency (from ) +#define CPU_PRESCALE(n) (CLKPR = 0x80, CLKPR = (n)) +#define CPU_16MHz 0x00 +#define CPU_8MHz 0x01 +#define CPU_4MHz 0x02 +#define CPU_2MHz 0x03 +#define CPU_1MHz 0x04 +#define CPU_500kHz 0x05 +#define CPU_250kHz 0x06 +#define CPU_125kHz 0x07 +#define CPU_62kHz 0x08 + +// TWI +#define TWI_FREQ 400000 // (see "lib/twi.(h|c)") + + +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +#include +#include "lib/arduino/twi.h" + +#include "teensy-2-0.h" + + +void teensy_init(void) { + CPU_PRESCALE(CPU_16MHz); // speed should match F_CPU in makefile + + // unused pins + DDRB &= ~0b00001110; // set B(1,2,3) as input + PORTB |= 0b00001110; // set B(1,2,3) internal pull-up enabled + DDRD &= ~0b01110000; // set D(4,5,6) as input + PORTD |= 0b01110000; // set D(4,5,6) internal pull-up enabled + DDRE &= ~0b01000000; // set E(6) as input + PORTE |= 0b01000000; // set E(6) internal pull-up enabled + + // LEDs (see "PWM on ports OC1(A|B|C)" in "teensy-2-0.md") + DDRB |= 0b11100000; // set B(5,6,7) as output + TCCR1A = 0b10101001; // set and configure fast PWM + TCCR1B = 0b00001001; // set and configure fast PWM + + // rows + DDRF |= 0b11110011; // set F(0,1,4,5,6,7) as output + PORTF |= 0b11110011; // set F(0,1,4,5,6,7) drive high + + // columns + DDRB &= ~0b00010001; // set B(0,4) as input + PORTB |= 0b00010001; // set B(0,4) internal pull-up enabled + DDRC &= ~0b11000000; // set C(6,7) as input + PORTC |= 0b11000000; // set C(6,7) internal pull-up enabled + DDRD &= ~0b10001100; // set D(2,3,7) as input + PORTD |= 0b10001100; // set D(2,3,7) internal pull-up enabled + + // I2C (TWI) + twi_init(); // (on pins D(0,1)) +} + diff --git a/src/keyboard/ergodox/teensy-2-0.h b/src/keyboard/ergodox/teensy-2-0.h new file mode 100644 index 0000000..7415ab0 --- /dev/null +++ b/src/keyboard/ergodox/teensy-2-0.h @@ -0,0 +1,36 @@ +/* ---------------------------------------------------------------------------- + * ergoDOX controller: Teensy 2.0 specific exports + * ---------------------------------------------------------------------------- + * Copyright (c) 2012 Ben Blazak + * Released under The MIT License (MIT) (see "license.md") at + * + * ------------------------------------------------------------------------- */ + + +#include // for the register macros + + +#ifndef TEENSY_2_0_h +#define TEENSY_2_0_h + + +// LED control +#define TEENSY_LED1_ON (OCR1A = 0xFF) +#define TEENSY_LED1_OFF (OCR1A = 0x00) +#define TEENSY_LED1_SET(n) (OCR1A = (uint8_t)(n)) +#define TEENSY_LED1_SET_PERCENT(n) (OCR1A = (uint8_t)((n) * 0xFF)) +#define TEENSY_LED2_ON (OCR1B = 0xFF) +#define TEENSY_LED2_OFF (OCR1B = 0x00) +#define TEENSY_LED2_SET(n) (OCR1B = (uint8_t)(n)) +#define TEENSY_LED2_SET_PERCENT(n) (OCR1B = (uint8_t)((n) * 0xFF)) +#define TEENSY_LED3_ON (OCR1C = 0xFF) +#define TEENSY_LED3_OFF (OCR1C = 0x00) +#define TEENSY_LED3_SET(n) (OCR1C = (uint8_t)(n)) +#define TEENSY_LED3_SET_PERCENT(n) (OCR1C = (uint8_t)((n) * 0xFF)) + + +void teensy_init(void); + + +#endif + diff --git a/src/keyboard/ergodox/teensy-2-0.md b/src/keyboard/ergodox/teensy-2-0.md new file mode 100644 index 0000000..87d5607 --- /dev/null +++ b/src/keyboard/ergodox/teensy-2-0.md @@ -0,0 +1,100 @@ +# Documentation : Teensy 2.0 + +## Pinouts and Pin assignments + +* `+` indicates pin +* `o` indicates unused pin +* `-`s inserted between some of the pin functions for readability +* `OC**` pins enclosed in parenthesis had lines over them in the pinout + +### Teensy 2.0 + + GND +---.....---+ VCC + SS PB0 + + PF0 ADC0 + SCLK PB1 + + PF1 ADC1 + MOSI PB2 + + PF4 ADC4 + MISO PB3 + + + + PF5 ADC5 + RTS OC1C OC0A --------- PB7 + PE6 AREF + PF6 ADC6 + OC0B INT0 SCL PD0 + AIN0 + PF7 ADC7 + INT1 SDA PD1 + INT6 + PB6 ADC13 OC1B OC4B + RXD1 ----------- INT2 --- PD2 + + PB5 ADC12 OC1A (OC4B) + TXD1 ----------- INT3 --- PD3 + + PB4 ADC11 + OC3A (OC4A) -------- PC6 + + PD7 ADC10 T0 -- OC4D + ICP3 ----- OC4A --------- PC7 +-+-+-+-+-+-+ PD6 ADC9 T1 - (OC4D) onboardLED + CTS XCK1 PD5 --/ | | | \-- PD4 ADC8 ------------ ICP1 + VCC ------------------/ | \-------------- RST + GND --------------------/ + +### Teensy 2.0 Pin Assignments + + power_negative GND +---.....---+ Vcc power_positive + column6 PB0 + + PF0 row6 + o + PF1 row7 + o + PF4 row8 + o o o + PF5 row9 + LED3 OC1C + + PF6 rowA + I2C SCL + + PF7 rowB + I2C SDA + + OC1B LED2 + column3 PD2 + + OC1A LED1 + column4 PD3 + + PB4 column0 + column1 PC6 + + PD7 column5 + column2 PC7 +-o-o-o-o-o-o + +* notes: + * SCL and SDA: Need external pull-up resistors. Sometimes the internal + pull-ups are enough (see datasheet section 20.5.1), but i think for this + project we'll want external ones, in case people want to separate the + halves very far. + +## Notes about Registers + +### General I/O (see datasheet section 10.2.1) + + DDRxn function PORTxn function + 1 output 1 drive high + 0 drive low + 0 input 1 internal pull-up on + 0 internal pull-up off + + PINxn action function + write 1 toggles the value of PORTxn + read returns the logical value (1|0) of the pin + +* notes: + * Unused pins should be set as input with internal pullup enabled (see + datasheet section 10.2.6). + * We want the row pins 'drive high' initially, and the column pins set as + input with internal pull-up. We'll cycle through driving the row pins low, + and checking the column pins in the update function. + +### PWM on ports OC1(A|B|C) (see datasheet section 14.10) + +* notes: + * PWM pins should be set as outputs. + * we want Waveform Generation Mode 5 + (fast PWM, 8-bit) + (see table 14-5) + * set `TCCRB[4,3],TCCRA[1,0]` to `0,1,0,1` + * we want "Compare Output Mode, Fast PWM" to be `0b10` + "Clear OCnA/OCnB/OCnC on compare match, set OCnA/OCnB/OCnC at TOP" + (see table 14-3) + this way higher values of `OCR1(A|B|C)` will mean longer 'on' times for the + LEDs + * when in a fast PWM mode, set `TCCR1A[7,6,5,4,3,2]` to `1,0,1,0,1,0` + * we want "Clock Select Bit Description" to be `0b001` + "clkI/O/1 (No prescaling)" + (see table 14-6) + * set `TCCR1B[2,1,0]` to `0,0,1` + * LEDs will be at minimum brightness until OCR1(A|B|C) are changed (since + the default value of all the bits in those registers is 0) + +* abbreviations: + * OCR = Output Compare Register + * TCCR = Timer/Counter Control Register + +------------------------------------------------------------------------------- + +Copyright © 2012 Ben Blazak +Released under The MIT License (MIT) (see "license.md") at + + diff --git a/src/lib/twi.c b/src/lib/arduino/twi.c similarity index 78% rename from src/lib/twi.c rename to src/lib/arduino/twi.c index 6b2db3c..236878c 100644 --- a/src/lib/twi.c +++ b/src/lib/arduino/twi.c @@ -15,8 +15,6 @@ You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - Modified 2012 by Todd Krein (todd@krein.org) to implement repeated starts */ #include @@ -25,7 +23,6 @@ #include #include #include -#include "Arduino.h" // for digitalWrite #ifndef cbi #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) @@ -35,20 +32,17 @@ #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) #endif -#include "pins_arduino.h" #include "twi.h" static volatile uint8_t twi_state; -static volatile uint8_t twi_slarw; -static volatile uint8_t twi_sendStop; // should the transaction end with a stop -static volatile uint8_t twi_inRepStart; // in the middle of a repeated start +static uint8_t twi_slarw; static void (*twi_onSlaveTransmit)(void); static void (*twi_onSlaveReceive)(uint8_t*, int); static uint8_t twi_masterBuffer[TWI_BUFFER_LENGTH]; static volatile uint8_t twi_masterBufferIndex; -static volatile uint8_t twi_masterBufferLength; +static uint8_t twi_masterBufferLength; static uint8_t twi_txBuffer[TWI_BUFFER_LENGTH]; static volatile uint8_t twi_txBufferIndex; @@ -69,17 +63,23 @@ void twi_init(void) { // initialize state twi_state = TWI_READY; - twi_sendStop = true; // default value - twi_inRepStart = false; - - // activate internal pullups for twi. - digitalWrite(SDA, 1); - digitalWrite(SCL, 1); + + #if defined(__AVR_ATmega168__) || defined(__AVR_ATmega8__) || defined(__AVR_ATmega328P__) + // activate internal pull-ups for twi + // as per note from atmega8 manual pg167 + sbi(PORTC, 4); + sbi(PORTC, 5); + #else + // activate internal pull-ups for twi + // as per note from atmega128 manual pg204 + sbi(PORTD, 0); + sbi(PORTD, 1); + #endif // initialize twi prescaler and bit rate cbi(TWSR, TWPS0); cbi(TWSR, TWPS1); - TWBR = ((F_CPU / TWI_FREQ) - 16) / 2; + TWBR = ((CPU_FREQ / TWI_FREQ) - 16) / 2; /* twi bit rate formula from atmega128 manual pg 204 SCL Frequency = CPU Clock Frequency / (16 + (2 * TWBR)) @@ -109,10 +109,9 @@ void twi_setAddress(uint8_t address) * Input address: 7bit i2c device address * data: pointer to byte array * length: number of bytes to read into array - * sendStop: Boolean indicating whether to send a stop at the end * Output number of bytes read */ -uint8_t twi_readFrom(uint8_t address, uint8_t* data, uint8_t length, uint8_t sendStop) +uint8_t twi_readFrom(uint8_t address, uint8_t* data, uint8_t length) { uint8_t i; @@ -126,7 +125,6 @@ uint8_t twi_readFrom(uint8_t address, uint8_t* data, uint8_t length, uint8_t sen continue; } twi_state = TWI_MRX; - twi_sendStop = sendStop; // reset error state (0xFF.. no error occured) twi_error = 0xFF; @@ -143,20 +141,8 @@ uint8_t twi_readFrom(uint8_t address, uint8_t* data, uint8_t length, uint8_t sen twi_slarw = TW_READ; twi_slarw |= address << 1; - if (true == twi_inRepStart) { - // if we're in the repeated start state, then we've already sent the start, - // (@@@ we hope), and the TWI statemachine is just waiting for the address byte. - // We need to remove ourselves from the repeated start state before we enable interrupts, - // since the ISR is ASYNC, and we could get confused if we hit the ISR before cleaning - // up. Also, don't enable the START interrupt. There may be one pending from the - // repeated start that we sent outselves, and that would really confuse things. - twi_inRepStart = false; // remember, we're dealing with an ASYNC ISR - TWDR = twi_slarw; - TWCR = _BV(TWINT) | _BV(TWEA) | _BV(TWEN) | _BV(TWIE); // enable INTs, but not START - } - else - // send start condition - TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTA); + // send start condition + TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTA); // wait for read operation to complete while(TWI_MRX == twi_state){ @@ -182,14 +168,13 @@ uint8_t twi_readFrom(uint8_t address, uint8_t* data, uint8_t length, uint8_t sen * data: pointer to byte array * length: number of bytes in array * wait: boolean indicating to wait for write or not - * sendStop: boolean indicating whether or not to send a stop at the end * Output 0 .. success * 1 .. length to long for buffer * 2 .. address send, NACK received * 3 .. data send, NACK received * 4 .. other twi error (lost bus arbitration, bus error, ..) */ -uint8_t twi_writeTo(uint8_t address, uint8_t* data, uint8_t length, uint8_t wait, uint8_t sendStop) +uint8_t twi_writeTo(uint8_t address, uint8_t* data, uint8_t length, uint8_t wait) { uint8_t i; @@ -203,7 +188,6 @@ uint8_t twi_writeTo(uint8_t address, uint8_t* data, uint8_t length, uint8_t wait continue; } twi_state = TWI_MTX; - twi_sendStop = sendStop; // reset error state (0xFF.. no error occured) twi_error = 0xFF; @@ -220,23 +204,8 @@ uint8_t twi_writeTo(uint8_t address, uint8_t* data, uint8_t length, uint8_t wait twi_slarw = TW_WRITE; twi_slarw |= address << 1; - // if we're in a repeated start, then we've already sent the START - // in the ISR. Don't do it again. - // - if (true == twi_inRepStart) { - // if we're in the repeated start state, then we've already sent the start, - // (@@@ we hope), and the TWI statemachine is just waiting for the address byte. - // We need to remove ourselves from the repeated start state before we enable interrupts, - // since the ISR is ASYNC, and we could get confused if we hit the ISR before cleaning - // up. Also, don't enable the START interrupt. There may be one pending from the - // repeated start that we sent outselves, and that would really confuse things. - twi_inRepStart = false; // remember, we're dealing with an ASYNC ISR - TWDR = twi_slarw; - TWCR = _BV(TWINT) | _BV(TWEA) | _BV(TWEN) | _BV(TWIE); // enable INTs, but not START - } - else - // send start condition - TWCR = _BV(TWINT) | _BV(TWEA) | _BV(TWEN) | _BV(TWIE) | _BV(TWSTA); // enable INTs + // send start condition + TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTA); // wait for write operation to complete while(wait && (TWI_MTX == twi_state)){ @@ -263,7 +232,7 @@ uint8_t twi_writeTo(uint8_t address, uint8_t* data, uint8_t length, uint8_t wait * 2 not slave transmitter * 0 ok */ -uint8_t twi_transmit(const uint8_t* data, uint8_t length) +uint8_t twi_transmit(uint8_t* data, uint8_t length) { uint8_t i; @@ -380,16 +349,7 @@ SIGNAL(TWI_vect) TWDR = twi_masterBuffer[twi_masterBufferIndex++]; twi_reply(1); }else{ - if (twi_sendStop) - twi_stop(); - else { - twi_inRepStart = true; // we're gonna send the START - // don't enable the interrupt. We'll generate the start, but we - // avoid handling the interrupt until we're in the next transaction, - // at the point where we would normally issue the start. - TWCR = _BV(TWINT) | _BV(TWSTA)| _BV(TWEN) ; - twi_state = TWI_READY; - } + twi_stop(); } break; case TW_MT_SLA_NACK: // address sent, nack received @@ -420,17 +380,6 @@ SIGNAL(TWI_vect) case TW_MR_DATA_NACK: // data received, nack sent // put final byte into buffer twi_masterBuffer[twi_masterBufferIndex++] = TWDR; - if (twi_sendStop) - twi_stop(); - else { - twi_inRepStart = true; // we're gonna send the START - // don't enable the interrupt. We'll generate the start, but we - // avoid handling the interrupt until we're in the next transaction, - // at the point where we would normally issue the start. - TWCR = _BV(TWINT) | _BV(TWSTA)| _BV(TWEN) ; - twi_state = TWI_READY; - } - break; case TW_MR_SLA_NACK: // address sent, nack received twi_stop(); break; diff --git a/src/lib/twi.h b/src/lib/arduino/twi.h similarity index 86% rename from src/lib/twi.h rename to src/lib/arduino/twi.h index 6526593..1258d8d 100644 --- a/src/lib/twi.h +++ b/src/lib/arduino/twi.h @@ -24,6 +24,10 @@ //#define ATMEGA8 + #ifndef CPU_FREQ + #define CPU_FREQ 16000000L + #endif + #ifndef TWI_FREQ #define TWI_FREQ 100000L #endif @@ -40,9 +44,9 @@ void twi_init(void); void twi_setAddress(uint8_t); - uint8_t twi_readFrom(uint8_t, uint8_t*, uint8_t, uint8_t); - uint8_t twi_writeTo(uint8_t, uint8_t*, uint8_t, uint8_t, uint8_t); - uint8_t twi_transmit(const uint8_t*, uint8_t); + uint8_t twi_readFrom(uint8_t, uint8_t*, uint8_t); + uint8_t twi_writeTo(uint8_t, uint8_t*, uint8_t, uint8_t); + uint8_t twi_transmit(uint8_t*, uint8_t); void twi_attachSlaveRxEvent( void (*)(uint8_t*, int) ); void twi_attachSlaveTxEvent( void (*)(void) ); void twi_reply(uint8_t); diff --git a/src/lib/teensy-makefile b/src/lib/pjrc/Makefile similarity index 100% rename from src/lib/teensy-makefile rename to src/lib/pjrc/Makefile diff --git a/src/lib/print.c b/src/lib/pjrc/print.c similarity index 100% rename from src/lib/print.c rename to src/lib/pjrc/print.c diff --git a/src/lib/print.h b/src/lib/pjrc/print.h similarity index 100% rename from src/lib/print.h rename to src/lib/pjrc/print.h diff --git a/src/lib/usb_debug_only.c b/src/lib/pjrc/usb_debug_only.c similarity index 100% rename from src/lib/usb_debug_only.c rename to src/lib/pjrc/usb_debug_only.c diff --git a/src/lib/usb_debug_only.h b/src/lib/pjrc/usb_debug_only.h similarity index 100% rename from src/lib/usb_debug_only.h rename to src/lib/pjrc/usb_debug_only.h diff --git a/src/makefile b/src/makefile index 5ece25a..92f890a 100644 --- a/src/makefile +++ b/src/makefile @@ -8,9 +8,12 @@ # ----------------------------------------------------------------------------- -SRC = firmware.c +SRC = $(shell find -name '*.c') +EXTRAINCDIRS = . -TEENSY_MAKE = $(MAKE) -f 'lib/teensy-makefile' SRC='$(SRC)' +TEENSY_MAKE = $(MAKE) -f 'lib/pjrc/Makefile' \ + SRC='$(SRC)' \ + EXTRAINCDIRS='$(EXTRAINCDIRS)' .PHONY: all clean From b77e74cacd05812e67321b24e00528802a5b7ca1 Mon Sep 17 00:00:00 2001 From: Ben Blazak Date: Wed, 21 Mar 2012 16:51:42 -0700 Subject: [PATCH 10/22] doing something clever with macro prefixes, which didn't work i'd like to keep it around in the history though, just for fun - :) --- src/keyboard/ergodox/teensy-2-0.h | 61 ++++++++++++++++++++----------- 1 file changed, 40 insertions(+), 21 deletions(-) diff --git a/src/keyboard/ergodox/teensy-2-0.h b/src/keyboard/ergodox/teensy-2-0.h index 7415ab0..9e0ce9b 100644 --- a/src/keyboard/ergodox/teensy-2-0.h +++ b/src/keyboard/ergodox/teensy-2-0.h @@ -1,36 +1,55 @@ /* ---------------------------------------------------------------------------- * ergoDOX controller: Teensy 2.0 specific exports * ---------------------------------------------------------------------------- - * Copyright (c) 2012 Ben Blazak - * Released under The MIT License (MIT) (see "license.md") at - * + * Copyright (c) 2012 Ben Blazak + * Released under The MIT License (MIT) (see "license.md") + * Project located at * ------------------------------------------------------------------------- */ -#include // for the register macros - - #ifndef TEENSY_2_0_h -#define TEENSY_2_0_h + #define TEENSY_2_0_h + #ifndef INCLUDE_PREFIX + #define INCLUDE_PREFIX teensy_ + #endif -// LED control -#define TEENSY_LED1_ON (OCR1A = 0xFF) -#define TEENSY_LED1_OFF (OCR1A = 0x00) -#define TEENSY_LED1_SET(n) (OCR1A = (uint8_t)(n)) -#define TEENSY_LED1_SET_PERCENT(n) (OCR1A = (uint8_t)((n) * 0xFF)) -#define TEENSY_LED2_ON (OCR1B = 0xFF) -#define TEENSY_LED2_OFF (OCR1B = 0x00) -#define TEENSY_LED2_SET(n) (OCR1B = (uint8_t)(n)) -#define TEENSY_LED2_SET_PERCENT(n) (OCR1B = (uint8_t)((n) * 0xFF)) -#define TEENSY_LED3_ON (OCR1C = 0xFF) -#define TEENSY_LED3_OFF (OCR1C = 0x00) -#define TEENSY_LED3_SET(n) (OCR1C = (uint8_t)(n)) -#define TEENSY_LED3_SET_PERCENT(n) (OCR1C = (uint8_t)((n) * 0xFF)) + #define prefix(s) INCLUDE_PREFIX##s + #define pprefix(s) PRIVATE_INCLUDE_PREFIX##s + // -------------------------------------------------------------------- -void teensy_init(void); + #include // for the register macros + // LED control + #define prefix(LED1_ON) (OCR1A = 0xFF) + #define prefix(LED1_OFF) (OCR1A = 0x00) + #define prefix(LED1_SET)(n) (OCR1A = (uint8_t)(n)) + #define prefix(LED1_SET_PERCENT)(n) (OCR1A = (uint8_t)((n) * 0xFF)) + #define prefix(LED2_ON) (OCR1B = 0xFF) + #define prefix(LED2_OFF) (OCR1B = 0x00) + #define prefix(LED2_SET)(n) (OCR1B = (uint8_t)(n)) + #define prefix(LED2_SET_PERCENT)(n) (OCR1B = (uint8_t)((n) * 0xFF)) + #define prefix(LED3_ON) (OCR1C = 0xFF) + #define prefix(LED3_OFF) (OCR1C = 0x00) + #define prefix(LED3_SET)(n) (OCR1C = (uint8_t)(n)) + #define prefix(LED3_SET_PERCENT)(n) (OCR1C = (uint8_t)((n) * 0xFF)) + + // -------------------------------------------------------------------- + + #ifdef PRIVATE_INCLUDE_PREFIX + + void pprefix(init)(void) + __attribute__((alias ("teensy_init"))); + + #endif + + // -------------------------------------------------------------------- + + #undef prefix + #undef pprefix + #undef INCLUDE_PREFIX + #undef PRIVATE_INCLUDE_PREFIX #endif From a288b8a04531f7eb0aaa2145e16f09a0e48ec46c Mon Sep 17 00:00:00 2001 From: Ben Blazak Date: Tue, 27 Mar 2012 03:06:52 -0700 Subject: [PATCH 11/22] intermitent checkin; lots of stuff; i2c on hold; kb logic in progress --- .gitignore | 3 + doc/references.md | 63 +- readme.md | 13 +- src/firmware.c | 10 +- src/keyboard.h | 12 - src/keyboard/ergodox.c | 0 src/keyboard/ergodox/layout.c | 82 --- src/keyboard/ergodox/layout.h | 44 +- src/keyboard/ergodox/main.c | 25 - src/keyboard/ergodox/matrix.h | 22 + src/keyboard/ergodox/matrix.md | 28 + src/keyboard/ergodox/mcp23018.c | 195 ++++-- src/keyboard/ergodox/mcp23018.h | 17 +- src/keyboard/ergodox/mcp23018.md | 19 +- src/keyboard/ergodox/teensy-2-0.c | 56 +- src/keyboard/ergodox/teensy-2-0.h | 46 +- src/keyboard/ergodox/teensy-2-0.md | 14 +- .../arduino/libraries/Wire/utility}/twi.c | 0 .../arduino/libraries/Wire/utility}/twi.h | 0 .../i2cmaster/group__pfleury__ic2master.html | 473 ++++++++++++++ .../peter-fleury/i2cmaster/i2cmaster.S | 302 +++++++++ .../peter-fleury/i2cmaster/i2cmaster.h | 178 +++++ src/lib-other/peter-fleury/i2cmaster/makefile | 392 +++++++++++ .../peter-fleury/i2cmaster/makefile.i2cmaster | 392 +++++++++++ .../peter-fleury/i2cmaster/makefile.twimaster | 502 ++++++++++++++ .../peter-fleury/i2cmaster/test_i2cmaster.c | 78 +++ .../peter-fleury/i2cmaster/twimaster.c | 202 ++++++ .../pjrc => lib-other/pjrc/blinky}/Makefile | 11 +- src/lib-other/pjrc/blinky/blinky.c | 159 +++++ .../pjrc => lib-other/pjrc/blinky}/print.c | 0 .../pjrc => lib-other/pjrc/blinky}/print.h | 0 .../pjrc/blinky}/usb_debug_only.c | 0 .../pjrc/blinky}/usb_debug_only.h | 0 src/lib-other/pjrc/usb_keyboard/Makefile | 614 ++++++++++++++++++ src/lib-other/pjrc/usb_keyboard/example.c | 124 ++++ .../pjrc/usb_keyboard/usb_keyboard.c | 592 +++++++++++++++++ .../pjrc/usb_keyboard/usb_keyboard.h | 206 ++++++ src/lib-other/readme.md | 34 + src/lib/data-types.h | 22 + src/lib/usb/keyboard-usage-page.h | 264 ++++++++ src/lib/usb/led-usage-page.h | 106 +++ src/makefile | 21 +- src/test.c | 49 ++ 43 files changed, 5081 insertions(+), 289 deletions(-) create mode 100644 .gitignore create mode 100644 src/keyboard/ergodox.c delete mode 100644 src/keyboard/ergodox/layout.c delete mode 100644 src/keyboard/ergodox/main.c create mode 100644 src/keyboard/ergodox/matrix.h create mode 100644 src/keyboard/ergodox/matrix.md rename src/{lib/arduino => lib-other/arduino/arduino/libraries/Wire/utility}/twi.c (100%) rename src/{lib/arduino => lib-other/arduino/arduino/libraries/Wire/utility}/twi.h (100%) create mode 100644 src/lib-other/peter-fleury/i2cmaster/group__pfleury__ic2master.html create mode 100644 src/lib-other/peter-fleury/i2cmaster/i2cmaster.S create mode 100644 src/lib-other/peter-fleury/i2cmaster/i2cmaster.h create mode 100644 src/lib-other/peter-fleury/i2cmaster/makefile create mode 100644 src/lib-other/peter-fleury/i2cmaster/makefile.i2cmaster create mode 100644 src/lib-other/peter-fleury/i2cmaster/makefile.twimaster create mode 100644 src/lib-other/peter-fleury/i2cmaster/test_i2cmaster.c create mode 100644 src/lib-other/peter-fleury/i2cmaster/twimaster.c rename src/{lib/pjrc => lib-other/pjrc/blinky}/Makefile (97%) create mode 100644 src/lib-other/pjrc/blinky/blinky.c rename src/{lib/pjrc => lib-other/pjrc/blinky}/print.c (100%) rename src/{lib/pjrc => lib-other/pjrc/blinky}/print.h (100%) rename src/{lib/pjrc => lib-other/pjrc/blinky}/usb_debug_only.c (100%) rename src/{lib/pjrc => lib-other/pjrc/blinky}/usb_debug_only.h (100%) create mode 100644 src/lib-other/pjrc/usb_keyboard/Makefile create mode 100644 src/lib-other/pjrc/usb_keyboard/example.c create mode 100644 src/lib-other/pjrc/usb_keyboard/usb_keyboard.c create mode 100644 src/lib-other/pjrc/usb_keyboard/usb_keyboard.h create mode 100644 src/lib-other/readme.md create mode 100644 src/lib/data-types.h create mode 100644 src/lib/usb/keyboard-usage-page.h create mode 100644 src/lib/usb/led-usage-page.h create mode 100644 src/test.c diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..70bb2a2 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +*~ +*.swp + diff --git a/doc/references.md b/doc/references.md index c540434..2ff1d7c 100644 --- a/doc/references.md +++ b/doc/references.md @@ -1,4 +1,4 @@ -## Noob Electronics Stuff +## Electronics Stuff * [Resistor Color Codes] (http://www.ladyada.net/wiki/lib/exe/fetch.php?hash=a2c6a9&w=501&h=785&media=http%3A%2F%2Fwww.ladyada.net%2Fimages%2Fmetertutorial%2Frescolorcode.jpg) @@ -34,8 +34,11 @@ * [All About Circuits : Reference] (http://www.allaboutcircuits.com/vol_5/index.html) +* [Effects of Varying I2C Pull-Up Resistors] + (http://dsscircuits.com/articles/effects-of-varying-i2c-pull-up-resistors.html) : article by Wayne Truchsess -## Noob C Stuff + +## C Stuff * [C Library Reference] (http://www.cplusplus.com/reference/) @@ -60,18 +63,11 @@ (http://www.ibiblio.org/pub/languages/fortran/append-c.html) (on ) +* [C preprocessor and concatenation] + (http://stackoverflow.com/questions/1489932/c-preprocessor-and-concatenation) + (on ) -## Noob Other Stuff - -* [Markdown: Syntax] - (http://daringfireball.net/projects/markdown/syntax) - -* [Keyboard Scan Rates] - (http://geekhack.org/showwiki.php?title=Keyboard+scan+rates) - list (on ) - - -## AVR C stuff +### For the AVR * [AVR Libc Library Reference] (http://www.nongnu.org/avr-libc/user-manual/modules.html) @@ -83,14 +79,47 @@ * [A Brief Tutorial on Programming the AVR without Arduino] by Chris Kuethe (https://www.mainframe.cx/~ckuethe/avr-c-tutorial/) +## Protocol Stuff -## Articles / Tutorials +### I²C * [Arduino I²C Expansion IO] (http://www.neufeld.newton.ks.us/electronics/?p=241) (from [Keith's Electronics Blog] (http://www.neufeld.newton.ks.us/electronics/)) +* [Arduino Playground :: Wire Library, Explored] + (http://arduino.cc/playground/Main/WireLibraryDetailedReference) + +### USB + +* About Keyboard [Scan Codes] + (http://geekhack.org/showwiki.php?title=Scan+Codes) + (on ) + +* [USB 2.0 Specification] + (http://www.usb.org/developers/docs/usb_20_101111.zip) + : zip (from ) + +* [HID Device Class Definition] + (http://www.usb.org/developers/devclass_docs/HID1_11.pdf) + : pdf (from ) + * HID = Human Interface Device + +* [HID Usage Tables] + (http://www.usb.org/developers/devclass_docs/Hut1_12v2.pdf) + : pdf (from ) + + +## Miscellaneous + +* [Markdown: Syntax] + (http://daringfireball.net/projects/markdown/syntax) + +* [Keyboard Scan Rates] + (http://geekhack.org/showwiki.php?title=Keyboard+scan+rates) + list (on ) + ## Other Firmware / Code @@ -192,7 +221,7 @@ ------------------------------------------------------------------------------- -Copyright © 2012 Ben Blazak -Released under The MIT License (MIT) (see "license.md") at - +Copyright © 2012 Ben Blazak +Released under The MIT License (MIT) (see "license.md") +Project located at diff --git a/readme.md b/readme.md index e1de6db..3531a1f 100644 --- a/readme.md +++ b/readme.md @@ -3,9 +3,16 @@ [ergodox-firmware]: https://github.com/benblazak/ergodox-firmware [ergodox keyboard]: http://geekhack.org/showthread.php?22780-Interest-Check-Custom-split-ergo-keyboard + +## dependencies + +* See the PJRC [Getting Started] (http://pjrc.com/teensy/first_use.html) page + for instructions on how to set up an AVR programming environment. This + project uses C (not Arduino). + ------------------------------------------------------------------------------- -Copyright © 2012 Ben Blazak -Released under The MIT License (MIT) (see "license.md") at - +Copyright © 2012 Ben Blazak +Released under The MIT License (MIT) (see "license.md") +Project located at diff --git a/src/firmware.c b/src/firmware.c index e40a0d1..e59e8ed 100644 --- a/src/firmware.c +++ b/src/firmware.c @@ -1,15 +1,15 @@ /* ---------------------------------------------------------------------------- * Firmware main file * ---------------------------------------------------------------------------- - * Copyright (c) 2012 Ben Blazak - * Released under The MIT License (MIT) (see "license.md") at - * + * Copyright (c) 2012 Ben Blazak + * Released under The MIT License (MIT) (see "license.md") + * Project located at * ------------------------------------------------------------------------- */ -#include "lib/pjrc/print.h" +// #include "lib/pjrc/print.h" -#include "keyboard.h" +// #include "keyboard.h" // TODO diff --git a/src/keyboard.h b/src/keyboard.h index e6de53b..e69de29 100644 --- a/src/keyboard.h +++ b/src/keyboard.h @@ -1,12 +0,0 @@ -/* ---------------------------------------------------------------------------- - * Keyboard specific stuff - * - public things are prefixed by `kb_` or `KB_` - * ---------------------------------------------------------------------------- - * Copyright (c) 2012 Ben Blazak - * Released under The MIT License (MIT) (see "license.md") at - * - * ------------------------------------------------------------------------- */ - - -// TODO - diff --git a/src/keyboard/ergodox.c b/src/keyboard/ergodox.c new file mode 100644 index 0000000..e69de29 diff --git a/src/keyboard/ergodox/layout.c b/src/keyboard/ergodox/layout.c deleted file mode 100644 index 7a1717a..0000000 --- a/src/keyboard/ergodox/layout.c +++ /dev/null @@ -1,82 +0,0 @@ -/* ---------------------------------------------------------------------------- - * ergoDOX layout specific stuff - * - public things are prefixed by `layout_` or `LAYOUT_` - * ---------------------------------------------------------------------------- - * Copyright (c) 2012 Ben Blazak - * Released under The MIT License (MIT) (see "license.md") at - * - * ------------------------------------------------------------------------- */ - - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * ~~~ documentation ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - -/* ---------------------------------------------------------------------------- - * Matrix [row.column] assignments - * - row and column numbers are in hex - * - coordinates without brackets are unused - * - left and right hands are mirrored, with `row += 6` for left hand rows - * ---------------------------------------------------------------------------- - * ....... rows x columns = positions; assigned, unassigned ....... - * ....... per hand: 6 x 7 = 42; 38, 4 ....... - * ....... total: 12 x 7 = 84; 76, 8 ....... - * ---------------------------------------------------------------------------- - * [66][65][64][63][62][61][60] [00][01][02][03][04][05][06] - * [76][75][74][73][72][71][70] [10][11][12][13][14][15][16] - * [86][85][84][83][82][81] 80 20 [21][22][23][24][25][26] - * [96][95][94][93][92][91][90] [30][31][32][33][34][35][36] - * [A6][A5][A4][A3][A2] A1 A0 40 41 [42][43][44][45][46] - * [B1] B0 50 [51] - * [B3] [B2] [52] [53] - * [B6][B5][B4] [54][55][56] - * ------------------------------------------------------------------------- */ - - -#include "layout.h" - - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * ~~~ variables ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - -// uint8_t kb_is_pressed[KB_ROWS][KB_COLUMNS] = { -// --- right hand --- -// column 0 1 2 3 4 5 6 -// 0, 0, 0, 0, 0, 0, 0, //row 0x0 -// 0, 0, 0, 0, 0, 0, 0, //row 0x1 -// 0, 0, 0, 0, 0, 0, 0, //row 0x2 -// 0, 0, 0, 0, 0, 0, 0, //row 0x3 -// 0, 0, 0, 0, 0, 0, 0, //row 0x4 -// 0, 0, 0, 0, 0, 0, 0, //row 0x5 -// --- left hand --- -// column 0 1 2 3 4 5 6 -// 0, 0, 0, 0, 0, 0, 0, //row 0x6 -// 0, 0, 0, 0, 0, 0, 0, //row 0x7 -// 0, 0, 0, 0, 0, 0, 0, //row 0x8 -// 0, 0, 0, 0, 0, 0, 0, //row 0x9 -// 0, 0, 0, 0, 0, 0, 0, //row 0xA -// 0, 0, 0, 0, 0, 0, 0 //row 0xB -// }; -// -// TODO: this belongs in program space -// uint8_t layout_layers[LAYOUT_LAYERS][LAYOUT_ROWS][LAYOUT_COLUMNS] = { -// ------- layer: default ------- -// --- right hand --- -// column 0 1 2 3 4 5 6 -// 0, 0, 0, 0, 0, 0, 0, //row 0x0 -// 0, 0, 0, 0, 0, 0, 0, //row 0x1 -// 0, 0, 0, 0, 0, 0, 0, //row 0x2 -// 0, 0, 0, 0, 0, 0, 0, //row 0x3 -// 0, 0, 0, 0, 0, 0, 0, //row 0x4 -// 0, 0, 0, 0, 0, 0, 0, //row 0x5 -// --- left hand --- -// column 0 1 2 3 4 5 6 -// 0, 0, 0, 0, 0, 0, 0, //row 0x6 -// 0, 0, 0, 0, 0, 0, 0, //row 0x7 -// 0, 0, 0, 0, 0, 0, 0, //row 0x8 -// 0, 0, 0, 0, 0, 0, 0, //row 0x9 -// 0, 0, 0, 0, 0, 0, 0, //row 0xA -// 0, 0, 0, 0, 0, 0, 0 //row 0xB -// }; - diff --git a/src/keyboard/ergodox/layout.h b/src/keyboard/ergodox/layout.h index 59069eb..ffc3445 100644 --- a/src/keyboard/ergodox/layout.h +++ b/src/keyboard/ergodox/layout.h @@ -1,16 +1,42 @@ /* ---------------------------------------------------------------------------- - * see "default.c" + * ergoDOX layout * ---------------------------------------------------------------------------- - * Copyright (c) 2012 Ben Blazak - * Released under The MIT License (MIT) (see "license.md") at - * + * Copyright (c) 2012 Ben Blazak + * Released under The MIT License (MIT) (see "license.md") + * Project located at * ------------------------------------------------------------------------- */ +#ifndef LAYOUT_h + #define LAYOUT_h -#define LAYOUT_LAYERS 1 -#define LAYOUT_ROWS 12 // must match real life -#define LAYOUT_COLUMNS 7 // must match real life + #include "lib/usb/keyboard-usage-page.h" + #include "matrix.h" + + #define KB_LAYERS 1 // anything >= 1, as long as there's memory + + extern const uint8_t kb_layout[KB_LAYERS][KB_ROWS][KB_COLUMNS] = { +// TODO (before release): put more effort into this +// ------- layer 0: default ------- +// --- right hand --- + /* 0 ---------- 1 --------------- 2 -------------- 3 ----------------- 4 --------------------- 5 -------------------------- 6 -------------------------- */ +/* 0 */ 0, KEY_6_Caret, KEY_7_Ampersand, KEY_8_Asterisk, KEY_9_LeftParenthesis, KEY_0_RightParenthesis, KEY_Dash_Underscore, /* 0 */ +/* 1 */ 0, KEY_y_Y, KEY_u_U, KEY_i_I, KEY_o_O, KEY_p_P, KEY_LeftBracket_LeftBrace, /* 1 */ +/* 2 */ 0,/*unused*/ KEY_h_H, KEY_j_J, KEY_k_K, KEY_l_L, KEY_Semicolon_Colon, KEY_SingleQuote_DoubleQuote, /* 2 */ +/* 3 */ 0, KEY_n_N, KEY_m_M, KEY_Comma_LessThan, KEY_Period_GreaterThan, KEY_Slash_Question, KEY_RightShift, /* 3 */ +/* 4 */ 0,/*unused*/ 0,/*unused*/ KEY_UpArrow, KEY_DownArrow, KEY_Backslash_Pipe, KEY_RightBracket_RightBrace, 0, /* 4 */ +/* 5 */ 0,/*unused*/ KEY_RightControl, KEY_RightAlt, KEY_PageUp, KEY_PageDown, KEY_ReturnEnter, KEY_Spacebar, /* 5 */ + /* 0 ---------- 1 --------------- 2 -------------- 3 ----------------- 4 --------------------- 5 -------------------------- 6 -------------------------- */ +// --- left hand --- + /* 0 ------------------ 1 -------------------- 2 ----------------- 3 ------------ 4 -------------- 5 ------------ 6 ----------- */ +/* 6 */ KEY_Equal_Plus, KEY_1_Exclamation, KEY_2_At, KEY_3_Pound, KEY_4_Dollar, KEY_5_Percent, 0, /* 6 */ +/* 7 */ KEY_Tab, KEY_q_Q, KEY_w_W, KEY_e_E, KEY_r_R, KEY_t_T, 0, /* 7 */ +/* 8 */ KEY_CapsLock, KEY_a_A, KEY_s_S, KEY_d_D, KEY_f_F, KEY_g_G, 0,/*unused*/ /* 8 */ +/* 9 */ KEY_LeftShift, KEY_z_Z, KEY_x_X, KEY_c_C, KEY_v_V, KEY_b_B, 0, /* 9 */ +/* A */ 0, KEY_GraveAccent_Tilde, KEY_Backslash_Pipe, KEY_LeftArrow, KEY_RightArrow, 0,/*unused*/ 0,/*unused*/ /* A */ +/* B */ KEY_DeleteBackspace, KEY_DeleteForward, KEY_End, KEY_Home, KEY_LeftAlt, KEY_LeftControl, 0, 0 /*unused*/ /* B */ + /* 0 ------------------ 1 -------------------- 2 ----------------- 3 ------------ 4 -------------- 5 ------------ 6 ----------- */ + } + +#endif -// TODO - diff --git a/src/keyboard/ergodox/main.c b/src/keyboard/ergodox/main.c deleted file mode 100644 index 7e00c79..0000000 --- a/src/keyboard/ergodox/main.c +++ /dev/null @@ -1,25 +0,0 @@ -#include -#include "teensy-2-0.h" - -int main(void) { - teensy_init(); - - TEENSY_LED1_ON; - TEENSY_LED2_ON; - TEENSY_LED3_ON; - - for(uint8_t i=0;;i++) { - TEENSY_LED1_SET( (i+(3*0xFF/2/3)) % 0xFF/2 ); - TEENSY_LED2_SET( (i+(2*0xFF/2/3)) % 0xFF/2 ); - TEENSY_LED3_SET( (i+(1*0xFF/2/3)) % 0xFF/2 ); - -// counting_up -// ? (i == 0xFF ? counting_up = 0 : i++) -// : (i == 0x00 ? counting_up = 1 : i--); - - _delay_ms(10); - } - - return 0; -} - diff --git a/src/keyboard/ergodox/matrix.h b/src/keyboard/ergodox/matrix.h new file mode 100644 index 0000000..18fb807 --- /dev/null +++ b/src/keyboard/ergodox/matrix.h @@ -0,0 +1,22 @@ +/* ---------------------------------------------------------------------------- + * ergoDOX: keyboard matrix specific exports + * ---------------------------------------------------------------------------- + * Copyright (c) 2012 Ben Blazak + * Released under The MIT License (MIT) (see "license.md") + * Project located at + * ------------------------------------------------------------------------- */ + + +#ifndef MATRIX_h + #define MATRIX_h + + #include "lib/data-types.h" + + #define KB_ROWS 12 // must match real life + #define KB_COLUMNS 7 // must match real life + + extern bool kb_is_pressed[KB_ROWS][KB_COLUMNS]; + bool kb_is_pressed[KB_ROWS][KB_COLUMNS]; + +#endif + diff --git a/src/keyboard/ergodox/matrix.md b/src/keyboard/ergodox/matrix.md new file mode 100644 index 0000000..dde42b4 --- /dev/null +++ b/src/keyboard/ergodox/matrix.md @@ -0,0 +1,28 @@ +# Documentation : Keyboard Matrix + +## Matrix [row.column] assignments + + * row and column numbers are in hex + * coordinates without brackets are unused + * left and right hands are mostly the same, except that `row += 6` for left + hand rows + + ....... rows x columns = positions; assigned, unassigned ....... + ....... per hand: 6 x 7 = 42; 38, 4 ....... + ....... total: 12 x 7 = 84; 76, 8 ....... + ---------------------------------------------------------------------------- + [60][61][62][63][64][65][66] [00][01][02][03][04][05][06] + [70][71][72][73][74][75][76] [10][11][12][13][14][15][16] + [80][81][82][83][84][85] 86 20 [21][22][23][24][25][26] + [90][91][92][93][94][95][96] [30][31][32][33][34][35][36] + [A0][A1][A2][A3][A4] A5 A6 40 41 [42][43][44][45][46] + [B0] B6 50 [56] + [B1] [B5] [51] [55] + [B2][B3][B4] [52][53][54] + +------------------------------------------------------------------------------- + +Copyright © 2012 Ben Blazak +Released under The MIT License (MIT) (see "license.md") +Project located at + diff --git a/src/keyboard/ergodox/mcp23018.c b/src/keyboard/ergodox/mcp23018.c index bd4bc07..ff0b73a 100644 --- a/src/keyboard/ergodox/mcp23018.c +++ b/src/keyboard/ergodox/mcp23018.c @@ -1,16 +1,80 @@ /* ---------------------------------------------------------------------------- * ergoDOX controller: MCP23018 specific code * ---------------------------------------------------------------------------- - * Copyright (c) 2012 Ben Blazak - * Released under The MIT License (MIT) (see "license.md") at - * + * Copyright (c) 2012 Ben Blazak + * Released under The MIT License (MIT) (see "license.md") + * Project located at * ------------------------------------------------------------------------- */ +// TODO: this is not working yet -#define TWI_ADDRESS MCP23018_TWI_ADDRESS // from header file +#if 0 // this is not the one we want; but it has all the right info +#include "lib-other/peter-fleury/i2cmaster/i2cmaster.h" + +// so we can say `TWI_ADDRESS|I2C_WRITE` +#define TWI_ADDRESS (MCP23018_TWI_ADDRESS<<1) + +uint8_t mcp23018_ready; // false + +uint8_t mcp23018_init(void) { + // declare vars + uint8_t error; + + // see if the device is ready + // - success: set `mcp23018_ready = true` and continue initializing + // - failure: return `error`; we can try again later + error = i2c_start(TWI_ADDRESS|I2C_WRITE); + if(error) { + return error; + } else { + mcp23018_ready = true; + i2c_stop(); // release bus + } + + // set pin direction + // - unused : input : 1 + // - rows : output : 0 + // - columns : input : 1 + i2c_start_wait(TWI_ADDRESS|I2C_WRITE); + i2c_write(IODIRA); // start register address + i2c_write(0b11000000); // IODIRA + i2c_write(0b11111111); // IODIRB + i2c_stop(); + + // set pull-up + // - unused : on : 1 + // - rows : on : 1 + // - columns : on : 1 + i2c_start_wait(TWI_ADDRESS|I2C_WRITE); + i2c_write(GPPUA); // start register address + i2c_write(0b11111111); // GPPUA + i2c_write(0b11111111); // GPPUB + i2c_stop(); + + // set output pins high + // - rows : high : 1 + // - other : low : 0 (or ignored) + i2c_start_wait(TWI_ADDRESS|I2C_WRITE); + i2c_write(OLATA); // start register address + i2c_write(0b00111111); // OLATA + i2c_stop(); + + return 0; // success +} +#endif + + +#include +#include +// #include "lib-other/arduino/arduino/libraries/Wire/utility/twi.h" +#include "lib-other/pjrc/blinky/print.h" +#include "lib-other/pjrc/blinky/usb_debug_only.h" + +#define MCP23018_h_INCLUDE_PRIVATE +#include "mcp23018.h" +#include "teensy-2-0.h" +#include "lib/data-types.h" -#define True ((uint8_t)1) -#define False ((uint8_t)0) // register addresses (see "mcp23018.md") #define IODIRA 0x00 // i/o direction register @@ -22,40 +86,89 @@ #define OLATA 0x14 // output latch register #define OLATB 0x15 - -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -#include "lib/arduino/twi.h" - -#include "mcp23018.h" - - -void mcp23018_init(void) { - uint8_t data[3]; - - // set pin direction - // - unused : input : 1 - // - rows : output : 0 - // - columns : input : 1 - data[0] = IODIRA; // start register address - data[1] = 0b11000000; // IODIRA - data[2] = 0b11111111; // IODIRB - twi_writeTo(TWI_ADDRESS, data, 3, True); - - // set pull-up - // - unused : on : 1 - // - rows : off : 0 - // - columns : on : 1 - data[0] = GPPUA; // start register address - data[1] = 0b11000000; // GPPUA - data[2] = 0b11111111; // GPPUB - twi_writeTo(TWI_ADDRESS, data, 3, True); - - // set output pins high - // - rows : high : 1 - // - other : low : 0 (or ignored) - data[0] = OLATA; // start register address - data[1] = 0b00111111; // OLATA - twi_writeTo(TWI_ADDRESS, data, 2, True); +static void twi_init(void) { +// TWSR &= ~( (1<=0; i--) { + (data & (1< + * Copyright (c) 2012 Ben Blazak + * Released under The MIT License (MIT) (see "license.md") + * Project located at * ------------------------------------------------------------------------- */ #ifndef MCP23018_h -#define MCP23018_h + #define MCP23018_h + #include "lib/data-types.h" -#define MCP23018_TWI_ADDRESS 0b0100000 + #ifdef MCP23018_h_INCLUDE_PRIVATE + #define MCP23018_TWI_ADDRESS 0b0100000 -void mcp23018_init(void); + extern bool mcp23018_ready; + uint8_t mcp23018_init(void); + + #endif #endif diff --git a/src/keyboard/ergodox/mcp23018.md b/src/keyboard/ergodox/mcp23018.md index 8f11300..de426db 100644 --- a/src/keyboard/ergodox/mcp23018.md +++ b/src/keyboard/ergodox/mcp23018.md @@ -70,6 +70,7 @@ * notes: * All addresses given for IOCON.BANK = 0, since that's the default value of the bit, and that's what we'll be using. + * Outputs are open drain, so we want pull-up resistors set for everything. * abbreviations: * IODIR = I/O Direction Register @@ -80,17 +81,17 @@ ## I²C Device Protocol (see datasheet section 1.3, figure 1-1) - S : Start OP : Device opcode - SR : Restart ADDR : Device address - P : Stop Dout : Data out from MCP23018 - W : Write Din : Data in to MCP23018 - R : Read + S : Start OP : Device opcode + SR : Restart ADDR : Device address + P : Stop Dout : Data out from MCP23018 + W : Write Din : Data in to MCP23018 + R : Read S OP W ADDR ----> Din ... Din --> P | |--> SR OP R Dout ... Dout ---> P - |<-------------------------| + |<--------------------------| | |--> SR OP W ADDR ... Din --> P | @@ -121,7 +122,7 @@ ------------------------------------------------------------------------------- -Copyright © 2012 Ben Blazak -Released under The MIT License (MIT) (see "license.md") at - +Copyright © 2012 Ben Blazak +Released under The MIT License (MIT) (see "license.md") +Project located at diff --git a/src/keyboard/ergodox/teensy-2-0.c b/src/keyboard/ergodox/teensy-2-0.c index da62913..4caf4ed 100644 --- a/src/keyboard/ergodox/teensy-2-0.c +++ b/src/keyboard/ergodox/teensy-2-0.c @@ -1,12 +1,18 @@ /* ---------------------------------------------------------------------------- * ergoDOX controller: Teensy 2.0 specific code * ---------------------------------------------------------------------------- - * Copyright (c) 2012 Ben Blazak - * Released under The MIT License (MIT) (see "license.md") at - * + * Copyright (c) 2012 Ben Blazak + * Released under The MIT License (MIT) (see "license.md") + * Project located at * ------------------------------------------------------------------------- */ +#include + +#define TEENSY_2_0_h_INCLUDE_PRIVATE +#include "teensy-2-0.h" + + // processor frequency (from ) #define CPU_PRESCALE(n) (CLKPR = 0x80, CLKPR = (n)) #define CPU_16MHz 0x00 @@ -19,47 +25,39 @@ #define CPU_125kHz 0x07 #define CPU_62kHz 0x08 -// TWI -#define TWI_FREQ 400000 // (see "lib/twi.(h|c)") - -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -#include -#include "lib/arduino/twi.h" - -#include "teensy-2-0.h" - - -void teensy_init(void) { +uint8_t teensy_init(void) { CPU_PRESCALE(CPU_16MHz); // speed should match F_CPU in makefile // unused pins - DDRB &= ~0b00001110; // set B(1,2,3) as input - PORTB |= 0b00001110; // set B(1,2,3) internal pull-up enabled - DDRD &= ~0b01110000; // set D(4,5,6) as input - PORTD |= 0b01110000; // set D(4,5,6) internal pull-up enabled + DDRB &= ~0b00001110; // set B(3,2,1) as input + PORTB |= 0b00001110; // set B(3,2,1) internal pull-up enabled + DDRD &= ~0b01110000; // set D(6,5,4) as input + PORTD |= 0b01110000; // set D(6,5,4) internal pull-up enabled DDRE &= ~0b01000000; // set E(6) as input PORTE |= 0b01000000; // set E(6) internal pull-up enabled // LEDs (see "PWM on ports OC1(A|B|C)" in "teensy-2-0.md") - DDRB |= 0b11100000; // set B(5,6,7) as output + DDRB |= 0b11100000; // set B(7,6,5) as output TCCR1A = 0b10101001; // set and configure fast PWM TCCR1B = 0b00001001; // set and configure fast PWM // rows - DDRF |= 0b11110011; // set F(0,1,4,5,6,7) as output - PORTF |= 0b11110011; // set F(0,1,4,5,6,7) drive high + DDRF |= 0b11110011; // set F(7,6,5,4,1,0) as output + PORTF |= 0b11110011; // set F(7,6,5,4,1,0) drive high // columns - DDRB &= ~0b00010001; // set B(0,4) as input - PORTB |= 0b00010001; // set B(0,4) internal pull-up enabled - DDRC &= ~0b11000000; // set C(6,7) as input - PORTC |= 0b11000000; // set C(6,7) internal pull-up enabled - DDRD &= ~0b10001100; // set D(2,3,7) as input - PORTD |= 0b10001100; // set D(2,3,7) internal pull-up enabled + DDRB &= ~0b00010001; // set B(4,0) as input + PORTB |= 0b00010001; // set B(4,0) internal pull-up enabled + DDRC &= ~0b11000000; // set C(7,6) as input + PORTC |= 0b11000000; // set C(7,6) internal pull-up enabled + DDRD &= ~0b10001100; // set D(7,3,2) as input + PORTD |= 0b10001100; // set D(7,3,2) internal pull-up enabled // I2C (TWI) - twi_init(); // (on pins D(0,1)) + // on pins D(1,0); leave them alone here, so the TWI library can do as + // it wishes + + return 0; // success } diff --git a/src/keyboard/ergodox/teensy-2-0.h b/src/keyboard/ergodox/teensy-2-0.h index 9e0ce9b..bb8f3ff 100644 --- a/src/keyboard/ergodox/teensy-2-0.h +++ b/src/keyboard/ergodox/teensy-2-0.h @@ -10,46 +10,28 @@ #ifndef TEENSY_2_0_h #define TEENSY_2_0_h - #ifndef INCLUDE_PREFIX - #define INCLUDE_PREFIX teensy_ - #endif - - #define prefix(s) INCLUDE_PREFIX##s - #define pprefix(s) PRIVATE_INCLUDE_PREFIX##s - - // -------------------------------------------------------------------- - #include // for the register macros // LED control - #define prefix(LED1_ON) (OCR1A = 0xFF) - #define prefix(LED1_OFF) (OCR1A = 0x00) - #define prefix(LED1_SET)(n) (OCR1A = (uint8_t)(n)) - #define prefix(LED1_SET_PERCENT)(n) (OCR1A = (uint8_t)((n) * 0xFF)) - #define prefix(LED2_ON) (OCR1B = 0xFF) - #define prefix(LED2_OFF) (OCR1B = 0x00) - #define prefix(LED2_SET)(n) (OCR1B = (uint8_t)(n)) - #define prefix(LED2_SET_PERCENT)(n) (OCR1B = (uint8_t)((n) * 0xFF)) - #define prefix(LED3_ON) (OCR1C = 0xFF) - #define prefix(LED3_OFF) (OCR1C = 0x00) - #define prefix(LED3_SET)(n) (OCR1C = (uint8_t)(n)) - #define prefix(LED3_SET_PERCENT)(n) (OCR1C = (uint8_t)((n) * 0xFF)) + #define KB_LED1_ON (OCR1A = 0xFF) + #define KB_LED1_OFF (OCR1A = 0x00) + #define KB_LED1_SET(n) (OCR1A = (uint8_t)(n)) + #define KB_LED1_SET_PERCENT(n) (OCR1A = (uint8_t)((n) * 0xFF)) + #define KB_LED2_ON (OCR1B = 0xFF) + #define KB_LED2_OFF (OCR1B = 0x00) + #define KB_LED2_SET(n) (OCR1B = (uint8_t)(n)) + #define KB_LED2_SET_PERCENT(n) (OCR1B = (uint8_t)((n) * 0xFF)) + #define KB_LED3_ON (OCR1C = 0xFF) + #define KB_LED3_OFF (OCR1C = 0x00) + #define KB_LED3_SET(n) (OCR1C = (uint8_t)(n)) + #define KB_LED3_SET_PERCENT(n) (OCR1C = (uint8_t)((n) * 0xFF)) - // -------------------------------------------------------------------- - #ifdef PRIVATE_INCLUDE_PREFIX + #ifdef TEENSY_2_0_h_INCLUDE_PRIVATE - void pprefix(init)(void) - __attribute__((alias ("teensy_init"))); + uint8_t teensy_init(void); #endif - // -------------------------------------------------------------------- - - #undef prefix - #undef pprefix - #undef INCLUDE_PREFIX - #undef PRIVATE_INCLUDE_PREFIX - #endif diff --git a/src/keyboard/ergodox/teensy-2-0.md b/src/keyboard/ergodox/teensy-2-0.md index 87d5607..a9da809 100644 --- a/src/keyboard/ergodox/teensy-2-0.md +++ b/src/keyboard/ergodox/teensy-2-0.md @@ -41,10 +41,10 @@ column2 PC7 +-o-o-o-o-o-o * notes: - * SCL and SDA: Need external pull-up resistors. Sometimes the internal - pull-ups are enough (see datasheet section 20.5.1), but i think for this - project we'll want external ones, in case people want to separate the - halves very far. + * SCL and SDA: Need external pull-up resistors. Sometimes the Teensy + internal pull-ups are enough (see datasheet section 20.5.1), but i think + for this project we'll want external ones, in case people want to separate + the halves very far. ## Notes about Registers @@ -94,7 +94,7 @@ ------------------------------------------------------------------------------- -Copyright © 2012 Ben Blazak -Released under The MIT License (MIT) (see "license.md") at - +Copyright © 2012 Ben Blazak +Released under The MIT License (MIT) (see "license.md") +Project located at diff --git a/src/lib/arduino/twi.c b/src/lib-other/arduino/arduino/libraries/Wire/utility/twi.c similarity index 100% rename from src/lib/arduino/twi.c rename to src/lib-other/arduino/arduino/libraries/Wire/utility/twi.c diff --git a/src/lib/arduino/twi.h b/src/lib-other/arduino/arduino/libraries/Wire/utility/twi.h similarity index 100% rename from src/lib/arduino/twi.h rename to src/lib-other/arduino/arduino/libraries/Wire/utility/twi.h diff --git a/src/lib-other/peter-fleury/i2cmaster/group__pfleury__ic2master.html b/src/lib-other/peter-fleury/i2cmaster/group__pfleury__ic2master.html new file mode 100644 index 0000000..23e3f8c --- /dev/null +++ b/src/lib-other/peter-fleury/i2cmaster/group__pfleury__ic2master.html @@ -0,0 +1,473 @@ + + +AVR-GCC libraries: I2C Master library + + + +

I2C Master library


Detailed Description

+I2C (TWI) Master Software Library. +

+

 #include <i2cmaster.h> 
+

+Basic routines for communicating with I2C slave devices. This single master implementation is limited to one bus master on the I2C bus.

+This I2c library is implemented as a compact assembler software implementation of the I2C protocol which runs on any AVR (i2cmaster.S) and as a TWI hardware interface for all AVR with built-in TWI hardware (twimaster.c). Since the API for these two implementations is exactly the same, an application can be linked either against the software I2C implementation or the hardware I2C implementation.

+Use 4.7k pull-up resistor on the SDA and SCL pin.

+Adapt the SCL and SDA port and pin definitions and eventually the delay routine in the module i2cmaster.S to your target when using the software I2C implementation !

+Adjust the CPU clock frequence F_CPU in twimaster.c or in the Makfile when using the TWI hardware implementaion.

+

Note:
The module i2cmaster.S is based on the Atmel Application Note AVR300, corrected and adapted to GNU assembler and AVR-GCC C call interface. Replaced the incorrect quarter period delays found in AVR300 with half period delays.
+
Author:
Peter Fleury pfleury@gmx.ch http://jump.to/fleury
+
API Usage Example
The following code shows typical usage of this library, see example test_i2cmaster.c
+
 #include <i2cmaster.h>
+
+
+ #define Dev24C02  0xA2      // device address of EEPROM 24C02, see datasheet
+
+ int main(void)
+ {
+     unsigned char ret;
+
+     i2c_init();                             // initialize I2C library
+
+     // write 0x75 to EEPROM address 5 (Byte Write) 
+     i2c_start_wait(Dev24C02+I2C_WRITE);     // set device address and write mode
+     i2c_write(0x05);                        // write address = 5
+     i2c_write(0x75);                        // write value 0x75 to EEPROM
+     i2c_stop();                             // set stop conditon = release bus
+
+
+     // read previously written value back from EEPROM address 5 
+     i2c_start_wait(Dev24C02+I2C_WRITE);     // set device address and write mode
+
+     i2c_write(0x05);                        // write address = 5
+     i2c_rep_start(Dev24C02+I2C_READ);       // set device address and read mode
+
+     ret = i2c_readNak();                    // read one byte from EEPROM
+     i2c_stop();
+
+     for(;;);
+ }
+
+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Defines

#define I2C_READ   1
#define I2C_WRITE   0
+#define i2c_read(ack)   (ack) ? i2c_readAck() : i2c_readNak();

Functions

void i2c_init (void)
 initialize the I2C master interace. Need to be called only once
void i2c_stop (void)
 Terminates the data transfer and releases the I2C bus.
unsigned char i2c_start (unsigned char addr)
 Issues a start condition and sends address and transfer direction.
unsigned char i2c_rep_start (unsigned char addr)
 Issues a repeated start condition and sends address and transfer direction.
void i2c_start_wait (unsigned char addr)
 Issues a start condition and sends address and transfer direction.
unsigned char i2c_write (unsigned char data)
 Send one byte to I2C device.
unsigned char i2c_readAck (void)
 read one byte from the I2C device, request more data from device
unsigned char i2c_readNak (void)
 read one byte from the I2C device, read is followed by a stop condition
unsigned char i2c_read (unsigned char ack)
 read one byte from the I2C device
+


Define Documentation

+

+ + + + +
+ + + + +
#define I2C_READ   1
+
+ + + + + +
+   + + +

+defines the data direction (reading from I2C device) in i2c_start(),i2c_rep_start()

+

+ + + + +
+ + + + +
#define I2C_WRITE   0
+
+ + + + + +
+   + + +

+defines the data direction (writing to I2C device) in i2c_start(),i2c_rep_start()

+


Function Documentation

+

+ + + + +
+ + + + + + + + + +
void i2c_init void   ) 
+
+ + + + + +
+   + + +

+initialize the I2C master interace. Need to be called only once +

+

Parameters:
+ + +
void 
+
+
Returns:
none
+
+

+ + + + +
+ + + + + + + + + +
void i2c_stop void   ) 
+
+ + + + + +
+   + + +

+Terminates the data transfer and releases the I2C bus. +

+

Parameters:
+ + +
void 
+
+
Returns:
none
+
+

+ + + + +
+ + + + + + + + + +
unsigned char i2c_start unsigned char  addr  ) 
+
+ + + + + +
+   + + +

+Issues a start condition and sends address and transfer direction. +

+

Parameters:
+ + +
addr address and transfer direction of I2C device
+
+
Return values:
+ + + +
0 device accessible
1 failed to access device
+
+
+

+ + + + +
+ + + + + + + + + +
unsigned char i2c_rep_start unsigned char  addr  ) 
+
+ + + + + +
+   + + +

+Issues a repeated start condition and sends address and transfer direction. +

+

Parameters:
+ + +
addr address and transfer direction of I2C device
+
+
Return values:
+ + + +
0 device accessible
1 failed to access device
+
+
+

+ + + + +
+ + + + + + + + + +
void i2c_start_wait unsigned char  addr  ) 
+
+ + + + + +
+   + + +

+Issues a start condition and sends address and transfer direction. +

+If device is busy, use ack polling to wait until device ready

Parameters:
+ + +
addr address and transfer direction of I2C device
+
+
Returns:
none
+
+

+ + + + +
+ + + + + + + + + +
unsigned char i2c_write unsigned char  data  ) 
+
+ + + + + +
+   + + +

+Send one byte to I2C device. +

+

Parameters:
+ + +
data byte to be transfered
+
+
Return values:
+ + + +
0 write successful
1 write failed
+
+
+

+ + + + +
+ + + + + + + + + +
unsigned char i2c_readAck void   ) 
+
+ + + + + +
+   + + +

+read one byte from the I2C device, request more data from device +

+

Returns:
byte read from I2C device
+
+

+ + + + +
+ + + + + + + + + +
unsigned char i2c_readNak void   ) 
+
+ + + + + +
+   + + +

+read one byte from the I2C device, read is followed by a stop condition +

+

Returns:
byte read from I2C device
+
+

+ + + + +
+ + + + + + + + + +
unsigned char i2c_read unsigned char  ack  ) 
+
+ + + + + +
+   + + +

+read one byte from the I2C device +

+Implemented as a macro, which calls either i2c_readAck or i2c_readNak

+

Parameters:
+ + +
ack 1 send ack, request more data from device
+ 0 send nak, read is followed by a stop condition
+
+
Returns:
byte read from I2C device
+
+


Generated on Tue Mar 29 16:54:08 2005 for AVR-GCC libraries by  + +doxygen 1.4.1
+ + diff --git a/src/lib-other/peter-fleury/i2cmaster/i2cmaster.S b/src/lib-other/peter-fleury/i2cmaster/i2cmaster.S new file mode 100644 index 0000000..9fb0bca --- /dev/null +++ b/src/lib-other/peter-fleury/i2cmaster/i2cmaster.S @@ -0,0 +1,302 @@ +;************************************************************************* +; Title : I2C (Single) Master Implementation +; Author: Peter Fleury http://jump.to/fleury +; based on Atmel Appl. Note AVR300 +; File: $Id: i2cmaster.S,v 1.12 2008/03/02 08:51:27 peter Exp $ +; Software: AVR-GCC 3.3 or higher +; Target: any AVR device +; +; DESCRIPTION +; Basic routines for communicating with I2C slave devices. This +; "single" master implementation is limited to one bus master on the +; I2C bus. +; +; Based on the Atmel Application Note AVR300, corrected and adapted +; to GNU assembler and AVR-GCC C call interface +; Replaced the incorrect quarter period delays found in AVR300 with +; half period delays. +; +; USAGE +; These routines can be called from C, refere to file i2cmaster.h. +; See example test_i2cmaster.c +; Adapt the SCL and SDA port and pin definitions and eventually +; the delay routine to your target ! +; Use 4.7k pull-up resistor on the SDA and SCL pin. +; +; NOTES +; The I2C routines can be called either from non-interrupt or +; interrupt routines, not both. +; +;************************************************************************* + +#if (__GNUC__ * 100 + __GNUC_MINOR__) < 303 +#error "This library requires AVR-GCC 3.3 or later, update to newer AVR-GCC compiler !" +#endif + + +#include + + + +;***** Adapt these SCA and SCL port and pin definition to your target !! +; +#define SDA 4 // SDA Port D, Pin 4 +#define SCL 5 // SCL Port D, Pin 5 +#define SDA_PORT PORTD // SDA Port D +#define SCL_PORT PORTD // SCL Port D + +;****** + +;-- map the IO register back into the IO address space +#define SDA_DDR (_SFR_IO_ADDR(SDA_PORT) - 1) +#define SCL_DDR (_SFR_IO_ADDR(SCL_PORT) - 1) +#define SDA_OUT _SFR_IO_ADDR(SDA_PORT) +#define SCL_OUT _SFR_IO_ADDR(SCL_PORT) +#define SDA_IN (_SFR_IO_ADDR(SDA_PORT) - 2) +#define SCL_IN (_SFR_IO_ADDR(SCL_PORT) - 2) + + +#ifndef __tmp_reg__ +#define __tmp_reg__ 0 +#endif + + + .section .text + +;************************************************************************* +; delay half period +; For I2C in normal mode (100kHz), use T/2 > 5us +; For I2C in fast mode (400kHz), use T/2 > 1.3us +;************************************************************************* + .stabs "",100,0,0,i2c_delay_T2 + .stabs "i2cmaster.S",100,0,0,i2c_delay_T2 + .func i2c_delay_T2 ; delay 5.0 microsec with 4 Mhz crystal +i2c_delay_T2: ; 4 cycles + rjmp 1f ; 2 " +1: rjmp 2f ; 2 " +2: rjmp 3f ; 2 " +3: rjmp 4f ; 2 " +4: rjmp 5f ; 2 " +5: rjmp 6f ; 2 " +6: nop ; 1 " + ret ; 3 " + .endfunc ; total 20 cyles = 5.0 microsec with 4 Mhz crystal + + +;************************************************************************* +; Initialization of the I2C bus interface. Need to be called only once +; +; extern void i2c_init(void) +;************************************************************************* + .global i2c_init + .func i2c_init +i2c_init: + cbi SDA_DDR,SDA ;release SDA + cbi SCL_DDR,SCL ;release SCL + cbi SDA_OUT,SDA + cbi SCL_OUT,SCL + ret + .endfunc + + +;************************************************************************* +; Issues a start condition and sends address and transfer direction. +; return 0 = device accessible, 1= failed to access device +; +; extern unsigned char i2c_start(unsigned char addr); +; addr = r24, return = r25(=0):r24 +;************************************************************************* + + .global i2c_start + .func i2c_start +i2c_start: + sbi SDA_DDR,SDA ;force SDA low + rcall i2c_delay_T2 ;delay T/2 + + rcall i2c_write ;write address + ret + .endfunc + + +;************************************************************************* +; Issues a repeated start condition and sends address and transfer direction. +; return 0 = device accessible, 1= failed to access device +; +; extern unsigned char i2c_rep_start(unsigned char addr); +; addr = r24, return = r25(=0):r24 +;************************************************************************* + + .global i2c_rep_start + .func i2c_rep_start +i2c_rep_start: + sbi SCL_DDR,SCL ;force SCL low + rcall i2c_delay_T2 ;delay T/2 + cbi SDA_DDR,SDA ;release SDA + rcall i2c_delay_T2 ;delay T/2 + cbi SCL_DDR,SCL ;release SCL + rcall i2c_delay_T2 ;delay T/2 + sbi SDA_DDR,SDA ;force SDA low + rcall i2c_delay_T2 ;delay T/2 + + rcall i2c_write ;write address + ret + .endfunc + + +;************************************************************************* +; Issues a start condition and sends address and transfer direction. +; If device is busy, use ack polling to wait until device is ready +; +; extern void i2c_start_wait(unsigned char addr); +; addr = r24 +;************************************************************************* + + .global i2c_start_wait + .func i2c_start_wait +i2c_start_wait: + mov __tmp_reg__,r24 +i2c_start_wait1: + sbi SDA_DDR,SDA ;force SDA low + rcall i2c_delay_T2 ;delay T/2 + mov r24,__tmp_reg__ + rcall i2c_write ;write address + tst r24 ;if device not busy -> done + breq i2c_start_wait_done + rcall i2c_stop ;terminate write operation + rjmp i2c_start_wait1 ;device busy, poll ack again +i2c_start_wait_done: + ret + .endfunc + + +;************************************************************************* +; Terminates the data transfer and releases the I2C bus +; +; extern void i2c_stop(void) +;************************************************************************* + + .global i2c_stop + .func i2c_stop +i2c_stop: + sbi SCL_DDR,SCL ;force SCL low + sbi SDA_DDR,SDA ;force SDA low + rcall i2c_delay_T2 ;delay T/2 + cbi SCL_DDR,SCL ;release SCL + rcall i2c_delay_T2 ;delay T/2 + cbi SDA_DDR,SDA ;release SDA + rcall i2c_delay_T2 ;delay T/2 + ret + .endfunc + + +;************************************************************************* +; Send one byte to I2C device +; return 0 = write successful, 1 = write failed +; +; extern unsigned char i2c_write( unsigned char data ); +; data = r24, return = r25(=0):r24 +;************************************************************************* + .global i2c_write + .func i2c_write +i2c_write: + sec ;set carry flag + rol r24 ;shift in carry and out bit one + rjmp i2c_write_first +i2c_write_bit: + lsl r24 ;if transmit register empty +i2c_write_first: + breq i2c_get_ack + sbi SCL_DDR,SCL ;force SCL low + brcc i2c_write_low + nop + cbi SDA_DDR,SDA ;release SDA + rjmp i2c_write_high +i2c_write_low: + sbi SDA_DDR,SDA ;force SDA low + rjmp i2c_write_high +i2c_write_high: + rcall i2c_delay_T2 ;delay T/2 + cbi SCL_DDR,SCL ;release SCL + rcall i2c_delay_T2 ;delay T/2 + rjmp i2c_write_bit + +i2c_get_ack: + sbi SCL_DDR,SCL ;force SCL low + cbi SDA_DDR,SDA ;release SDA + rcall i2c_delay_T2 ;delay T/2 + cbi SCL_DDR,SCL ;release SCL +i2c_ack_wait: + sbis SCL_IN,SCL ;wait SCL high (in case wait states are inserted) + rjmp i2c_ack_wait + + clr r24 ;return 0 + sbic SDA_IN,SDA ;if SDA high -> return 1 + ldi r24,1 + rcall i2c_delay_T2 ;delay T/2 + clr r25 + ret + .endfunc + + + +;************************************************************************* +; read one byte from the I2C device, send ack or nak to device +; (ack=1, send ack, request more data from device +; ack=0, send nak, read is followed by a stop condition) +; +; extern unsigned char i2c_read(unsigned char ack); +; ack = r24, return = r25(=0):r24 +; extern unsigned char i2c_readAck(void); +; extern unsigned char i2c_readNak(void); +; return = r25(=0):r24 +;************************************************************************* + .global i2c_readAck + .global i2c_readNak + .global i2c_read + .func i2c_read +i2c_readNak: + clr r24 + rjmp i2c_read +i2c_readAck: + ldi r24,0x01 +i2c_read: + ldi r23,0x01 ;data = 0x01 +i2c_read_bit: + sbi SCL_DDR,SCL ;force SCL low + cbi SDA_DDR,SDA ;release SDA (from previous ACK) + rcall i2c_delay_T2 ;delay T/2 + + cbi SCL_DDR,SCL ;release SCL + rcall i2c_delay_T2 ;delay T/2 + +i2c_read_stretch: + sbis SCL_IN, SCL ;loop until SCL is high (allow slave to stretch SCL) + rjmp i2c_read_stretch + + clc ;clear carry flag + sbic SDA_IN,SDA ;if SDA is high + sec ; set carry flag + + rol r23 ;store bit + brcc i2c_read_bit ;while receive register not full + +i2c_put_ack: + sbi SCL_DDR,SCL ;force SCL low + cpi r24,1 + breq i2c_put_ack_low ;if (ack=0) + cbi SDA_DDR,SDA ; release SDA + rjmp i2c_put_ack_high +i2c_put_ack_low: ;else + sbi SDA_DDR,SDA ; force SDA low +i2c_put_ack_high: + rcall i2c_delay_T2 ;delay T/2 + cbi SCL_DDR,SCL ;release SCL +i2c_put_ack_wait: + sbis SCL_IN,SCL ;wait SCL high + rjmp i2c_put_ack_wait + rcall i2c_delay_T2 ;delay T/2 + mov r24,r23 + clr r25 + ret + .endfunc + diff --git a/src/lib-other/peter-fleury/i2cmaster/i2cmaster.h b/src/lib-other/peter-fleury/i2cmaster/i2cmaster.h new file mode 100644 index 0000000..70f51fd --- /dev/null +++ b/src/lib-other/peter-fleury/i2cmaster/i2cmaster.h @@ -0,0 +1,178 @@ +#ifndef _I2CMASTER_H +#define _I2CMASTER_H 1 +/************************************************************************* +* Title: C include file for the I2C master interface +* (i2cmaster.S or twimaster.c) +* Author: Peter Fleury http://jump.to/fleury +* File: $Id: i2cmaster.h,v 1.10 2005/03/06 22:39:57 Peter Exp $ +* Software: AVR-GCC 3.4.3 / avr-libc 1.2.3 +* Target: any AVR device +* Usage: see Doxygen manual +**************************************************************************/ + +#ifdef DOXYGEN +/** + @defgroup pfleury_ic2master I2C Master library + @code #include @endcode + + @brief I2C (TWI) Master Software Library + + Basic routines for communicating with I2C slave devices. This single master + implementation is limited to one bus master on the I2C bus. + + This I2c library is implemented as a compact assembler software implementation of the I2C protocol + which runs on any AVR (i2cmaster.S) and as a TWI hardware interface for all AVR with built-in TWI hardware (twimaster.c). + Since the API for these two implementations is exactly the same, an application can be linked either against the + software I2C implementation or the hardware I2C implementation. + + Use 4.7k pull-up resistor on the SDA and SCL pin. + + Adapt the SCL and SDA port and pin definitions and eventually the delay routine in the module + i2cmaster.S to your target when using the software I2C implementation ! + + Adjust the CPU clock frequence F_CPU in twimaster.c or in the Makfile when using the TWI hardware implementaion. + + @note + The module i2cmaster.S is based on the Atmel Application Note AVR300, corrected and adapted + to GNU assembler and AVR-GCC C call interface. + Replaced the incorrect quarter period delays found in AVR300 with + half period delays. + + @author Peter Fleury pfleury@gmx.ch http://jump.to/fleury + + @par API Usage Example + The following code shows typical usage of this library, see example test_i2cmaster.c + + @code + + #include + + + #define Dev24C02 0xA2 // device address of EEPROM 24C02, see datasheet + + int main(void) + { + unsigned char ret; + + i2c_init(); // initialize I2C library + + // write 0x75 to EEPROM address 5 (Byte Write) + i2c_start_wait(Dev24C02+I2C_WRITE); // set device address and write mode + i2c_write(0x05); // write address = 5 + i2c_write(0x75); // write value 0x75 to EEPROM + i2c_stop(); // set stop conditon = release bus + + + // read previously written value back from EEPROM address 5 + i2c_start_wait(Dev24C02+I2C_WRITE); // set device address and write mode + + i2c_write(0x05); // write address = 5 + i2c_rep_start(Dev24C02+I2C_READ); // set device address and read mode + + ret = i2c_readNak(); // read one byte from EEPROM + i2c_stop(); + + for(;;); + } + @endcode + +*/ +#endif /* DOXYGEN */ + +/**@{*/ + +#if (__GNUC__ * 100 + __GNUC_MINOR__) < 304 +#error "This library requires AVR-GCC 3.4 or later, update to newer AVR-GCC compiler !" +#endif + +#include + +/** defines the data direction (reading from I2C device) in i2c_start(),i2c_rep_start() */ +#define I2C_READ 1 + +/** defines the data direction (writing to I2C device) in i2c_start(),i2c_rep_start() */ +#define I2C_WRITE 0 + + +/** + @brief initialize the I2C master interace. Need to be called only once + @param void + @return none + */ +extern void i2c_init(void); + + +/** + @brief Terminates the data transfer and releases the I2C bus + @param void + @return none + */ +extern void i2c_stop(void); + + +/** + @brief Issues a start condition and sends address and transfer direction + + @param addr address and transfer direction of I2C device + @retval 0 device accessible + @retval 1 failed to access device + */ +extern unsigned char i2c_start(unsigned char addr); + + +/** + @brief Issues a repeated start condition and sends address and transfer direction + + @param addr address and transfer direction of I2C device + @retval 0 device accessible + @retval 1 failed to access device + */ +extern unsigned char i2c_rep_start(unsigned char addr); + + +/** + @brief Issues a start condition and sends address and transfer direction + + If device is busy, use ack polling to wait until device ready + @param addr address and transfer direction of I2C device + @return none + */ +extern void i2c_start_wait(unsigned char addr); + + +/** + @brief Send one byte to I2C device + @param data byte to be transfered + @retval 0 write successful + @retval 1 write failed + */ +extern unsigned char i2c_write(unsigned char data); + + +/** + @brief read one byte from the I2C device, request more data from device + @return byte read from I2C device + */ +extern unsigned char i2c_readAck(void); + +/** + @brief read one byte from the I2C device, read is followed by a stop condition + @return byte read from I2C device + */ +extern unsigned char i2c_readNak(void); + +/** + @brief read one byte from the I2C device + + Implemented as a macro, which calls either i2c_readAck or i2c_readNak + + @param ack 1 send ack, request more data from device
+ 0 send nak, read is followed by a stop condition + @return byte read from I2C device + */ +extern unsigned char i2c_read(unsigned char ack); +#define i2c_read(ack) (ack) ? i2c_readAck() : i2c_readNak(); + + +/**@}*/ +#endif diff --git a/src/lib-other/peter-fleury/i2cmaster/makefile b/src/lib-other/peter-fleury/i2cmaster/makefile new file mode 100644 index 0000000..c8206b8 --- /dev/null +++ b/src/lib-other/peter-fleury/i2cmaster/makefile @@ -0,0 +1,392 @@ +# Makefile to compile and link the I2C Master library and test program +# +# based on +# WinAVR Sample makefile written by Eric B. Weddington, Jörg Wunsch, et al. +# +# Note: +# The warnings which appear while converting ELF to AVR Extended COFF (make extcoff) +# can be ignored +# +# +# On command line: +# +# make all = Make software. +# +# make clean = Clean out built project files. +# +# make coff = Convert ELF to AVR COFF (for use with AVR Studio 3.x or VMLAB). +# +# make extcoff = Convert ELF to AVR Extended COFF (for use with AVR Studio +# 4.07 or greater). +# +# make program = Download the hex file to the device, using avrdude. Please +# customize the avrdude settings below first! +# +# make filename.s = Just compile filename.c into the assembler code only +# +# To rebuild project do "make clean" then "make all". +# + + +# MCU name +MCU = at90s8515 + +# Output format. (can be srec, ihex, binary) +FORMAT = ihex + +# Optimization level, can be [0, 1, 2, 3, s]. 0 turns off optimization. +# (Note: 3 is not always the best optimization level. See avr-libc FAQ.) +OPT = s + + +# Target file name (without extension). +TARGET = test_i2cmaster + + +# List C source files here. (C dependencies are automatically generated.) +SRC = $(TARGET).c + +# 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 = i2cmaster.S + + +# List any extra directories to look for include files here. +# Each directory must be seperated by a space. +EXTRAINCDIRS = + + +# Optional compiler flags. +# -g: generate debugging information (for GDB, or for COFF conversion) +# -O*: optimization level +# -f...: tuning, see gcc manual and avr-libc documentation +# -Wall...: warning level +# -Wa,...: tell GCC to pass this to the assembler. +# -ahlms: create assembler listing +CFLAGS = -g -O$(OPT) \ +-funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums \ +-Wall -Wstrict-prototypes \ +-Wa,-adhlns=$(<:.c=.lst) \ +$(patsubst %,-I%,$(EXTRAINCDIRS)) + + +# Set a "language standard" compiler flag. +# Unremark just one line below to set the language standard to use. +# gnu99 = C99 + GNU extensions. See GCC manual for more information. +#CFLAGS += -std=c89 +#CFLAGS += -std=gnu89 +#CFLAGS += -std=c99 +CFLAGS += -std=gnu99 + + + +# Optional assembler flags. +# -Wa,...: tell GCC to pass this to the assembler. +# -ahlms: 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] +ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs + + + +# Optional linker flags. +# -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 + + + +# Additional libraries + +# Minimalistic printf version +#LDFLAGS += -Wl,-u,vfprintf -lprintf_min + +# Floating point printf version (requires -lm below) +#LDFLAGS += -Wl,-u,vfprintf -lprintf_flt + +# -lm = math library +LDFLAGS += -lm + + + + +# Programming support using avrdude. Settings and variables. + +# 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 = stk500 + + +AVRDUDE_PORT = com1 # programmer connected to serial device +#AVRDUDE_PORT = lpt1 # programmer connected to parallel port + +AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex +#AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep + +AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) + +# 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 += -y + +# Uncomment the following if you do /not/ wish a verification to be +# performed after programming the device. +#AVRDUDE_FLAGS += -V + +# Increase verbosity level. Please use this when submitting bug +# reports about avrdude. See +# to submit bug reports. +#AVRDUDE_FLAGS += -v -v + + + + +# --------------------------------------------------------------------------- + +# Define directories, if needed. +DIRAVR = c:/winavr +DIRAVRBIN = $(DIRAVR)/bin +DIRAVRUTILS = $(DIRAVR)/utils/bin +DIRINC = . +DIRLIB = $(DIRAVR)/avr/lib + + +# Define programs and commands. +SHELL = sh + +CC = avr-gcc + +OBJCOPY = avr-objcopy +OBJDUMP = avr-objdump +SIZE = avr-size + + +# Programming support using avrdude. +AVRDUDE = avrdude + + +REMOVE = rm -f +COPY = cp + +HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex +ELFSIZE = $(SIZE) -A $(TARGET).elf + + + +# 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: +MSG_ASSEMBLING = Assembling: +MSG_CLEANING = Cleaning project: + + + + +# Define all object files. +OBJ = $(SRC:.c=.o) $(ASRC:.S=.o) + +# Define all listing files. +LST = $(ASRC:.S=.lst) $(SRC:.c=.lst) + +# Combine all necessary flags and optional flags. +# Add target processor to flags. +ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) +ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS) + + + +# Default target. +all: begin gccversion sizebefore $(TARGET).elf $(TARGET).hex $(TARGET).eep \ + $(TARGET).lss $(TARGET).sym sizeafter finished end + + +# 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) + +finished: + @echo $(MSG_ERRORS_NONE) + +end: + @echo $(MSG_END) + @echo + + +# Display size of file. +sizebefore: + @if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); echo; fi + +sizeafter: + @if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); echo; fi + + + +# Display compiler version information. +gccversion : + @$(CC) --version + + + + +# Convert ELF to COFF for use in debugging / simulating in +# AVR Studio or VMLAB. +COFFCONVERT=$(OBJCOPY) --debugging \ + --change-section-address .data-0x800000 \ + --change-section-address .bss-0x800000 \ + --change-section-address .noinit-0x800000 \ + --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 + + + + +# Program the device. +program: $(TARGET).hex $(TARGET).eep + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM) + + + + +# Create final output files (.hex, .eep) from ELF output file. +%.hex: %.elf + @echo + @echo $(MSG_FLASH) $@ + $(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@ + +%.eep: %.elf + @echo + @echo $(MSG_EEPROM) $@ + -$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \ + --change-section-lma .eeprom=0 -O $(FORMAT) $< $@ + +# 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) $@ + avr-nm -n $< > $@ + + + +# Link: create ELF output file from object files. +.SECONDARY : $(TARGET).elf +.PRECIOUS : $(OBJ) +%.elf: $(OBJ) + @echo + @echo $(MSG_LINKING) $@ + $(CC) $(ALL_CFLAGS) $(OBJ) --output $@ $(LDFLAGS) + + +# Compile: create object files from C source files. +%.o : %.c + @echo + @echo $(MSG_COMPILING) $< + $(CC) -c $(ALL_CFLAGS) $< -o $@ + + +# Compile: create assembler files from C source files. +%.s : %.c + $(CC) -S $(ALL_CFLAGS) $< -o $@ + + +# Assemble: create object files from assembler source files. +%.o : %.S + @echo + @echo $(MSG_ASSEMBLING) $< + $(CC) -c $(ALL_ASFLAGS) $< -o $@ + + + + + + +# Target: clean project. +clean: begin clean_list finished end + +clean_list : + @echo + @echo $(MSG_CLEANING) + $(REMOVE) $(TARGET).hex + $(REMOVE) $(TARGET).eep + $(REMOVE) $(TARGET).obj + $(REMOVE) $(TARGET).cof + $(REMOVE) $(TARGET).elf + $(REMOVE) $(TARGET).map + $(REMOVE) $(TARGET).obj + $(REMOVE) $(TARGET).a90 + $(REMOVE) $(TARGET).sym + $(REMOVE) $(TARGET).lnk + $(REMOVE) $(TARGET).lss + $(REMOVE) $(OBJ) + $(REMOVE) $(LST) + $(REMOVE) $(SRC:.c=.s) + $(REMOVE) $(SRC:.c=.d) + + +# Automatically generate C source code dependencies. +# (Code originally taken from the GNU make user manual and modified +# (See README.txt Credits).) +# +# Note that this will work with sh (bash) and sed that is shipped with WinAVR +# (see the SHELL variable defined above). +# This may not work with other shells or other seds. +# +%.d: %.c + set -e; $(CC) -MM $(ALL_CFLAGS) $< \ + | sed 's,\(.*\)\.o[ :]*,\1.o \1.d : ,g' > $@; \ + [ -s $@ ] || rm -f $@ + + +# Remove the '-' if you want to see the dependency files generated. +-include $(SRC:.c=.d) + + + +# Listing of phony targets. +.PHONY : all begin finish end sizebefore sizeafter gccversion coff extcoff \ + clean clean_list program + diff --git a/src/lib-other/peter-fleury/i2cmaster/makefile.i2cmaster b/src/lib-other/peter-fleury/i2cmaster/makefile.i2cmaster new file mode 100644 index 0000000..c8206b8 --- /dev/null +++ b/src/lib-other/peter-fleury/i2cmaster/makefile.i2cmaster @@ -0,0 +1,392 @@ +# Makefile to compile and link the I2C Master library and test program +# +# based on +# WinAVR Sample makefile written by Eric B. Weddington, Jörg Wunsch, et al. +# +# Note: +# The warnings which appear while converting ELF to AVR Extended COFF (make extcoff) +# can be ignored +# +# +# On command line: +# +# make all = Make software. +# +# make clean = Clean out built project files. +# +# make coff = Convert ELF to AVR COFF (for use with AVR Studio 3.x or VMLAB). +# +# make extcoff = Convert ELF to AVR Extended COFF (for use with AVR Studio +# 4.07 or greater). +# +# make program = Download the hex file to the device, using avrdude. Please +# customize the avrdude settings below first! +# +# make filename.s = Just compile filename.c into the assembler code only +# +# To rebuild project do "make clean" then "make all". +# + + +# MCU name +MCU = at90s8515 + +# Output format. (can be srec, ihex, binary) +FORMAT = ihex + +# Optimization level, can be [0, 1, 2, 3, s]. 0 turns off optimization. +# (Note: 3 is not always the best optimization level. See avr-libc FAQ.) +OPT = s + + +# Target file name (without extension). +TARGET = test_i2cmaster + + +# List C source files here. (C dependencies are automatically generated.) +SRC = $(TARGET).c + +# 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 = i2cmaster.S + + +# List any extra directories to look for include files here. +# Each directory must be seperated by a space. +EXTRAINCDIRS = + + +# Optional compiler flags. +# -g: generate debugging information (for GDB, or for COFF conversion) +# -O*: optimization level +# -f...: tuning, see gcc manual and avr-libc documentation +# -Wall...: warning level +# -Wa,...: tell GCC to pass this to the assembler. +# -ahlms: create assembler listing +CFLAGS = -g -O$(OPT) \ +-funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums \ +-Wall -Wstrict-prototypes \ +-Wa,-adhlns=$(<:.c=.lst) \ +$(patsubst %,-I%,$(EXTRAINCDIRS)) + + +# Set a "language standard" compiler flag. +# Unremark just one line below to set the language standard to use. +# gnu99 = C99 + GNU extensions. See GCC manual for more information. +#CFLAGS += -std=c89 +#CFLAGS += -std=gnu89 +#CFLAGS += -std=c99 +CFLAGS += -std=gnu99 + + + +# Optional assembler flags. +# -Wa,...: tell GCC to pass this to the assembler. +# -ahlms: 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] +ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs + + + +# Optional linker flags. +# -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 + + + +# Additional libraries + +# Minimalistic printf version +#LDFLAGS += -Wl,-u,vfprintf -lprintf_min + +# Floating point printf version (requires -lm below) +#LDFLAGS += -Wl,-u,vfprintf -lprintf_flt + +# -lm = math library +LDFLAGS += -lm + + + + +# Programming support using avrdude. Settings and variables. + +# 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 = stk500 + + +AVRDUDE_PORT = com1 # programmer connected to serial device +#AVRDUDE_PORT = lpt1 # programmer connected to parallel port + +AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex +#AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep + +AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) + +# 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 += -y + +# Uncomment the following if you do /not/ wish a verification to be +# performed after programming the device. +#AVRDUDE_FLAGS += -V + +# Increase verbosity level. Please use this when submitting bug +# reports about avrdude. See +# to submit bug reports. +#AVRDUDE_FLAGS += -v -v + + + + +# --------------------------------------------------------------------------- + +# Define directories, if needed. +DIRAVR = c:/winavr +DIRAVRBIN = $(DIRAVR)/bin +DIRAVRUTILS = $(DIRAVR)/utils/bin +DIRINC = . +DIRLIB = $(DIRAVR)/avr/lib + + +# Define programs and commands. +SHELL = sh + +CC = avr-gcc + +OBJCOPY = avr-objcopy +OBJDUMP = avr-objdump +SIZE = avr-size + + +# Programming support using avrdude. +AVRDUDE = avrdude + + +REMOVE = rm -f +COPY = cp + +HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex +ELFSIZE = $(SIZE) -A $(TARGET).elf + + + +# 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: +MSG_ASSEMBLING = Assembling: +MSG_CLEANING = Cleaning project: + + + + +# Define all object files. +OBJ = $(SRC:.c=.o) $(ASRC:.S=.o) + +# Define all listing files. +LST = $(ASRC:.S=.lst) $(SRC:.c=.lst) + +# Combine all necessary flags and optional flags. +# Add target processor to flags. +ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) +ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS) + + + +# Default target. +all: begin gccversion sizebefore $(TARGET).elf $(TARGET).hex $(TARGET).eep \ + $(TARGET).lss $(TARGET).sym sizeafter finished end + + +# 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) + +finished: + @echo $(MSG_ERRORS_NONE) + +end: + @echo $(MSG_END) + @echo + + +# Display size of file. +sizebefore: + @if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); echo; fi + +sizeafter: + @if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); echo; fi + + + +# Display compiler version information. +gccversion : + @$(CC) --version + + + + +# Convert ELF to COFF for use in debugging / simulating in +# AVR Studio or VMLAB. +COFFCONVERT=$(OBJCOPY) --debugging \ + --change-section-address .data-0x800000 \ + --change-section-address .bss-0x800000 \ + --change-section-address .noinit-0x800000 \ + --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 + + + + +# Program the device. +program: $(TARGET).hex $(TARGET).eep + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM) + + + + +# Create final output files (.hex, .eep) from ELF output file. +%.hex: %.elf + @echo + @echo $(MSG_FLASH) $@ + $(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@ + +%.eep: %.elf + @echo + @echo $(MSG_EEPROM) $@ + -$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \ + --change-section-lma .eeprom=0 -O $(FORMAT) $< $@ + +# 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) $@ + avr-nm -n $< > $@ + + + +# Link: create ELF output file from object files. +.SECONDARY : $(TARGET).elf +.PRECIOUS : $(OBJ) +%.elf: $(OBJ) + @echo + @echo $(MSG_LINKING) $@ + $(CC) $(ALL_CFLAGS) $(OBJ) --output $@ $(LDFLAGS) + + +# Compile: create object files from C source files. +%.o : %.c + @echo + @echo $(MSG_COMPILING) $< + $(CC) -c $(ALL_CFLAGS) $< -o $@ + + +# Compile: create assembler files from C source files. +%.s : %.c + $(CC) -S $(ALL_CFLAGS) $< -o $@ + + +# Assemble: create object files from assembler source files. +%.o : %.S + @echo + @echo $(MSG_ASSEMBLING) $< + $(CC) -c $(ALL_ASFLAGS) $< -o $@ + + + + + + +# Target: clean project. +clean: begin clean_list finished end + +clean_list : + @echo + @echo $(MSG_CLEANING) + $(REMOVE) $(TARGET).hex + $(REMOVE) $(TARGET).eep + $(REMOVE) $(TARGET).obj + $(REMOVE) $(TARGET).cof + $(REMOVE) $(TARGET).elf + $(REMOVE) $(TARGET).map + $(REMOVE) $(TARGET).obj + $(REMOVE) $(TARGET).a90 + $(REMOVE) $(TARGET).sym + $(REMOVE) $(TARGET).lnk + $(REMOVE) $(TARGET).lss + $(REMOVE) $(OBJ) + $(REMOVE) $(LST) + $(REMOVE) $(SRC:.c=.s) + $(REMOVE) $(SRC:.c=.d) + + +# Automatically generate C source code dependencies. +# (Code originally taken from the GNU make user manual and modified +# (See README.txt Credits).) +# +# Note that this will work with sh (bash) and sed that is shipped with WinAVR +# (see the SHELL variable defined above). +# This may not work with other shells or other seds. +# +%.d: %.c + set -e; $(CC) -MM $(ALL_CFLAGS) $< \ + | sed 's,\(.*\)\.o[ :]*,\1.o \1.d : ,g' > $@; \ + [ -s $@ ] || rm -f $@ + + +# Remove the '-' if you want to see the dependency files generated. +-include $(SRC:.c=.d) + + + +# Listing of phony targets. +.PHONY : all begin finish end sizebefore sizeafter gccversion coff extcoff \ + clean clean_list program + diff --git a/src/lib-other/peter-fleury/i2cmaster/makefile.twimaster b/src/lib-other/peter-fleury/i2cmaster/makefile.twimaster new file mode 100644 index 0000000..593ca45 --- /dev/null +++ b/src/lib-other/peter-fleury/i2cmaster/makefile.twimaster @@ -0,0 +1,502 @@ +# ---------------------------------------------------------------------------- +# Makefile to compile and link the TWImaster library and test program +# Author: Peter Fleury +# File: $Id: makefile.twimaster,v 1.1 2005/03/29 14:50:05 Peter Exp $ +# based on WinAVR Makefile Template written by Eric B. Weddington, Jörg Wunsch, et al. +# +# Adjust F_CPU below to the clock frequency in Mhz of your AVR target +# +# rename this file to "makefile" or invoke with "make -f makefile.twimaster" +# +#---------------------------------------------------------------------------- +# 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 = atmega8 + + +# Processor frequency. +# This will define a symbol, F_CPU, in all source code files equal to the +# processor frequency. You can then use this symbol in your source code to +# calculate timings. Do NOT tack on a 'UL' at the end, this will be done +# automatically to create a 32-bit value in your source code. +F_CPU = 4000000 + + +# Output format. (can be srec, ihex, binary) +FORMAT = ihex + + +# Target file name (without extension). +TARGET = test_i2cmaster + + +# List C source files here. (C dependencies are automatically generated.) +SRC = $(TARGET).c twimaster.c + + +# 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 +CDEFS = -DF_CPU=$(F_CPU)UL + + +# Place -I options here +CINCS = + + + +#---------------- Compiler Options ---------------- +# -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) $(CINCS) +CFLAGS += -O$(OPT) +CFLAGS += -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums +CFLAGS += -Wall -Wstrict-prototypes +CFLAGS += -Wa,-adhlns=$(<:.c=.lst) +CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS)) +CFLAGS += $(CSTANDARD) + + +#---------------- Assembler Options ---------------- +# -Wa,...: tell GCC to pass this to the assembler. +# -ahlms: 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] +ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs + + +#---------------- 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 + + + +#---------------- 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,--defsym=__heap_start=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 += $(PRINTF_LIB) $(SCANF_LIB) $(MATH_LIB) + + + +#---------------- 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 = stk500 + +# com1 = serial port. Use lpt1 to connect to parallel port. +AVRDUDE_PORT = com1 # programmer connected to serial device + +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 +# to submit bug reports. +#AVRDUDE_VERBOSE = -v -v + +AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) +AVRDUDE_FLAGS += $(AVRDUDE_NO_VERIFY) +AVRDUDE_FLAGS += $(AVRDUDE_VERBOSE) +AVRDUDE_FLAGS += $(AVRDUDE_ERASE_COUNTER) + + + +#---------------- Debugging Options ---------------- + +# For simulavr only - target MCU frequency. +DEBUG_MFREQ = $(F_CPU) + +# Set the DEBUG_UI to either gdb or insight. +# DEBUG_UI = gdb +DEBUG_UI = insight + +# Set the debugging back-end to either avarice, simulavr. +DEBUG_BACKEND = avarice +#DEBUG_BACKEND = simulavr + +# GDB Init Filename. +GDBINIT_FILE = __avr_gdbinit + +# When using avarice settings for the JTAG +JTAG_DEV = /dev/com1 + +# Debugging port used to communicate between GDB / avarice / simulavr. +DEBUG_PORT = 4242 + +# Debugging host used to communicate between GDB / avarice / simulavr, normally +# just set to localhost unless doing some sort of crazy debugging when +# avarice is running on a different computer. +DEBUG_HOST = localhost + + + +#============================================================================ + + +# Define programs and commands. +SHELL = sh +CC = avr-gcc +OBJCOPY = avr-objcopy +OBJDUMP = avr-objdump +SIZE = avr-size +NM = avr-nm +AVRDUDE = avrdude +REMOVE = rm -f +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: +MSG_ASSEMBLING = Assembling: +MSG_CLEANING = Cleaning project: + + + + +# Define all object files. +OBJ = $(SRC:.c=.o) $(ASRC:.S=.o) + +# Define all listing files. +LST = $(SRC:.c=.lst) $(ASRC:.S=.lst) + + +# Compiler flags to generate dependency files. +GENDEPFLAGS = -MD -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_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS) + + + + + +# Default target. +all: begin gccversion sizebefore build sizeafter end + +build: elf hex eep lss sym + +elf: $(TARGET).elf +hex: $(TARGET).hex +eep: $(TARGET).eep +lss: $(TARGET).lss +sym: $(TARGET).sym + + + +# 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) -A $(TARGET).elf +AVRMEM = avr-mem.sh $(TARGET).elf $(MCU) + +sizebefore: + @if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); \ + $(AVRMEM) 2>/dev/null; echo; fi + +sizeafter: + @if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); \ + $(AVRMEM) 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 \ +--change-section-address .data-0x800000 \ +--change-section-address .bss-0x800000 \ +--change-section-address .noinit-0x800000 \ +--change-section-address .eeprom-0x810000 + + +coff: $(TARGET).elf + @echo + @echo $(MSG_COFF) $(TARGET).cof + $(COFFCONVERT) -O coff-avr $< $(TARGET).cof + + +extcoff: $(TARGET).elf + @echo + @echo $(MSG_EXTENDED_COFF) $(TARGET).cof + $(COFFCONVERT) -O coff-ext-avr $< $(TARGET).cof + + + +# Create final output files (.hex, .eep) from ELF output file. +%.hex: %.elf + @echo + @echo $(MSG_FLASH) $@ + $(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@ + +%.eep: %.elf + @echo + @echo $(MSG_EEPROM) $@ + -$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \ + --change-section-lma .eeprom=0 -O $(FORMAT) $< $@ + +# 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 $< > $@ + + + +# 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. +%.o : %.c + @echo + @echo $(MSG_COMPILING) $< + $(CC) -c $(ALL_CFLAGS) $< -o $@ + + +# Compile: create assembler files from C source files. +%.s : %.c + $(CC) -S $(ALL_CFLAGS) $< -o $@ + + +# Assemble: create object files from assembler source files. +%.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) $(OBJ) + $(REMOVE) $(LST) + $(REMOVE) $(SRC:.c=.s) + $(REMOVE) $(SRC:.c=.d) + $(REMOVE) .dep/* + + + +# 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 + diff --git a/src/lib-other/peter-fleury/i2cmaster/test_i2cmaster.c b/src/lib-other/peter-fleury/i2cmaster/test_i2cmaster.c new file mode 100644 index 0000000..fdeda29 --- /dev/null +++ b/src/lib-other/peter-fleury/i2cmaster/test_i2cmaster.c @@ -0,0 +1,78 @@ +/**************************************************************************** +Title: Access serial EEPROM 24C02 using I2C interace +Author: Peter Fleury http://jump.to/fleury +File: $Id: test_i2cmaster.c,v 1.2 2003/12/06 17:07:18 peter Exp $ +Software: AVR-GCC 3.3 +Hardware: AT90S8515 at 4 Mhz, any AVR device can be used + +Description: + This example shows how the I2C library i2cmaster.S can be used to + access a serial eeprom. + Based on Atmel Application Note AVR300, adapted to AVR-GCC C interface + +*****************************************************************************/ +#include +#include "i2cmaster.h" + + +#define Dev24C02 0xA2 // device address of EEPROM 24C02, see datasheet + + +int main(void) +{ + unsigned char ret; + + + DDRB = 0xff; // use all pins on port B for output + PORTB = 0xff; // (active low LED's ) + + i2c_init(); // init I2C interface + + /* write 0x75 to eeprom address 0x05 (Byte Write) */ + ret = i2c_start(Dev24C02+I2C_WRITE); // set device address and write mode + if ( ret ) { + /* failed to issue start condition, possibly no device found */ + i2c_stop(); + PORTB=0x00; // activate all 8 LED to show error */ + }else { + /* issuing start condition ok, device accessible */ + i2c_write(0x05); // write address = 5 + i2c_write(0x75); // ret=0 -> Ok, ret=1 -> no ACK + i2c_stop(); // set stop conditon = release bus + + /* write ok, read value back from eeprom address 0x05, wait until + the device is no longer busy from the previous write operation */ + i2c_start_wait(Dev24C02+I2C_WRITE); // set device address and write mode + i2c_write(0x05); // write address = 5 + i2c_rep_start(Dev24C02+I2C_READ); // set device address and read mode + ret = i2c_readNak(); // read one byte + i2c_stop(); + + PORTB = ~ret; // output byte on the LED's + + /* write 0x70,0x71,072,073 to eeprom address 0x00..0x03 (Page Write), + wait until the device is no longer busy from the previous write operation */ + i2c_start_wait(Dev24C02+I2C_WRITE); // set device address and write mode + i2c_write(0x00); // write start address = 0 + i2c_write(0x70); // write data to address 0 + i2c_write(0x71); // " " " " 1 + i2c_write(0x72); // " " " " 2 + i2c_write(0x74); // " " " " 3 + i2c_stop(); // set stop conditon = release bus + + /* write ok, read value back from eeprom address 0..3 (Sequencial Read), + wait until the device is no longer busy from the previous write operation */ + i2c_start_wait(Dev24C02+I2C_WRITE); // set device address and write mode + i2c_write(0x00); // write address = 0 + i2c_rep_start(Dev24C02+I2C_READ); // set device address and read mode + ret = i2c_readAck(); // read one byte form address 0 + ret = i2c_readAck(); // " " " " " 1 + ret = i2c_readAck(); // " " " " " 2 + ret = i2c_readNak(); // " " " " " 3 + i2c_stop(); // set stop condition = release bus + + PORTB = ~ret; // output byte on the LED's + } + + for(;;); +} diff --git a/src/lib-other/peter-fleury/i2cmaster/twimaster.c b/src/lib-other/peter-fleury/i2cmaster/twimaster.c new file mode 100644 index 0000000..a3744ba --- /dev/null +++ b/src/lib-other/peter-fleury/i2cmaster/twimaster.c @@ -0,0 +1,202 @@ +/************************************************************************* +* Title: I2C master library using hardware TWI interface +* Author: Peter Fleury http://jump.to/fleury +* File: $Id: twimaster.c,v 1.3 2005/07/02 11:14:21 Peter Exp $ +* Software: AVR-GCC 3.4.3 / avr-libc 1.2.3 +* Target: any AVR device with hardware TWI +* Usage: API compatible with I2C Software Library i2cmaster.h +**************************************************************************/ +#include +#include + +#include "i2cmaster.h" + + +/* define CPU frequency in Mhz here if not defined in Makefile */ +#ifndef F_CPU +#define F_CPU 4000000UL +#endif + +/* I2C clock in Hz */ +#define SCL_CLOCK 400000 // previously set to 100000L ::2012, Ben Blazak:: + + +/************************************************************************* + Initialization of the I2C bus interface. Need to be called only once +*************************************************************************/ +void i2c_init(void) +{ + /* initialize TWI clock: 100 kHz clock, TWPS = 0 => prescaler = 1 */ + + TWSR = 0; /* no prescaler */ + TWBR = ((F_CPU/SCL_CLOCK)-16)/2; /* must be > 10 for stable operation */ + +}/* i2c_init */ + + +/************************************************************************* + Issues a start condition and sends address and transfer direction. + return 0 = device accessible, 1= failed to access device +*************************************************************************/ +unsigned char i2c_start(unsigned char address) +{ + uint8_t twst; + + // send START condition + TWCR = (1<. Modified slightly to work -# with . -#---------------------------------------------------------------------------- -#---------------------------------------------------------------------------- # WinAVR Makefile Template written by Eric B. Weddington, Jörg Wunsch, et al. # # Released to the Public Domain @@ -46,11 +41,13 @@ # Target file name (without extension). -TARGET = ergodox-firmware +TARGET = blinky # List C source files here. (C dependencies are automatically generated.) -SRC = $(TARGET).c +SRC = $(TARGET).c \ + usb_debug_only.c \ + print.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 diff --git a/src/lib-other/pjrc/blinky/blinky.c b/src/lib-other/pjrc/blinky/blinky.c new file mode 100644 index 0000000..b9a8da8 --- /dev/null +++ b/src/lib-other/pjrc/blinky/blinky.c @@ -0,0 +1,159 @@ +/* LED Blink Example with USB Debug Channel for Teensy USB Development Board + * http://www.pjrc.com/teensy/ + * Copyright (c) 2008, 2010 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. + */ + +#include +#include +#include +#include "usb_debug_only.h" +#include "print.h" + + +// Teensy 2.0: LED is active high +#if defined(__AVR_ATmega32U4__) || defined(__AVR_AT90USB1286__) +#define LED_ON (PORTD |= (1<<6)) +#define LED_OFF (PORTD &= ~(1<<6)) + +// Teensy 1.0: LED is active low +#else +#define LED_ON (PORTD &= ~(1<<6)) +#define LED_OFF (PORTD |= (1<<6)) +#endif + +#define LED_CONFIG (DDRD |= (1<<6)) +#define CPU_PRESCALE(n) (CLKPR = 0x80, CLKPR = (n)) +#define DIT 80 /* unit time for morse code */ + +void morse_character(char c); +void morse_P(const char *s); +const unsigned char morse_code_table[]; + + +int main(void) +{ + unsigned char i; + + // set for 16 MHz clock, and make sure the LED is off + CPU_PRESCALE(0); + LED_CONFIG; + LED_OFF; + + // initialize the USB, but don't want for the host to + // configure. The first several messages sent will be + // lost because the PC hasn't configured the USB yet, + // but we care more about blinking than debug messages! + usb_init(); + + // blink morse code messages! + while (1) { + for (i=0; i<6; i++) { + morse_P(PSTR("SOS")); + _delay_ms(1500); + } + morse_P(PSTR("DOES ANYBODY STILL KNOW MORSE CODE?")); + _delay_ms(4000); + } +} + +// blink a single character in Morse code +void morse_character(char c) +{ + unsigned char code, count; + + if (c == ' ') { + print("Space\n"); + _delay_ms(DIT * 7); + return; + } + if (c < 'A' || c > 'Z') { + print("Opps, unsupported character: "); + pchar(c); + print("\n"); + return; + } + print("Char "); + pchar(c); + pchar(':'); + code = pgm_read_byte(morse_code_table + (c - 'A')); + for (count = code & 0x07; count > 0; count--) { + LED_ON; + if (code & 0x80) { + print(" dah"); + _delay_ms(DIT * 3); + } else { + print(" dit"); + _delay_ms(DIT); + } + LED_OFF; + _delay_ms(DIT); + code = code << 1; + } + print("\n"); + _delay_ms(DIT * 2); +} + +// blink an entire message in Morse code +// the string must be in flash memory (using PSTR macro) +void morse_P(const char *s) +{ + char c; + + while (1) { + c = pgm_read_byte(s++); + if (!c) break; + morse_character(c); + } + print("\n"); +} + +// lookup table for all 26 letters. Upper 5 bits are the pulses +// to send (MSB first), and the lower 3 bits are the number of +// bits to send for this letter. +const unsigned char PROGMEM morse_code_table[] = { + 0x40 + 2, // A: .- + 0x80 + 4, // B: -... + 0xA0 + 4, // C: -.-. + 0x80 + 3, // D: -.. + 0x00 + 1, // E: . + 0x20 + 4, // F: ..-. + 0xC0 + 3, // G: --. + 0x00 + 4, // H: .... + 0x00 + 2, // I: .. + 0x70 + 4, // J: .--- + 0xA0 + 3, // K: -.- + 0x40 + 4, // L: .-.. + 0xC0 + 2, // M: -- + 0x80 + 2, // N: -. + 0xE0 + 3, // O: --- + 0x60 + 4, // P: .--. + 0xD0 + 4, // Q: --.- + 0x40 + 3, // R: .-. + 0x00 + 3, // S: ... + 0x80 + 1, // T: - + 0x20 + 3, // U: ..- + 0x10 + 4, // V: ...- + 0x60 + 3, // W: .-- + 0x90 + 4, // X: -..- + 0xB0 + 4, // Y: -.-- + 0xC0 + 4 // Z: --.. +}; + diff --git a/src/lib/pjrc/print.c b/src/lib-other/pjrc/blinky/print.c similarity index 100% rename from src/lib/pjrc/print.c rename to src/lib-other/pjrc/blinky/print.c diff --git a/src/lib/pjrc/print.h b/src/lib-other/pjrc/blinky/print.h similarity index 100% rename from src/lib/pjrc/print.h rename to src/lib-other/pjrc/blinky/print.h diff --git a/src/lib/pjrc/usb_debug_only.c b/src/lib-other/pjrc/blinky/usb_debug_only.c similarity index 100% rename from src/lib/pjrc/usb_debug_only.c rename to src/lib-other/pjrc/blinky/usb_debug_only.c diff --git a/src/lib/pjrc/usb_debug_only.h b/src/lib-other/pjrc/blinky/usb_debug_only.h similarity index 100% rename from src/lib/pjrc/usb_debug_only.h rename to src/lib-other/pjrc/blinky/usb_debug_only.h diff --git a/src/lib-other/pjrc/usb_keyboard/Makefile b/src/lib-other/pjrc/usb_keyboard/Makefile new file mode 100644 index 0000000..1ef8689 --- /dev/null +++ b/src/lib-other/pjrc/usb_keyboard/Makefile @@ -0,0 +1,614 @@ +# 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 = example + + +# List C source files here. (C dependencies are automatically generated.) +SRC = $(TARGET).c \ + usb_keyboard.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 + + + +#---------------- 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. +AVRDUDE_PORT = com1 # programmer connected to serial device + +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 +# to submit bug reports. +#AVRDUDE_VERBOSE = -v -v + +AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) +AVRDUDE_FLAGS += $(AVRDUDE_NO_VERIFY) +AVRDUDE_FLAGS += $(AVRDUDE_VERBOSE) +AVRDUDE_FLAGS += $(AVRDUDE_ERASE_COUNTER) + + + +#---------------- Debugging Options ---------------- + +# For simulavr only - target MCU frequency. +DEBUG_MFREQ = $(F_CPU) + +# Set the DEBUG_UI to either gdb or insight. +# DEBUG_UI = gdb +DEBUG_UI = insight + +# Set the debugging back-end to either avarice, simulavr. +DEBUG_BACKEND = avarice +#DEBUG_BACKEND = simulavr + +# GDB Init Filename. +GDBINIT_FILE = __avr_gdbinit + +# When using avarice settings for the JTAG +JTAG_DEV = /dev/com1 + +# Debugging port used to communicate between GDB / avarice / simulavr. +DEBUG_PORT = 4242 + +# Debugging host used to communicate between GDB / avarice / simulavr, normally +# just set to localhost unless doing some sort of crazy debugging when +# avarice is running on a different computer. +DEBUG_HOST = localhost + + + +#============================================================================ + + +# Define programs and commands. +SHELL = sh +CC = avr-gcc +OBJCOPY = avr-objcopy +OBJDUMP = avr-objdump +SIZE = avr-size +AR = avr-ar rcs +NM = avr-nm +AVRDUDE = avrdude +REMOVE = rm -f +REMOVEDIR = rm -rf +COPY = cp +WINSHELL = cmd + + +# Define Messages +# English +MSG_ERRORS_NONE = Errors: none +MSG_BEGIN = -------- begin -------- +MSG_END = -------- end -------- +MSG_SIZE_BEFORE = Size before: +MSG_SIZE_AFTER = Size after: +MSG_COFF = Converting to AVR COFF: +MSG_EXTENDED_COFF = Converting to AVR Extended COFF: +MSG_FLASH = Creating load file for Flash: +MSG_EEPROM = Creating load file for EEPROM: +MSG_EXTENDED_LISTING = Creating Extended Listing: +MSG_SYMBOL_TABLE = Creating Symbol Table: +MSG_LINKING = Linking: +MSG_COMPILING = Compiling C: +MSG_COMPILING_CPP = Compiling C++: +MSG_ASSEMBLING = Assembling: +MSG_CLEANING = Cleaning project: +MSG_CREATING_LIBRARY = Creating library: + + + + +# Define all object files. +OBJ = $(SRC:%.c=$(OBJDIR)/%.o) $(CPPSRC:%.cpp=$(OBJDIR)/%.o) $(ASRC:%.S=$(OBJDIR)/%.o) + +# Define all listing files. +LST = $(SRC:%.c=$(OBJDIR)/%.lst) $(CPPSRC:%.cpp=$(OBJDIR)/%.lst) $(ASRC:%.S=$(OBJDIR)/%.lst) + + +# Compiler flags to generate dependency files. +GENDEPFLAGS = -MMD -MP -MF .dep/$(@F).d + + +# Combine all necessary flags and optional flags. +# Add target processor to flags. +ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) $(GENDEPFLAGS) +ALL_CPPFLAGS = -mmcu=$(MCU) -I. -x c++ $(CPPFLAGS) $(GENDEPFLAGS) +ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS) + + + + + +# Default target. +all: begin gccversion sizebefore build 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. +program: $(TARGET).hex $(TARGET).eep + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM) + + +# Generate avr-gdb config/init file which does the following: +# define the reset signal, load the target file, connect to target, and set +# a breakpoint at main(). +gdb-config: + @$(REMOVE) $(GDBINIT_FILE) + @echo define reset >> $(GDBINIT_FILE) + @echo SIGNAL SIGHUP >> $(GDBINIT_FILE) + @echo end >> $(GDBINIT_FILE) + @echo file $(TARGET).elf >> $(GDBINIT_FILE) + @echo target remote $(DEBUG_HOST):$(DEBUG_PORT) >> $(GDBINIT_FILE) +ifeq ($(DEBUG_BACKEND),simulavr) + @echo load >> $(GDBINIT_FILE) +endif + @echo break main >> $(GDBINIT_FILE) + +debug: gdb-config $(TARGET).elf +ifeq ($(DEBUG_BACKEND), avarice) + @echo Starting AVaRICE - Press enter when "waiting to connect" message displays. + @$(WINSHELL) /c start avarice --jtag $(JTAG_DEV) --erase --program --file \ + $(TARGET).elf $(DEBUG_HOST):$(DEBUG_PORT) + @$(WINSHELL) /c pause + +else + @$(WINSHELL) /c start simulavr --gdbserver --device $(MCU) --clock-freq \ + $(DEBUG_MFREQ) --port $(DEBUG_PORT) +endif + @$(WINSHELL) /c start avr-$(DEBUG_UI) --command=$(GDBINIT_FILE) + + + + +# Convert ELF to COFF for use in debugging / simulating in AVR Studio or VMLAB. +COFFCONVERT = $(OBJCOPY) --debugging +COFFCONVERT += --change-section-address .data-0x800000 +COFFCONVERT += --change-section-address .bss-0x800000 +COFFCONVERT += --change-section-address .noinit-0x800000 +COFFCONVERT += --change-section-address .eeprom-0x810000 + + + +coff: $(TARGET).elf + @echo + @echo $(MSG_COFF) $(TARGET).cof + $(COFFCONVERT) -O coff-avr $< $(TARGET).cof + + +extcoff: $(TARGET).elf + @echo + @echo $(MSG_EXTENDED_COFF) $(TARGET).cof + $(COFFCONVERT) -O coff-ext-avr $< $(TARGET).cof + + + +# Create final output files (.hex, .eep) from ELF output file. +%.hex: %.elf + @echo + @echo $(MSG_FLASH) $@ + $(OBJCOPY) -O $(FORMAT) -R .eeprom -R .fuse -R .lock -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 diff --git a/src/lib-other/pjrc/usb_keyboard/example.c b/src/lib-other/pjrc/usb_keyboard/example.c new file mode 100644 index 0000000..9e090ba --- /dev/null +++ b/src/lib-other/pjrc/usb_keyboard/example.c @@ -0,0 +1,124 @@ +/* Keyboard example for Teensy USB Development Board + * http://www.pjrc.com/teensy/usb_keyboard.html + * Copyright (c) 2008 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. + */ + +#include +#include +#include +#include +#include "usb_keyboard.h" + +#define LED_CONFIG (DDRD |= (1<<6)) +#define LED_ON (PORTD &= ~(1<<6)) +#define LED_OFF (PORTD |= (1<<6)) +#define CPU_PRESCALE(n) (CLKPR = 0x80, CLKPR = (n)) + +uint8_t number_keys[10]= + {KEY_0,KEY_1,KEY_2,KEY_3,KEY_4,KEY_5,KEY_6,KEY_7,KEY_8,KEY_9}; + +uint16_t idle_count=0; + +int main(void) +{ + uint8_t b, d, mask, i, reset_idle; + uint8_t b_prev=0xFF, d_prev=0xFF; + + // set for 16 MHz clock + CPU_PRESCALE(0); + + // Configure all port B and port D pins as inputs with pullup resistors. + // See the "Using I/O Pins" page for details. + // http://www.pjrc.com/teensy/pins.html + DDRD = 0x00; + DDRB = 0x00; + PORTB = 0xFF; + PORTD = 0xFF; + + // 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 */ ; + + // Wait an extra second for the PC's operating system to load drivers + // and do whatever it does to actually be ready for input + _delay_ms(1000); + + // Configure timer 0 to generate a timer overflow interrupt every + // 256*1024 clock cycles, or approx 61 Hz when using 16 MHz clock + // This demonstrates how to use interrupts to implement a simple + // inactivity timeout. + TCCR0A = 0x00; + TCCR0B = 0x05; + TIMSK0 = (1< 61 * 8) { + idle_count = 0; + usb_keyboard_press(KEY_SPACE, 0); + } +} + + diff --git a/src/lib-other/pjrc/usb_keyboard/usb_keyboard.c b/src/lib-other/pjrc/usb_keyboard/usb_keyboard.c new file mode 100644 index 0000000..89b2e9b --- /dev/null +++ b/src/lib-other/pjrc/usb_keyboard/usb_keyboard.c @@ -0,0 +1,592 @@ +/* USB Keyboard Example for Teensy USB Development Board + * http://www.pjrc.com/teensy/usb_keyboard.html + * Copyright (c) 2009 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: Add support for Teensy 2.0 + +#define USB_SERIAL_PRIVATE_INCLUDE +#include "usb_keyboard.h" + +/************************************************************************** + * + * Configurable Options + * + **************************************************************************/ + +// You can change these to give your code its own name. +#define STR_MANUFACTURER L"MfgName" +#define STR_PRODUCT L"Keyboard" + + +// 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 0x047C + + +// 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 102 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 + * + **************************************************************************/ + +#define ENDPOINT0_SIZE 32 + +#define KEYBOARD_INTERFACE 0 +#define KEYBOARD_ENDPOINT 3 +#define KEYBOARD_SIZE 8 +#define KEYBOARD_BUFFER EP_DOUBLE_BUFFER + +static const uint8_t PROGMEM endpoint_config_table[] = { + 0, + 0, + 1, EP_TYPE_INTERRUPT_IN, EP_SIZE(KEYBOARD_SIZE) | KEYBOARD_BUFFER, + 0 +}; + + +/************************************************************************** + * + * Descriptor Data + * + **************************************************************************/ + +// Descriptors are the data that your computer reads when it auto-detects +// this USB device (called "enumeration" in USB lingo). The most commonly +// changed items are editable at the top of this file. Changing things +// in here should only be done by those who've read chapter 9 of the USB +// spec and relevant portions of any USB class specifications! + + +static uint8_t PROGMEM device_descriptor[] = { + 18, // bLength + 1, // bDescriptorType + 0x00, 0x02, // bcdUSB + 0, // bDeviceClass + 0, // bDeviceSubClass + 0, // bDeviceProtocol + ENDPOINT0_SIZE, // bMaxPacketSize0 + LSB(VENDOR_ID), MSB(VENDOR_ID), // idVendor + LSB(PRODUCT_ID), MSB(PRODUCT_ID), // idProduct + 0x00, 0x01, // bcdDevice + 1, // iManufacturer + 2, // iProduct + 0, // iSerialNumber + 1 // bNumConfigurations +}; + +// Keyboard Protocol 1, HID 1.11 spec, Appendix B, page 59-60 +static uint8_t PROGMEM keyboard_hid_report_desc[] = { + 0x05, 0x01, // Usage Page (Generic Desktop), + 0x09, 0x06, // Usage (Keyboard), + 0xA1, 0x01, // Collection (Application), + 0x75, 0x01, // Report Size (1), + 0x95, 0x08, // Report Count (8), + 0x05, 0x07, // Usage Page (Key Codes), + 0x19, 0xE0, // Usage Minimum (224), + 0x29, 0xE7, // Usage Maximum (231), + 0x15, 0x00, // Logical Minimum (0), + 0x25, 0x01, // Logical Maximum (1), + 0x81, 0x02, // Input (Data, Variable, Absolute), ;Modifier byte + 0x95, 0x01, // Report Count (1), + 0x75, 0x08, // Report Size (8), + 0x81, 0x03, // Input (Constant), ;Reserved byte + 0x95, 0x05, // Report Count (5), + 0x75, 0x01, // Report Size (1), + 0x05, 0x08, // Usage Page (LEDs), + 0x19, 0x01, // Usage Minimum (1), + 0x29, 0x05, // Usage Maximum (5), + 0x91, 0x02, // Output (Data, Variable, Absolute), ;LED report + 0x95, 0x01, // Report Count (1), + 0x75, 0x03, // Report Size (3), + 0x91, 0x03, // Output (Constant), ;LED report padding + 0x95, 0x06, // Report Count (6), + 0x75, 0x08, // Report Size (8), + 0x15, 0x00, // Logical Minimum (0), + 0x25, 0x68, // Logical Maximum(104), + 0x05, 0x07, // Usage Page (Key Codes), + 0x19, 0x00, // Usage Minimum (0), + 0x29, 0x68, // Usage Maximum (104), + 0x81, 0x00, // Input (Data, Array), + 0xc0 // End Collection +}; + +#define CONFIG1_DESC_SIZE (9+9+9+7) +#define KEYBOARD_HID_DESC_OFFSET (9+9) +static uint8_t PROGMEM config1_descriptor[CONFIG1_DESC_SIZE] = { + // configuration descriptor, USB spec 9.6.3, page 264-266, Table 9-10 + 9, // bLength; + 2, // bDescriptorType; + LSB(CONFIG1_DESC_SIZE), // wTotalLength + MSB(CONFIG1_DESC_SIZE), + 1, // bNumInterfaces + 1, // bConfigurationValue + 0, // iConfiguration + 0xC0, // bmAttributes + 50, // bMaxPower + // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12 + 9, // bLength + 4, // bDescriptorType + KEYBOARD_INTERFACE, // bInterfaceNumber + 0, // bAlternateSetting + 1, // bNumEndpoints + 0x03, // bInterfaceClass (0x03 = HID) + 0x01, // bInterfaceSubClass (0x01 = Boot) + 0x01, // bInterfaceProtocol (0x01 = Keyboard) + 0, // iInterface + // HID interface descriptor, HID 1.11 spec, section 6.2.1 + 9, // bLength + 0x21, // bDescriptorType + 0x11, 0x01, // bcdHID + 0, // bCountryCode + 1, // bNumDescriptors + 0x22, // bDescriptorType + sizeof(keyboard_hid_report_desc), // wDescriptorLength + 0, + // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 + 7, // bLength + 5, // bDescriptorType + KEYBOARD_ENDPOINT | 0x80, // bEndpointAddress + 0x03, // bmAttributes (0x03=intr) + KEYBOARD_SIZE, 0, // wMaxPacketSize + 1 // bInterval +}; + +// If you're desperate for a little extra code memory, these strings +// can be completely removed if iManufacturer, iProduct, iSerialNumber +// in the device desciptor are changed to zeros. +struct usb_string_descriptor_struct { + uint8_t bLength; + uint8_t bDescriptorType; + int16_t wString[]; +}; +static struct usb_string_descriptor_struct PROGMEM string0 = { + 4, + 3, + {0x0409} +}; +static struct usb_string_descriptor_struct PROGMEM string1 = { + sizeof(STR_MANUFACTURER), + 3, + STR_MANUFACTURER +}; +static struct usb_string_descriptor_struct PROGMEM string2 = { + sizeof(STR_PRODUCT), + 3, + STR_PRODUCT +}; + +// This table defines which descriptor data is sent for each specific +// request from the host (in wValue and wIndex). +static struct descriptor_list_struct { + uint16_t wValue; + uint16_t wIndex; + const uint8_t *addr; + uint8_t length; +} PROGMEM descriptor_list[] = { + {0x0100, 0x0000, device_descriptor, sizeof(device_descriptor)}, + {0x0200, 0x0000, config1_descriptor, sizeof(config1_descriptor)}, + {0x2200, KEYBOARD_INTERFACE, keyboard_hid_report_desc, sizeof(keyboard_hid_report_desc)}, + {0x2100, KEYBOARD_INTERFACE, config1_descriptor+KEYBOARD_HID_DESC_OFFSET, 9}, + {0x0300, 0x0000, (const uint8_t *)&string0, 4}, + {0x0301, 0x0409, (const uint8_t *)&string1, sizeof(STR_MANUFACTURER)}, + {0x0302, 0x0409, (const uint8_t *)&string2, sizeof(STR_PRODUCT)} +}; +#define NUM_DESC_LIST (sizeof(descriptor_list)/sizeof(struct descriptor_list_struct)) + + +/************************************************************************** + * + * Variables - these are the only non-stack RAM usage + * + **************************************************************************/ + +// zero when we are not configured, non-zero when enumerated +static volatile uint8_t usb_configuration=0; + +// which modifier keys are currently pressed +// 1=left ctrl, 2=left shift, 4=left alt, 8=left gui +// 16=right ctrl, 32=right shift, 64=right alt, 128=right gui +uint8_t keyboard_modifier_keys=0; + +// which keys are currently pressed, up to 6 keys may be down at once +uint8_t keyboard_keys[6]={0,0,0,0,0,0}; + +// protocol setting from the host. We use exactly the same report +// either way, so this variable only stores the setting since we +// are required to be able to report which setting is in use. +static uint8_t keyboard_protocol=1; + +// the idle configuration, how often we send the report to the +// host (ms * 4) even when it hasn't changed +static uint8_t keyboard_idle_config=125; + +// count until idle timeout +static uint8_t keyboard_idle_count=0; + +// 1=num lock, 2=caps lock, 4=scroll lock, 8=compose, 16=kana +volatile uint8_t keyboard_leds=0; + + +/************************************************************************** + * + * Public Functions - these are the API intended for the user + * + **************************************************************************/ + + +// initialize USB +void usb_init(void) +{ + HW_CONFIG(); + USB_FREEZE(); // enable USB + PLL_CONFIG(); // config PLL + while (!(PLLCSR & (1<= NUM_DESC_LIST) { + UECONX = (1< desc_length) len = desc_length; + do { + // wait for host ready for IN packet + do { + i = UEINTX; + } while (!(i & ((1<= 1 && i <= MAX_ENDPOINT) { + usb_send_in(); + UENUM = i; + if (bRequest == SET_FEATURE) { + UECONX = (1<> 8); + keyboard_idle_count = 0; + usb_send_in(); + return; + } + if (bRequest == HID_SET_PROTOCOL) { + keyboard_protocol = wValue; + usb_send_in(); + return; + } + } + } + } + UECONX = (1< + +void usb_init(void); // initialize everything +uint8_t usb_configured(void); // is the USB port configured + +int8_t usb_keyboard_press(uint8_t key, uint8_t modifier); +int8_t usb_keyboard_send(void); +extern uint8_t keyboard_modifier_keys; +extern uint8_t keyboard_keys[6]; +extern volatile uint8_t keyboard_leds; + +// This file does not include the HID debug functions, so these empty +// macros replace them with nothing, so users can compile code that +// has calls to these functions. +#define usb_debug_putchar(c) +#define usb_debug_flush_output() + + +#define KEY_CTRL 0x01 +#define KEY_SHIFT 0x02 +#define KEY_ALT 0x04 +#define KEY_GUI 0x08 +#define KEY_LEFT_CTRL 0x01 +#define KEY_LEFT_SHIFT 0x02 +#define KEY_LEFT_ALT 0x04 +#define KEY_LEFT_GUI 0x08 +#define KEY_RIGHT_CTRL 0x10 +#define KEY_RIGHT_SHIFT 0x20 +#define KEY_RIGHT_ALT 0x40 +#define KEY_RIGHT_GUI 0x80 + +#define KEY_A 4 +#define KEY_B 5 +#define KEY_C 6 +#define KEY_D 7 +#define KEY_E 8 +#define KEY_F 9 +#define KEY_G 10 +#define KEY_H 11 +#define KEY_I 12 +#define KEY_J 13 +#define KEY_K 14 +#define KEY_L 15 +#define KEY_M 16 +#define KEY_N 17 +#define KEY_O 18 +#define KEY_P 19 +#define KEY_Q 20 +#define KEY_R 21 +#define KEY_S 22 +#define KEY_T 23 +#define KEY_U 24 +#define KEY_V 25 +#define KEY_W 26 +#define KEY_X 27 +#define KEY_Y 28 +#define KEY_Z 29 +#define KEY_1 30 +#define KEY_2 31 +#define KEY_3 32 +#define KEY_4 33 +#define KEY_5 34 +#define KEY_6 35 +#define KEY_7 36 +#define KEY_8 37 +#define KEY_9 38 +#define KEY_0 39 +#define KEY_ENTER 40 +#define KEY_ESC 41 +#define KEY_BACKSPACE 42 +#define KEY_TAB 43 +#define KEY_SPACE 44 +#define KEY_MINUS 45 +#define KEY_EQUAL 46 +#define KEY_LEFT_BRACE 47 +#define KEY_RIGHT_BRACE 48 +#define KEY_BACKSLASH 49 +#define KEY_NUMBER 50 +#define KEY_SEMICOLON 51 +#define KEY_QUOTE 52 +#define KEY_TILDE 53 +#define KEY_COMMA 54 +#define KEY_PERIOD 55 +#define KEY_SLASH 56 +#define KEY_CAPS_LOCK 57 +#define KEY_F1 58 +#define KEY_F2 59 +#define KEY_F3 60 +#define KEY_F4 61 +#define KEY_F5 62 +#define KEY_F6 63 +#define KEY_F7 64 +#define KEY_F8 65 +#define KEY_F9 66 +#define KEY_F10 67 +#define KEY_F11 68 +#define KEY_F12 69 +#define KEY_PRINTSCREEN 70 +#define KEY_SCROLL_LOCK 71 +#define KEY_PAUSE 72 +#define KEY_INSERT 73 +#define KEY_HOME 74 +#define KEY_PAGE_UP 75 +#define KEY_DELETE 76 +#define KEY_END 77 +#define KEY_PAGE_DOWN 78 +#define KEY_RIGHT 79 +#define KEY_LEFT 80 +#define KEY_DOWN 81 +#define KEY_UP 82 +#define KEY_NUM_LOCK 83 +#define KEYPAD_SLASH 84 +#define KEYPAD_ASTERIX 85 +#define KEYPAD_MINUS 86 +#define KEYPAD_PLUS 87 +#define KEYPAD_ENTER 88 +#define KEYPAD_1 89 +#define KEYPAD_2 90 +#define KEYPAD_3 91 +#define KEYPAD_4 92 +#define KEYPAD_5 93 +#define KEYPAD_6 94 +#define KEYPAD_7 95 +#define KEYPAD_8 96 +#define KEYPAD_9 97 +#define KEYPAD_0 98 +#define KEYPAD_PERIOD 99 + + + + +// Everything below this point is only intended for usb_serial.c +#ifdef USB_SERIAL_PRIVATE_INCLUDE +#include +#include +#include + +#define EP_TYPE_CONTROL 0x00 +#define EP_TYPE_BULK_IN 0x81 +#define EP_TYPE_BULK_OUT 0x80 +#define EP_TYPE_INTERRUPT_IN 0xC1 +#define EP_TYPE_INTERRUPT_OUT 0xC0 +#define EP_TYPE_ISOCHRONOUS_IN 0x41 +#define EP_TYPE_ISOCHRONOUS_OUT 0x40 + +#define EP_SINGLE_BUFFER 0x02 +#define EP_DOUBLE_BUFFER 0x06 + +#define EP_SIZE(s) ((s) == 64 ? 0x30 : \ + ((s) == 32 ? 0x20 : \ + ((s) == 16 ? 0x10 : \ + 0x00))) + +#define MAX_ENDPOINT 4 + +#define LSB(n) (n & 255) +#define MSB(n) ((n >> 8) & 255) + +#if defined(__AVR_AT90USB162__) +#define HW_CONFIG() +#define PLL_CONFIG() (PLLCSR = ((1<). + * [i2cmaster] (http://homepage.hispeed.ch/peterfleury/i2cmaster.zip) + +* [arduino] (https://github.com/arduino) + * [arduino] (https://github.com/arduino/Arduino) + * .../twi.c and .../twi.h + * note: The version here is from the Ubuntu package, so it's probably + old. The (new) version from github has dependencies galore on random + other Arduino files, so it wasn't really usable. + +------------------------------------------------------------------------------- + +Copyright © 2012 Ben Blazak +Released under The MIT License (MIT) (see "license.md") +Project located at + diff --git a/src/lib/data-types.h b/src/lib/data-types.h new file mode 100644 index 0000000..594ca1d --- /dev/null +++ b/src/lib/data-types.h @@ -0,0 +1,22 @@ +/* ---------------------------------------------------------------------------- + * Common data types + * ---------------------------------------------------------------------------- + * Copyright (c) 2012 Ben Blazak + * Released under The MIT License (MIT) (see "license.md") + * Project located at + * ------------------------------------------------------------------------- */ + + +#ifndef DATA_TYPES_h + #define DATA_TYPES_h + + // -------------------------------------------------------------------- + #define bool _Bool + + #define true ((bool)1) + #define false ((bool)0) + + // -------------------------------------------------------------------- + +#endif + diff --git a/src/lib/usb/keyboard-usage-page.h b/src/lib/usb/keyboard-usage-page.h new file mode 100644 index 0000000..7b1c8f9 --- /dev/null +++ b/src/lib/usb/keyboard-usage-page.h @@ -0,0 +1,264 @@ +/* ---------------------------------------------------------------------------- + * USB Keyboard Key Codes (usage page 0x07) + * + * Taken from [the HID Usage Tables pdf][1], Section 10, + * which can be found on [the HID Page][2] at + * + * - `Boot Keyboard Req.` indicates that the usage code is one that should be + * supported by the listed types of keyboards (104-key, ...) on boot + * + * - `KEY_` indicates a Keyboard key + * - `KEYPAD_` indicates a Keypad key + * - Multiple names concatenated in CamelCase indicate a single value + * - Multiple names separated by `_`s indicate shifted or alternate values + * + * [1]: http://www.usb.org/developers/devclass_docs/Hut1_12v2.pdf + * [2]: http://www.usb.org/developers/hidpage + * ---------------------------------------------------------------------------- + * Copyright (c) 2012 Ben Blazak + * Released under The MIT License (MIT) (see "license.md") + * Project located at + * ------------------------------------------------------------------------- */ + + +// Name ID // PC Mac Unix Boot Keyboard Req. +// --------------------------- ---- -- --- ---- --------------------- + +// (Reserved) 0x00 // √ √ √ 84/101/104 + +#define KEY_ErrorRollOver 0x01 // √ √ √ 84/101/104 +#define KEY_POSTFail 0x02 // √ √ √ 84/101/104 +#define KEY_ErrorUndefined 0x03 // √ √ √ 84/101/104 +#define KEY_a_A 0x04 // √ √ √ 84/101/104 +#define KEY_b_B 0x05 // √ √ √ 84/101/104 +#define KEY_c_C 0x06 // √ √ √ 84/101/104 +#define KEY_d_D 0x07 // √ √ √ 84/101/104 +#define KEY_e_E 0x08 // √ √ √ 84/101/104 +#define KEY_f_F 0x09 // √ √ √ 84/101/104 +#define KEY_g_G 0x0A // √ √ √ 84/101/104 +#define KEY_h_H 0x0B // √ √ √ 84/101/104 +#define KEY_i_I 0x0C // √ √ √ 84/101/104 +#define KEY_j_J 0x0D // √ √ √ 84/101/104 +#define KEY_k_K 0x0E // √ √ √ 84/101/104 +#define KEY_l_L 0x0F // √ √ √ 84/101/104 +#define KEY_m_M 0x10 // √ √ √ 84/101/104 +#define KEY_n_N 0x11 // √ √ √ 84/101/104 +#define KEY_o_O 0x12 // √ √ √ 84/101/104 +#define KEY_p_P 0x13 // √ √ √ 84/101/104 +#define KEY_q_Q 0x14 // √ √ √ 84/101/104 +#define KEY_r_R 0x15 // √ √ √ 84/101/104 +#define KEY_s_S 0x16 // √ √ √ 84/101/104 +#define KEY_t_T 0x17 // √ √ √ 84/101/104 +#define KEY_u_U 0x18 // √ √ √ 84/101/104 +#define KEY_v_V 0x19 // √ √ √ 84/101/104 +#define KEY_w_W 0x1A // √ √ √ 84/101/104 +#define KEY_x_X 0x1B // √ √ √ 84/101/104 +#define KEY_y_Y 0x1C // √ √ √ 84/101/104 +#define KEY_z_Z 0x1D // √ √ √ 84/101/104 +#define KEY_1_Exclamation 0x1E // √ √ √ 84/101/104 +#define KEY_2_At 0x1F // √ √ √ 84/101/104 +#define KEY_3_Pound 0x20 // √ √ √ 84/101/104 +#define KEY_4_Dollar 0x21 // √ √ √ 84/101/104 +#define KEY_5_Percent 0x22 // √ √ √ 84/101/104 +#define KEY_6_Caret 0x23 // √ √ √ 84/101/104 +#define KEY_7_Ampersand 0x24 // √ √ √ 84/101/104 +#define KEY_8_Asterisk 0x25 // √ √ √ 84/101/104 +#define KEY_9_LeftParenthesis 0x26 // √ √ √ 84/101/104 +#define KEY_0_RightParenthesis 0x27 // √ √ √ 84/101/104 +#define KEY_ReturnEnter 0x28 // √ √ √ 84/101/104 +#define KEY_Escape 0x29 // √ √ √ 84/101/104 +#define KEY_DeleteBackspace 0x2A // √ √ √ 84/101/104 +#define KEY_Tab 0x2B // √ √ √ 84/101/104 +#define KEY_Spacebar 0x2C // √ √ √ 84/101/104 +#define KEY_Dash_Underscore 0x2D // √ √ √ 84/101/104 +#define KEY_Equal_Plus 0x2E // √ √ √ 84/101/104 +#define KEY_LeftBracket_LeftBrace 0x2F // √ √ √ 84/101/104 +#define KEY_RightBracket_RightBrace 0x30 // √ √ √ 84/101/104 +#define KEY_Backslash_Pipe 0x31 // √ √ √ 84/101/104 +#define KEY_NonUS_Pound_Tilde 0x32 // √ √ √ 84/101/104 +#define KEY_Semicolon_Colon 0x33 // √ √ √ 84/101/104 +#define KEY_SingleQuote_DoubleQuote 0x34 // √ √ √ 84/101/104 +#define KEY_GraveAccent_Tilde 0x35 // √ √ √ 84/101/104 +#define KEY_Comma_LessThan 0x36 // √ √ √ 84/101/104 +#define KEY_Period_GreaterThan 0x37 // √ √ √ 84/101/104 +#define KEY_Slash_Question 0x38 // √ √ √ 84/101/104 +#define KEY_CapsLock 0x39 // √ √ √ 84/101/104 +#define KEY_F1 0x3A // √ √ √ 84/101/104 +#define KEY_F2 0x3B // √ √ √ 84/101/104 +#define KEY_F3 0x3C // √ √ √ 84/101/104 +#define KEY_F4 0x3D // √ √ √ 84/101/104 +#define KEY_F5 0x3E // √ √ √ 84/101/104 +#define KEY_F6 0x3F // √ √ √ 84/101/104 +#define KEY_F7 0x40 // √ √ √ 84/101/104 +#define KEY_F8 0x41 // √ √ √ 84/101/104 +#define KEY_F9 0x42 // √ √ √ 84/101/104 +#define KEY_F10 0x43 // √ √ √ 84/101/104 +#define KEY_F11 0x44 // √ √ √ 101/104 +#define KEY_F12 0x45 // √ √ √ 101/104 +#define KEY_PrintScreen 0x46 // √ √ √ 101/104 +#define KEY_ScrollLock 0x47 // √ √ √ 84/101/104 +#define KEY_Pause 0x48 // √ √ √ 101/104 +#define KEY_Insert 0x49 // √ √ √ 101/104 +#define KEY_Home 0x4A // √ √ √ 101/104 +#define KEY_PageUp 0x4B // √ √ √ 101/104 +#define KEY_DeleteForward 0x4C // √ √ √ 101/104 +#define KEY_End 0x4D // √ √ √ 101/104 +#define KEY_PageDown 0x4E // √ √ √ 101/104 +#define KEY_RightArrow 0x4F // √ √ √ 101/104 +#define KEY_LeftArrow 0x50 // √ √ √ 101/104 +#define KEY_DownArrow 0x51 // √ √ √ 101/104 +#define KEY_UpArrow 0x52 // √ √ √ 101/104 + +#define KEYPAD_NumLock_Clear 0x53 // √ √ √ 101/104 +#define KEYPAD_Slash 0x54 // √ √ √ 101/104 +#define KEYPAD_Asterisk 0x55 // √ √ √ 84/101/104 +#define KEYPAD_Minus 0x56 // √ √ √ 84/101/104 +#define KEYPAD_Plus 0x57 // √ √ √ 84/101/104 +#define KEYPAD_ENTER 0x58 // √ √ √ 101/104 +#define KEYPAD_1_End 0x59 // √ √ √ 84/101/104 +#define KEYPAD_2_DownArrow 0x5A // √ √ √ 84/101/104 +#define KEYPAD_3_PageDown 0x5B // √ √ √ 84/101/104 +#define KEYPAD_4_LeftArrow 0x5C // √ √ √ 84/101/104 +#define KEYPAD_5 0x5D // √ √ √ 84/101/104 +#define KEYPAD_6_RightArrow 0x5E // √ √ √ 84/101/104 +#define KEYPAD_7_Home 0x5F // √ √ √ 84/101/104 +#define KEYPAD_8_UpArrow 0x60 // √ √ √ 84/101/104 +#define KEYPAD_9_PageUp 0x61 // √ √ √ 84/101/104 +#define KEYPAD_0_Insert 0x62 // √ √ √ 84/101/104 +#define KEYPAD_Period_Delete 0x63 // √ √ √ 84/101/104 + +#define KEY_NonUS_Backslash_Pipe 0x64 // √ √ √ 84/101/104 +#define KEY_Application 0x65 // √ - √ 104 +#define KEY_Power 0x66 // - √ √ - + +#define KEYPAD_Equal 0x67 // - √ - - + +#define KEY_F13 0x68 // - √ - - +#define KEY_F14 0x69 // - √ - - +#define KEY_F15 0x6A // - √ - - +#define KEY_F16 0x6B // - - - - +#define KEY_F17 0x6C // - - - - +#define KEY_F18 0x6D // - - - - +#define KEY_F19 0x6E // - - - - +#define KEY_F20 0x6F // - - - - +#define KEY_F21 0x70 // - - - - +#define KEY_F22 0x71 // - - - - +#define KEY_F23 0x72 // - - - - +#define KEY_F24 0x73 // - - - - +#define KEY_Execute 0x74 // - - √ - +#define KEY_Help 0x75 // - - √ - +#define KEY_Menu 0x76 // - - √ - +#define KEY_Select 0x77 // - - √ - +#define KEY_Stop 0x78 // - - √ - +#define KEY_Again 0x79 // - - √ - +#define KEY_Undo 0x7A // - - √ - +#define KEY_Cut 0x7B // - - √ - +#define KEY_Copy 0x7C // - - √ - +#define KEY_Paste 0x7D // - - √ - +#define KEY_Find 0x7E // - - √ - +#define KEY_Mute 0x7F // - - √ - +#define KEY_VolumeUp 0x80 // - - √ - +#define KEY_VolumeDown 0x81 // - - √ - +#define KEY_LockingCapsLock 0x82 // - - √ - +#define KEY_LockingNumLock 0x83 // - - √ - +#define KEY_LockingScrollLock 0x84 // - - √ - + +#define KEYPAD_Comma 0x85 // - - - - +#define KEYPAD_Equal 0x86 // - - - - + +#define KEY_International1 0x87 // - - - - +#define KEY_International2 0x88 // - - - - +#define KEY_International3 0x89 // - - - - +#define KEY_International4 0x8A // - - - - +#define KEY_International5 0x8B // - - - - +#define KEY_International6 0x8C // - - - - +#define KEY_International7 0x8D // - - - - +#define KEY_International8 0x8E // - - - - +#define KEY_International9 0x8F // - - - - +#define KEY_LANG1 0x90 // - - - - +#define KEY_LANG2 0x91 // - - - - +#define KEY_LANG3 0x92 // - - - - +#define KEY_LANG4 0x93 // - - - - +#define KEY_LANG5 0x94 // - - - - +#define KEY_LANG6 0x95 // - - - - +#define KEY_LANG7 0x96 // - - - - +#define KEY_LANG8 0x97 // - - - - +#define KEY_LANG9 0x98 // - - - - +#define KEY_AlternateErase 0x99 // - - - - +#define KEY_SysReq_Attention 0x9A // - - - - +#define KEY_Cancel 0x9B // - - - - +#define KEY_Clear 0x9C // - - - - +#define KEY_Prior 0x9D // - - - - +#define KEY_Return 0x9E // - - - - +#define KEY_Separator 0x9F // - - - - +#define KEY_Out 0xA0 // - - - - +#define KEY_Oper 0xA1 // - - - - +#define KEY_Clear_Again 0xA2 // - - - - +#define KEY_CrSel_Props 0xA3 // - - - - +#define KEY_ExSel 0xA4 // - - - - + +// (Reserved) 0xA5..0xAF // - - - - + +#define KEYPAD_00 0xB0 // - - - - +#define KEYPAD_000 0xB1 // - - - - + +#define KEY_ThousandsSeparator 0xB2 // - - - - +#define KEY_DecimalSeparator 0xB3 // - - - - +#define KEY_CurrencyUnit 0xB4 // - - - - +#define KEY_CurrencySubunit 0xB5 // - - - - + +#define KEYPAD_LeftParenthesis 0xB6 // - - - - +#define KEYPAD_RightParenthesis 0xB7 // - - - - +#define KEYPAD_LeftBrace 0xB8 // - - - - +#define KEYPAD_RightBrace 0xB9 // - - - - + +#define KEYPAD_Tab 0xBA // - - - - +#define KEYPAD_Backspace 0xBB // - - - - +#define KEYPAD_A 0xBC // - - - - +#define KEYPAD_B 0xBD // - - - - +#define KEYPAD_C 0xBE // - - - - +#define KEYPAD_D 0xBF // - - - - +#define KEYPAD_E 0xC0 // - - - - +#define KEYPAD_F 0xC1 // - - - - +#define KEYPAD_XOR 0xC2 // - - - - +#define KEYPAD_Caret 0xC3 // - - - - +#define KEYPAD_Percent 0xC4 // - - - - +#define KEYPAD_LessThan 0xC5 // - - - - +#define KEYPAD_GreaterThan 0xC6 // - - - - +#define KEYPAD_Ampersand 0xC7 // - - - - +#define KEYPAD_AmpersandAmpersand 0xC8 // - - - - +#define KEYPAD_Pipe 0xC9 // - - - - +#define KEYPAD_PipePipe 0xCA // - - - - +#define KEYPAD_Colon 0xCB // - - - - +#define KEYPAD_Pound 0xCC // - - - - +#define KEYPAD_Space 0xCD // - - - - +#define KEYPAD_At 0xCE // - - - - +#define KEYPAD_Exclamation 0xCF // - - - - +#define KEYPAD_MemoryStore 0xD0 // - - - - +#define KEYPAD_MemoryRecall 0xD1 // - - - - +#define KEYPAD_MemoryClear 0xD2 // - - - - +#define KEYPAD_MemoryAdd 0xD3 // - - - - +#define KEYPAD_MemorySubtract 0xD4 // - - - - +#define KEYPAD_MemoryMultiply 0xD5 // - - - - +#define KEYPAD_MemoryDivide 0xD6 // - - - - +#define KEYPAD_PlusMinux 0xD7 // - - - - +#define KEYPAD_Clear 0xD8 // - - - - +#define KEYPAD_ClearEntry 0xD9 // - - - - +#define KEYPAD_Binary 0xDA // - - - - +#define KEYPAD_Octal 0xDB // - - - - +#define KEYPAD_Decimal 0xDC // - - - - +#define KEYPAD_Hexadecimal 0xDD // - - - - + +// (Reserved) 0xDE..0xDF // - - - - + +#define KEY_LeftControl 0xE0 // √ √ √ 84/101/104 +#define KEY_LeftShift 0xE1 // √ √ √ 84/101/104 +#define KEY_LeftAlt 0xE2 // √ √ √ 84/101/104 +#define KEY_LeftGUI 0xE3 // √ √ √ 104 +#define KEY_RightControl 0xE4 // √ √ √ 101/104 +#define KEY_RightShift 0xE5 // √ √ √ 84/101/104 +#define KEY_RightAlt 0xE6 // √ √ √ 101/104 +#define KEY_RightGUI 0xE7 // √ √ √ 104 + +// (Reserved) 0xE8..0xFFFF // - - - - + diff --git a/src/lib/usb/led-usage-page.h b/src/lib/usb/led-usage-page.h new file mode 100644 index 0000000..45c9754 --- /dev/null +++ b/src/lib/usb/led-usage-page.h @@ -0,0 +1,106 @@ +/* ---------------------------------------------------------------------------- + * USB LED Codes (usage page 0x08) + * + * Taken from [the HID Usage Tables pdf][1], Section 11, + * which can be found on [the HID Page][2] at + * + * - applicable Usage Types (from Section 3.4) + * - OOC : On/Off Control + * - Sel : Selector + * - DV : Dynamic Value + * - US : Usage Switch + * - UM : Usage Modifier + * + * [1]: http://www.usb.org/developers/devclass_docs/Hut1_12v2.pdf + * [2]: http://www.usb.org/developers/hidpage + * ---------------------------------------------------------------------------- + * Copyright (c) 2012 Ben Blazak + * Released under The MIT License (MIT) (see "license.md") + * Project located at + * ------------------------------------------------------------------------- */ + + +// Name ID Usage Type Section of HID Tables +// --------------------------- ---- ---------- ---------------------- + +// (Undefined) 0x00 // - - + +#define LED_NumLock 0x01 // OOC 11.1 +#define LED_CapsLock 0x02 // OOC 11.1 +#define LED_ScrollLock 0x03 // OOC 11.1 +#define LED_Compose 0x04 // OOC 11.1 +#define LED_Kana 0x05 // OOC 11.1 +#define LED_Power 0x06 // OOC 11.6 +#define LED_Shift 0x07 // OOC 11.1 +#define LED_DoNotDisturb 0x08 // OOC 11.2 +#define LED_Mute 0x09 // OOC 11.3 +#define LED_ToneEnable 0x0A // OOC 11.3 +#define LED_HighCutFilter 0x0B // OOC 11.3 +#define LED_LowCutFilter 0x0C // OOC 11.3 +#define LED_EqualizerEnable 0x0D // OOC 11.3 +#define LED_SoundFieldOn 0x0E // OOC 11.3 +#define LED_SurroundOn 0x0F // OOC 11.3 +#define LED_Repeat 0x10 // OOC 11.3 +#define LED_Stereo 0x11 // OOC 11.3 +#define LED_SamplingRateDetect 0x12 // OOC 11.3 +#define LED_Spinning 0x13 // OOC 11.4 +#define LED_CAV 0x14 // OOC 11.3 +#define LED_CLV 0x15 // OOC 11.3 +#define LED_RecordingFormatDetect 0x16 // OOC 11.4 +#define LED_OffHook 0x17 // OOC 11.2 +#define LED_Ring 0x18 // OOC 11.2 +#define LED_MessageWaiting 0x19 // OOC 11.2 +#define LED_DataMode 0x1A // OOC 11.2 +#define LED_BatteryOperation 0x1B // OOC 11.6 +#define LED_BatteryOK 0x1C // OOC 11.6 +#define LED_BatteryLow 0x1D // OOC 11.6 +#define LED_Speaker 0x1E // OOC 11.2 +#define LED_HeadSet 0x1F // OOC 11.2 +#define LED_Hold 0x20 // OOC 11.2 +#define LED_Microphone 0x21 // OOC 11.2 +#define LED_Coverage 0x22 // OOC 11.2 +#define LED_NightMode 0x23 // OOC 11.2 +#define LED_SendCalls 0x24 // OOC 11.2 +#define LED_CallPickup 0x25 // OOC 11.2 +#define LED_Conference 0x26 // OOC 11.2 +#define LED_Standby 0x27 // OOC 11.6 +#define LED_CameraOn 0x28 // OOC 11.3 +#define LED_CameraOff 0x29 // OOC 11.3 +#define LED_OnLine 0x2A // OOC 11.6 +#define LED_OffLine 0x2B // OOC 11.6 +#define LED_Busy 0x2C // OOC 11.6 +#define LED_Ready 0x2D // OOC 11.6 +#define LED_PaperOut 0x2E // OOC 11.5 +#define LED_PaperJam 0x2F // OOC 11.5 +#define LED_Remote 0x30 // OOC 11.6 +#define LED_Forward 0x31 // OOC 11.4 +#define LED_Reverse 0x32 // OOC 11.4 +#define LED_Stop 0x33 // OOC 11.4 +#define LED_Rewind 0x34 // OOC 11.4 +#define LED_FastForward 0x35 // OOC 11.4 +#define LED_Play 0x36 // OOC 11.4 +#define LED_Pause 0x37 // OOC 11.4 +#define LED_Record 0x38 // OOC 11.4 +#define LED_Error 0x39 // OOC 11.6 +#define LED_UsageSelectedIndicator 0x3A // US 11.6 +#define LED_UsageInUseIndicator 0x3B // US 11.6 +#define LED_UsageMultiModeIndicator 0x3C // UM 11.6 +#define LED_IndicatorOn 0x3D // Sel 11.6 +#define LED_IndicatorFlash 0x3E // Sel 11.6 +#define LED_IndicatorSlowBlink 0x3F // Sel 11.6 +#define LED_IndicatorFastBlink 0x40 // Sel 11.6 +#define LED_IndicatorOff 0x41 // Sel 11.6 +#define LED_FlashOnTime 0x42 // DV 11.6 +#define LED_SlowBlinkOnTime 0x43 // DV 11.6 +#define LED_SlowBlinkOffTime 0x44 // DV 11.6 +#define LED_FastBlinkOnTime 0x45 // DV 11.6 +#define LED_FastBlinkOffTime 0x46 // DV 11.6 +#define LED_UsageIndicatorColor 0x47 // UM 11.6 +#define LED_IndicatorRed 0x48 // Sel 11.6 +#define LED_IndicatorGreen 0x49 // Sel 11.6 +#define LED_IndicatorAmber 0x4A // Sel 11.6 +#define LED_GenericIndicator 0x4B // OOC 11.6 +#define LED_SystemSuspend 0x4C // OOC 11.6 +#define LED_ExternalPowerConnected 0x4D // OOC 11.6 + +// (Reserved) 0x4E..0xFFFF // - - diff --git a/src/makefile b/src/makefile index 92f890a..32902bf 100644 --- a/src/makefile +++ b/src/makefile @@ -2,16 +2,27 @@ # This is mostly a stub at the moment, but I'm keeping it separate so I can # mess with it later without changing the original # ----------------------------------------------------------------------------- -# Copyright (c) 2012 Ben Blazak -# Released under The MIT License (MIT) (see "license.md") at -# +# Copyright (c) 2012 Ben Blazak +# Released under The MIT License (MIT) (see "license.md") +# Project located at # ----------------------------------------------------------------------------- -SRC = $(shell find -name '*.c') +TARGET = ergodox-firmware + +SRC = $(shell find -maxdepth 1 -name '*.c') \ + $(shell find ./keyboard -name '*.c') \ + $(shell find ./lib -name '*.c') \ + ./lib-other/peter-fleury/i2cmaster/twimaster.c \ + ./lib-other/pjrc/blinky/print.c \ + ./lib-other/pjrc/blinky/usb_debug_only.c \ + ./lib-other/arduino/arduino/libraries/Wire/utility/twi.c + + EXTRAINCDIRS = . -TEENSY_MAKE = $(MAKE) -f 'lib/pjrc/Makefile' \ +TEENSY_MAKE = $(MAKE) -f 'lib-other/pjrc/blinky/Makefile' \ + TARGET='$(TARGET)' \ SRC='$(SRC)' \ EXTRAINCDIRS='$(EXTRAINCDIRS)' diff --git a/src/test.c b/src/test.c new file mode 100644 index 0000000..16a3d91 --- /dev/null +++ b/src/test.c @@ -0,0 +1,49 @@ +#include +#include + +#include "lib-other/pjrc/blinky/print.h" +#include "lib-other/pjrc/blinky/usb_debug_only.h" + +#define TEENSY_2_0_h_INCLUDE_PRIVATE +#include "keyboard/ergodox/teensy-2-0.h" + +int test_i2c(void); +int test_kb_teensy(void); +int main(void); + +// ---------------------------------------------------------------------------- + +int main(void) { + test_i2c(); + print("--------------"); + test_kb_teensy(); +} + +// ---------------------------------------------------------------------------- + +int test_i2c(void) { + usb_init(); + _delay_ms(500); // just to be safe + + uint8_t ret; + + uint8_t len; + char str[10]; + + print("\nhello"); + + ret = teensy_init(); + print("\nteensy_init() returned: 0x"); phex(ret); + + ret = mcp23018_init(); + print("\nmcp23018_init() returned: 0x"); phex(ret); + + usb_debug_flush_output(); + return 0; +} + +// ---------------------------------------------------------------------------- + +int test_kb_teensy(void) { +} + From f49d50369864bcefcd0700edd1b846663af7fea4 Mon Sep 17 00:00:00 2001 From: Ben Blazak Date: Wed, 28 Mar 2012 01:03:11 -0700 Subject: [PATCH 12/22] little work on the teensy init function and header; not much else --- src/firmware.c | 2 +- src/keyboard/ergodox/matrix.h | 3 +- src/keyboard/ergodox/teensy-2-0.c | 2 +- src/keyboard/ergodox/teensy-2-0.h | 12 +++---- src/keyboard/ergodox/teensy-2-0.md | 17 +++++++--- src/test.c | 53 ++++++++++++++++++++++++++++++ 6 files changed, 75 insertions(+), 14 deletions(-) diff --git a/src/firmware.c b/src/firmware.c index e59e8ed..888ca0b 100644 --- a/src/firmware.c +++ b/src/firmware.c @@ -1,5 +1,5 @@ /* ---------------------------------------------------------------------------- - * Firmware main file + * main() * ---------------------------------------------------------------------------- * Copyright (c) 2012 Ben Blazak * Released under The MIT License (MIT) (see "license.md") diff --git a/src/keyboard/ergodox/matrix.h b/src/keyboard/ergodox/matrix.h index 18fb807..f3c4fa5 100644 --- a/src/keyboard/ergodox/matrix.h +++ b/src/keyboard/ergodox/matrix.h @@ -15,8 +15,7 @@ #define KB_ROWS 12 // must match real life #define KB_COLUMNS 7 // must match real life - extern bool kb_is_pressed[KB_ROWS][KB_COLUMNS]; - bool kb_is_pressed[KB_ROWS][KB_COLUMNS]; + extern bool kb_is_pressed[KB_ROWS][KB_COLUMNS] = {}; #endif diff --git a/src/keyboard/ergodox/teensy-2-0.c b/src/keyboard/ergodox/teensy-2-0.c index 4caf4ed..34bf457 100644 --- a/src/keyboard/ergodox/teensy-2-0.c +++ b/src/keyboard/ergodox/teensy-2-0.c @@ -33,7 +33,7 @@ uint8_t teensy_init(void) { DDRB &= ~0b00001110; // set B(3,2,1) as input PORTB |= 0b00001110; // set B(3,2,1) internal pull-up enabled DDRD &= ~0b01110000; // set D(6,5,4) as input - PORTD |= 0b01110000; // set D(6,5,4) internal pull-up enabled + PORTD |= 0b00110000; // set D( 5,4) internal pull-up enabled DDRE &= ~0b01000000; // set E(6) as input PORTE |= 0b01000000; // set E(6) internal pull-up enabled diff --git a/src/keyboard/ergodox/teensy-2-0.h b/src/keyboard/ergodox/teensy-2-0.h index bb8f3ff..1dc7770 100644 --- a/src/keyboard/ergodox/teensy-2-0.h +++ b/src/keyboard/ergodox/teensy-2-0.h @@ -13,16 +13,16 @@ #include // for the register macros // LED control - #define KB_LED1_ON (OCR1A = 0xFF) - #define KB_LED1_OFF (OCR1A = 0x00) + #define KB_LED1_ON (DDRB |= (1<<5)) + #define KB_LED1_OFF (DDRB &= ~(1<<5)) #define KB_LED1_SET(n) (OCR1A = (uint8_t)(n)) #define KB_LED1_SET_PERCENT(n) (OCR1A = (uint8_t)((n) * 0xFF)) - #define KB_LED2_ON (OCR1B = 0xFF) - #define KB_LED2_OFF (OCR1B = 0x00) + #define KB_LED2_ON (DDRB |= (1<<6)) + #define KB_LED2_OFF (DDRB &= ~(1<<6)) #define KB_LED2_SET(n) (OCR1B = (uint8_t)(n)) #define KB_LED2_SET_PERCENT(n) (OCR1B = (uint8_t)((n) * 0xFF)) - #define KB_LED3_ON (OCR1C = 0xFF) - #define KB_LED3_OFF (OCR1C = 0x00) + #define KB_LED3_ON (DDRB |= (1<<7)) + #define KB_LED3_OFF (DDRB &= ~(1<<7)) #define KB_LED3_SET(n) (OCR1C = (uint8_t)(n)) #define KB_LED3_SET_PERCENT(n) (OCR1C = (uint8_t)((n) * 0xFF)) diff --git a/src/keyboard/ergodox/teensy-2-0.md b/src/keyboard/ergodox/teensy-2-0.md index a9da809..b66415a 100644 --- a/src/keyboard/ergodox/teensy-2-0.md +++ b/src/keyboard/ergodox/teensy-2-0.md @@ -43,8 +43,7 @@ * notes: * SCL and SDA: Need external pull-up resistors. Sometimes the Teensy internal pull-ups are enough (see datasheet section 20.5.1), but i think - for this project we'll want external ones, in case people want to separate - the halves very far. + for this project we'll want external ones. ## Notes about Registers @@ -62,14 +61,17 @@ * notes: * Unused pins should be set as input with internal pullup enabled (see - datasheet section 10.2.6). + datasheet section 10.2.6) in order to give them a defined level. + * PD6 already has a defined level (low) since it's hooked up to the onboard + LED, so there's no reason to set internal pull-up enabled on it. If we + do, it will source current to the LED, which is fine, but unnecessary. * We want the row pins 'drive high' initially, and the column pins set as input with internal pull-up. We'll cycle through driving the row pins low, and checking the column pins in the update function. ### PWM on ports OC1(A|B|C) (see datasheet section 14.10) -* notes: +* notes: settings: * PWM pins should be set as outputs. * we want Waveform Generation Mode 5 (fast PWM, 8-bit) @@ -88,6 +90,13 @@ * LEDs will be at minimum brightness until OCR1(A|B|C) are changed (since the default value of all the bits in those registers is 0) +* notes: behavior: + * The pins source current when on, and sink current when off. They aren't + set to high impediance for either. + * In Fast PWM mode setting `OCR1(A|B|C)` to `0` does not make the output on + `OC1(A|B|C)` constant low; just close. Per the datasheet, this isn't true + for every PWM mode. + * abbreviations: * OCR = Output Compare Register * TCCR = Timer/Counter Control Register diff --git a/src/test.c b/src/test.c index 16a3d91..1868c23 100644 --- a/src/test.c +++ b/src/test.c @@ -4,9 +4,12 @@ #include "lib-other/pjrc/blinky/print.h" #include "lib-other/pjrc/blinky/usb_debug_only.h" +#include "lib/data-types.h" + #define TEENSY_2_0_h_INCLUDE_PRIVATE #include "keyboard/ergodox/teensy-2-0.h" +int blink_leds(void); int test_i2c(void); int test_kb_teensy(void); int main(void); @@ -14,6 +17,14 @@ int main(void); // ---------------------------------------------------------------------------- int main(void) { + teensy_init(); + + KB_LED1_SET_PERCENT(.03); + KB_LED2_SET_PERCENT(.03); + KB_LED3_SET_PERCENT(.03); + +// blink_leds(); +// print("--------------"); test_i2c(); print("--------------"); test_kb_teensy(); @@ -21,6 +32,48 @@ int main(void) { // ---------------------------------------------------------------------------- +int blink_leds(void) { + for (uint8_t i=0; i<3; i++) { + KB_LED1_SET(0x10); + KB_LED2_SET(0x20); + KB_LED3_SET(0xFF); + _delay_ms(500); + KB_LED1_SET(0x20); + KB_LED2_SET(0xFF); + KB_LED3_SET(0x10); + _delay_ms(500); + KB_LED1_SET(0xFF); + KB_LED2_SET(0x10); + KB_LED3_SET(0x20); + _delay_ms(500); + } + + for (uint8_t i=0; i<2; i++) { + KB_LED1_OFF; + KB_LED2_OFF; + KB_LED3_OFF; + _delay_ms(500); + KB_LED1_ON; + KB_LED2_ON; + KB_LED3_ON; + _delay_ms(500); + } + + bool counting_up = true; + for (uint8_t i=0;;) { + (counting_up) ? i++ : i--; + if (i == 0xFF) + counting_up = false; + else if (i == 0) + counting_up = true; + + KB_LED1_SET(i/2); + KB_LED2_SET(i/2); + KB_LED3_SET(i/2); + _delay_ms(10); + } +} + int test_i2c(void) { usb_init(); _delay_ms(500); // just to be safe From b0b9335651d765def338a04f998ca767141bc6f2 Mon Sep 17 00:00:00 2001 From: Ben Blazak Date: Sat, 31 Mar 2012 17:02:55 -0700 Subject: [PATCH 13/22] few things; mostly, I2C works now!; it was a hardware error i had been leaving the RESET pin floating... this does not work. it must be externally biased - high, if you want the chip to work.. :) lol --- src/firmware.c | 5 +- src/keyboard/ergodox/mcp23018.c | 157 ++++++++++------------------- src/keyboard/ergodox/mcp23018.md | 7 +- src/keyboard/ergodox/teensy-2-0.md | 26 +++++ src/makefile | 6 +- src/test.c | 102 ------------------- src/test/makefile | 34 +++++++ src/test/test_pwm.c | 65 ++++++++++++ src/test/test_twi.c | 105 +++++++++++++++++++ 9 files changed, 294 insertions(+), 213 deletions(-) delete mode 100644 src/test.c create mode 100644 src/test/makefile create mode 100644 src/test/test_pwm.c create mode 100644 src/test/test_twi.c diff --git a/src/firmware.c b/src/firmware.c index 888ca0b..93fed58 100644 --- a/src/firmware.c +++ b/src/firmware.c @@ -13,7 +13,6 @@ // TODO -// int main(void) { -// return 0; -// } +void main(void) { +} diff --git a/src/keyboard/ergodox/mcp23018.c b/src/keyboard/ergodox/mcp23018.c index ff0b73a..8d9b165 100644 --- a/src/keyboard/ergodox/mcp23018.c +++ b/src/keyboard/ergodox/mcp23018.c @@ -8,67 +8,26 @@ // TODO: this is not working yet -#if 0 // this is not the one we want; but it has all the right info -#include "lib-other/peter-fleury/i2cmaster/i2cmaster.h" - -// so we can say `TWI_ADDRESS|I2C_WRITE` -#define TWI_ADDRESS (MCP23018_TWI_ADDRESS<<1) - -uint8_t mcp23018_ready; // false - -uint8_t mcp23018_init(void) { - // declare vars - uint8_t error; - // see if the device is ready // - success: set `mcp23018_ready = true` and continue initializing // - failure: return `error`; we can try again later - error = i2c_start(TWI_ADDRESS|I2C_WRITE); - if(error) { - return error; - } else { - mcp23018_ready = true; - i2c_stop(); // release bus - } // set pin direction // - unused : input : 1 // - rows : output : 0 // - columns : input : 1 - i2c_start_wait(TWI_ADDRESS|I2C_WRITE); - i2c_write(IODIRA); // start register address - i2c_write(0b11000000); // IODIRA - i2c_write(0b11111111); // IODIRB - i2c_stop(); // set pull-up // - unused : on : 1 // - rows : on : 1 // - columns : on : 1 - i2c_start_wait(TWI_ADDRESS|I2C_WRITE); - i2c_write(GPPUA); // start register address - i2c_write(0b11111111); // GPPUA - i2c_write(0b11111111); // GPPUB - i2c_stop(); // set output pins high // - rows : high : 1 // - other : low : 0 (or ignored) - i2c_start_wait(TWI_ADDRESS|I2C_WRITE); - i2c_write(OLATA); // start register address - i2c_write(0b00111111); // OLATA - i2c_stop(); - - return 0; // success -} -#endif -#include #include -// #include "lib-other/arduino/arduino/libraries/Wire/utility/twi.h" -#include "lib-other/pjrc/blinky/print.h" -#include "lib-other/pjrc/blinky/usb_debug_only.h" #define MCP23018_h_INCLUDE_PRIVATE #include "mcp23018.h" @@ -86,27 +45,60 @@ uint8_t mcp23018_init(void) { #define OLATA 0x14 // output latch register #define OLATB 0x15 -static void twi_init(void) { -// TWSR &= ~( (1< +#include + +#define blink_led(time1, time2) { \ + /* Teensy 2.0 onboard LED on PD6 + on high, off low */ \ + PORTD |= (1<<6); \ + _delay_ms(time1); \ + PORTD &= ~(1<<6); \ + _delay_ms(time2); \ } -static uint8_t twi_start(void) { - TWCR = (1<=0; i--) { - (data & (1< + * ## Notes about Registers diff --git a/src/keyboard/ergodox/teensy-2-0.md b/src/keyboard/ergodox/teensy-2-0.md index b66415a..f4f3cbb 100644 --- a/src/keyboard/ergodox/teensy-2-0.md +++ b/src/keyboard/ergodox/teensy-2-0.md @@ -1,5 +1,6 @@ # Documentation : Teensy 2.0 + ## Pinouts and Pin assignments * `+` indicates pin @@ -45,6 +46,7 @@ internal pull-ups are enough (see datasheet section 20.5.1), but i think for this project we'll want external ones. + ## Notes about Registers ### General I/O (see datasheet section 10.2.1) @@ -101,6 +103,30 @@ * OCR = Output Compare Register * TCCR = Timer/Counter Control Register + +## I²C Status Codes (for Master modes) + +### Master Transmitter + +* `0x08` A START condition has been transmitted +* `0x10` A repeated START condition has been transmitted +* `0x18` SLA+W has been transmitted; ACK has been received +* `0x20` SLA+W has been transmitted; NOT ACK has been received +* `0x28` Data byte has been transmitted; ACK has been received +* `0x30` Data byte has been transmitted; NOT ACK has been received +* `0x38` Arbitration lost in SLA+W or data bytes + +### Master Receiver + +* `0x08` A START condition has been transmitted +* `0x10` A repeated START condition has been transmitted +* `0x38` Arbitration lost in SLA+R or NOT ACK bit +* `0x40` SLA+R has been transmitted; ACK has been received +* `0x48` SLA+R has been transmitted; NOT ACK has been received +* `0x50` Data byte has been received; ACK has been returned +* `0x58` Data byte has been received; NOT ACK has been returned + + ------------------------------------------------------------------------------- Copyright © 2012 Ben Blazak diff --git a/src/makefile b/src/makefile index 32902bf..af27005 100644 --- a/src/makefile +++ b/src/makefile @@ -12,11 +12,7 @@ TARGET = ergodox-firmware SRC = $(shell find -maxdepth 1 -name '*.c') \ $(shell find ./keyboard -name '*.c') \ - $(shell find ./lib -name '*.c') \ - ./lib-other/peter-fleury/i2cmaster/twimaster.c \ - ./lib-other/pjrc/blinky/print.c \ - ./lib-other/pjrc/blinky/usb_debug_only.c \ - ./lib-other/arduino/arduino/libraries/Wire/utility/twi.c + $(shell find ./lib -name '*.c') EXTRAINCDIRS = . diff --git a/src/test.c b/src/test.c deleted file mode 100644 index 1868c23..0000000 --- a/src/test.c +++ /dev/null @@ -1,102 +0,0 @@ -#include -#include - -#include "lib-other/pjrc/blinky/print.h" -#include "lib-other/pjrc/blinky/usb_debug_only.h" - -#include "lib/data-types.h" - -#define TEENSY_2_0_h_INCLUDE_PRIVATE -#include "keyboard/ergodox/teensy-2-0.h" - -int blink_leds(void); -int test_i2c(void); -int test_kb_teensy(void); -int main(void); - -// ---------------------------------------------------------------------------- - -int main(void) { - teensy_init(); - - KB_LED1_SET_PERCENT(.03); - KB_LED2_SET_PERCENT(.03); - KB_LED3_SET_PERCENT(.03); - -// blink_leds(); -// print("--------------"); - test_i2c(); - print("--------------"); - test_kb_teensy(); -} - -// ---------------------------------------------------------------------------- - -int blink_leds(void) { - for (uint8_t i=0; i<3; i++) { - KB_LED1_SET(0x10); - KB_LED2_SET(0x20); - KB_LED3_SET(0xFF); - _delay_ms(500); - KB_LED1_SET(0x20); - KB_LED2_SET(0xFF); - KB_LED3_SET(0x10); - _delay_ms(500); - KB_LED1_SET(0xFF); - KB_LED2_SET(0x10); - KB_LED3_SET(0x20); - _delay_ms(500); - } - - for (uint8_t i=0; i<2; i++) { - KB_LED1_OFF; - KB_LED2_OFF; - KB_LED3_OFF; - _delay_ms(500); - KB_LED1_ON; - KB_LED2_ON; - KB_LED3_ON; - _delay_ms(500); - } - - bool counting_up = true; - for (uint8_t i=0;;) { - (counting_up) ? i++ : i--; - if (i == 0xFF) - counting_up = false; - else if (i == 0) - counting_up = true; - - KB_LED1_SET(i/2); - KB_LED2_SET(i/2); - KB_LED3_SET(i/2); - _delay_ms(10); - } -} - -int test_i2c(void) { - usb_init(); - _delay_ms(500); // just to be safe - - uint8_t ret; - - uint8_t len; - char str[10]; - - print("\nhello"); - - ret = teensy_init(); - print("\nteensy_init() returned: 0x"); phex(ret); - - ret = mcp23018_init(); - print("\nmcp23018_init() returned: 0x"); phex(ret); - - usb_debug_flush_output(); - return 0; -} - -// ---------------------------------------------------------------------------- - -int test_kb_teensy(void) { -} - diff --git a/src/test/makefile b/src/test/makefile new file mode 100644 index 0000000..657fec0 --- /dev/null +++ b/src/test/makefile @@ -0,0 +1,34 @@ +# ----------------------------------------------------------------------------- +# This is mostly a stub at the moment, but I'm keeping it separate so I can +# mess with it later without changing the original +# ----------------------------------------------------------------------------- +# Copyright (c) 2012 Ben Blazak +# Released under The MIT License (MIT) (see "license.md") +# Project located at +# ----------------------------------------------------------------------------- + + +TARGET = test + +EXTRAINCDIRS = . + +TEENSY_MAKE = $(MAKE) -f '../lib-other/pjrc/blinky/Makefile' \ + TARGET='$(TARGET)' \ + EXTRAINCDIRS='$(EXTRAINCDIRS)' + +.PHONY: test_pwm test_twi + +test_pwm: + $(TEENSY_MAKE) all \ + SRC='test_pwm.c' + +test_twi: + $(TEENSY_MAKE) all \ + SRC='test_twi.c' + +.PHONY: clean + +clean: + $(TEENSY_MAKE) clean \ + SRC='$(shell find -name '*.c')' + diff --git a/src/test/test_pwm.c b/src/test/test_pwm.c new file mode 100644 index 0000000..aadb02a --- /dev/null +++ b/src/test/test_pwm.c @@ -0,0 +1,65 @@ +/* ---------------------------------------------------------------------------- + * Test the Teensy 2.0 PWM code (see `#include`s) + * ---------------------------------------------------------------------------- + * Copyright (c) 2012 Ben Blazak + * Released under The MIT License (MIT) (see "license.md") + * Project located at + * ------------------------------------------------------------------------- */ + + +#include + +#define TEENSY_2_0_h_INCLUDE_PRIVATE +#include "../keyboard/ergodox/teensy-2-0.h" +#include "../keyboard/ergodox/teensy-2-0.c" + + +#define bool uint8_t +#define true 1 +#define false 0 + + +void main(void) { + teensy_init(); + + for (uint8_t i=0; i<3; i++) { + KB_LED1_SET(0x10); + KB_LED2_SET(0x20); + KB_LED3_SET(0xFF); + _delay_ms(500); + KB_LED1_SET(0x20); + KB_LED2_SET(0xFF); + KB_LED3_SET(0x10); + _delay_ms(500); + KB_LED1_SET(0xFF); + KB_LED2_SET(0x10); + KB_LED3_SET(0x20); + _delay_ms(500); + } + + for (uint8_t i=0; i<2; i++) { + KB_LED1_OFF; + KB_LED2_OFF; + KB_LED3_OFF; + _delay_ms(500); + KB_LED1_ON; + KB_LED2_ON; + KB_LED3_ON; + _delay_ms(500); + } + + bool counting_up = true; + for (uint8_t i=0;;) { + (counting_up) ? i++ : i--; + if (i == 0xFF) + counting_up = false; + else if (i == 0) + counting_up = true; + + KB_LED1_SET(i/2); + KB_LED2_SET(i/2); + KB_LED3_SET(i/2); + _delay_ms(10); + } +} + diff --git a/src/test/test_twi.c b/src/test/test_twi.c new file mode 100644 index 0000000..4801c8f --- /dev/null +++ b/src/test/test_twi.c @@ -0,0 +1,105 @@ +/* ---------------------------------------------------------------------------- + * Test for ACK on address write (with a Teensy 2.0 and I/O expander) + * ---------------------------------------------------------------------------- + * Copyright (c) 2012 Ben Blazak + * Released under The MIT License (MIT) (see "license.md") + * Project located at + * ------------------------------------------------------------------------- */ + +#include +#include +#include + + +// processor frequency (from ) +#define CPU_PRESCALE(n) (CLKPR = 0x80, CLKPR = (n)) +#define CPU_16MHz 0x00 +#define CPU_8MHz 0x01 +#define CPU_4MHz 0x02 +#define CPU_2MHz 0x03 +#define CPU_1MHz 0x04 +#define CPU_500kHz 0x05 +#define CPU_250kHz 0x06 +#define CPU_125kHz 0x07 +#define CPU_62kHz 0x08 + + +// ---------------------------------------------------------------------------- +// helper functions +// ---------------------------------------------------------------------------- + +#define blink_led(time1, time2) { \ + /* Teensy 2.0 onboard LED on PD6 + on high, off low */ \ + PORTD |= (1<<6); \ + _delay_ms(time1); \ + PORTD &= ~(1<<6); \ + _delay_ms(time2); \ +} + +// ---------------------------------------------------------------------------- // TWI +// ---------------------------------------------------------------------------- + +void twi_init(void) { + TWSR &= ~( (1< Date: Mon, 2 Apr 2012 01:59:00 -0700 Subject: [PATCH 14/22] mostly working on mcp23018.c; init() and update() might be ready :) also, moved the twi code to lib/teensy-2-0/twi* --- doc/references.md | 7 ++ src/keyboard/ergodox/layout.h | 36 +++--- src/keyboard/ergodox/matrix.h | 2 +- src/keyboard/ergodox/mcp23018.c | 184 +++++++++++++++-------------- src/keyboard/ergodox/mcp23018.h | 6 +- src/keyboard/ergodox/mcp23018.md | 11 +- src/keyboard/ergodox/teensy-2-0.c | 4 + src/keyboard/ergodox/teensy-2-0.md | 27 +---- src/lib-other/readme.md | 3 + src/lib/teensy-2-0/twi.c | 79 +++++++++++++ src/lib/teensy-2-0/twi.h | 25 ++++ src/lib/teensy-2-0/twi.md | 30 +++++ 12 files changed, 275 insertions(+), 139 deletions(-) create mode 100644 src/lib/teensy-2-0/twi.c create mode 100644 src/lib/teensy-2-0/twi.h create mode 100644 src/lib/teensy-2-0/twi.md diff --git a/doc/references.md b/doc/references.md index 2ff1d7c..a2a34d6 100644 --- a/doc/references.md +++ b/doc/references.md @@ -40,6 +40,13 @@ ## C Stuff +* [comp.lang.c Frequently Asked Questions] + (http://c-faq.com/index.html) + +* [The C Preprocessor] + (http://gcc.gnu.org/onlinedocs/gcc-2.95.3/cpp_1.html#SEC1) + (on ) + * [C Library Reference] (http://www.cplusplus.com/reference/) (on ) diff --git a/src/keyboard/ergodox/layout.h b/src/keyboard/ergodox/layout.h index ffc3445..861792c 100644 --- a/src/keyboard/ergodox/layout.h +++ b/src/keyboard/ergodox/layout.h @@ -14,27 +14,31 @@ #define KB_LAYERS 1 // anything >= 1, as long as there's memory + #if KB_ROWS != 12 || KB_COLUMNS != 7 + #error "Expecting different keyboard dimensions" + #endif + extern const uint8_t kb_layout[KB_LAYERS][KB_ROWS][KB_COLUMNS] = { // TODO (before release): put more effort into this // ------- layer 0: default ------- // --- right hand --- - /* 0 ---------- 1 --------------- 2 -------------- 3 ----------------- 4 --------------------- 5 -------------------------- 6 -------------------------- */ -/* 0 */ 0, KEY_6_Caret, KEY_7_Ampersand, KEY_8_Asterisk, KEY_9_LeftParenthesis, KEY_0_RightParenthesis, KEY_Dash_Underscore, /* 0 */ -/* 1 */ 0, KEY_y_Y, KEY_u_U, KEY_i_I, KEY_o_O, KEY_p_P, KEY_LeftBracket_LeftBrace, /* 1 */ -/* 2 */ 0,/*unused*/ KEY_h_H, KEY_j_J, KEY_k_K, KEY_l_L, KEY_Semicolon_Colon, KEY_SingleQuote_DoubleQuote, /* 2 */ -/* 3 */ 0, KEY_n_N, KEY_m_M, KEY_Comma_LessThan, KEY_Period_GreaterThan, KEY_Slash_Question, KEY_RightShift, /* 3 */ -/* 4 */ 0,/*unused*/ 0,/*unused*/ KEY_UpArrow, KEY_DownArrow, KEY_Backslash_Pipe, KEY_RightBracket_RightBrace, 0, /* 4 */ -/* 5 */ 0,/*unused*/ KEY_RightControl, KEY_RightAlt, KEY_PageUp, KEY_PageDown, KEY_ReturnEnter, KEY_Spacebar, /* 5 */ - /* 0 ---------- 1 --------------- 2 -------------- 3 ----------------- 4 --------------------- 5 -------------------------- 6 -------------------------- */ + /* 0 -------------------------- 1 -------------------------- 2 -------------------------- 3 -------------------------- 4 -------------------------- 5 -------------------------- 6 -------------------------- */ +/* 0 */ 0, KEY_6_Caret, KEY_7_Ampersand, KEY_8_Asterisk, KEY_9_LeftParenthesis, KEY_0_RightParenthesis, KEY_Dash_Underscore, /* 0 */ +/* 1 */ 0, KEY_y_Y, KEY_u_U, KEY_i_I, KEY_o_O, KEY_p_P, KEY_LeftBracket_LeftBrace, /* 1 */ +/* 2 */ 0,/*unused*/ KEY_h_H, KEY_j_J, KEY_k_K, KEY_l_L, KEY_Semicolon_Colon, KEY_SingleQuote_DoubleQuote, /* 2 */ +/* 3 */ 0, KEY_n_N, KEY_m_M, KEY_Comma_LessThan, KEY_Period_GreaterThan, KEY_Slash_Question, KEY_RightShift, /* 3 */ +/* 4 */ 0,/*unused*/ 0,/*unused*/ KEY_UpArrow, KEY_DownArrow, KEY_Backslash_Pipe, KEY_RightBracket_RightBrace, 0, /* 4 */ +/* 5 */ 0,/*unused*/ KEY_RightControl, KEY_RightAlt, KEY_PageUp, KEY_PageDown, KEY_ReturnEnter, KEY_Spacebar, /* 5 */ + /* 0 -------------------------- 1 -------------------------- 2 -------------------------- 3 -------------------------- 4 -------------------------- 5 -------------------------- 6 -------------------------- */ // --- left hand --- - /* 0 ------------------ 1 -------------------- 2 ----------------- 3 ------------ 4 -------------- 5 ------------ 6 ----------- */ -/* 6 */ KEY_Equal_Plus, KEY_1_Exclamation, KEY_2_At, KEY_3_Pound, KEY_4_Dollar, KEY_5_Percent, 0, /* 6 */ -/* 7 */ KEY_Tab, KEY_q_Q, KEY_w_W, KEY_e_E, KEY_r_R, KEY_t_T, 0, /* 7 */ -/* 8 */ KEY_CapsLock, KEY_a_A, KEY_s_S, KEY_d_D, KEY_f_F, KEY_g_G, 0,/*unused*/ /* 8 */ -/* 9 */ KEY_LeftShift, KEY_z_Z, KEY_x_X, KEY_c_C, KEY_v_V, KEY_b_B, 0, /* 9 */ -/* A */ 0, KEY_GraveAccent_Tilde, KEY_Backslash_Pipe, KEY_LeftArrow, KEY_RightArrow, 0,/*unused*/ 0,/*unused*/ /* A */ -/* B */ KEY_DeleteBackspace, KEY_DeleteForward, KEY_End, KEY_Home, KEY_LeftAlt, KEY_LeftControl, 0, 0 /*unused*/ /* B */ - /* 0 ------------------ 1 -------------------- 2 ----------------- 3 ------------ 4 -------------- 5 ------------ 6 ----------- */ + /* 0 -------------------------- 1 -------------------------- 2 -------------------------- 3 -------------------------- 4 -------------------------- 5 -------------------------- 6 -------------------------- */ +/* 6 */ KEY_Equal_Plus, KEY_1_Exclamation, KEY_2_At, KEY_3_Pound, KEY_4_Dollar, KEY_5_Percent, 0, /* 6 */ +/* 7 */ KEY_Tab, KEY_q_Q, KEY_w_W, KEY_e_E, KEY_r_R, KEY_t_T, 0, /* 7 */ +/* 8 */ KEY_CapsLock, KEY_a_A, KEY_s_S, KEY_d_D, KEY_f_F, KEY_g_G, 0,/*unused*/ /* 8 */ +/* 9 */ KEY_LeftShift, KEY_z_Z, KEY_x_X, KEY_c_C, KEY_v_V, KEY_b_B, 0, /* 9 */ +/* A */ 0, KEY_GraveAccent_Tilde, KEY_Backslash_Pipe, KEY_LeftArrow, KEY_RightArrow, 0,/*unused*/ 0,/*unused*/ /* A */ +/* B */ KEY_DeleteBackspace, KEY_DeleteForward, KEY_End, KEY_Home, KEY_LeftAlt, KEY_LeftControl, 0, 0 /*unused*/ /* B */ + /* 0 -------------------------- 1 -------------------------- 2 -------------------------- 3 -------------------------- 4 -------------------------- 5 -------------------------- 6 -------------------------- */ } #endif diff --git a/src/keyboard/ergodox/matrix.h b/src/keyboard/ergodox/matrix.h index f3c4fa5..89fc4ae 100644 --- a/src/keyboard/ergodox/matrix.h +++ b/src/keyboard/ergodox/matrix.h @@ -15,7 +15,7 @@ #define KB_ROWS 12 // must match real life #define KB_COLUMNS 7 // must match real life - extern bool kb_is_pressed[KB_ROWS][KB_COLUMNS] = {}; + extern bool kb_is_pressed[KB_ROWS][KB_COLUMNS] = {false}; #endif diff --git a/src/keyboard/ergodox/mcp23018.c b/src/keyboard/ergodox/mcp23018.c index 8d9b165..3733084 100644 --- a/src/keyboard/ergodox/mcp23018.c +++ b/src/keyboard/ergodox/mcp23018.c @@ -6,33 +6,16 @@ * Project located at * ------------------------------------------------------------------------- */ -// TODO: this is not working yet - - // see if the device is ready - // - success: set `mcp23018_ready = true` and continue initializing - // - failure: return `error`; we can try again later - - // set pin direction - // - unused : input : 1 - // - rows : output : 0 - // - columns : input : 1 - - // set pull-up - // - unused : on : 1 - // - rows : on : 1 - // - columns : on : 1 - - // set output pins high - // - rows : high : 1 - // - other : low : 0 (or ignored) - #include +#include "lib/data-types.h" +#define TWI_FREQ 400000 +#include "lib/teensy-2-0/twi.h" + +#include "matrix.h" #define MCP23018_h_INCLUDE_PRIVATE #include "mcp23018.h" -#include "teensy-2-0.h" -#include "lib/data-types.h" // register addresses (see "mcp23018.md") @@ -45,83 +28,106 @@ #define OLATA 0x14 // output latch register #define OLATB 0x15 +// TWI aliases +#define TWI_ADDR_WRITE ( (MCP23018_TWI_ADDRESS<<1) | TW_WRITE ) +#define TWI_ADDR_READ ( (MCP23018_TWI_ADDRESS<<1) | TW_READ ) -// ---------------------------------------------------------------------------- -// dbg -// ---------------------------------------------------------------------------- -#include -#include +// error check +#if KB_ROWS != 12 || KB_COLUMNS != 7 + #error "Expecting different keyboard dimensions" +#endif -#define blink_led(time1, time2) { \ - /* Teensy 2.0 onboard LED on PD6 - on high, off low */ \ - PORTD |= (1<<6); \ - _delay_ms(time1); \ - PORTD &= ~(1<<6); \ - _delay_ms(time2); \ -} - -void blink_hex(uint8_t num) { - // initial blink (get ready) - blink_led(700, 200); - // 1st hex number - for (uint8_t i=0; i<(num/0x10); i++) { - blink_led(200, 100); - } - _delay_ms(400); - // 2nd hex number - for (uint8_t i=0; i<(num%0x10); i++) { - blink_led(200, 100); - } -} - -// ---------------------------------------------------------------------------- // TWI -// ---------------------------------------------------------------------------- - -void twi_init(void) { - TWSR &= ~( (1< * @@ -76,6 +78,9 @@ * All addresses given for IOCON.BANK = 0, since that's the default value of the bit, and that's what we'll be using. * Outputs are open drain, so we want pull-up resistors set for everything. + * We want the row pins set as output high initially, and the column pins set + as input. We'll cycle through driving the row pins low and checking the + column pins in the update function. * abbreviations: * IODIR = I/O Direction Register diff --git a/src/keyboard/ergodox/teensy-2-0.c b/src/keyboard/ergodox/teensy-2-0.c index 34bf457..56fbb5b 100644 --- a/src/keyboard/ergodox/teensy-2-0.c +++ b/src/keyboard/ergodox/teensy-2-0.c @@ -26,6 +26,10 @@ #define CPU_62kHz 0x08 +/* returns: + * - success: 0 + * + will never return failure + */ uint8_t teensy_init(void) { CPU_PRESCALE(CPU_16MHz); // speed should match F_CPU in makefile diff --git a/src/keyboard/ergodox/teensy-2-0.md b/src/keyboard/ergodox/teensy-2-0.md index f4f3cbb..507d910 100644 --- a/src/keyboard/ergodox/teensy-2-0.md +++ b/src/keyboard/ergodox/teensy-2-0.md @@ -1,6 +1,5 @@ # Documentation : Teensy 2.0 - ## Pinouts and Pin assignments * `+` indicates pin @@ -68,7 +67,7 @@ LED, so there's no reason to set internal pull-up enabled on it. If we do, it will source current to the LED, which is fine, but unnecessary. * We want the row pins 'drive high' initially, and the column pins set as - input with internal pull-up. We'll cycle through driving the row pins low, + input with internal pull-up. We'll cycle through driving the row pins low and checking the column pins in the update function. ### PWM on ports OC1(A|B|C) (see datasheet section 14.10) @@ -103,30 +102,6 @@ * OCR = Output Compare Register * TCCR = Timer/Counter Control Register - -## I²C Status Codes (for Master modes) - -### Master Transmitter - -* `0x08` A START condition has been transmitted -* `0x10` A repeated START condition has been transmitted -* `0x18` SLA+W has been transmitted; ACK has been received -* `0x20` SLA+W has been transmitted; NOT ACK has been received -* `0x28` Data byte has been transmitted; ACK has been received -* `0x30` Data byte has been transmitted; NOT ACK has been received -* `0x38` Arbitration lost in SLA+W or data bytes - -### Master Receiver - -* `0x08` A START condition has been transmitted -* `0x10` A repeated START condition has been transmitted -* `0x38` Arbitration lost in SLA+R or NOT ACK bit -* `0x40` SLA+R has been transmitted; ACK has been received -* `0x48` SLA+R has been transmitted; NOT ACK has been received -* `0x50` Data byte has been received; ACK has been returned -* `0x58` Data byte has been received; NOT ACK has been returned - - ------------------------------------------------------------------------------- Copyright © 2012 Ben Blazak diff --git a/src/lib-other/readme.md b/src/lib-other/readme.md index 9cae856..69b2d11 100644 --- a/src/lib-other/readme.md +++ b/src/lib-other/readme.md @@ -1,3 +1,6 @@ + # src/lib-other Files taken from other projects diff --git a/src/lib/teensy-2-0/twi.c b/src/lib/teensy-2-0/twi.c new file mode 100644 index 0000000..4e77f38 --- /dev/null +++ b/src/lib/teensy-2-0/twi.c @@ -0,0 +1,79 @@ +/* ---------------------------------------------------------------------------- + * Very simple Teensy 2.0 TWI library : code + * + * - This is mostly straight from the datasheet, section 20.6.6, figure 20-11 + * (the code example in C), and section 20.8.1, figure 20-12 + * - Also see the documentation for `` at + * + * Some other (more complete) TWI libraries for the Teensy 2.0 (and other Amtel + * processors): + * - [i2cmaster] (http://homepage.hispeed.ch/peterfleury/i2cmaster.zip) + * - written by [peter-fleury] (http://homepage.hispeed.ch/peterfleury/) + * - [the arduino twi library] (https://github.com/arduino/Arduino/tree/master/libraries/Wire/utility) + * - look for an older version if you need one that doesn't depend on all the + * other Arduino stuff + * ---------------------------------------------------------------------------- + * Copyright (c) 2012 Ben Blazak + * Released under The MIT License (MIT) (see "license.md") + * Project located at + * ------------------------------------------------------------------------- */ + + +#include + +#include "twi.h" + + +void twi_init(void) { + // set the prescaler value to 0 + TWSR &= ~( (1< + * Released under The MIT License (MIT) (see "license.md") + * Project located at + * ------------------------------------------------------------------------- */ + + +#ifndef TWI_h + #define TWI_h + + #ifndef TWI_FREQ + #define TWI_FREQ 100000 + #endif + + + void twi_init(void); + uint8_t twi_start(void); + void twi_stop(void); + uint8_t twi_send(uint8_t data); + uint8_t twi_read(uint8_t * data); + +#endif + diff --git a/src/lib/teensy-2-0/twi.md b/src/lib/teensy-2-0/twi.md new file mode 100644 index 0000000..49c2126 --- /dev/null +++ b/src/lib/teensy-2-0/twi.md @@ -0,0 +1,30 @@ +# Documentation : Teensy 2.0 I²C + +## I²C Status Codes (for Master modes) + +### Master Transmitter (datasheet section 20.8.1, table 20-3) + +* `0x08` A START condition has been transmitted +* `0x10` A repeated START condition has been transmitted +* `0x18` SLA+W has been transmitted; ACK has been received +* `0x20` SLA+W has been transmitted; NOT ACK has been received +* `0x28` Data byte has been transmitted; ACK has been received +* `0x30` Data byte has been transmitted; NOT ACK has been received +* `0x38` Arbitration lost in SLA+W or data bytes + +### Master Receiver (datasheet section 20.8.2, table 20-4) + +* `0x08` A START condition has been transmitted +* `0x10` A repeated START condition has been transmitted +* `0x38` Arbitration lost in SLA+R or NOT ACK bit +* `0x40` SLA+R has been transmitted; ACK has been received +* `0x48` SLA+R has been transmitted; NOT ACK has been received +* `0x50` Data byte has been received; ACK has been returned +* `0x58` Data byte has been received; NOT ACK has been returned + +------------------------------------------------------------------------------- + +Copyright © 2012 Ben Blazak +Released under The MIT License (MIT) (see "license.md") +Project located at + From 2dce6e406661d25d16fc0b523599784b77080720 Mon Sep 17 00:00:00 2001 From: Ben Blazak Date: Thu, 5 Apr 2012 03:08:20 -0700 Subject: [PATCH 15/22] lots - fixed some includes (`uint8_t` comes from a header, not the language) - put code from some of the .h files into .c files - now using open drain logic (hi-Z or GND) on both chips instead of driving the row pins high on the teensy, or using a pull-up resistor on the row pins with the mcp23018 - put `return 0;` at the end of some functions that weren't void - fixed/updated some documentation; esp. the row assignments for the mcp23018 - generalized the unused/row/column pin assignment and init code using macros, so they'll be much easier to move around if necessary - fixed a redefinition error in "lib/usb/keyboard-usage-page.h" --- src/firmware.c | 2 +- src/keyboard/ergodox/layout.h | 33 +------- src/keyboard/ergodox/matrix.h | 2 +- src/keyboard/ergodox/matrix.md | 9 +-- src/keyboard/ergodox/mcp23018.c | 39 +++++---- src/keyboard/ergodox/mcp23018.h | 2 + src/keyboard/ergodox/mcp23018.md | 19 ++--- src/keyboard/ergodox/teensy-2-0.c | 124 ++++++++++++++++++++++++----- src/keyboard/ergodox/teensy-2-0.h | 2 + src/keyboard/ergodox/teensy-2-0.md | 28 ++++--- src/lib/data-types.h | 6 +- src/lib/teensy-2-0/twi.c | 5 +- src/lib/usb/keyboard-usage-page.h | 2 +- src/makefile | 1 + 14 files changed, 170 insertions(+), 104 deletions(-) diff --git a/src/firmware.c b/src/firmware.c index 93fed58..e72df08 100644 --- a/src/firmware.c +++ b/src/firmware.c @@ -13,6 +13,6 @@ // TODO -void main(void) { +int main(void) { } diff --git a/src/keyboard/ergodox/layout.h b/src/keyboard/ergodox/layout.h index 861792c..c9d76f6 100644 --- a/src/keyboard/ergodox/layout.h +++ b/src/keyboard/ergodox/layout.h @@ -1,5 +1,5 @@ /* ---------------------------------------------------------------------------- - * ergoDOX layout + * ergoDOX layout specific exports * ---------------------------------------------------------------------------- * Copyright (c) 2012 Ben Blazak * Released under The MIT License (MIT) (see "license.md") @@ -9,38 +9,13 @@ #ifndef LAYOUT_h #define LAYOUT_h - #include "lib/usb/keyboard-usage-page.h" + #include "lib/data-types.h" + #include "matrix.h" #define KB_LAYERS 1 // anything >= 1, as long as there's memory - #if KB_ROWS != 12 || KB_COLUMNS != 7 - #error "Expecting different keyboard dimensions" - #endif - - extern const uint8_t kb_layout[KB_LAYERS][KB_ROWS][KB_COLUMNS] = { -// TODO (before release): put more effort into this -// ------- layer 0: default ------- -// --- right hand --- - /* 0 -------------------------- 1 -------------------------- 2 -------------------------- 3 -------------------------- 4 -------------------------- 5 -------------------------- 6 -------------------------- */ -/* 0 */ 0, KEY_6_Caret, KEY_7_Ampersand, KEY_8_Asterisk, KEY_9_LeftParenthesis, KEY_0_RightParenthesis, KEY_Dash_Underscore, /* 0 */ -/* 1 */ 0, KEY_y_Y, KEY_u_U, KEY_i_I, KEY_o_O, KEY_p_P, KEY_LeftBracket_LeftBrace, /* 1 */ -/* 2 */ 0,/*unused*/ KEY_h_H, KEY_j_J, KEY_k_K, KEY_l_L, KEY_Semicolon_Colon, KEY_SingleQuote_DoubleQuote, /* 2 */ -/* 3 */ 0, KEY_n_N, KEY_m_M, KEY_Comma_LessThan, KEY_Period_GreaterThan, KEY_Slash_Question, KEY_RightShift, /* 3 */ -/* 4 */ 0,/*unused*/ 0,/*unused*/ KEY_UpArrow, KEY_DownArrow, KEY_Backslash_Pipe, KEY_RightBracket_RightBrace, 0, /* 4 */ -/* 5 */ 0,/*unused*/ KEY_RightControl, KEY_RightAlt, KEY_PageUp, KEY_PageDown, KEY_ReturnEnter, KEY_Spacebar, /* 5 */ - /* 0 -------------------------- 1 -------------------------- 2 -------------------------- 3 -------------------------- 4 -------------------------- 5 -------------------------- 6 -------------------------- */ -// --- left hand --- - /* 0 -------------------------- 1 -------------------------- 2 -------------------------- 3 -------------------------- 4 -------------------------- 5 -------------------------- 6 -------------------------- */ -/* 6 */ KEY_Equal_Plus, KEY_1_Exclamation, KEY_2_At, KEY_3_Pound, KEY_4_Dollar, KEY_5_Percent, 0, /* 6 */ -/* 7 */ KEY_Tab, KEY_q_Q, KEY_w_W, KEY_e_E, KEY_r_R, KEY_t_T, 0, /* 7 */ -/* 8 */ KEY_CapsLock, KEY_a_A, KEY_s_S, KEY_d_D, KEY_f_F, KEY_g_G, 0,/*unused*/ /* 8 */ -/* 9 */ KEY_LeftShift, KEY_z_Z, KEY_x_X, KEY_c_C, KEY_v_V, KEY_b_B, 0, /* 9 */ -/* A */ 0, KEY_GraveAccent_Tilde, KEY_Backslash_Pipe, KEY_LeftArrow, KEY_RightArrow, 0,/*unused*/ 0,/*unused*/ /* A */ -/* B */ KEY_DeleteBackspace, KEY_DeleteForward, KEY_End, KEY_Home, KEY_LeftAlt, KEY_LeftControl, 0, 0 /*unused*/ /* B */ - /* 0 -------------------------- 1 -------------------------- 2 -------------------------- 3 -------------------------- 4 -------------------------- 5 -------------------------- 6 -------------------------- */ - } + extern uint8_t const kb_layout[KB_LAYERS][KB_ROWS][KB_COLUMNS]; #endif - diff --git a/src/keyboard/ergodox/matrix.h b/src/keyboard/ergodox/matrix.h index 89fc4ae..43b95bf 100644 --- a/src/keyboard/ergodox/matrix.h +++ b/src/keyboard/ergodox/matrix.h @@ -15,7 +15,7 @@ #define KB_ROWS 12 // must match real life #define KB_COLUMNS 7 // must match real life - extern bool kb_is_pressed[KB_ROWS][KB_COLUMNS] = {false}; + extern bool kb_is_pressed[KB_ROWS][KB_COLUMNS]; #endif diff --git a/src/keyboard/ergodox/matrix.md b/src/keyboard/ergodox/matrix.md index dde42b4..723e5f0 100644 --- a/src/keyboard/ergodox/matrix.md +++ b/src/keyboard/ergodox/matrix.md @@ -1,11 +1,10 @@ # Documentation : Keyboard Matrix -## Matrix [row.column] assignments +## Matrix [row##column] assignments - * row and column numbers are in hex - * coordinates without brackets are unused - * left and right hands are mostly the same, except that `row += 6` for left - hand rows +* row and column numbers are in hex +* coordinates without brackets are unused +* left and right hands are mostly the same except that `row += 6` for the left ....... rows x columns = positions; assigned, unassigned ....... ....... per hand: 6 x 7 = 42; 38, 4 ....... diff --git a/src/keyboard/ergodox/mcp23018.c b/src/keyboard/ergodox/mcp23018.c index 3733084..a1de01f 100644 --- a/src/keyboard/ergodox/mcp23018.c +++ b/src/keyboard/ergodox/mcp23018.c @@ -33,12 +33,6 @@ #define TWI_ADDR_READ ( (MCP23018_TWI_ADDRESS<<1) | TW_READ ) -// error check -#if KB_ROWS != 12 || KB_COLUMNS != 7 - #error "Expecting different keyboard dimensions" -#endif - - /* * returns: * - success: 0 @@ -69,36 +63,37 @@ uint8_t mcp23018_init(void) { twi_send(0b11111111); // IODIRB // set pull-up - // - unused : on : 1 - // - rows : on : 1 - // - columns : on : 1 + // - unused : on : 1 + // - rows : off : 0 + // - columns : on : 1 twi_start(); twi_send(TWI_ADDR_WRITE); twi_send(GPPUA); - twi_send(0b11111111); // GPPUA + twi_send(0b11000000); // GPPUA twi_send(0b11111111); // GPPUB - // set output pins high - // - unused : low : 0 - // - rows : high : 1 - // - columns : low : 0 + // set logical value (doesn't matter on inputs) + // - unused : high (hi-Z) : 1 + // - rows : high (hi-Z) : 1 + // - columns : high (hi-Z) : 1 twi_start(); twi_send(TWI_ADDR_WRITE); twi_send(GPIOA); - twi_send(0b00111111); //GPIOA - twi_send(0b00000000); //GPIOB + twi_send(0b11111111); //GPIOA + twi_send(0b11111111); //GPIOB twi_stop(); + + return 0; // success } -/* args: - * - `matrix[][]`: `KB_ROWS` and `KB_COLUMNS` must be what we're expecting (see - * 'error check' in the `#include` section) - * - * returns: +/* returns: * - success: 0 * - failure: twi status code */ +#if KB_ROWS != 12 || KB_COLUMNS != 7 + #error "Expecting different keyboard dimensions" +#endif uint8_t mcp23018_update_matrix(uint8_t matrix[KB_ROWS][KB_COLUMNS]) { uint8_t ret, data; @@ -129,5 +124,7 @@ uint8_t mcp23018_update_matrix(uint8_t matrix[KB_ROWS][KB_COLUMNS]) { } twi_stop(); + + return 0; // success } diff --git a/src/keyboard/ergodox/mcp23018.h b/src/keyboard/ergodox/mcp23018.h index 5952182..39327e3 100644 --- a/src/keyboard/ergodox/mcp23018.h +++ b/src/keyboard/ergodox/mcp23018.h @@ -10,6 +10,8 @@ #ifndef MCP23018_h #define MCP23018_h + #include "lib/data-types.h" + #ifdef MCP23018_h_INCLUDE_PRIVATE #define MCP23018_TWI_ADDRESS 0b0100000 diff --git a/src/keyboard/ergodox/mcp23018.md b/src/keyboard/ergodox/mcp23018.md index 216d53d..492db5d 100644 --- a/src/keyboard/ergodox/mcp23018.md +++ b/src/keyboard/ergodox/mcp23018.md @@ -43,13 +43,14 @@ * notes: * ADDR (pin15): Set slave address to `0b0100000` by connecting to Vss(GND). (The user-defined bits are the three least significant). - * RESET (pin16) must be externally biased.Since we're not going to trigger it - ourselves, we'll tie it high. + * RESET (pin16) must be externally biased. Since we're not going to trigger + it ourselves, we can tie it high. * This is not noted in the I2C Pinout Description section of the MCP23018 datasheet, but it's true (empirically), and it is noted in the SPI Pinout - Description section, and in the MCP23017 datasheet. - * - * + Description section, and in the MCP23017 datasheet. + * I'm not the first person who's failed to notice ;) + * + * ## Notes about Registers @@ -77,10 +78,10 @@ * notes: * All addresses given for IOCON.BANK = 0, since that's the default value of the bit, and that's what we'll be using. - * Outputs are open drain, so we want pull-up resistors set for everything. - * We want the row pins set as output high initially, and the column pins set - as input. We'll cycle through driving the row pins low and checking the - column pins in the update function. + * We want the row pins set as output high (hi-Z) without pull-ups initially, + and the column pins set as input with pull-ups. We'll cycle through + driving the row pins low and checking the column pins in the update + function. * abbreviations: * IODIR = I/O Direction Register diff --git a/src/keyboard/ergodox/teensy-2-0.c b/src/keyboard/ergodox/teensy-2-0.c index 56fbb5b..39e4233 100644 --- a/src/keyboard/ergodox/teensy-2-0.c +++ b/src/keyboard/ergodox/teensy-2-0.c @@ -9,6 +9,8 @@ #include +#include "lib/data-types.h" + #define TEENSY_2_0_h_INCLUDE_PRIVATE #include "teensy-2-0.h" @@ -26,6 +28,54 @@ #define CPU_62kHz 0x08 +/* pin macros + * - note: you can move the `UNUSED`, `ROW`, and `COLUMN` pins around, but be + * sure to keep the set of pins listed in those catagories constant. other + * pins are not movable, and either are referenced explicitly or have macros + * defined for them elsewhere. + * - note: if you change pin assignments, please be sure to update + * "teensy-2-0.md". + */ +// --- helpers +#define TEENSYPIN_WRITE(register, operation, pin) \ + _TEENSYPIN_WRITE(register, operation, pin) +#define _TEENSYPIN_WRITE(register, operation, pin_letter, pin_number) \ + ((register##pin_letter) operation (1<<(pin_number))) + +#define TEENSYPIN_READ(pin) \ + _TEENSYPIN_READ(pin) +#define _TEENSYPIN_READ(pin_letter, pin_number) \ + ((PIN##pin_letter) & (1<<(pin_number))) + +#define SET |= +#define CLEAR &=~ + +// --- unused +#define UNUSED_0 B, 1 // SPI pin +#define UNUSED_1 B, 2 // SPI pin +#define UNUSED_2 B, 3 // SPI pin +#define UNUSED_3 D, 4 // hard to use with breadboard (on the end) +#define UNUSED_4 D, 5 // hard to use with breadboard (on the end) +#define UNUSED_5 E, 6 // hard to use with breadboard (internal) + +// --- rows +#define ROW_0 F, 0 +#define ROW_1 F, 1 +#define ROW_2 F, 4 +#define ROW_3 F, 5 +#define ROW_4 F, 6 +#define ROW_5 F, 7 + +// --- columns +#define COLUMN_0 B, 4 +#define COLUMN_1 C, 6 +#define COLUMN_2 C, 7 +#define COLUMN_3 D, 2 +#define COLUMN_4 D, 3 +#define COLUMN_5 D, 7 +#define COLUMN_6 B, 0 + + /* returns: * - success: 0 * + will never return failure @@ -33,34 +83,68 @@ uint8_t teensy_init(void) { CPU_PRESCALE(CPU_16MHz); // speed should match F_CPU in makefile - // unused pins - DDRB &= ~0b00001110; // set B(3,2,1) as input - PORTB |= 0b00001110; // set B(3,2,1) internal pull-up enabled - DDRD &= ~0b01110000; // set D(6,5,4) as input - PORTD |= 0b00110000; // set D( 5,4) internal pull-up enabled - DDRE &= ~0b01000000; // set E(6) as input - PORTE |= 0b01000000; // set E(6) internal pull-up enabled + // onboard LED + DDRD &= ~(1<<6); // set D(6) as input + PORTD &= ~(1<<6); // set D(6) internal pull-up disabled - // LEDs (see "PWM on ports OC1(A|B|C)" in "teensy-2-0.md") + // keyboard LEDs (see "PWM on ports OC1(A|B|C)" in "teensy-2-0.md") DDRB |= 0b11100000; // set B(7,6,5) as output TCCR1A = 0b10101001; // set and configure fast PWM TCCR1B = 0b00001001; // set and configure fast PWM + // I2C (TWI) + // on pins D(1,0); leave them alone here so the TWI library can do as + // it wishes + + // unused pins + // --- set as input + TEENSYPIN_WRITE(DDR, CLEAR, UNUSED_0); + TEENSYPIN_WRITE(DDR, CLEAR, UNUSED_1); + TEENSYPIN_WRITE(DDR, CLEAR, UNUSED_2); + TEENSYPIN_WRITE(DDR, CLEAR, UNUSED_3); + TEENSYPIN_WRITE(DDR, CLEAR, UNUSED_4); + TEENSYPIN_WRITE(DDR, CLEAR, UNUSED_5); + // --- set internal pull-up enabled + TEENSYPIN_WRITE(PORT, SET, UNUSED_0); + TEENSYPIN_WRITE(PORT, SET, UNUSED_1); + TEENSYPIN_WRITE(PORT, SET, UNUSED_2); + TEENSYPIN_WRITE(PORT, SET, UNUSED_3); + TEENSYPIN_WRITE(PORT, SET, UNUSED_4); + TEENSYPIN_WRITE(PORT, SET, UNUSED_5); + // rows - DDRF |= 0b11110011; // set F(7,6,5,4,1,0) as output - PORTF |= 0b11110011; // set F(7,6,5,4,1,0) drive high + // --- set as input (hi-Z) + TEENSYPIN_WRITE(DDR, CLEAR, ROW_0); + TEENSYPIN_WRITE(DDR, CLEAR, ROW_1); + TEENSYPIN_WRITE(DDR, CLEAR, ROW_2); + TEENSYPIN_WRITE(DDR, CLEAR, ROW_3); + TEENSYPIN_WRITE(DDR, CLEAR, ROW_4); + TEENSYPIN_WRITE(DDR, CLEAR, ROW_5); + // --- set internal pull-up disabled + TEENSYPIN_WRITE(PORT, CLEAR, ROW_0); + TEENSYPIN_WRITE(PORT, CLEAR, ROW_1); + TEENSYPIN_WRITE(PORT, CLEAR, ROW_2); + TEENSYPIN_WRITE(PORT, CLEAR, ROW_3); + TEENSYPIN_WRITE(PORT, CLEAR, ROW_4); + TEENSYPIN_WRITE(PORT, CLEAR, ROW_5); // columns - DDRB &= ~0b00010001; // set B(4,0) as input - PORTB |= 0b00010001; // set B(4,0) internal pull-up enabled - DDRC &= ~0b11000000; // set C(7,6) as input - PORTC |= 0b11000000; // set C(7,6) internal pull-up enabled - DDRD &= ~0b10001100; // set D(7,3,2) as input - PORTD |= 0b10001100; // set D(7,3,2) internal pull-up enabled - - // I2C (TWI) - // on pins D(1,0); leave them alone here, so the TWI library can do as - // it wishes + // --- set as input + TEENSYPIN_WRITE(DDR, CLEAR, COLUMN_0); + TEENSYPIN_WRITE(DDR, CLEAR, COLUMN_1); + TEENSYPIN_WRITE(DDR, CLEAR, COLUMN_2); + TEENSYPIN_WRITE(DDR, CLEAR, COLUMN_3); + TEENSYPIN_WRITE(DDR, CLEAR, COLUMN_4); + TEENSYPIN_WRITE(DDR, CLEAR, COLUMN_5); + TEENSYPIN_WRITE(DDR, CLEAR, COLUMN_6); + // --- set internal pull-up enabled + TEENSYPIN_WRITE(PORT, SET, COLUMN_0); + TEENSYPIN_WRITE(PORT, SET, COLUMN_1); + TEENSYPIN_WRITE(PORT, SET, COLUMN_2); + TEENSYPIN_WRITE(PORT, SET, COLUMN_3); + TEENSYPIN_WRITE(PORT, SET, COLUMN_4); + TEENSYPIN_WRITE(PORT, SET, COLUMN_5); + TEENSYPIN_WRITE(PORT, SET, COLUMN_6); return 0; // success } diff --git a/src/keyboard/ergodox/teensy-2-0.h b/src/keyboard/ergodox/teensy-2-0.h index 1dc7770..06b0e47 100644 --- a/src/keyboard/ergodox/teensy-2-0.h +++ b/src/keyboard/ergodox/teensy-2-0.h @@ -12,6 +12,8 @@ #include // for the register macros + #include "lib/data-types.h" + // LED control #define KB_LED1_ON (DDRB |= (1<<5)) #define KB_LED1_OFF (DDRB &= ~(1<<5)) diff --git a/src/keyboard/ergodox/teensy-2-0.md b/src/keyboard/ergodox/teensy-2-0.md index 507d910..8864860 100644 --- a/src/keyboard/ergodox/teensy-2-0.md +++ b/src/keyboard/ergodox/teensy-2-0.md @@ -28,12 +28,12 @@ ### Teensy 2.0 Pin Assignments power_negative GND +---.....---+ Vcc power_positive - column6 PB0 + + PF0 row6 - o + PF1 row7 - o + PF4 row8 - o o o + PF5 row9 - LED3 OC1C + + PF6 rowA - I2C SCL + + PF7 rowB + column6 PB0 + + PF0 row0 + o + PF1 row1 + o + PF4 row2 + o o o + PF5 row3 + LED3 OC1C + + PF6 row4 + I2C SCL + + PF7 row5 I2C SDA + + OC1B LED2 column3 PD2 + + OC1A LED1 column4 PD3 + + PB4 column0 @@ -63,12 +63,16 @@ * notes: * Unused pins should be set as input with internal pullup enabled (see datasheet section 10.2.6) in order to give them a defined level. - * PD6 already has a defined level (low) since it's hooked up to the onboard - LED, so there's no reason to set internal pull-up enabled on it. If we - do, it will source current to the LED, which is fine, but unnecessary. - * We want the row pins 'drive high' initially, and the column pins set as - input with internal pull-up. We'll cycle through driving the row pins low - and checking the column pins in the update function. + * PD6 already has a defined level (low) since it's hooked up to the onboard + LED, so there's no reason to set internal pull-up enabled on it. If we do, + it will source current to the LED, which is fine, but unnecessary. + * We want the row pins 'hi-Z' initially (set as input with pull-up disabled), + and the column pins set as input with internal pull-up enabled. We'll + cycle through driving the row pins low (setting them as output) and + checking the column pins in the update function. + * Switching the row pins between hi-Z and drive low (treating them as if + they were open drain) seems just as good as, and a little safer than, + driving them high when the row's not active. ### PWM on ports OC1(A|B|C) (see datasheet section 14.10) diff --git a/src/lib/data-types.h b/src/lib/data-types.h index 594ca1d..cd7d470 100644 --- a/src/lib/data-types.h +++ b/src/lib/data-types.h @@ -10,13 +10,11 @@ #ifndef DATA_TYPES_h #define DATA_TYPES_h - // -------------------------------------------------------------------- - #define bool _Bool + #include + #define bool _Bool #define true ((bool)1) #define false ((bool)0) - // -------------------------------------------------------------------- - #endif diff --git a/src/lib/teensy-2-0/twi.c b/src/lib/teensy-2-0/twi.c index 4e77f38..9f339a1 100644 --- a/src/lib/teensy-2-0/twi.c +++ b/src/lib/teensy-2-0/twi.c @@ -42,6 +42,7 @@ uint8_t twi_start(void) { if (! (TW_STATUS == TW_START) || (TW_STATUS == TW_REP_START) ) return TW_STATUS; // error + return 0; // success } void twi_stop(void) { @@ -63,6 +64,7 @@ uint8_t twi_send(uint8_t data) { (TW_STATUS == TW_MT_DATA_ACK)|| (TW_STATUS == TW_MR_SLA_ACK) ) return TW_STATUS; // error + return 0; // success } uint8_t twi_read(uint8_t * data) { @@ -71,9 +73,10 @@ uint8_t twi_read(uint8_t * data) { // wait for transmission to complete while (!(TWCR & (1< Date: Fri, 6 Apr 2012 00:19:57 -0700 Subject: [PATCH 16/22] wrote teensy update() (need to test); minor mcp23018 update() fix --- src/keyboard/ergodox/mcp23018.c | 9 +++++- src/keyboard/ergodox/teensy-2-0.c | 52 +++++++++++++++++++++++++++++-- src/keyboard/ergodox/teensy-2-0.h | 2 ++ 3 files changed, 59 insertions(+), 4 deletions(-) diff --git a/src/keyboard/ergodox/mcp23018.c b/src/keyboard/ergodox/mcp23018.c index a1de01f..62f224e 100644 --- a/src/keyboard/ergodox/mcp23018.c +++ b/src/keyboard/ergodox/mcp23018.c @@ -108,10 +108,11 @@ uint8_t mcp23018_update_matrix(uint8_t matrix[KB_ROWS][KB_COLUMNS]) { for (uint8_t row=0x6; row<=0xB; row++) { // set row low : 0 + // set other rows high : 1 twi_start(); twi_send(TWI_ADDR_WRITE); twi_send(GPIOA); - twi_send( 0b00111111 & ~(1<<(row-6)) ); // GPIOA + twi_send( 0b11111111 & ~(1<<(row-6)) ); // GPIOA // get column data twi_start(); @@ -123,6 +124,12 @@ uint8_t mcp23018_update_matrix(uint8_t matrix[KB_ROWS][KB_COLUMNS]) { matrix[row][col] = !( data & (1< Date: Fri, 6 Apr 2012 00:21:07 -0700 Subject: [PATCH 17/22] (forgot to add these to git the other day) --- src/keyboard/ergodox/layout.c | 44 +++++++++++++++++++++++++++++++++++ src/keyboard/ergodox/matrix.c | 16 +++++++++++++ 2 files changed, 60 insertions(+) create mode 100644 src/keyboard/ergodox/layout.c create mode 100644 src/keyboard/ergodox/matrix.c diff --git a/src/keyboard/ergodox/layout.c b/src/keyboard/ergodox/layout.c new file mode 100644 index 0000000..0a0655c --- /dev/null +++ b/src/keyboard/ergodox/layout.c @@ -0,0 +1,44 @@ +/* ---------------------------------------------------------------------------- + * ergoDOX layout specific code + * ---------------------------------------------------------------------------- + * Copyright (c) 2012 Ben Blazak + * Released under The MIT License (MIT) (see "license.md") + * Project located at + * ------------------------------------------------------------------------- */ + + +#include "lib/data-types.h" +#include "lib/usb/keyboard-usage-page.h" + +#include "matrix.h" +#include "layout.h" + + +// TODO (before release): put more effort into this +#if KB_ROWS != 12 || KB_COLUMNS != 7 + #error "Expecting different keyboard dimensions" +#endif +uint8_t const kb_layout[KB_LAYERS][KB_ROWS][KB_COLUMNS] = { +{ // layer 0: default + // right hand + /* 0 -------------------------- 1 -------------------------- 2 -------------------------- 3 -------------------------- 4 -------------------------- 5 -------------------------- 6 -------------------------- */ +/* 0 */ { 0, KEY_6_Caret, KEY_7_Ampersand, KEY_8_Asterisk, KEY_9_LeftParenthesis, KEY_0_RightParenthesis, KEY_Dash_Underscore }, /* 0 */ +/* 1 */ { 0, KEY_y_Y, KEY_u_U, KEY_i_I, KEY_o_O, KEY_p_P, KEY_LeftBracket_LeftBrace }, /* 1 */ +/* 2 */ { 0,/*unused*/ KEY_h_H, KEY_j_J, KEY_k_K, KEY_l_L, KEY_Semicolon_Colon, KEY_SingleQuote_DoubleQuote }, /* 2 */ +/* 3 */ { 0, KEY_n_N, KEY_m_M, KEY_Comma_LessThan, KEY_Period_GreaterThan, KEY_Slash_Question, KEY_RightShift }, /* 3 */ +/* 4 */ { 0,/*unused*/ 0,/*unused*/ KEY_UpArrow, KEY_DownArrow, KEY_Backslash_Pipe, KEY_RightBracket_RightBrace, 0 }, /* 4 */ +/* 5 */ { 0,/*unused*/ KEY_RightControl, KEY_RightAlt, KEY_PageUp, KEY_PageDown, KEY_ReturnEnter, KEY_Spacebar }, /* 5 */ + /* 0 -------------------------- 1 -------------------------- 2 -------------------------- 3 -------------------------- 4 -------------------------- 5 -------------------------- 6 -------------------------- */ + // left hand + /* 0 -------------------------- 1 -------------------------- 2 -------------------------- 3 -------------------------- 4 -------------------------- 5 -------------------------- 6 -------------------------- */ +/* 6 */ { KEY_Equal_Plus, KEY_1_Exclamation, KEY_2_At, KEY_3_Pound, KEY_4_Dollar, KEY_5_Percent, 0 }, /* 6 */ +/* 7 */ { KEY_Tab, KEY_q_Q, KEY_w_W, KEY_e_E, KEY_r_R, KEY_t_T, 0 }, /* 7 */ +/* 8 */ { KEY_CapsLock, KEY_a_A, KEY_s_S, KEY_d_D, KEY_f_F, KEY_g_G, 0/*unused*/ }, /* 8 */ +/* 9 */ { KEY_LeftShift, KEY_z_Z, KEY_x_X, KEY_c_C, KEY_v_V, KEY_b_B, 0 }, /* 9 */ +/* A */ { 0, KEY_GraveAccent_Tilde, KEY_Backslash_Pipe, KEY_LeftArrow, KEY_RightArrow, 0,/*unused*/ 0/*unused*/ }, /* A */ +/* B */ { KEY_DeleteBackspace, KEY_DeleteForward, KEY_End, KEY_Home, KEY_LeftAlt, KEY_LeftControl, 0/*unused*/ } /* B */ + /* 0 -------------------------- 1 -------------------------- 2 -------------------------- 3 -------------------------- 4 -------------------------- 5 -------------------------- 6 -------------------------- */ +} + +}; + diff --git a/src/keyboard/ergodox/matrix.c b/src/keyboard/ergodox/matrix.c new file mode 100644 index 0000000..a7761bf --- /dev/null +++ b/src/keyboard/ergodox/matrix.c @@ -0,0 +1,16 @@ +/* ---------------------------------------------------------------------------- + * ergoDOX: keyboard matrix specific code + * ---------------------------------------------------------------------------- + * Copyright (c) 2012 Ben Blazak + * Released under The MIT License (MIT) (see "license.md") + * Project located at + * ------------------------------------------------------------------------- */ + + +#include "lib/data-types.h" + +#include "matrix.h" + + +bool kb_is_pressed[KB_ROWS][KB_COLUMNS] = {{false}}; + From 57e82aebcf7e616284689646653549ce7dde0a6b Mon Sep 17 00:00:00 2001 From: Ben Blazak Date: Tue, 10 Apr 2012 01:44:27 -0700 Subject: [PATCH 18/22] lots and lots; now writing/debugging keyboard logic also, mcp23018_init() needs fixing: `twi_stop()` needs to be at the end of transmission blocks. i wouldn't think that would be necessary, but it seems to be the only thing that'll make it work, and it also seems consistent with the protocol diagram in the datasheet (lol, imagine that), so i think that's what i'll have to do. not as though it matters much i guess, since it's a single master / single slave system anyway, i was just hoping not to release the bus till i was finished.. --- doc/references.md | 38 ++++++- src/firmware.c | 18 --- src/key-functions.c | 90 +++++++++++++++ src/key-functions.h | 31 +++++ src/keyboard.h | 12 ++ src/keyboard/ergodox.c | 43 +++++++ src/keyboard/ergodox.h | 24 ++++ src/keyboard/ergodox/layout.c | 58 +++++++++- src/keyboard/ergodox/layout.h | 11 +- src/keyboard/ergodox/matrix.c | 6 +- src/keyboard/ergodox/matrix.h | 4 +- src/keyboard/ergodox/mcp23018.c | 106 ++++++++++++------ src/keyboard/ergodox/mcp23018.h | 4 +- src/keyboard/ergodox/mcp23018.md | 4 +- src/keyboard/ergodox/teensy-2-0.c | 45 ++++---- src/keyboard/ergodox/teensy-2-0.h | 6 +- src/keyboard/ergodox/teensy-2-0.md | 20 ++-- .../pjrc/usb_keyboard/usb_keyboard.c | 3 +- .../pjrc/usb_keyboard/usb_keyboard.h | 4 + src/lib/data-types.h | 1 + src/lib/teensy-2-0/twi.c | 10 +- src/lib/teensy-2-0/twi.h | 2 +- src/main.c | 98 ++++++++++++++++ src/makefile | 10 +- src/test/makefile | 8 +- src/test/test_pwm.c | 34 ++++-- src/test/test_twi_2.c | 92 +++++++++++++++ 27 files changed, 662 insertions(+), 120 deletions(-) delete mode 100644 src/firmware.c create mode 100644 src/key-functions.c create mode 100644 src/key-functions.h create mode 100644 src/main.c create mode 100644 src/test/test_twi_2.c diff --git a/doc/references.md b/doc/references.md index a2a34d6..c57a2c6 100644 --- a/doc/references.md +++ b/doc/references.md @@ -70,12 +70,28 @@ (http://www.ibiblio.org/pub/languages/fortran/append-c.html) (on ) +* [how to use array of function pointers?] + (http://stackoverflow.com/questions/252748/how-to-use-array-of-function-pointers) + (on ) + +* [The Function Pointer Tutorials] + (http://www.newty.de/fpt/index.html) + * [C preprocessor and concatenation] (http://stackoverflow.com/questions/1489932/c-preprocessor-and-concatenation) (on ) +* [The New C: Inline Functions] + (http://drdobbs.com/184401540) + by Randy Meyers + (on ) + ### For the AVR +* [AVR Newbie guide] + (http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=70673) + by stu_san (on ) + * [AVR Libc Library Reference] (http://www.nongnu.org/avr-libc/user-manual/modules.html) @@ -83,8 +99,9 @@ (http://svn.savannah.nongnu.org/viewvc/trunk/avr-libc/include/avr/iom32u4.h?revision=2288&root=avr-libc&view=markup) : list of registers and associated bit numbers for ATmega32U4 -* [A Brief Tutorial on Programming the AVR without Arduino] by Chris Kuethe +* [A Brief Tutorial on Programming the AVR without Arduino] (https://www.mainframe.cx/~ckuethe/avr-c-tutorial/) + by Chris Kuethe ## Protocol Stuff @@ -137,13 +154,22 @@ (http://geekhack.org/showwiki.php?title=Island:26742) article (on ) +* github: [tmk / tmk_keyboard] + (https://github.com/tmk/tmk_keyboard) -* github: [Pyrolistical / tmk_keyboard] - (https://github.com/Pyrolistical/tmk_keyboard/tree/master/fourway) + * forked by [Pyrolistical / tmk_keyboard] + (https://github.com/Pyrolistical/tmk_keyboard/tree/master/fourway) - * mentioned in the [KeyPoard] - (http://geekhack.org/showwiki.php?title=Island:26845) - article (on ) + * mentioned in the [KeyPoard] + (http://geekhack.org/showwiki.php?title=Island:26845) + article on + + * forked by [riffautae / tmk_keyboard] + (https://github.com/riffautae/tmk_keyboard) + + * mentioned on the [Teensy Keyboard Firmware Discussion] + (http://geekhack.org/showthread.php?26730-Teensy-Keyboard-Firmware-Discussion/page2) + thread on * github: [humblehacker / keyboard] (https://github.com/humblehacker/keyboard) diff --git a/src/firmware.c b/src/firmware.c deleted file mode 100644 index e72df08..0000000 --- a/src/firmware.c +++ /dev/null @@ -1,18 +0,0 @@ -/* ---------------------------------------------------------------------------- - * main() - * ---------------------------------------------------------------------------- - * Copyright (c) 2012 Ben Blazak - * Released under The MIT License (MIT) (see "license.md") - * Project located at - * ------------------------------------------------------------------------- */ - - -// #include "lib/pjrc/print.h" - -// #include "keyboard.h" - - -// TODO -int main(void) { -} - diff --git a/src/key-functions.c b/src/key-functions.c new file mode 100644 index 0000000..f09c656 --- /dev/null +++ b/src/key-functions.c @@ -0,0 +1,90 @@ +/* ---------------------------------------------------------------------------- + * key functions: code + * ---------------------------------------------------------------------------- + * Copyright (c) 2012 Ben Blazak + * Released under The MIT License (MIT) (see "license.md") + * Project located at + * ------------------------------------------------------------------------- */ + + +#include "lib-other/pjrc/usb_keyboard/usb_keyboard.h" + +#include "lib/data-types.h" +#include "lib/usb/keyboard-usage-page.h" + +#include "keyboard.h" + +// ---------------------------------------------------------------------------- + +#if 0 // not being used right now +static uint8_t _inc_current_layer(uint8_t * current_layer) { + if (*current_layer < (KB_LAYERS-1)) + (*current_layer)++; + else + return 1; // error: can't increase + + return 0; // success +} + +static uint8_t _dec_current_layer(uint8_t * current_layer) { + if (*current_layer > 0) + (*current_layer)--; + else + return 1; // error: can't decrease + + return 0; // success +} +#endif + +// ---------------------------------------------------------------------------- + +void kbfun_press( + uint8_t * keycode, uint8_t * current_layer, + uint8_t * row, uint8_t * col ) { + + for (uint8_t i=0; i<6; i++) + if (keyboard_keys[i] == 0) + keyboard_keys[i] = *keycode; +} + +void kbfun_release( + uint8_t * keycode, uint8_t * current_layer, + uint8_t * row, uint8_t * col ) { + + for (uint8_t i=0; i<6; i++) + if (keyboard_keys[i] == *keycode) + keyboard_keys[i] = 0; +} + +void kbfun_mod_press( + uint8_t * keycode, uint8_t * current_layer, + uint8_t * row, uint8_t * col ) { + + switch (*keycode) { + case KEY_LeftControl: keyboard_modifier_keys |= (1<<0); break; + case KEY_LeftShift: keyboard_modifier_keys |= (1<<1); break; + case KEY_LeftAlt: keyboard_modifier_keys |= (1<<2); break; + case KEY_LeftGUI: keyboard_modifier_keys |= (1<<3); break; + case KEY_RightControl: keyboard_modifier_keys |= (1<<4); break; + case KEY_RightShift: keyboard_modifier_keys |= (1<<5); break; + case KEY_RightAlt: keyboard_modifier_keys |= (1<<6); break; + case KEY_RightGUI: keyboard_modifier_keys |= (1<<7); break; + } +} + +void kbfun_mod_release( + uint8_t * keycode, uint8_t * current_layer, + uint8_t * row, uint8_t * col ) { + + switch (*keycode) { + case KEY_LeftControl: keyboard_modifier_keys &= ~(1<<0); break; + case KEY_LeftShift: keyboard_modifier_keys &= ~(1<<1); break; + case KEY_LeftAlt: keyboard_modifier_keys &= ~(1<<2); break; + case KEY_LeftGUI: keyboard_modifier_keys &= ~(1<<3); break; + case KEY_RightControl:keyboard_modifier_keys &= ~(1<<4); break; + case KEY_RightShift: keyboard_modifier_keys &= ~(1<<5); break; + case KEY_RightAlt: keyboard_modifier_keys &= ~(1<<6); break; + case KEY_RightGUI: keyboard_modifier_keys &= ~(1<<7); break; + } +} + diff --git a/src/key-functions.h b/src/key-functions.h new file mode 100644 index 0000000..887dfa6 --- /dev/null +++ b/src/key-functions.h @@ -0,0 +1,31 @@ +/* ---------------------------------------------------------------------------- + * key functions: exports + * ---------------------------------------------------------------------------- + * Copyright (c) 2012 Ben Blazak + * Released under The MIT License (MIT) (see "license.md") + * Project located at + * ------------------------------------------------------------------------- */ + + +#ifndef KEY_FUNCTIONS_h + #define KEY_FUNCTIONS_h + + #include "lib/data-types.h" + + typedef void (*kbfun_funptr_t)(uint8_t*, uint8_t*, uint8_t*, uint8_t*); + + void kbfun_press( + uint8_t * keycode, uint8_t * current_layer, + uint8_t * row, uint8_t * col ); + void kbfun_release( + uint8_t * keycode, uint8_t * current_layer, + uint8_t * row, uint8_t * col ); + void kbfun_mod_press( + uint8_t * keycode, uint8_t * current_layer, + uint8_t * row, uint8_t * col ); + void kbfun_mod_release( + uint8_t * keycode, uint8_t * current_layer, + uint8_t * row, uint8_t * col ); + +#endif + diff --git a/src/keyboard.h b/src/keyboard.h index e69de29..6b0dd15 100644 --- a/src/keyboard.h +++ b/src/keyboard.h @@ -0,0 +1,12 @@ +/* ---------------------------------------------------------------------------- + * keyboard specific exports + * use this file to include the keyboard you're compiling for + * ---------------------------------------------------------------------------- + * Copyright (c) 2012 Ben Blazak + * Released under The MIT License (MIT) (see "license.md") + * Project located at + * ------------------------------------------------------------------------- */ + + +#include "keyboard/ergodox.h" // only supported keyboard right now + diff --git a/src/keyboard/ergodox.c b/src/keyboard/ergodox.c index e69de29..250f205 100644 --- a/src/keyboard/ergodox.c +++ b/src/keyboard/ergodox.c @@ -0,0 +1,43 @@ +/* ---------------------------------------------------------------------------- + * ergoDOX specific code: tying it all together + * ---------------------------------------------------------------------------- + * Copyright (c) 2012 Ben Blazak + * Released under The MIT License (MIT) (see "license.md") + * Project located at + * ------------------------------------------------------------------------- */ + + +#include "lib/data-types.h" + +#define KEYBOARD_INCLUDE_PRIVATE +#include "ergodox/matrix.h" +#include "ergodox/mcp23018.h" +#include "ergodox/teensy-2-0.h" + + +/* returns + * - success: 0 + * - error: number of the function that failed + */ +uint8_t kb_init(void) { + if (teensy_init()) // must be first + return 1; + if (mcp23018_init()) // must be second + return 2; + + return 0; // success +} + +/* returns + * - success: 0 + * - error: number of the function that failed + */ +uint8_t kb_update_matrix(bool matrix[KB_ROWS][KB_COLUMNS]) { + if (teensy_update_matrix(matrix)) // must be first + return 1; + if (mcp23018_update_matrix(matrix)) // must be second + return 2; + + return 0; // success +} + diff --git a/src/keyboard/ergodox.h b/src/keyboard/ergodox.h index e69de29..77e0c76 100644 --- a/src/keyboard/ergodox.h +++ b/src/keyboard/ergodox.h @@ -0,0 +1,24 @@ +/* ---------------------------------------------------------------------------- + * ergoDOX specific exports + * ---------------------------------------------------------------------------- + * Copyright (c) 2012 Ben Blazak + * Released under The MIT License (MIT) (see "license.md") + * Project located at + * ------------------------------------------------------------------------- */ + + +#ifndef ERGODOX_h + #define ERGODOX_h + + #include "lib/data-types.h" + + #include "ergodox/layout.h" // number of layers, layout + #include "ergodox/matrix.h" // kb dimensions, matrix status + #include "ergodox/mcp23018.h" // (nothing right now) + #include "ergodox/teensy-2-0.h" // LED controls + + uint8_t kb_init(void); + uint8_t kb_update_matrix(bool matrix[KB_ROWS][KB_COLUMNS]); + +#endif + diff --git a/src/keyboard/ergodox/layout.c b/src/keyboard/ergodox/layout.c index 0a0655c..663de73 100644 --- a/src/keyboard/ergodox/layout.c +++ b/src/keyboard/ergodox/layout.c @@ -10,15 +10,20 @@ #include "lib/data-types.h" #include "lib/usb/keyboard-usage-page.h" +#include "key-functions.h" + #include "matrix.h" #include "layout.h" -// TODO (before release): put more effort into this -#if KB_ROWS != 12 || KB_COLUMNS != 7 +// error check; everything below assumes these dimensions +#if KB_LAYERS != 1 || KB_ROWS != 12 || KB_COLUMNS != 7 #error "Expecting different keyboard dimensions" #endif -uint8_t const kb_layout[KB_LAYERS][KB_ROWS][KB_COLUMNS] = { + + +// TODO (before release): put more effort into this +uint8_t kb_layout[KB_LAYERS][KB_ROWS][KB_COLUMNS] = { { // layer 0: default // right hand /* 0 -------------------------- 1 -------------------------- 2 -------------------------- 3 -------------------------- 4 -------------------------- 5 -------------------------- 6 -------------------------- */ @@ -39,6 +44,51 @@ uint8_t const kb_layout[KB_LAYERS][KB_ROWS][KB_COLUMNS] = { /* B */ { KEY_DeleteBackspace, KEY_DeleteForward, KEY_End, KEY_Home, KEY_LeftAlt, KEY_LeftControl, 0/*unused*/ } /* B */ /* 0 -------------------------- 1 -------------------------- 2 -------------------------- 3 -------------------------- 4 -------------------------- 5 -------------------------- 6 -------------------------- */ } - +}; + +kbfun_funptr_t kb_layout_press[KB_LAYERS][KB_ROWS][KB_COLUMNS] = { +{ // layer 0: default + // right hand + /* 0 -------------------------- 1 -------------------------- 2 -------------------------- 3 -------------------------- 4 -------------------------- 5 -------------------------- 6 -------------------------- */ +/* 0 */ { NULL, &kbfun_press, &kbfun_press, &kbfun_press, &kbfun_press, &kbfun_press, &kbfun_press }, /* 0 */ +/* 1 */ { NULL, &kbfun_press, &kbfun_press, &kbfun_press, &kbfun_press, &kbfun_press, &kbfun_press }, /* 1 */ +/* 2 */ { NULL,/*unused*/ &kbfun_press, &kbfun_press, &kbfun_press, &kbfun_press, &kbfun_press, &kbfun_press }, /* 2 */ +/* 3 */ { NULL, &kbfun_press, &kbfun_press, &kbfun_press, &kbfun_press, &kbfun_press, &kbfun_mod_press }, /* 3 */ +/* 4 */ { NULL,/*unused*/ NULL,/*unused*/ &kbfun_press, &kbfun_press, &kbfun_press, &kbfun_press, NULL }, /* 4 */ +/* 5 */ { NULL,/*unused*/ &kbfun_mod_press, &kbfun_mod_press, &kbfun_press, &kbfun_press, &kbfun_press, &kbfun_press }, /* 5 */ + /* 0 -------------------------- 1 -------------------------- 2 -------------------------- 3 -------------------------- 4 -------------------------- 5 -------------------------- 6 -------------------------- */ + // left hand + /* 0 -------------------------- 1 -------------------------- 2 -------------------------- 3 -------------------------- 4 -------------------------- 5 -------------------------- 6 -------------------------- */ +/* 6 */ { &kbfun_press, &kbfun_press, &kbfun_press, &kbfun_press, &kbfun_press, &kbfun_press, NULL }, /* 6 */ +/* 7 */ { &kbfun_press, &kbfun_press, &kbfun_press, &kbfun_press, &kbfun_press, &kbfun_press, NULL }, /* 7 */ +/* 8 */ { &kbfun_press, &kbfun_press, &kbfun_press, &kbfun_press, &kbfun_press, &kbfun_press, NULL/*unused*/ }, /* 8 */ +/* 9 */ { &kbfun_mod_press, &kbfun_press, &kbfun_press, &kbfun_press, &kbfun_press, &kbfun_press, NULL }, /* 9 */ +/* A */ { NULL, &kbfun_press, &kbfun_press, &kbfun_press, &kbfun_press, NULL,/*unused*/ NULL/*unused*/ }, /* A */ +/* B */ { &kbfun_press, &kbfun_press, &kbfun_press, &kbfun_press, &kbfun_mod_press, &kbfun_mod_press, NULL/*unused*/ } /* B */ + /* 0 -------------------------- 1 -------------------------- 2 -------------------------- 3 -------------------------- 4 -------------------------- 5 -------------------------- 6 -------------------------- */ +} +}; + +kbfun_funptr_t kb_layout_release[KB_LAYERS][KB_ROWS][KB_COLUMNS] = { +{ // layer 0: default + // right hand + /* 0 -------------------------- 1 -------------------------- 2 -------------------------- 3 -------------------------- 4 -------------------------- 5 -------------------------- 6 -------------------------- */ +/* 0 */ { NULL, &kbfun_release, &kbfun_release, &kbfun_release, &kbfun_release, &kbfun_release, &kbfun_release }, /* 0 */ +/* 1 */ { NULL, &kbfun_release, &kbfun_release, &kbfun_release, &kbfun_release, &kbfun_release, &kbfun_release }, /* 1 */ +/* 2 */ { NULL,/*unused*/ &kbfun_release, &kbfun_release, &kbfun_release, &kbfun_release, &kbfun_release, &kbfun_release }, /* 2 */ +/* 3 */ { NULL, &kbfun_release, &kbfun_release, &kbfun_release, &kbfun_release, &kbfun_release, &kbfun_mod_release }, /* 3 */ +/* 4 */ { NULL,/*unused*/ NULL,/*unused*/ &kbfun_release, &kbfun_release, &kbfun_release, &kbfun_release, NULL }, /* 4 */ +/* 5 */ { NULL,/*unused*/ &kbfun_mod_release, &kbfun_mod_release, &kbfun_release, &kbfun_release, &kbfun_release, &kbfun_release }, /* 5 */ + /* 0 -------------------------- 1 -------------------------- 2 -------------------------- 3 -------------------------- 4 -------------------------- 5 -------------------------- 6 -------------------------- */ + // left hand + /* 0 -------------------------- 1 -------------------------- 2 -------------------------- 3 -------------------------- 4 -------------------------- 5 -------------------------- 6 -------------------------- */ +/* 6 */ { &kbfun_release, &kbfun_release, &kbfun_release, &kbfun_release, &kbfun_release, &kbfun_release, NULL }, /* 6 */ +/* 7 */ { &kbfun_release, &kbfun_release, &kbfun_release, &kbfun_release, &kbfun_release, &kbfun_release, NULL }, /* 7 */ +/* 8 */ { &kbfun_release, &kbfun_release, &kbfun_release, &kbfun_release, &kbfun_release, &kbfun_release, NULL/*unused*/ }, /* 8 */ +/* 9 */ { &kbfun_mod_release, &kbfun_release, &kbfun_release, &kbfun_release, &kbfun_release, &kbfun_release, NULL }, /* 9 */ +/* A */ { NULL, &kbfun_release, &kbfun_release, &kbfun_release, &kbfun_release, NULL,/*unused*/ NULL/*unused*/ }, /* A */ +/* B */ { &kbfun_release, &kbfun_release, &kbfun_release, &kbfun_release, &kbfun_mod_release, &kbfun_mod_release, NULL/*unused*/ } /* B */ + /* 0 -------------------------- 1 -------------------------- 2 -------------------------- 3 -------------------------- 4 -------------------------- 5 -------------------------- 6 -------------------------- */ +} }; diff --git a/src/keyboard/ergodox/layout.h b/src/keyboard/ergodox/layout.h index c9d76f6..8b786f1 100644 --- a/src/keyboard/ergodox/layout.h +++ b/src/keyboard/ergodox/layout.h @@ -11,11 +11,18 @@ #include "lib/data-types.h" + #include "key-functions.h" + #include "matrix.h" - #define KB_LAYERS 1 // anything >= 1, as long as there's memory + #define KB_LAYERS 1 // must match what's defined in "layout.c" - extern uint8_t const kb_layout[KB_LAYERS][KB_ROWS][KB_COLUMNS]; + extern uint8_t + kb_layout [KB_LAYERS][KB_ROWS][KB_COLUMNS]; + extern kbfun_funptr_t + kb_layout_press [KB_LAYERS][KB_ROWS][KB_COLUMNS]; + extern kbfun_funptr_t + kb_layout_release[KB_LAYERS][KB_ROWS][KB_COLUMNS]; #endif diff --git a/src/keyboard/ergodox/matrix.c b/src/keyboard/ergodox/matrix.c index a7761bf..3a1f9e7 100644 --- a/src/keyboard/ergodox/matrix.c +++ b/src/keyboard/ergodox/matrix.c @@ -12,5 +12,9 @@ #include "matrix.h" -bool kb_is_pressed[KB_ROWS][KB_COLUMNS] = {{false}}; +static bool _kb_is_pressed[KB_ROWS][KB_COLUMNS]; +static bool _kb_was_pressed[KB_ROWS][KB_COLUMNS]; + +bool (*kb_is_pressed)[KB_ROWS][KB_COLUMNS] = &_kb_is_pressed; +bool (*kb_was_pressed)[KB_ROWS][KB_COLUMNS] = &_kb_was_pressed; diff --git a/src/keyboard/ergodox/matrix.h b/src/keyboard/ergodox/matrix.h index 43b95bf..1ee9907 100644 --- a/src/keyboard/ergodox/matrix.h +++ b/src/keyboard/ergodox/matrix.h @@ -15,7 +15,9 @@ #define KB_ROWS 12 // must match real life #define KB_COLUMNS 7 // must match real life - extern bool kb_is_pressed[KB_ROWS][KB_COLUMNS]; + extern bool (*kb_is_pressed)[KB_ROWS][KB_COLUMNS]; + extern bool (*kb_was_pressed)[KB_ROWS][KB_COLUMNS]; + #endif diff --git a/src/keyboard/ergodox/mcp23018.c b/src/keyboard/ergodox/mcp23018.c index 62f224e..e5e324c 100644 --- a/src/keyboard/ergodox/mcp23018.c +++ b/src/keyboard/ergodox/mcp23018.c @@ -6,15 +6,19 @@ * Project located at * ------------------------------------------------------------------------- */ +// TODO: still working on all this +// - need to separate the 'check if everything's all right' function, i think +// - do more error checking in update_matrix() ? +// - does update_matrix() really need a helper function? can it be conditional? +// - [and lots of stuff, just need to clean it up] :) #include #include "lib/data-types.h" -#define TWI_FREQ 400000 -#include "lib/teensy-2-0/twi.h" +#include "lib/teensy-2-0/twi.h" // `TWI_FREQ` defined in "teensy-2-0.c" +#define KEYBOARD_INCLUDE_PRIVATE #include "matrix.h" -#define MCP23018_h_INCLUDE_PRIVATE #include "mcp23018.h" @@ -23,7 +27,7 @@ #define IODIRB 0x01 #define GPPUA 0x0C // GPIO pull-up resistor register #define GPPUB 0x0D -#define GPIOA 0x12 // general purpose i/o port register +#define GPIOA 0x12 // general purpose i/o port register (write modifies OLAT) #define GPIOB 0x13 #define OLATA 0x14 // output latch register #define OLATB 0x15 @@ -33,24 +37,36 @@ #define TWI_ADDR_READ ( (MCP23018_TWI_ADDRESS<<1) | TW_READ ) -/* - * returns: +// ---------------------------------------------------------------------------- + +/* returns: * - success: 0 * - failure: twi status code + * + * notes: + * - this checks whether the device is initialized by reading from it. not the + * most efficient method, but easy and fairly reliable. */ -uint8_t mcp23018_init(void) { - uint8_t ret; +static uint8_t _init(bool release_twi_bus) { + static bool initialized; + uint8_t ret, data; - twi_init(); + // check for errors and previous initialization - // quick check to see if the device is responding; if it is, we'll - // assume things are going to work twi_start(); ret = twi_send(TWI_ADDR_WRITE); - if (ret) { - twi_stop(); - return ret; - } + + if (ret) goto out; // address write failed (no ACK) + + twi_send(OLATA); + twi_start(); + twi_send(TWI_ADDR_READ); + ret = twi_read(&data); + + if (ret) goto out; // read failed + if (data == 0xFF) goto out; // already initialized (OLATA == 0xFF) + + // initialize things, if we need to and we can // set pin direction // - unused : input : 1 @@ -78,13 +94,28 @@ uint8_t mcp23018_init(void) { // - columns : high (hi-Z) : 1 twi_start(); twi_send(TWI_ADDR_WRITE); - twi_send(GPIOA); - twi_send(0b11111111); //GPIOA - twi_send(0b11111111); //GPIOB - - twi_stop(); + twi_send(OLATA); + twi_send(0b11111111); //OLATA + twi_send(0b11111111); //OLATB - return 0; // success +out: + if (release_twi_bus) + twi_stop(); + + if (ret) initialized = false; + else initialized = true; + + return ret; +} + +// ---------------------------------------------------------------------------- + +/* returns: + * - success: 0 + * - failure: twi status code + */ +uint8_t mcp23018_init(void) { + return _init(true); } /* returns: @@ -94,44 +125,53 @@ uint8_t mcp23018_init(void) { #if KB_ROWS != 12 || KB_COLUMNS != 7 #error "Expecting different keyboard dimensions" #endif -uint8_t mcp23018_update_matrix(uint8_t matrix[KB_ROWS][KB_COLUMNS]) { +uint8_t mcp23018_update_matrix(bool matrix[KB_ROWS][KB_COLUMNS]) { uint8_t ret, data; - // quick check to see if the device is responding; if it is, we'll - // assume things are going to work - twi_start(); - ret = twi_send(TWI_ADDR_WRITE); + // initialize things if necessary + ret = _init(false); + + // if there was an error if (ret) { + // clear the matrix + for (uint8_t row=0x6; row<=0xB; row++) + for (uint8_t col=0; col<=6; col++) + matrix[row][col] = 0; + + // release the twi bus and return twi_stop(); return ret; } + // update our part of the matrix for (uint8_t row=0x6; row<=0xB; row++) { - // set row low : 0 - // set other rows high : 1 + // set active row low : 0 + // set other rows high (hi-Z) : 1 twi_start(); twi_send(TWI_ADDR_WRITE); - twi_send(GPIOA); - twi_send( 0b11111111 & ~(1<<(row-6)) ); // GPIOA + twi_send(OLATA); + twi_send( 0b11111111 & ~(1<<(row-6)) ); // OLATA // get column data twi_start(); + twi_send(TWI_ADDR_WRITE); + twi_send(GPIOB); twi_send(TWI_ADDR_READ); - twi_read(&data); // GPIOB TODO: confirm + twi_read(&data); // GPIOB // update matrix for (uint8_t col=0; col<=6; col++) matrix[row][col] = !( data & (1< #include "lib/data-types.h" +#define TWI_FREQ 400000 +#include "lib/teensy-2-0/twi.h" +#define KEYBOARD_INCLUDE_PRIVATE #include "matrix.h" -#define TEENSY_2_0_h_INCLUDE_PRIVATE #include "teensy-2-0.h" @@ -77,9 +79,8 @@ #define COLUMN_6 B, 0 -/* returns: +/* returns * - success: 0 - * + will never return failure */ uint8_t teensy_init(void) { CPU_PRESCALE(CPU_16MHz); // speed should match F_CPU in makefile @@ -93,9 +94,12 @@ uint8_t teensy_init(void) { TCCR1A = 0b10101001; // set and configure fast PWM TCCR1B = 0b00001001; // set and configure fast PWM + KB_LED1_SET_PERCENT(0.5); KB_LED1_OFF; + KB_LED2_SET_PERCENT(0.5); KB_LED2_OFF; + KB_LED3_SET_PERCENT(0.5); KB_LED3_OFF; + // I2C (TWI) - // on pins D(1,0); leave them alone here so the TWI library can do as - // it wishes + twi_init(); // on pins D(1,0) // unused pins // --- set as input @@ -150,15 +154,14 @@ uint8_t teensy_init(void) { return 0; // success } -/* returns: +/* returns * - success: 0 - * + will never return failure */ #if KB_ROWS != 12 || KB_COLUMNS != 7 #error "Expecting different keyboard dimensions" #endif static inline void _update_columns( - uint8_t matrix[KB_ROWS][KB_COLUMNS], uint8_t row ) { + bool matrix[KB_ROWS][KB_COLUMNS], uint8_t row ) { matrix[row][0] = ! TEENSYPIN_READ(COLUMN_0); matrix[row][1] = ! TEENSYPIN_READ(COLUMN_1); matrix[row][2] = ! TEENSYPIN_READ(COLUMN_2); @@ -167,30 +170,30 @@ static inline void _update_columns( matrix[row][5] = ! TEENSYPIN_READ(COLUMN_5); matrix[row][6] = ! TEENSYPIN_READ(COLUMN_6); } -uint8_t teensy_update_matrix(uint8_t matrix[KB_ROWS][KB_COLUMNS]) { - TEENSYPIN_WRITE(DDR, CLEAR, ROW_0); // set row low (as output) +uint8_t teensy_update_matrix(bool matrix[KB_ROWS][KB_COLUMNS]) { + TEENSYPIN_WRITE(DDR, SET, ROW_0); // set row low (set as output) _update_columns(matrix, 0); // read col 0..6 and update matrix - TEENSYPIN_WRITE(DDR, SET, ROW_0); // set row hi-Z (as input) + TEENSYPIN_WRITE(DDR, CLEAR, ROW_0); // set row hi-Z (set as input) - TEENSYPIN_WRITE(DDR, CLEAR, ROW_1); - _update_columns(matrix, 1); TEENSYPIN_WRITE(DDR, SET, ROW_1); + _update_columns(matrix, 1); + TEENSYPIN_WRITE(DDR, CLEAR, ROW_1); - TEENSYPIN_WRITE(DDR, CLEAR, ROW_2); - _update_columns(matrix, 2); TEENSYPIN_WRITE(DDR, SET, ROW_2); + _update_columns(matrix, 2); + TEENSYPIN_WRITE(DDR, CLEAR, ROW_2); - TEENSYPIN_WRITE(DDR, CLEAR, ROW_3); - _update_columns(matrix, 3); TEENSYPIN_WRITE(DDR, SET, ROW_3); + _update_columns(matrix, 3); + TEENSYPIN_WRITE(DDR, CLEAR, ROW_3); - TEENSYPIN_WRITE(DDR, CLEAR, ROW_4); - _update_columns(matrix, 4); TEENSYPIN_WRITE(DDR, SET, ROW_4); + _update_columns(matrix, 4); + TEENSYPIN_WRITE(DDR, CLEAR, ROW_4); - TEENSYPIN_WRITE(DDR, CLEAR, ROW_5); - _update_columns(matrix, 5); TEENSYPIN_WRITE(DDR, SET, ROW_5); + _update_columns(matrix, 5); + TEENSYPIN_WRITE(DDR, CLEAR, ROW_5); return 0; // success } diff --git a/src/keyboard/ergodox/teensy-2-0.h b/src/keyboard/ergodox/teensy-2-0.h index 945cc94..b7f6d32 100644 --- a/src/keyboard/ergodox/teensy-2-0.h +++ b/src/keyboard/ergodox/teensy-2-0.h @@ -14,6 +14,8 @@ #include "lib/data-types.h" + #include "matrix.h" + // LED control #define KB_LED1_ON (DDRB |= (1<<5)) #define KB_LED1_OFF (DDRB &= ~(1<<5)) @@ -29,11 +31,11 @@ #define KB_LED3_SET_PERCENT(n) (OCR1C = (uint8_t)((n) * 0xFF)) - #ifdef TEENSY_2_0_h_INCLUDE_PRIVATE + #ifdef KEYBOARD_INCLUDE_PRIVATE uint8_t teensy_init(void); uint8_t teensy_update_matrix( - uint8_t matrix[KB_ROWS][KB_COLUMNS] ); + bool matrix[KB_ROWS][KB_COLUMNS] ); #endif diff --git a/src/keyboard/ergodox/teensy-2-0.md b/src/keyboard/ergodox/teensy-2-0.md index 8864860..79bff59 100644 --- a/src/keyboard/ergodox/teensy-2-0.md +++ b/src/keyboard/ergodox/teensy-2-0.md @@ -1,6 +1,6 @@ # Documentation : Teensy 2.0 -## Pinouts and Pin assignments +## Pinout and Pin assignments * `+` indicates pin * `o` indicates unused pin @@ -38,12 +38,13 @@ column3 PD2 + + OC1A LED1 column4 PD3 + + PB4 column0 column1 PC6 + + PD7 column5 - column2 PC7 +-o-o-o-o-o-o + column2 PC7 +-o-o-o-o-o-+ PD6 onboardLED * notes: * SCL and SDA: Need external pull-up resistors. Sometimes the Teensy internal pull-ups are enough (see datasheet section 20.5.1), but i think - for this project we'll want external ones. + for this project we'll want external ones. The general recommendation for + 400kHz I²C seems to be 2.2kΩ. ## Notes about Registers @@ -61,11 +62,11 @@ read returns the logical value (1|0) of the pin * notes: - * Unused pins should be set as input with internal pullup enabled (see - datasheet section 10.2.6) in order to give them a defined level. - * PD6 already has a defined level (low) since it's hooked up to the onboard - LED, so there's no reason to set internal pull-up enabled on it. If we do, - it will source current to the LED, which is fine, but unnecessary. + * Unused pins should be set as input, with internal pullup enabled in order + to give them a defined level (see datasheet section 10.2.6). + * PD6 (the onboard LED) already has a defined level (low), so there's no + reason to set internal pull-up enabled on it. If we do, it will source + current to the LED, which is fine, but unnecessary. * We want the row pins 'hi-Z' initially (set as input with pull-up disabled), and the column pins set as input with internal pull-up enabled. We'll cycle through driving the row pins low (setting them as output) and @@ -86,7 +87,8 @@ "Clear OCnA/OCnB/OCnC on compare match, set OCnA/OCnB/OCnC at TOP" (see table 14-3) this way higher values of `OCR1(A|B|C)` will mean longer 'on' times for the - LEDs + LEDs (provided they're hooked up to GND; other way around if they're hooked + up to Vcc) * when in a fast PWM mode, set `TCCR1A[7,6,5,4,3,2]` to `1,0,1,0,1,0` * we want "Clock Select Bit Description" to be `0b001` "clkI/O/1 (No prescaling)" diff --git a/src/lib-other/pjrc/usb_keyboard/usb_keyboard.c b/src/lib-other/pjrc/usb_keyboard/usb_keyboard.c index 89b2e9b..1501f2a 100644 --- a/src/lib-other/pjrc/usb_keyboard/usb_keyboard.c +++ b/src/lib-other/pjrc/usb_keyboard/usb_keyboard.c @@ -349,7 +349,8 @@ int8_t usb_keyboard_send(void) // ISR(USB_GEN_vect) { - uint8_t intbits, t, i; + uint8_t intbits, i; // used to declare `t` as well, but it wasn't used + // ::Blazak, 2012:: static uint8_t div4=0; intbits = UDINT; diff --git a/src/lib-other/pjrc/usb_keyboard/usb_keyboard.h b/src/lib-other/pjrc/usb_keyboard/usb_keyboard.h index d9f1fc0..cd9e8a9 100644 --- a/src/lib-other/pjrc/usb_keyboard/usb_keyboard.h +++ b/src/lib-other/pjrc/usb_keyboard/usb_keyboard.h @@ -19,6 +19,8 @@ extern volatile uint8_t keyboard_leds; #define usb_debug_flush_output() +#if 0 // removed in favor of equilivent code elsewhere ::Ben Blazak, 2012:: + #define KEY_CTRL 0x01 #define KEY_SHIFT 0x02 #define KEY_ALT 0x04 @@ -129,6 +131,8 @@ extern volatile uint8_t keyboard_leds; #define KEYPAD_0 98 #define KEYPAD_PERIOD 99 +#endif + diff --git a/src/lib/data-types.h b/src/lib/data-types.h index cd7d470..453dca1 100644 --- a/src/lib/data-types.h +++ b/src/lib/data-types.h @@ -10,6 +10,7 @@ #ifndef DATA_TYPES_h #define DATA_TYPES_h + #include #include #define bool _Bool diff --git a/src/lib/teensy-2-0/twi.c b/src/lib/teensy-2-0/twi.c index 9f339a1..9cd5c8d 100644 --- a/src/lib/teensy-2-0/twi.c +++ b/src/lib/teensy-2-0/twi.c @@ -39,8 +39,8 @@ uint8_t twi_start(void) { // wait for transmission to complete while (!(TWCR & (1< + * Released under The MIT License (MIT) (see "license.md") + * Project located at + * ------------------------------------------------------------------------- */ + + +#include + +#include "lib-other/pjrc/usb_keyboard/usb_keyboard.h" + +#include "lib/data-types.h" + +#include "keyboard.h" + +//dbg +int main(void) { + kb_init(); // does controller initialization too + + usb_init(); + while (!usb_configured()); + _delay_ms(1000); // make sure the OS has had time to load drivers, etc. + + for (;;) { +// int current_layer = 0; + + KB_LED1_ON; _delay_ms(200); KB_LED1_OFF; _delay_ms(200); + KB_LED1_ON; _delay_ms(200); KB_LED1_OFF; _delay_ms(200); + +// for (int row=0; row - -#define TEENSY_2_0_h_INCLUDE_PRIVATE -#include "../keyboard/ergodox/teensy-2-0.h" -#include "../keyboard/ergodox/teensy-2-0.c" +#include -#define bool uint8_t +#define bool _Bool #define true 1 #define false 0 +#define CPU_PRESCALE(n) (CLKPR = 0x80, CLKPR = (n)) + +// LED control +#define KB_LED1_ON (DDRB |= (1<<5)) +#define KB_LED1_OFF (DDRB &= ~(1<<5)) +#define KB_LED1_SET(n) (OCR1A = (uint8_t)(n)) +#define KB_LED1_SET_PERCENT(n) (OCR1A = (uint8_t)((n) * 0xFF)) +#define KB_LED2_ON (DDRB |= (1<<6)) +#define KB_LED2_OFF (DDRB &= ~(1<<6)) +#define KB_LED2_SET(n) (OCR1B = (uint8_t)(n)) +#define KB_LED2_SET_PERCENT(n) (OCR1B = (uint8_t)((n) * 0xFF)) +#define KB_LED3_ON (DDRB |= (1<<7)) +#define KB_LED3_OFF (DDRB &= ~(1<<7)) +#define KB_LED3_SET(n) (OCR1C = (uint8_t)(n)) +#define KB_LED3_SET_PERCENT(n) (OCR1C = (uint8_t)((n) * 0xFF)) + + +int main(void) { + CPU_PRESCALE(0); // set for 16MHz + + // pwm init for keyboard LEDs + // (see "PWM on ports OC1(A|B|C)" in "teensy-2-0.md") + DDRB |= 0b11100000; // set B(7,6,5) as output + TCCR1A = 0b10101001; // set and configure fast PWM + TCCR1B = 0b00001001; // set and configure fast PWM -void main(void) { - teensy_init(); for (uint8_t i=0; i<3; i++) { KB_LED1_SET(0x10); diff --git a/src/test/test_twi_2.c b/src/test/test_twi_2.c new file mode 100644 index 0000000..b6e0207 --- /dev/null +++ b/src/test/test_twi_2.c @@ -0,0 +1,92 @@ +/* ---------------------------------------------------------------------------- + * Test TWI write (with a Teensy 2.0 and I/O expander) + * ---------------------------------------------------------------------------- + * Copyright (c) 2012 Ben Blazak + * Released under The MIT License (MIT) (see "license.md") + * Project located at + * ------------------------------------------------------------------------- */ + +#include +#include +#include + +#define TWI_FREQ 400000 +#include "../lib/teensy-2-0/twi.c" + + +// processor frequency (from ) +#define CPU_PRESCALE(n) (CLKPR = 0x80, CLKPR = (n)) +#define CPU_16MHz 0x00 + + +// ---------------------------------------------------------------------------- +// helper functions +// ---------------------------------------------------------------------------- + +#define blink_led(time1, time2) { \ + /* Teensy 2.0 onboard LED on PD6 + on high, off low */ \ + PORTD |= (1<<6); \ + _delay_ms(time1); \ + PORTD &= ~(1<<6); \ + _delay_ms(time2); \ +} + + +// ---------------------------------------------------------------------------- // TWI +// ---------------------------------------------------------------------------- + +#define IODIRA 0x00 +#define IODIRB 0x01 +#define GPPUA 0x0C +#define GPPUB 0x0D +#define GPIOA 0x12 +#define GPIOB 0x13 +#define OLATA 0x14 +#define OLATB 0x15 + +#define TWI_ADDR_WRITE (0b0100000<<1)|TW_WRITE +#define TWI_ADDR_READ (0b0100000<<1)|TW_READ + + +// ---------------------------------------------------------------------------- +// main +// ---------------------------------------------------------------------------- + +/* notes: + * - won't work without the `twi_stop()`s after each block + */ +int main(void) { + CPU_PRESCALE(CPU_16MHz); + + twi_init(); + + // set all gpio pins as: + + // output + twi_start(); + twi_send(TWI_ADDR_WRITE); + twi_send(IODIRA); + twi_send(0); + twi_send(0); + twi_stop(); + + // with pull-up + twi_start(); + twi_send(TWI_ADDR_WRITE); + twi_send(GPPUA); + twi_send(0xff); + twi_send(0xff); + twi_stop(); + + // logical 1 + twi_start(); + twi_send(TWI_ADDR_WRITE); + twi_send(OLATA); + twi_send(0xff); + twi_send(0xff); + twi_stop(); + + return 0; +} + From cd6826eeb5564a3410df22b8808f4cf8516ff775 Mon Sep 17 00:00:00 2001 From: Ben Blazak Date: Tue, 10 Apr 2012 18:58:26 -0700 Subject: [PATCH 19/22] checkin before deleting the debug code; almost ready for first beta! - simple bug fix in kbfun_press() and kbfun_release() - no longer check for previous init() in the mcp23018 functions; something would happen when i tried to read from it, sometimes, when it'd been unplugged or stoped some other way, and it would hang - and the only thing that would make it better was running the test_twi_2 function (a series of writes, with stops after each). so now mcp23018_init() is a series of writes, with stops after each. it doesn't take appreciably longer to run... maybe it should be looked into later though. - changed the main() loop a little --- doc/references.md | 26 ++++---- src/key-functions.c | 8 ++- src/keyboard/ergodox/mcp23018.c | 78 +++++++----------------- src/lib/teensy-2-0/twi.c | 1 + src/main.c | 104 ++++++++++++++++++-------------- src/makefile | 2 +- 6 files changed, 103 insertions(+), 116 deletions(-) diff --git a/doc/references.md b/doc/references.md index c57a2c6..e3274e5 100644 --- a/doc/references.md +++ b/doc/references.md @@ -135,16 +135,6 @@ : pdf (from ) -## Miscellaneous - -* [Markdown: Syntax] - (http://daringfireball.net/projects/markdown/syntax) - -* [Keyboard Scan Rates] - (http://geekhack.org/showwiki.php?title=Keyboard+scan+rates) - list (on ) - - ## Other Firmware / Code * zip: [Phantom Firmware from PrinsValium] @@ -208,7 +198,7 @@ (http://pjrc.com/teensy/gcc.html) -## Chip Documentation +## Hardware Documentation * [Microchip: Analog & Interface Product Selector Guide] (http://ww1.microchip.com/downloads/en/DeviceDoc/21060z.pdf) @@ -252,6 +242,20 @@ * from [the PJRC website] (http://pjrc.com/teensy/datasheets.html) +* [Cherry MX Series Keyswitches : Specifications] + (http://www.cherrycorp.com/english/switches/key/mx.htm) + + +## Miscellaneous + +* [Markdown: Syntax] + (http://daringfireball.net/projects/markdown/syntax) + +* [Keyboard Scan Rates] + (http://geekhack.org/showwiki.php?title=Keyboard+scan+rates) + list (on ) + + ------------------------------------------------------------------------------- Copyright © 2012 Ben Blazak diff --git a/src/key-functions.c b/src/key-functions.c index f09c656..bc7a79a 100644 --- a/src/key-functions.c +++ b/src/key-functions.c @@ -43,8 +43,10 @@ void kbfun_press( uint8_t * row, uint8_t * col ) { for (uint8_t i=0; i<6; i++) - if (keyboard_keys[i] == 0) + if (keyboard_keys[i] == 0) { keyboard_keys[i] = *keycode; + break; + } } void kbfun_release( @@ -52,8 +54,10 @@ void kbfun_release( uint8_t * row, uint8_t * col ) { for (uint8_t i=0; i<6; i++) - if (keyboard_keys[i] == *keycode) + if (keyboard_keys[i] == *keycode) { keyboard_keys[i] = 0; + break; + } } void kbfun_mod_press( diff --git a/src/keyboard/ergodox/mcp23018.c b/src/keyboard/ergodox/mcp23018.c index e5e324c..eae2d1e 100644 --- a/src/keyboard/ergodox/mcp23018.c +++ b/src/keyboard/ergodox/mcp23018.c @@ -6,11 +6,6 @@ * Project located at * ------------------------------------------------------------------------- */ -// TODO: still working on all this -// - need to separate the 'check if everything's all right' function, i think -// - do more error checking in update_matrix() ? -// - does update_matrix() really need a helper function? can it be conditional? -// - [and lots of stuff, just need to clean it up] :) #include @@ -37,46 +32,28 @@ #define TWI_ADDR_READ ( (MCP23018_TWI_ADDRESS<<1) | TW_READ ) -// ---------------------------------------------------------------------------- - /* returns: * - success: 0 * - failure: twi status code * * notes: - * - this checks whether the device is initialized by reading from it. not the - * most efficient method, but easy and fairly reliable. + * - `twi_stop()` must be called *exactly once* for each twi block, the way + * things are currently set up. this may change in the future. */ -static uint8_t _init(bool release_twi_bus) { - static bool initialized; - uint8_t ret, data; - - // check for errors and previous initialization - - twi_start(); - ret = twi_send(TWI_ADDR_WRITE); - - if (ret) goto out; // address write failed (no ACK) - - twi_send(OLATA); - twi_start(); - twi_send(TWI_ADDR_READ); - ret = twi_read(&data); - - if (ret) goto out; // read failed - if (data == 0xFF) goto out; // already initialized (OLATA == 0xFF) - - // initialize things, if we need to and we can +uint8_t mcp23018_init(void) { + uint8_t ret; // set pin direction // - unused : input : 1 // - rows : output : 0 // - columns : input : 1 twi_start(); - twi_send(TWI_ADDR_WRITE); + ret = twi_send(TWI_ADDR_WRITE); + if (ret) goto out; // make sure we got an ACK twi_send(IODIRA); twi_send(0b11000000); // IODIRA twi_send(0b11111111); // IODIRB + twi_stop(); // set pull-up // - unused : on : 1 @@ -87,6 +64,7 @@ static uint8_t _init(bool release_twi_bus) { twi_send(GPPUA); twi_send(0b11000000); // GPPUA twi_send(0b11111111); // GPPUB + twi_stop(); // set logical value (doesn't matter on inputs) // - unused : high (hi-Z) : 1 @@ -99,25 +77,10 @@ static uint8_t _init(bool release_twi_bus) { twi_send(0b11111111); //OLATB out: - if (release_twi_bus) - twi_stop(); - - if (ret) initialized = false; - else initialized = true; - + twi_stop(); return ret; } -// ---------------------------------------------------------------------------- - -/* returns: - * - success: 0 - * - failure: twi status code - */ -uint8_t mcp23018_init(void) { - return _init(true); -} - /* returns: * - success: 0 * - failure: twi status code @@ -128,8 +91,11 @@ uint8_t mcp23018_init(void) { uint8_t mcp23018_update_matrix(bool matrix[KB_ROWS][KB_COLUMNS]) { uint8_t ret, data; - // initialize things if necessary - ret = _init(false); + // initialize things, just to make sure + // - it's not appreciably faster to skip this, and it takes care of the + // case when the i/o expander isn't plugged in during the first + // init() + ret = mcp23018_init(); // if there was an error if (ret) { @@ -138,8 +104,6 @@ uint8_t mcp23018_update_matrix(bool matrix[KB_ROWS][KB_COLUMNS]) { for (uint8_t col=0; col<=6; col++) matrix[row][col] = 0; - // release the twi bus and return - twi_stop(); return ret; } @@ -150,14 +114,17 @@ uint8_t mcp23018_update_matrix(bool matrix[KB_ROWS][KB_COLUMNS]) { twi_start(); twi_send(TWI_ADDR_WRITE); twi_send(OLATA); - twi_send( 0b11111111 & ~(1<<(row-6)) ); // OLATA + twi_send( 0b11111111 & ~(1<<(row-6)) ); + twi_stop(); - // get column data + // read column data twi_start(); twi_send(TWI_ADDR_WRITE); twi_send(GPIOB); + twi_start(); twi_send(TWI_ADDR_READ); - twi_read(&data); // GPIOB + twi_read(&data); + twi_stop(); // update matrix for (uint8_t col=0; col<=6; col++) @@ -169,9 +136,8 @@ uint8_t mcp23018_update_matrix(bool matrix[KB_ROWS][KB_COLUMNS]) { twi_send(TWI_ADDR_WRITE); twi_send(GPIOA); twi_send(0b11111111); - - // release the twi bus and return twi_stop(); - return 0; // success + + return ret; // success } diff --git a/src/lib/teensy-2-0/twi.c b/src/lib/teensy-2-0/twi.c index 9cd5c8d..1492d9c 100644 --- a/src/lib/teensy-2-0/twi.c +++ b/src/lib/teensy-2-0/twi.c @@ -19,6 +19,7 @@ * ------------------------------------------------------------------------- */ +#include //dbg #include #include "twi.h" diff --git a/src/main.c b/src/main.c index 697f010..927381d 100644 --- a/src/main.c +++ b/src/main.c @@ -14,39 +14,30 @@ #include "lib/data-types.h" +// #include "keyboard.h" +//dbg +#define KEYBOARD_INCLUDE_PRIVATE +#include "keyboard/ergodox/teensy-2-0.h" +#include "keyboard/ergodox/mcp23018.h" #include "keyboard.h" +/// + + +#define DEBOUNCE_TIME 5 // in ms; see the spec for your keyswitches + //dbg -int main(void) { - kb_init(); // does controller initialization too - - usb_init(); - while (!usb_configured()); - _delay_ms(1000); // make sure the OS has had time to load drivers, etc. - - for (;;) { -// int current_layer = 0; - - KB_LED1_ON; _delay_ms(200); KB_LED1_OFF; _delay_ms(200); - KB_LED1_ON; _delay_ms(200); KB_LED1_OFF; _delay_ms(200); - -// for (int row=0; row= 1000) + counter = 0; + /// static uint8_t current_layer = 0; // swap `kb_is_pressed` and `kb_was_pressed`, then update @@ -64,35 +64,47 @@ int main(void) { kb_update_matrix(*kb_is_pressed); - // call the appropriate function for each key, then send the report - for (uint8_t row=0; row Date: Wed, 11 Apr 2012 18:52:31 -0700 Subject: [PATCH 20/22] added ergodox circuit diagram; and a few misc things; time to clean up --- doc/references.md | 46 +- src/keyboard/ergodox/_circuit-diagram.svg | 3349 +++++++++++++++++ src/keyboard/ergodox/teensy-2-0.md | 4 +- .../arduino/libraries/Wire/utility/twi.c | 476 --- .../arduino/libraries/Wire/utility/twi.h | 57 - .../i2cmaster/group__pfleury__ic2master.html | 473 --- .../peter-fleury/i2cmaster/i2cmaster.S | 302 -- .../peter-fleury/i2cmaster/i2cmaster.h | 178 - src/lib-other/peter-fleury/i2cmaster/makefile | 392 -- .../peter-fleury/i2cmaster/makefile.i2cmaster | 392 -- .../peter-fleury/i2cmaster/makefile.twimaster | 502 --- .../peter-fleury/i2cmaster/test_i2cmaster.c | 78 - .../peter-fleury/i2cmaster/twimaster.c | 202 - src/lib-other/readme.md | 23 - src/main.c | 2 +- src/makefile | 2 +- src/test/readme.md | 12 + 17 files changed, 3410 insertions(+), 3080 deletions(-) create mode 100644 src/keyboard/ergodox/_circuit-diagram.svg delete mode 100644 src/lib-other/arduino/arduino/libraries/Wire/utility/twi.c delete mode 100644 src/lib-other/arduino/arduino/libraries/Wire/utility/twi.h delete mode 100644 src/lib-other/peter-fleury/i2cmaster/group__pfleury__ic2master.html delete mode 100644 src/lib-other/peter-fleury/i2cmaster/i2cmaster.S delete mode 100644 src/lib-other/peter-fleury/i2cmaster/i2cmaster.h delete mode 100644 src/lib-other/peter-fleury/i2cmaster/makefile delete mode 100644 src/lib-other/peter-fleury/i2cmaster/makefile.i2cmaster delete mode 100644 src/lib-other/peter-fleury/i2cmaster/makefile.twimaster delete mode 100644 src/lib-other/peter-fleury/i2cmaster/test_i2cmaster.c delete mode 100644 src/lib-other/peter-fleury/i2cmaster/twimaster.c create mode 100644 src/test/readme.md diff --git a/doc/references.md b/doc/references.md index e3274e5..f604210 100644 --- a/doc/references.md +++ b/doc/references.md @@ -103,6 +103,7 @@ (https://www.mainframe.cx/~ckuethe/avr-c-tutorial/) by Chris Kuethe + ## Protocol Stuff ### I²C @@ -135,7 +136,9 @@ : pdf (from ) -## Other Firmware / Code +## Other People's Code + +### Keyboard Firmware * zip: [Phantom Firmware from PrinsValium] (http://geekhack.org/attachment.php?attachmentid=38982&d=1327895092) @@ -173,10 +176,17 @@ * mentioned on [the designer's blog] (http://humblehacker.com/blog/) +### TWI Libraries + * github: [TWI library in C] (https://github.com/arduino/Arduino/tree/master/libraries/Wire/utility) : (arduino / Arduino / libraries / Wire / utility) +* zip: [i2cmaster] + (http://homepage.hispeed.ch/peterfleury/i2cmaster.zip) + (by Peter Fleury, on [his homepage] + (http://homepage.hispeed.ch/peterfleury/)) + * forum: [Interfacing MCP23018 io expander via Arduino] (http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1282150189) : contains a quick MCP23017 library in C++ @@ -185,12 +195,16 @@ (https://github.com/maniacbug/Arduino/tree/master/libraries/MCP23018) : library in C++ +### USB + * zip: [PJRC: usb_keyboard] (http://pjrc.com/teensy/usb_keyboard.zip) * mentioned on [the PJRC website] (http://pjrc.com/teensy/usb_keyboard.html) +### Miscellaneous + * zip: [PJRC: blinky] (http://pjrc.com/teensy/blinky.zip) @@ -248,9 +262,39 @@ ## Miscellaneous +### Documentation and Design Tools + * [Markdown: Syntax] (http://daringfireball.net/projects/markdown/syntax) +* [KiCAD Tutorial] + (http://teholabs.com/knowledge/kicad.html) + (on ) + + * mentioned on the [circuit/block-diagram drawing] + (http://stackoverflow.com/questions/6422603/circuit-block-diagram-drawing) + question (on ) + +* [Ti_k_Z and PGF] + (http://www.texample.net/tikz/) + : a TeX graphics package + + * mentioned on the [circuit/block-diagram drawing] + (http://stackoverflow.com/questions/6422603/circuit-block-diagram-drawing) + question (on ) + + * [Documentation (for version 2010-09-28)] + (http://www.texample.net/media/pgf/builds/pgfmanualCVS2010-09-28.pdf) + : pdf + + * [Example: Block diagram line junctions] + (http://www.texample.net/tikz/examples/line-junctions/) + +* [Inkscape : Connector tool tutorial] + (http://wiki.inkscape.org/wiki/index.php/UsingTheConnectorTool) + +### Typical Keyboard Information + * [Keyboard Scan Rates] (http://geekhack.org/showwiki.php?title=Keyboard+scan+rates) list (on ) diff --git a/src/keyboard/ergodox/_circuit-diagram.svg b/src/keyboard/ergodox/_circuit-diagram.svg new file mode 100644 index 0000000..a834901 --- /dev/null +++ b/src/keyboard/ergodox/_circuit-diagram.svg @@ -0,0 +1,3349 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + USB + R = 220 Ω + R = 2.2 kΩ + + + + + + SCL + SDA + PWM + PWM + PWM + + reset only active during power-on + address = 0b 0100 000 + + + + row 0 + row 1 + row 2 + row 3 + row 4 + row 5 + col 0 + col 1 + col 2 + col 3 + col 4 + col 5 + col 6 + + + + + + + + + col 0 + col 1 + col 2 + col 3 + col 4 + col 5 + col 6 + row 6 + row 7 + row 8 + row 9 + row A + row B + + + + + + + + + + + + + + + + + + + + Vss + NC + GPB0 + GPB1 + GPB2 + GPB3 + GPB4 + GPB5 + GPB6 + GPB7 + Vdd + SCL + SDA + NC + NC + GPA7 + GPA6 + GPA5 + GPA4 + GPA3 + GPA2 + GPA1 + GPA0 + INTA + INTB + NC + RESET + ADDR + GND + PB0 + PB1 + PB2 + PB3 + PB7 + PD0 + PD1 + PD2 + PD3 + PC6 + PC7 + PD5 + Vcc + GND + RST + PD4 + PD6 + PF0 + PF1 + PF4 + PF5 + PF6 + PF7 + PB6 + PB5 + PB4 + PD7 + Vcc + PE6 + AREF + + + diff --git a/src/keyboard/ergodox/teensy-2-0.md b/src/keyboard/ergodox/teensy-2-0.md index 79bff59..326826f 100644 --- a/src/keyboard/ergodox/teensy-2-0.md +++ b/src/keyboard/ergodox/teensy-2-0.md @@ -9,7 +9,7 @@ ### Teensy 2.0 - GND +---.....---+ VCC + GND +---.....---+ Vcc SS PB0 + + PF0 ADC0 SCLK PB1 + + PF1 ADC1 MOSI PB2 + + PF4 ADC4 @@ -22,7 +22,7 @@ OC3A (OC4A) -------- PC6 + + PD7 ADC10 T0 -- OC4D ICP3 ----- OC4A --------- PC7 +-+-+-+-+-+-+ PD6 ADC9 T1 - (OC4D) onboardLED CTS XCK1 PD5 --/ | | | \-- PD4 ADC8 ------------ ICP1 - VCC ------------------/ | \-------------- RST + Vcc ------------------/ | \-------------- RST GND --------------------/ ### Teensy 2.0 Pin Assignments diff --git a/src/lib-other/arduino/arduino/libraries/Wire/utility/twi.c b/src/lib-other/arduino/arduino/libraries/Wire/utility/twi.c deleted file mode 100644 index 236878c..0000000 --- a/src/lib-other/arduino/arduino/libraries/Wire/utility/twi.c +++ /dev/null @@ -1,476 +0,0 @@ -/* - twi.c - TWI/I2C library for Wiring & Arduino - Copyright (c) 2006 Nicholas Zambetti. All right reserved. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include -#include -#include -#include -#include -#include - -#ifndef cbi -#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) -#endif - -#ifndef sbi -#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) -#endif - -#include "twi.h" - -static volatile uint8_t twi_state; -static uint8_t twi_slarw; - -static void (*twi_onSlaveTransmit)(void); -static void (*twi_onSlaveReceive)(uint8_t*, int); - -static uint8_t twi_masterBuffer[TWI_BUFFER_LENGTH]; -static volatile uint8_t twi_masterBufferIndex; -static uint8_t twi_masterBufferLength; - -static uint8_t twi_txBuffer[TWI_BUFFER_LENGTH]; -static volatile uint8_t twi_txBufferIndex; -static volatile uint8_t twi_txBufferLength; - -static uint8_t twi_rxBuffer[TWI_BUFFER_LENGTH]; -static volatile uint8_t twi_rxBufferIndex; - -static volatile uint8_t twi_error; - -/* - * Function twi_init - * Desc readys twi pins and sets twi bitrate - * Input none - * Output none - */ -void twi_init(void) -{ - // initialize state - twi_state = TWI_READY; - - #if defined(__AVR_ATmega168__) || defined(__AVR_ATmega8__) || defined(__AVR_ATmega328P__) - // activate internal pull-ups for twi - // as per note from atmega8 manual pg167 - sbi(PORTC, 4); - sbi(PORTC, 5); - #else - // activate internal pull-ups for twi - // as per note from atmega128 manual pg204 - sbi(PORTD, 0); - sbi(PORTD, 1); - #endif - - // initialize twi prescaler and bit rate - cbi(TWSR, TWPS0); - cbi(TWSR, TWPS1); - TWBR = ((CPU_FREQ / TWI_FREQ) - 16) / 2; - - /* twi bit rate formula from atmega128 manual pg 204 - SCL Frequency = CPU Clock Frequency / (16 + (2 * TWBR)) - note: TWBR should be 10 or higher for master mode - It is 72 for a 16mhz Wiring board with 100kHz TWI */ - - // enable twi module, acks, and twi interrupt - TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA); -} - -/* - * Function twi_slaveInit - * Desc sets slave address and enables interrupt - * Input none - * Output none - */ -void twi_setAddress(uint8_t address) -{ - // set twi slave address (skip over TWGCE bit) - TWAR = address << 1; -} - -/* - * Function twi_readFrom - * Desc attempts to become twi bus master and read a - * series of bytes from a device on the bus - * Input address: 7bit i2c device address - * data: pointer to byte array - * length: number of bytes to read into array - * Output number of bytes read - */ -uint8_t twi_readFrom(uint8_t address, uint8_t* data, uint8_t length) -{ - uint8_t i; - - // ensure data will fit into buffer - if(TWI_BUFFER_LENGTH < length){ - return 0; - } - - // wait until twi is ready, become master receiver - while(TWI_READY != twi_state){ - continue; - } - twi_state = TWI_MRX; - // reset error state (0xFF.. no error occured) - twi_error = 0xFF; - - // initialize buffer iteration vars - twi_masterBufferIndex = 0; - twi_masterBufferLength = length-1; // This is not intuitive, read on... - // On receive, the previously configured ACK/NACK setting is transmitted in - // response to the received byte before the interrupt is signalled. - // Therefor we must actually set NACK when the _next_ to last byte is - // received, causing that NACK to be sent in response to receiving the last - // expected byte of data. - - // build sla+w, slave device address + w bit - twi_slarw = TW_READ; - twi_slarw |= address << 1; - - // send start condition - TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTA); - - // wait for read operation to complete - while(TWI_MRX == twi_state){ - continue; - } - - if (twi_masterBufferIndex < length) - length = twi_masterBufferIndex; - - // copy twi buffer to data - for(i = 0; i < length; ++i){ - data[i] = twi_masterBuffer[i]; - } - - return length; -} - -/* - * Function twi_writeTo - * Desc attempts to become twi bus master and write a - * series of bytes to a device on the bus - * Input address: 7bit i2c device address - * data: pointer to byte array - * length: number of bytes in array - * wait: boolean indicating to wait for write or not - * Output 0 .. success - * 1 .. length to long for buffer - * 2 .. address send, NACK received - * 3 .. data send, NACK received - * 4 .. other twi error (lost bus arbitration, bus error, ..) - */ -uint8_t twi_writeTo(uint8_t address, uint8_t* data, uint8_t length, uint8_t wait) -{ - uint8_t i; - - // ensure data will fit into buffer - if(TWI_BUFFER_LENGTH < length){ - return 1; - } - - // wait until twi is ready, become master transmitter - while(TWI_READY != twi_state){ - continue; - } - twi_state = TWI_MTX; - // reset error state (0xFF.. no error occured) - twi_error = 0xFF; - - // initialize buffer iteration vars - twi_masterBufferIndex = 0; - twi_masterBufferLength = length; - - // copy data to twi buffer - for(i = 0; i < length; ++i){ - twi_masterBuffer[i] = data[i]; - } - - // build sla+w, slave device address + w bit - twi_slarw = TW_WRITE; - twi_slarw |= address << 1; - - // send start condition - TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTA); - - // wait for write operation to complete - while(wait && (TWI_MTX == twi_state)){ - continue; - } - - if (twi_error == 0xFF) - return 0; // success - else if (twi_error == TW_MT_SLA_NACK) - return 2; // error: address send, nack received - else if (twi_error == TW_MT_DATA_NACK) - return 3; // error: data send, nack received - else - return 4; // other twi error -} - -/* - * Function twi_transmit - * Desc fills slave tx buffer with data - * must be called in slave tx event callback - * Input data: pointer to byte array - * length: number of bytes in array - * Output 1 length too long for buffer - * 2 not slave transmitter - * 0 ok - */ -uint8_t twi_transmit(uint8_t* data, uint8_t length) -{ - uint8_t i; - - // ensure data will fit into buffer - if(TWI_BUFFER_LENGTH < length){ - return 1; - } - - // ensure we are currently a slave transmitter - if(TWI_STX != twi_state){ - return 2; - } - - // set length and copy data into tx buffer - twi_txBufferLength = length; - for(i = 0; i < length; ++i){ - twi_txBuffer[i] = data[i]; - } - - return 0; -} - -/* - * Function twi_attachSlaveRxEvent - * Desc sets function called before a slave read operation - * Input function: callback function to use - * Output none - */ -void twi_attachSlaveRxEvent( void (*function)(uint8_t*, int) ) -{ - twi_onSlaveReceive = function; -} - -/* - * Function twi_attachSlaveTxEvent - * Desc sets function called before a slave write operation - * Input function: callback function to use - * Output none - */ -void twi_attachSlaveTxEvent( void (*function)(void) ) -{ - twi_onSlaveTransmit = function; -} - -/* - * Function twi_reply - * Desc sends byte or readys receive line - * Input ack: byte indicating to ack or to nack - * Output none - */ -void twi_reply(uint8_t ack) -{ - // transmit master read ready signal, with or without ack - if(ack){ - TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWINT) | _BV(TWEA); - }else{ - TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWINT); - } -} - -/* - * Function twi_stop - * Desc relinquishes bus master status - * Input none - * Output none - */ -void twi_stop(void) -{ - // send stop condition - TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTO); - - // wait for stop condition to be exectued on bus - // TWINT is not set after a stop condition! - while(TWCR & _BV(TWSTO)){ - continue; - } - - // update twi state - twi_state = TWI_READY; -} - -/* - * Function twi_releaseBus - * Desc releases bus control - * Input none - * Output none - */ -void twi_releaseBus(void) -{ - // release bus - TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT); - - // update twi state - twi_state = TWI_READY; -} - -SIGNAL(TWI_vect) -{ - switch(TW_STATUS){ - // All Master - case TW_START: // sent start condition - case TW_REP_START: // sent repeated start condition - // copy device address and r/w bit to output register and ack - TWDR = twi_slarw; - twi_reply(1); - break; - - // Master Transmitter - case TW_MT_SLA_ACK: // slave receiver acked address - case TW_MT_DATA_ACK: // slave receiver acked data - // if there is data to send, send it, otherwise stop - if(twi_masterBufferIndex < twi_masterBufferLength){ - // copy data to output register and ack - TWDR = twi_masterBuffer[twi_masterBufferIndex++]; - twi_reply(1); - }else{ - twi_stop(); - } - break; - case TW_MT_SLA_NACK: // address sent, nack received - twi_error = TW_MT_SLA_NACK; - twi_stop(); - break; - case TW_MT_DATA_NACK: // data sent, nack received - twi_error = TW_MT_DATA_NACK; - twi_stop(); - break; - case TW_MT_ARB_LOST: // lost bus arbitration - twi_error = TW_MT_ARB_LOST; - twi_releaseBus(); - break; - - // Master Receiver - case TW_MR_DATA_ACK: // data received, ack sent - // put byte into buffer - twi_masterBuffer[twi_masterBufferIndex++] = TWDR; - case TW_MR_SLA_ACK: // address sent, ack received - // ack if more bytes are expected, otherwise nack - if(twi_masterBufferIndex < twi_masterBufferLength){ - twi_reply(1); - }else{ - twi_reply(0); - } - break; - case TW_MR_DATA_NACK: // data received, nack sent - // put final byte into buffer - twi_masterBuffer[twi_masterBufferIndex++] = TWDR; - case TW_MR_SLA_NACK: // address sent, nack received - twi_stop(); - break; - // TW_MR_ARB_LOST handled by TW_MT_ARB_LOST case - - // Slave Receiver - case TW_SR_SLA_ACK: // addressed, returned ack - case TW_SR_GCALL_ACK: // addressed generally, returned ack - case TW_SR_ARB_LOST_SLA_ACK: // lost arbitration, returned ack - case TW_SR_ARB_LOST_GCALL_ACK: // lost arbitration, returned ack - // enter slave receiver mode - twi_state = TWI_SRX; - // indicate that rx buffer can be overwritten and ack - twi_rxBufferIndex = 0; - twi_reply(1); - break; - case TW_SR_DATA_ACK: // data received, returned ack - case TW_SR_GCALL_DATA_ACK: // data received generally, returned ack - // if there is still room in the rx buffer - if(twi_rxBufferIndex < TWI_BUFFER_LENGTH){ - // put byte in buffer and ack - twi_rxBuffer[twi_rxBufferIndex++] = TWDR; - twi_reply(1); - }else{ - // otherwise nack - twi_reply(0); - } - break; - case TW_SR_STOP: // stop or repeated start condition received - // put a null char after data if there's room - if(twi_rxBufferIndex < TWI_BUFFER_LENGTH){ - twi_rxBuffer[twi_rxBufferIndex] = '\0'; - } - // sends ack and stops interface for clock stretching - twi_stop(); - // callback to user defined callback - twi_onSlaveReceive(twi_rxBuffer, twi_rxBufferIndex); - // since we submit rx buffer to "wire" library, we can reset it - twi_rxBufferIndex = 0; - // ack future responses and leave slave receiver state - twi_releaseBus(); - break; - case TW_SR_DATA_NACK: // data received, returned nack - case TW_SR_GCALL_DATA_NACK: // data received generally, returned nack - // nack back at master - twi_reply(0); - break; - - // Slave Transmitter - case TW_ST_SLA_ACK: // addressed, returned ack - case TW_ST_ARB_LOST_SLA_ACK: // arbitration lost, returned ack - // enter slave transmitter mode - twi_state = TWI_STX; - // ready the tx buffer index for iteration - twi_txBufferIndex = 0; - // set tx buffer length to be zero, to verify if user changes it - twi_txBufferLength = 0; - // request for txBuffer to be filled and length to be set - // note: user must call twi_transmit(bytes, length) to do this - twi_onSlaveTransmit(); - // if they didn't change buffer & length, initialize it - if(0 == twi_txBufferLength){ - twi_txBufferLength = 1; - twi_txBuffer[0] = 0x00; - } - // transmit first byte from buffer, fall - case TW_ST_DATA_ACK: // byte sent, ack returned - // copy data to output register - TWDR = twi_txBuffer[twi_txBufferIndex++]; - // if there is more to send, ack, otherwise nack - if(twi_txBufferIndex < twi_txBufferLength){ - twi_reply(1); - }else{ - twi_reply(0); - } - break; - case TW_ST_DATA_NACK: // received nack, we are done - case TW_ST_LAST_DATA: // received ack, but we are done already! - // ack future responses - twi_reply(1); - // leave slave receiver state - twi_state = TWI_READY; - break; - - // All - case TW_NO_INFO: // no state information - break; - case TW_BUS_ERROR: // bus error, illegal stop/start - twi_error = TW_BUS_ERROR; - twi_stop(); - break; - } -} - diff --git a/src/lib-other/arduino/arduino/libraries/Wire/utility/twi.h b/src/lib-other/arduino/arduino/libraries/Wire/utility/twi.h deleted file mode 100644 index 1258d8d..0000000 --- a/src/lib-other/arduino/arduino/libraries/Wire/utility/twi.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - twi.h - TWI/I2C library for Wiring & Arduino - Copyright (c) 2006 Nicholas Zambetti. All right reserved. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef twi_h -#define twi_h - - #include - - //#define ATMEGA8 - - #ifndef CPU_FREQ - #define CPU_FREQ 16000000L - #endif - - #ifndef TWI_FREQ - #define TWI_FREQ 100000L - #endif - - #ifndef TWI_BUFFER_LENGTH - #define TWI_BUFFER_LENGTH 32 - #endif - - #define TWI_READY 0 - #define TWI_MRX 1 - #define TWI_MTX 2 - #define TWI_SRX 3 - #define TWI_STX 4 - - void twi_init(void); - void twi_setAddress(uint8_t); - uint8_t twi_readFrom(uint8_t, uint8_t*, uint8_t); - uint8_t twi_writeTo(uint8_t, uint8_t*, uint8_t, uint8_t); - uint8_t twi_transmit(uint8_t*, uint8_t); - void twi_attachSlaveRxEvent( void (*)(uint8_t*, int) ); - void twi_attachSlaveTxEvent( void (*)(void) ); - void twi_reply(uint8_t); - void twi_stop(void); - void twi_releaseBus(void); - -#endif - diff --git a/src/lib-other/peter-fleury/i2cmaster/group__pfleury__ic2master.html b/src/lib-other/peter-fleury/i2cmaster/group__pfleury__ic2master.html deleted file mode 100644 index 23e3f8c..0000000 --- a/src/lib-other/peter-fleury/i2cmaster/group__pfleury__ic2master.html +++ /dev/null @@ -1,473 +0,0 @@ - - -AVR-GCC libraries: I2C Master library - - - -

I2C Master library


Detailed Description

-I2C (TWI) Master Software Library. -

-

 #include <i2cmaster.h> 
-

-Basic routines for communicating with I2C slave devices. This single master implementation is limited to one bus master on the I2C bus.

-This I2c library is implemented as a compact assembler software implementation of the I2C protocol which runs on any AVR (i2cmaster.S) and as a TWI hardware interface for all AVR with built-in TWI hardware (twimaster.c). Since the API for these two implementations is exactly the same, an application can be linked either against the software I2C implementation or the hardware I2C implementation.

-Use 4.7k pull-up resistor on the SDA and SCL pin.

-Adapt the SCL and SDA port and pin definitions and eventually the delay routine in the module i2cmaster.S to your target when using the software I2C implementation !

-Adjust the CPU clock frequence F_CPU in twimaster.c or in the Makfile when using the TWI hardware implementaion.

-

Note:
The module i2cmaster.S is based on the Atmel Application Note AVR300, corrected and adapted to GNU assembler and AVR-GCC C call interface. Replaced the incorrect quarter period delays found in AVR300 with half period delays.
-
Author:
Peter Fleury pfleury@gmx.ch http://jump.to/fleury
-
API Usage Example
The following code shows typical usage of this library, see example test_i2cmaster.c
-
 #include <i2cmaster.h>
-
-
- #define Dev24C02  0xA2      // device address of EEPROM 24C02, see datasheet
-
- int main(void)
- {
-     unsigned char ret;
-
-     i2c_init();                             // initialize I2C library
-
-     // write 0x75 to EEPROM address 5 (Byte Write) 
-     i2c_start_wait(Dev24C02+I2C_WRITE);     // set device address and write mode
-     i2c_write(0x05);                        // write address = 5
-     i2c_write(0x75);                        // write value 0x75 to EEPROM
-     i2c_stop();                             // set stop conditon = release bus
-
-
-     // read previously written value back from EEPROM address 5 
-     i2c_start_wait(Dev24C02+I2C_WRITE);     // set device address and write mode
-
-     i2c_write(0x05);                        // write address = 5
-     i2c_rep_start(Dev24C02+I2C_READ);       // set device address and read mode
-
-     ret = i2c_readNak();                    // read one byte from EEPROM
-     i2c_stop();
-
-     for(;;);
- }
-
-

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Defines

#define I2C_READ   1
#define I2C_WRITE   0
-#define i2c_read(ack)   (ack) ? i2c_readAck() : i2c_readNak();

Functions

void i2c_init (void)
 initialize the I2C master interace. Need to be called only once
void i2c_stop (void)
 Terminates the data transfer and releases the I2C bus.
unsigned char i2c_start (unsigned char addr)
 Issues a start condition and sends address and transfer direction.
unsigned char i2c_rep_start (unsigned char addr)
 Issues a repeated start condition and sends address and transfer direction.
void i2c_start_wait (unsigned char addr)
 Issues a start condition and sends address and transfer direction.
unsigned char i2c_write (unsigned char data)
 Send one byte to I2C device.
unsigned char i2c_readAck (void)
 read one byte from the I2C device, request more data from device
unsigned char i2c_readNak (void)
 read one byte from the I2C device, read is followed by a stop condition
unsigned char i2c_read (unsigned char ack)
 read one byte from the I2C device
-


Define Documentation

-

- - - - -
- - - - -
#define I2C_READ   1
-
- - - - - -
-   - - -

-defines the data direction (reading from I2C device) in i2c_start(),i2c_rep_start()

-

- - - - -
- - - - -
#define I2C_WRITE   0
-
- - - - - -
-   - - -

-defines the data direction (writing to I2C device) in i2c_start(),i2c_rep_start()

-


Function Documentation

-

- - - - -
- - - - - - - - - -
void i2c_init void   ) 
-
- - - - - -
-   - - -

-initialize the I2C master interace. Need to be called only once -

-

Parameters:
- - -
void 
-
-
Returns:
none
-
-

- - - - -
- - - - - - - - - -
void i2c_stop void   ) 
-
- - - - - -
-   - - -

-Terminates the data transfer and releases the I2C bus. -

-

Parameters:
- - -
void 
-
-
Returns:
none
-
-

- - - - -
- - - - - - - - - -
unsigned char i2c_start unsigned char  addr  ) 
-
- - - - - -
-   - - -

-Issues a start condition and sends address and transfer direction. -

-

Parameters:
- - -
addr address and transfer direction of I2C device
-
-
Return values:
- - - -
0 device accessible
1 failed to access device
-
-
-

- - - - -
- - - - - - - - - -
unsigned char i2c_rep_start unsigned char  addr  ) 
-
- - - - - -
-   - - -

-Issues a repeated start condition and sends address and transfer direction. -

-

Parameters:
- - -
addr address and transfer direction of I2C device
-
-
Return values:
- - - -
0 device accessible
1 failed to access device
-
-
-

- - - - -
- - - - - - - - - -
void i2c_start_wait unsigned char  addr  ) 
-
- - - - - -
-   - - -

-Issues a start condition and sends address and transfer direction. -

-If device is busy, use ack polling to wait until device ready

Parameters:
- - -
addr address and transfer direction of I2C device
-
-
Returns:
none
-
-

- - - - -
- - - - - - - - - -
unsigned char i2c_write unsigned char  data  ) 
-
- - - - - -
-   - - -

-Send one byte to I2C device. -

-

Parameters:
- - -
data byte to be transfered
-
-
Return values:
- - - -
0 write successful
1 write failed
-
-
-

- - - - -
- - - - - - - - - -
unsigned char i2c_readAck void   ) 
-
- - - - - -
-   - - -

-read one byte from the I2C device, request more data from device -

-

Returns:
byte read from I2C device
-
-

- - - - -
- - - - - - - - - -
unsigned char i2c_readNak void   ) 
-
- - - - - -
-   - - -

-read one byte from the I2C device, read is followed by a stop condition -

-

Returns:
byte read from I2C device
-
-

- - - - -
- - - - - - - - - -
unsigned char i2c_read unsigned char  ack  ) 
-
- - - - - -
-   - - -

-read one byte from the I2C device -

-Implemented as a macro, which calls either i2c_readAck or i2c_readNak

-

Parameters:
- - -
ack 1 send ack, request more data from device
- 0 send nak, read is followed by a stop condition
-
-
Returns:
byte read from I2C device
-
-


Generated on Tue Mar 29 16:54:08 2005 for AVR-GCC libraries by  - -doxygen 1.4.1
- - diff --git a/src/lib-other/peter-fleury/i2cmaster/i2cmaster.S b/src/lib-other/peter-fleury/i2cmaster/i2cmaster.S deleted file mode 100644 index 9fb0bca..0000000 --- a/src/lib-other/peter-fleury/i2cmaster/i2cmaster.S +++ /dev/null @@ -1,302 +0,0 @@ -;************************************************************************* -; Title : I2C (Single) Master Implementation -; Author: Peter Fleury http://jump.to/fleury -; based on Atmel Appl. Note AVR300 -; File: $Id: i2cmaster.S,v 1.12 2008/03/02 08:51:27 peter Exp $ -; Software: AVR-GCC 3.3 or higher -; Target: any AVR device -; -; DESCRIPTION -; Basic routines for communicating with I2C slave devices. This -; "single" master implementation is limited to one bus master on the -; I2C bus. -; -; Based on the Atmel Application Note AVR300, corrected and adapted -; to GNU assembler and AVR-GCC C call interface -; Replaced the incorrect quarter period delays found in AVR300 with -; half period delays. -; -; USAGE -; These routines can be called from C, refere to file i2cmaster.h. -; See example test_i2cmaster.c -; Adapt the SCL and SDA port and pin definitions and eventually -; the delay routine to your target ! -; Use 4.7k pull-up resistor on the SDA and SCL pin. -; -; NOTES -; The I2C routines can be called either from non-interrupt or -; interrupt routines, not both. -; -;************************************************************************* - -#if (__GNUC__ * 100 + __GNUC_MINOR__) < 303 -#error "This library requires AVR-GCC 3.3 or later, update to newer AVR-GCC compiler !" -#endif - - -#include - - - -;***** Adapt these SCA and SCL port and pin definition to your target !! -; -#define SDA 4 // SDA Port D, Pin 4 -#define SCL 5 // SCL Port D, Pin 5 -#define SDA_PORT PORTD // SDA Port D -#define SCL_PORT PORTD // SCL Port D - -;****** - -;-- map the IO register back into the IO address space -#define SDA_DDR (_SFR_IO_ADDR(SDA_PORT) - 1) -#define SCL_DDR (_SFR_IO_ADDR(SCL_PORT) - 1) -#define SDA_OUT _SFR_IO_ADDR(SDA_PORT) -#define SCL_OUT _SFR_IO_ADDR(SCL_PORT) -#define SDA_IN (_SFR_IO_ADDR(SDA_PORT) - 2) -#define SCL_IN (_SFR_IO_ADDR(SCL_PORT) - 2) - - -#ifndef __tmp_reg__ -#define __tmp_reg__ 0 -#endif - - - .section .text - -;************************************************************************* -; delay half period -; For I2C in normal mode (100kHz), use T/2 > 5us -; For I2C in fast mode (400kHz), use T/2 > 1.3us -;************************************************************************* - .stabs "",100,0,0,i2c_delay_T2 - .stabs "i2cmaster.S",100,0,0,i2c_delay_T2 - .func i2c_delay_T2 ; delay 5.0 microsec with 4 Mhz crystal -i2c_delay_T2: ; 4 cycles - rjmp 1f ; 2 " -1: rjmp 2f ; 2 " -2: rjmp 3f ; 2 " -3: rjmp 4f ; 2 " -4: rjmp 5f ; 2 " -5: rjmp 6f ; 2 " -6: nop ; 1 " - ret ; 3 " - .endfunc ; total 20 cyles = 5.0 microsec with 4 Mhz crystal - - -;************************************************************************* -; Initialization of the I2C bus interface. Need to be called only once -; -; extern void i2c_init(void) -;************************************************************************* - .global i2c_init - .func i2c_init -i2c_init: - cbi SDA_DDR,SDA ;release SDA - cbi SCL_DDR,SCL ;release SCL - cbi SDA_OUT,SDA - cbi SCL_OUT,SCL - ret - .endfunc - - -;************************************************************************* -; Issues a start condition and sends address and transfer direction. -; return 0 = device accessible, 1= failed to access device -; -; extern unsigned char i2c_start(unsigned char addr); -; addr = r24, return = r25(=0):r24 -;************************************************************************* - - .global i2c_start - .func i2c_start -i2c_start: - sbi SDA_DDR,SDA ;force SDA low - rcall i2c_delay_T2 ;delay T/2 - - rcall i2c_write ;write address - ret - .endfunc - - -;************************************************************************* -; Issues a repeated start condition and sends address and transfer direction. -; return 0 = device accessible, 1= failed to access device -; -; extern unsigned char i2c_rep_start(unsigned char addr); -; addr = r24, return = r25(=0):r24 -;************************************************************************* - - .global i2c_rep_start - .func i2c_rep_start -i2c_rep_start: - sbi SCL_DDR,SCL ;force SCL low - rcall i2c_delay_T2 ;delay T/2 - cbi SDA_DDR,SDA ;release SDA - rcall i2c_delay_T2 ;delay T/2 - cbi SCL_DDR,SCL ;release SCL - rcall i2c_delay_T2 ;delay T/2 - sbi SDA_DDR,SDA ;force SDA low - rcall i2c_delay_T2 ;delay T/2 - - rcall i2c_write ;write address - ret - .endfunc - - -;************************************************************************* -; Issues a start condition and sends address and transfer direction. -; If device is busy, use ack polling to wait until device is ready -; -; extern void i2c_start_wait(unsigned char addr); -; addr = r24 -;************************************************************************* - - .global i2c_start_wait - .func i2c_start_wait -i2c_start_wait: - mov __tmp_reg__,r24 -i2c_start_wait1: - sbi SDA_DDR,SDA ;force SDA low - rcall i2c_delay_T2 ;delay T/2 - mov r24,__tmp_reg__ - rcall i2c_write ;write address - tst r24 ;if device not busy -> done - breq i2c_start_wait_done - rcall i2c_stop ;terminate write operation - rjmp i2c_start_wait1 ;device busy, poll ack again -i2c_start_wait_done: - ret - .endfunc - - -;************************************************************************* -; Terminates the data transfer and releases the I2C bus -; -; extern void i2c_stop(void) -;************************************************************************* - - .global i2c_stop - .func i2c_stop -i2c_stop: - sbi SCL_DDR,SCL ;force SCL low - sbi SDA_DDR,SDA ;force SDA low - rcall i2c_delay_T2 ;delay T/2 - cbi SCL_DDR,SCL ;release SCL - rcall i2c_delay_T2 ;delay T/2 - cbi SDA_DDR,SDA ;release SDA - rcall i2c_delay_T2 ;delay T/2 - ret - .endfunc - - -;************************************************************************* -; Send one byte to I2C device -; return 0 = write successful, 1 = write failed -; -; extern unsigned char i2c_write( unsigned char data ); -; data = r24, return = r25(=0):r24 -;************************************************************************* - .global i2c_write - .func i2c_write -i2c_write: - sec ;set carry flag - rol r24 ;shift in carry and out bit one - rjmp i2c_write_first -i2c_write_bit: - lsl r24 ;if transmit register empty -i2c_write_first: - breq i2c_get_ack - sbi SCL_DDR,SCL ;force SCL low - brcc i2c_write_low - nop - cbi SDA_DDR,SDA ;release SDA - rjmp i2c_write_high -i2c_write_low: - sbi SDA_DDR,SDA ;force SDA low - rjmp i2c_write_high -i2c_write_high: - rcall i2c_delay_T2 ;delay T/2 - cbi SCL_DDR,SCL ;release SCL - rcall i2c_delay_T2 ;delay T/2 - rjmp i2c_write_bit - -i2c_get_ack: - sbi SCL_DDR,SCL ;force SCL low - cbi SDA_DDR,SDA ;release SDA - rcall i2c_delay_T2 ;delay T/2 - cbi SCL_DDR,SCL ;release SCL -i2c_ack_wait: - sbis SCL_IN,SCL ;wait SCL high (in case wait states are inserted) - rjmp i2c_ack_wait - - clr r24 ;return 0 - sbic SDA_IN,SDA ;if SDA high -> return 1 - ldi r24,1 - rcall i2c_delay_T2 ;delay T/2 - clr r25 - ret - .endfunc - - - -;************************************************************************* -; read one byte from the I2C device, send ack or nak to device -; (ack=1, send ack, request more data from device -; ack=0, send nak, read is followed by a stop condition) -; -; extern unsigned char i2c_read(unsigned char ack); -; ack = r24, return = r25(=0):r24 -; extern unsigned char i2c_readAck(void); -; extern unsigned char i2c_readNak(void); -; return = r25(=0):r24 -;************************************************************************* - .global i2c_readAck - .global i2c_readNak - .global i2c_read - .func i2c_read -i2c_readNak: - clr r24 - rjmp i2c_read -i2c_readAck: - ldi r24,0x01 -i2c_read: - ldi r23,0x01 ;data = 0x01 -i2c_read_bit: - sbi SCL_DDR,SCL ;force SCL low - cbi SDA_DDR,SDA ;release SDA (from previous ACK) - rcall i2c_delay_T2 ;delay T/2 - - cbi SCL_DDR,SCL ;release SCL - rcall i2c_delay_T2 ;delay T/2 - -i2c_read_stretch: - sbis SCL_IN, SCL ;loop until SCL is high (allow slave to stretch SCL) - rjmp i2c_read_stretch - - clc ;clear carry flag - sbic SDA_IN,SDA ;if SDA is high - sec ; set carry flag - - rol r23 ;store bit - brcc i2c_read_bit ;while receive register not full - -i2c_put_ack: - sbi SCL_DDR,SCL ;force SCL low - cpi r24,1 - breq i2c_put_ack_low ;if (ack=0) - cbi SDA_DDR,SDA ; release SDA - rjmp i2c_put_ack_high -i2c_put_ack_low: ;else - sbi SDA_DDR,SDA ; force SDA low -i2c_put_ack_high: - rcall i2c_delay_T2 ;delay T/2 - cbi SCL_DDR,SCL ;release SCL -i2c_put_ack_wait: - sbis SCL_IN,SCL ;wait SCL high - rjmp i2c_put_ack_wait - rcall i2c_delay_T2 ;delay T/2 - mov r24,r23 - clr r25 - ret - .endfunc - diff --git a/src/lib-other/peter-fleury/i2cmaster/i2cmaster.h b/src/lib-other/peter-fleury/i2cmaster/i2cmaster.h deleted file mode 100644 index 70f51fd..0000000 --- a/src/lib-other/peter-fleury/i2cmaster/i2cmaster.h +++ /dev/null @@ -1,178 +0,0 @@ -#ifndef _I2CMASTER_H -#define _I2CMASTER_H 1 -/************************************************************************* -* Title: C include file for the I2C master interface -* (i2cmaster.S or twimaster.c) -* Author: Peter Fleury http://jump.to/fleury -* File: $Id: i2cmaster.h,v 1.10 2005/03/06 22:39:57 Peter Exp $ -* Software: AVR-GCC 3.4.3 / avr-libc 1.2.3 -* Target: any AVR device -* Usage: see Doxygen manual -**************************************************************************/ - -#ifdef DOXYGEN -/** - @defgroup pfleury_ic2master I2C Master library - @code #include @endcode - - @brief I2C (TWI) Master Software Library - - Basic routines for communicating with I2C slave devices. This single master - implementation is limited to one bus master on the I2C bus. - - This I2c library is implemented as a compact assembler software implementation of the I2C protocol - which runs on any AVR (i2cmaster.S) and as a TWI hardware interface for all AVR with built-in TWI hardware (twimaster.c). - Since the API for these two implementations is exactly the same, an application can be linked either against the - software I2C implementation or the hardware I2C implementation. - - Use 4.7k pull-up resistor on the SDA and SCL pin. - - Adapt the SCL and SDA port and pin definitions and eventually the delay routine in the module - i2cmaster.S to your target when using the software I2C implementation ! - - Adjust the CPU clock frequence F_CPU in twimaster.c or in the Makfile when using the TWI hardware implementaion. - - @note - The module i2cmaster.S is based on the Atmel Application Note AVR300, corrected and adapted - to GNU assembler and AVR-GCC C call interface. - Replaced the incorrect quarter period delays found in AVR300 with - half period delays. - - @author Peter Fleury pfleury@gmx.ch http://jump.to/fleury - - @par API Usage Example - The following code shows typical usage of this library, see example test_i2cmaster.c - - @code - - #include - - - #define Dev24C02 0xA2 // device address of EEPROM 24C02, see datasheet - - int main(void) - { - unsigned char ret; - - i2c_init(); // initialize I2C library - - // write 0x75 to EEPROM address 5 (Byte Write) - i2c_start_wait(Dev24C02+I2C_WRITE); // set device address and write mode - i2c_write(0x05); // write address = 5 - i2c_write(0x75); // write value 0x75 to EEPROM - i2c_stop(); // set stop conditon = release bus - - - // read previously written value back from EEPROM address 5 - i2c_start_wait(Dev24C02+I2C_WRITE); // set device address and write mode - - i2c_write(0x05); // write address = 5 - i2c_rep_start(Dev24C02+I2C_READ); // set device address and read mode - - ret = i2c_readNak(); // read one byte from EEPROM - i2c_stop(); - - for(;;); - } - @endcode - -*/ -#endif /* DOXYGEN */ - -/**@{*/ - -#if (__GNUC__ * 100 + __GNUC_MINOR__) < 304 -#error "This library requires AVR-GCC 3.4 or later, update to newer AVR-GCC compiler !" -#endif - -#include - -/** defines the data direction (reading from I2C device) in i2c_start(),i2c_rep_start() */ -#define I2C_READ 1 - -/** defines the data direction (writing to I2C device) in i2c_start(),i2c_rep_start() */ -#define I2C_WRITE 0 - - -/** - @brief initialize the I2C master interace. Need to be called only once - @param void - @return none - */ -extern void i2c_init(void); - - -/** - @brief Terminates the data transfer and releases the I2C bus - @param void - @return none - */ -extern void i2c_stop(void); - - -/** - @brief Issues a start condition and sends address and transfer direction - - @param addr address and transfer direction of I2C device - @retval 0 device accessible - @retval 1 failed to access device - */ -extern unsigned char i2c_start(unsigned char addr); - - -/** - @brief Issues a repeated start condition and sends address and transfer direction - - @param addr address and transfer direction of I2C device - @retval 0 device accessible - @retval 1 failed to access device - */ -extern unsigned char i2c_rep_start(unsigned char addr); - - -/** - @brief Issues a start condition and sends address and transfer direction - - If device is busy, use ack polling to wait until device ready - @param addr address and transfer direction of I2C device - @return none - */ -extern void i2c_start_wait(unsigned char addr); - - -/** - @brief Send one byte to I2C device - @param data byte to be transfered - @retval 0 write successful - @retval 1 write failed - */ -extern unsigned char i2c_write(unsigned char data); - - -/** - @brief read one byte from the I2C device, request more data from device - @return byte read from I2C device - */ -extern unsigned char i2c_readAck(void); - -/** - @brief read one byte from the I2C device, read is followed by a stop condition - @return byte read from I2C device - */ -extern unsigned char i2c_readNak(void); - -/** - @brief read one byte from the I2C device - - Implemented as a macro, which calls either i2c_readAck or i2c_readNak - - @param ack 1 send ack, request more data from device
- 0 send nak, read is followed by a stop condition - @return byte read from I2C device - */ -extern unsigned char i2c_read(unsigned char ack); -#define i2c_read(ack) (ack) ? i2c_readAck() : i2c_readNak(); - - -/**@}*/ -#endif diff --git a/src/lib-other/peter-fleury/i2cmaster/makefile b/src/lib-other/peter-fleury/i2cmaster/makefile deleted file mode 100644 index c8206b8..0000000 --- a/src/lib-other/peter-fleury/i2cmaster/makefile +++ /dev/null @@ -1,392 +0,0 @@ -# Makefile to compile and link the I2C Master library and test program -# -# based on -# WinAVR Sample makefile written by Eric B. Weddington, Jörg Wunsch, et al. -# -# Note: -# The warnings which appear while converting ELF to AVR Extended COFF (make extcoff) -# can be ignored -# -# -# On command line: -# -# make all = Make software. -# -# make clean = Clean out built project files. -# -# make coff = Convert ELF to AVR COFF (for use with AVR Studio 3.x or VMLAB). -# -# make extcoff = Convert ELF to AVR Extended COFF (for use with AVR Studio -# 4.07 or greater). -# -# make program = Download the hex file to the device, using avrdude. Please -# customize the avrdude settings below first! -# -# make filename.s = Just compile filename.c into the assembler code only -# -# To rebuild project do "make clean" then "make all". -# - - -# MCU name -MCU = at90s8515 - -# Output format. (can be srec, ihex, binary) -FORMAT = ihex - -# Optimization level, can be [0, 1, 2, 3, s]. 0 turns off optimization. -# (Note: 3 is not always the best optimization level. See avr-libc FAQ.) -OPT = s - - -# Target file name (without extension). -TARGET = test_i2cmaster - - -# List C source files here. (C dependencies are automatically generated.) -SRC = $(TARGET).c - -# 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 = i2cmaster.S - - -# List any extra directories to look for include files here. -# Each directory must be seperated by a space. -EXTRAINCDIRS = - - -# Optional compiler flags. -# -g: generate debugging information (for GDB, or for COFF conversion) -# -O*: optimization level -# -f...: tuning, see gcc manual and avr-libc documentation -# -Wall...: warning level -# -Wa,...: tell GCC to pass this to the assembler. -# -ahlms: create assembler listing -CFLAGS = -g -O$(OPT) \ --funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums \ --Wall -Wstrict-prototypes \ --Wa,-adhlns=$(<:.c=.lst) \ -$(patsubst %,-I%,$(EXTRAINCDIRS)) - - -# Set a "language standard" compiler flag. -# Unremark just one line below to set the language standard to use. -# gnu99 = C99 + GNU extensions. See GCC manual for more information. -#CFLAGS += -std=c89 -#CFLAGS += -std=gnu89 -#CFLAGS += -std=c99 -CFLAGS += -std=gnu99 - - - -# Optional assembler flags. -# -Wa,...: tell GCC to pass this to the assembler. -# -ahlms: 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] -ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs - - - -# Optional linker flags. -# -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 - - - -# Additional libraries - -# Minimalistic printf version -#LDFLAGS += -Wl,-u,vfprintf -lprintf_min - -# Floating point printf version (requires -lm below) -#LDFLAGS += -Wl,-u,vfprintf -lprintf_flt - -# -lm = math library -LDFLAGS += -lm - - - - -# Programming support using avrdude. Settings and variables. - -# 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 = stk500 - - -AVRDUDE_PORT = com1 # programmer connected to serial device -#AVRDUDE_PORT = lpt1 # programmer connected to parallel port - -AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex -#AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep - -AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) - -# 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 += -y - -# Uncomment the following if you do /not/ wish a verification to be -# performed after programming the device. -#AVRDUDE_FLAGS += -V - -# Increase verbosity level. Please use this when submitting bug -# reports about avrdude. See -# to submit bug reports. -#AVRDUDE_FLAGS += -v -v - - - - -# --------------------------------------------------------------------------- - -# Define directories, if needed. -DIRAVR = c:/winavr -DIRAVRBIN = $(DIRAVR)/bin -DIRAVRUTILS = $(DIRAVR)/utils/bin -DIRINC = . -DIRLIB = $(DIRAVR)/avr/lib - - -# Define programs and commands. -SHELL = sh - -CC = avr-gcc - -OBJCOPY = avr-objcopy -OBJDUMP = avr-objdump -SIZE = avr-size - - -# Programming support using avrdude. -AVRDUDE = avrdude - - -REMOVE = rm -f -COPY = cp - -HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex -ELFSIZE = $(SIZE) -A $(TARGET).elf - - - -# 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: -MSG_ASSEMBLING = Assembling: -MSG_CLEANING = Cleaning project: - - - - -# Define all object files. -OBJ = $(SRC:.c=.o) $(ASRC:.S=.o) - -# Define all listing files. -LST = $(ASRC:.S=.lst) $(SRC:.c=.lst) - -# Combine all necessary flags and optional flags. -# Add target processor to flags. -ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) -ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS) - - - -# Default target. -all: begin gccversion sizebefore $(TARGET).elf $(TARGET).hex $(TARGET).eep \ - $(TARGET).lss $(TARGET).sym sizeafter finished end - - -# 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) - -finished: - @echo $(MSG_ERRORS_NONE) - -end: - @echo $(MSG_END) - @echo - - -# Display size of file. -sizebefore: - @if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); echo; fi - -sizeafter: - @if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); echo; fi - - - -# Display compiler version information. -gccversion : - @$(CC) --version - - - - -# Convert ELF to COFF for use in debugging / simulating in -# AVR Studio or VMLAB. -COFFCONVERT=$(OBJCOPY) --debugging \ - --change-section-address .data-0x800000 \ - --change-section-address .bss-0x800000 \ - --change-section-address .noinit-0x800000 \ - --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 - - - - -# Program the device. -program: $(TARGET).hex $(TARGET).eep - $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM) - - - - -# Create final output files (.hex, .eep) from ELF output file. -%.hex: %.elf - @echo - @echo $(MSG_FLASH) $@ - $(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@ - -%.eep: %.elf - @echo - @echo $(MSG_EEPROM) $@ - -$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \ - --change-section-lma .eeprom=0 -O $(FORMAT) $< $@ - -# 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) $@ - avr-nm -n $< > $@ - - - -# Link: create ELF output file from object files. -.SECONDARY : $(TARGET).elf -.PRECIOUS : $(OBJ) -%.elf: $(OBJ) - @echo - @echo $(MSG_LINKING) $@ - $(CC) $(ALL_CFLAGS) $(OBJ) --output $@ $(LDFLAGS) - - -# Compile: create object files from C source files. -%.o : %.c - @echo - @echo $(MSG_COMPILING) $< - $(CC) -c $(ALL_CFLAGS) $< -o $@ - - -# Compile: create assembler files from C source files. -%.s : %.c - $(CC) -S $(ALL_CFLAGS) $< -o $@ - - -# Assemble: create object files from assembler source files. -%.o : %.S - @echo - @echo $(MSG_ASSEMBLING) $< - $(CC) -c $(ALL_ASFLAGS) $< -o $@ - - - - - - -# Target: clean project. -clean: begin clean_list finished end - -clean_list : - @echo - @echo $(MSG_CLEANING) - $(REMOVE) $(TARGET).hex - $(REMOVE) $(TARGET).eep - $(REMOVE) $(TARGET).obj - $(REMOVE) $(TARGET).cof - $(REMOVE) $(TARGET).elf - $(REMOVE) $(TARGET).map - $(REMOVE) $(TARGET).obj - $(REMOVE) $(TARGET).a90 - $(REMOVE) $(TARGET).sym - $(REMOVE) $(TARGET).lnk - $(REMOVE) $(TARGET).lss - $(REMOVE) $(OBJ) - $(REMOVE) $(LST) - $(REMOVE) $(SRC:.c=.s) - $(REMOVE) $(SRC:.c=.d) - - -# Automatically generate C source code dependencies. -# (Code originally taken from the GNU make user manual and modified -# (See README.txt Credits).) -# -# Note that this will work with sh (bash) and sed that is shipped with WinAVR -# (see the SHELL variable defined above). -# This may not work with other shells or other seds. -# -%.d: %.c - set -e; $(CC) -MM $(ALL_CFLAGS) $< \ - | sed 's,\(.*\)\.o[ :]*,\1.o \1.d : ,g' > $@; \ - [ -s $@ ] || rm -f $@ - - -# Remove the '-' if you want to see the dependency files generated. --include $(SRC:.c=.d) - - - -# Listing of phony targets. -.PHONY : all begin finish end sizebefore sizeafter gccversion coff extcoff \ - clean clean_list program - diff --git a/src/lib-other/peter-fleury/i2cmaster/makefile.i2cmaster b/src/lib-other/peter-fleury/i2cmaster/makefile.i2cmaster deleted file mode 100644 index c8206b8..0000000 --- a/src/lib-other/peter-fleury/i2cmaster/makefile.i2cmaster +++ /dev/null @@ -1,392 +0,0 @@ -# Makefile to compile and link the I2C Master library and test program -# -# based on -# WinAVR Sample makefile written by Eric B. Weddington, Jörg Wunsch, et al. -# -# Note: -# The warnings which appear while converting ELF to AVR Extended COFF (make extcoff) -# can be ignored -# -# -# On command line: -# -# make all = Make software. -# -# make clean = Clean out built project files. -# -# make coff = Convert ELF to AVR COFF (for use with AVR Studio 3.x or VMLAB). -# -# make extcoff = Convert ELF to AVR Extended COFF (for use with AVR Studio -# 4.07 or greater). -# -# make program = Download the hex file to the device, using avrdude. Please -# customize the avrdude settings below first! -# -# make filename.s = Just compile filename.c into the assembler code only -# -# To rebuild project do "make clean" then "make all". -# - - -# MCU name -MCU = at90s8515 - -# Output format. (can be srec, ihex, binary) -FORMAT = ihex - -# Optimization level, can be [0, 1, 2, 3, s]. 0 turns off optimization. -# (Note: 3 is not always the best optimization level. See avr-libc FAQ.) -OPT = s - - -# Target file name (without extension). -TARGET = test_i2cmaster - - -# List C source files here. (C dependencies are automatically generated.) -SRC = $(TARGET).c - -# 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 = i2cmaster.S - - -# List any extra directories to look for include files here. -# Each directory must be seperated by a space. -EXTRAINCDIRS = - - -# Optional compiler flags. -# -g: generate debugging information (for GDB, or for COFF conversion) -# -O*: optimization level -# -f...: tuning, see gcc manual and avr-libc documentation -# -Wall...: warning level -# -Wa,...: tell GCC to pass this to the assembler. -# -ahlms: create assembler listing -CFLAGS = -g -O$(OPT) \ --funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums \ --Wall -Wstrict-prototypes \ --Wa,-adhlns=$(<:.c=.lst) \ -$(patsubst %,-I%,$(EXTRAINCDIRS)) - - -# Set a "language standard" compiler flag. -# Unremark just one line below to set the language standard to use. -# gnu99 = C99 + GNU extensions. See GCC manual for more information. -#CFLAGS += -std=c89 -#CFLAGS += -std=gnu89 -#CFLAGS += -std=c99 -CFLAGS += -std=gnu99 - - - -# Optional assembler flags. -# -Wa,...: tell GCC to pass this to the assembler. -# -ahlms: 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] -ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs - - - -# Optional linker flags. -# -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 - - - -# Additional libraries - -# Minimalistic printf version -#LDFLAGS += -Wl,-u,vfprintf -lprintf_min - -# Floating point printf version (requires -lm below) -#LDFLAGS += -Wl,-u,vfprintf -lprintf_flt - -# -lm = math library -LDFLAGS += -lm - - - - -# Programming support using avrdude. Settings and variables. - -# 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 = stk500 - - -AVRDUDE_PORT = com1 # programmer connected to serial device -#AVRDUDE_PORT = lpt1 # programmer connected to parallel port - -AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex -#AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep - -AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) - -# 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 += -y - -# Uncomment the following if you do /not/ wish a verification to be -# performed after programming the device. -#AVRDUDE_FLAGS += -V - -# Increase verbosity level. Please use this when submitting bug -# reports about avrdude. See -# to submit bug reports. -#AVRDUDE_FLAGS += -v -v - - - - -# --------------------------------------------------------------------------- - -# Define directories, if needed. -DIRAVR = c:/winavr -DIRAVRBIN = $(DIRAVR)/bin -DIRAVRUTILS = $(DIRAVR)/utils/bin -DIRINC = . -DIRLIB = $(DIRAVR)/avr/lib - - -# Define programs and commands. -SHELL = sh - -CC = avr-gcc - -OBJCOPY = avr-objcopy -OBJDUMP = avr-objdump -SIZE = avr-size - - -# Programming support using avrdude. -AVRDUDE = avrdude - - -REMOVE = rm -f -COPY = cp - -HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex -ELFSIZE = $(SIZE) -A $(TARGET).elf - - - -# 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: -MSG_ASSEMBLING = Assembling: -MSG_CLEANING = Cleaning project: - - - - -# Define all object files. -OBJ = $(SRC:.c=.o) $(ASRC:.S=.o) - -# Define all listing files. -LST = $(ASRC:.S=.lst) $(SRC:.c=.lst) - -# Combine all necessary flags and optional flags. -# Add target processor to flags. -ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) -ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS) - - - -# Default target. -all: begin gccversion sizebefore $(TARGET).elf $(TARGET).hex $(TARGET).eep \ - $(TARGET).lss $(TARGET).sym sizeafter finished end - - -# 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) - -finished: - @echo $(MSG_ERRORS_NONE) - -end: - @echo $(MSG_END) - @echo - - -# Display size of file. -sizebefore: - @if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); echo; fi - -sizeafter: - @if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); echo; fi - - - -# Display compiler version information. -gccversion : - @$(CC) --version - - - - -# Convert ELF to COFF for use in debugging / simulating in -# AVR Studio or VMLAB. -COFFCONVERT=$(OBJCOPY) --debugging \ - --change-section-address .data-0x800000 \ - --change-section-address .bss-0x800000 \ - --change-section-address .noinit-0x800000 \ - --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 - - - - -# Program the device. -program: $(TARGET).hex $(TARGET).eep - $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM) - - - - -# Create final output files (.hex, .eep) from ELF output file. -%.hex: %.elf - @echo - @echo $(MSG_FLASH) $@ - $(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@ - -%.eep: %.elf - @echo - @echo $(MSG_EEPROM) $@ - -$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \ - --change-section-lma .eeprom=0 -O $(FORMAT) $< $@ - -# 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) $@ - avr-nm -n $< > $@ - - - -# Link: create ELF output file from object files. -.SECONDARY : $(TARGET).elf -.PRECIOUS : $(OBJ) -%.elf: $(OBJ) - @echo - @echo $(MSG_LINKING) $@ - $(CC) $(ALL_CFLAGS) $(OBJ) --output $@ $(LDFLAGS) - - -# Compile: create object files from C source files. -%.o : %.c - @echo - @echo $(MSG_COMPILING) $< - $(CC) -c $(ALL_CFLAGS) $< -o $@ - - -# Compile: create assembler files from C source files. -%.s : %.c - $(CC) -S $(ALL_CFLAGS) $< -o $@ - - -# Assemble: create object files from assembler source files. -%.o : %.S - @echo - @echo $(MSG_ASSEMBLING) $< - $(CC) -c $(ALL_ASFLAGS) $< -o $@ - - - - - - -# Target: clean project. -clean: begin clean_list finished end - -clean_list : - @echo - @echo $(MSG_CLEANING) - $(REMOVE) $(TARGET).hex - $(REMOVE) $(TARGET).eep - $(REMOVE) $(TARGET).obj - $(REMOVE) $(TARGET).cof - $(REMOVE) $(TARGET).elf - $(REMOVE) $(TARGET).map - $(REMOVE) $(TARGET).obj - $(REMOVE) $(TARGET).a90 - $(REMOVE) $(TARGET).sym - $(REMOVE) $(TARGET).lnk - $(REMOVE) $(TARGET).lss - $(REMOVE) $(OBJ) - $(REMOVE) $(LST) - $(REMOVE) $(SRC:.c=.s) - $(REMOVE) $(SRC:.c=.d) - - -# Automatically generate C source code dependencies. -# (Code originally taken from the GNU make user manual and modified -# (See README.txt Credits).) -# -# Note that this will work with sh (bash) and sed that is shipped with WinAVR -# (see the SHELL variable defined above). -# This may not work with other shells or other seds. -# -%.d: %.c - set -e; $(CC) -MM $(ALL_CFLAGS) $< \ - | sed 's,\(.*\)\.o[ :]*,\1.o \1.d : ,g' > $@; \ - [ -s $@ ] || rm -f $@ - - -# Remove the '-' if you want to see the dependency files generated. --include $(SRC:.c=.d) - - - -# Listing of phony targets. -.PHONY : all begin finish end sizebefore sizeafter gccversion coff extcoff \ - clean clean_list program - diff --git a/src/lib-other/peter-fleury/i2cmaster/makefile.twimaster b/src/lib-other/peter-fleury/i2cmaster/makefile.twimaster deleted file mode 100644 index 593ca45..0000000 --- a/src/lib-other/peter-fleury/i2cmaster/makefile.twimaster +++ /dev/null @@ -1,502 +0,0 @@ -# ---------------------------------------------------------------------------- -# Makefile to compile and link the TWImaster library and test program -# Author: Peter Fleury -# File: $Id: makefile.twimaster,v 1.1 2005/03/29 14:50:05 Peter Exp $ -# based on WinAVR Makefile Template written by Eric B. Weddington, Jörg Wunsch, et al. -# -# Adjust F_CPU below to the clock frequency in Mhz of your AVR target -# -# rename this file to "makefile" or invoke with "make -f makefile.twimaster" -# -#---------------------------------------------------------------------------- -# 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 = atmega8 - - -# Processor frequency. -# This will define a symbol, F_CPU, in all source code files equal to the -# processor frequency. You can then use this symbol in your source code to -# calculate timings. Do NOT tack on a 'UL' at the end, this will be done -# automatically to create a 32-bit value in your source code. -F_CPU = 4000000 - - -# Output format. (can be srec, ihex, binary) -FORMAT = ihex - - -# Target file name (without extension). -TARGET = test_i2cmaster - - -# List C source files here. (C dependencies are automatically generated.) -SRC = $(TARGET).c twimaster.c - - -# 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 -CDEFS = -DF_CPU=$(F_CPU)UL - - -# Place -I options here -CINCS = - - - -#---------------- Compiler Options ---------------- -# -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) $(CINCS) -CFLAGS += -O$(OPT) -CFLAGS += -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -CFLAGS += -Wall -Wstrict-prototypes -CFLAGS += -Wa,-adhlns=$(<:.c=.lst) -CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS)) -CFLAGS += $(CSTANDARD) - - -#---------------- Assembler Options ---------------- -# -Wa,...: tell GCC to pass this to the assembler. -# -ahlms: 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] -ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs - - -#---------------- 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 - - - -#---------------- 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,--defsym=__heap_start=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 += $(PRINTF_LIB) $(SCANF_LIB) $(MATH_LIB) - - - -#---------------- 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 = stk500 - -# com1 = serial port. Use lpt1 to connect to parallel port. -AVRDUDE_PORT = com1 # programmer connected to serial device - -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 -# to submit bug reports. -#AVRDUDE_VERBOSE = -v -v - -AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) -AVRDUDE_FLAGS += $(AVRDUDE_NO_VERIFY) -AVRDUDE_FLAGS += $(AVRDUDE_VERBOSE) -AVRDUDE_FLAGS += $(AVRDUDE_ERASE_COUNTER) - - - -#---------------- Debugging Options ---------------- - -# For simulavr only - target MCU frequency. -DEBUG_MFREQ = $(F_CPU) - -# Set the DEBUG_UI to either gdb or insight. -# DEBUG_UI = gdb -DEBUG_UI = insight - -# Set the debugging back-end to either avarice, simulavr. -DEBUG_BACKEND = avarice -#DEBUG_BACKEND = simulavr - -# GDB Init Filename. -GDBINIT_FILE = __avr_gdbinit - -# When using avarice settings for the JTAG -JTAG_DEV = /dev/com1 - -# Debugging port used to communicate between GDB / avarice / simulavr. -DEBUG_PORT = 4242 - -# Debugging host used to communicate between GDB / avarice / simulavr, normally -# just set to localhost unless doing some sort of crazy debugging when -# avarice is running on a different computer. -DEBUG_HOST = localhost - - - -#============================================================================ - - -# Define programs and commands. -SHELL = sh -CC = avr-gcc -OBJCOPY = avr-objcopy -OBJDUMP = avr-objdump -SIZE = avr-size -NM = avr-nm -AVRDUDE = avrdude -REMOVE = rm -f -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: -MSG_ASSEMBLING = Assembling: -MSG_CLEANING = Cleaning project: - - - - -# Define all object files. -OBJ = $(SRC:.c=.o) $(ASRC:.S=.o) - -# Define all listing files. -LST = $(SRC:.c=.lst) $(ASRC:.S=.lst) - - -# Compiler flags to generate dependency files. -GENDEPFLAGS = -MD -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_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS) - - - - - -# Default target. -all: begin gccversion sizebefore build sizeafter end - -build: elf hex eep lss sym - -elf: $(TARGET).elf -hex: $(TARGET).hex -eep: $(TARGET).eep -lss: $(TARGET).lss -sym: $(TARGET).sym - - - -# 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) -A $(TARGET).elf -AVRMEM = avr-mem.sh $(TARGET).elf $(MCU) - -sizebefore: - @if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); \ - $(AVRMEM) 2>/dev/null; echo; fi - -sizeafter: - @if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); \ - $(AVRMEM) 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 \ ---change-section-address .data-0x800000 \ ---change-section-address .bss-0x800000 \ ---change-section-address .noinit-0x800000 \ ---change-section-address .eeprom-0x810000 - - -coff: $(TARGET).elf - @echo - @echo $(MSG_COFF) $(TARGET).cof - $(COFFCONVERT) -O coff-avr $< $(TARGET).cof - - -extcoff: $(TARGET).elf - @echo - @echo $(MSG_EXTENDED_COFF) $(TARGET).cof - $(COFFCONVERT) -O coff-ext-avr $< $(TARGET).cof - - - -# Create final output files (.hex, .eep) from ELF output file. -%.hex: %.elf - @echo - @echo $(MSG_FLASH) $@ - $(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@ - -%.eep: %.elf - @echo - @echo $(MSG_EEPROM) $@ - -$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \ - --change-section-lma .eeprom=0 -O $(FORMAT) $< $@ - -# 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 $< > $@ - - - -# 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. -%.o : %.c - @echo - @echo $(MSG_COMPILING) $< - $(CC) -c $(ALL_CFLAGS) $< -o $@ - - -# Compile: create assembler files from C source files. -%.s : %.c - $(CC) -S $(ALL_CFLAGS) $< -o $@ - - -# Assemble: create object files from assembler source files. -%.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) $(OBJ) - $(REMOVE) $(LST) - $(REMOVE) $(SRC:.c=.s) - $(REMOVE) $(SRC:.c=.d) - $(REMOVE) .dep/* - - - -# 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 - diff --git a/src/lib-other/peter-fleury/i2cmaster/test_i2cmaster.c b/src/lib-other/peter-fleury/i2cmaster/test_i2cmaster.c deleted file mode 100644 index fdeda29..0000000 --- a/src/lib-other/peter-fleury/i2cmaster/test_i2cmaster.c +++ /dev/null @@ -1,78 +0,0 @@ -/**************************************************************************** -Title: Access serial EEPROM 24C02 using I2C interace -Author: Peter Fleury http://jump.to/fleury -File: $Id: test_i2cmaster.c,v 1.2 2003/12/06 17:07:18 peter Exp $ -Software: AVR-GCC 3.3 -Hardware: AT90S8515 at 4 Mhz, any AVR device can be used - -Description: - This example shows how the I2C library i2cmaster.S can be used to - access a serial eeprom. - Based on Atmel Application Note AVR300, adapted to AVR-GCC C interface - -*****************************************************************************/ -#include -#include "i2cmaster.h" - - -#define Dev24C02 0xA2 // device address of EEPROM 24C02, see datasheet - - -int main(void) -{ - unsigned char ret; - - - DDRB = 0xff; // use all pins on port B for output - PORTB = 0xff; // (active low LED's ) - - i2c_init(); // init I2C interface - - /* write 0x75 to eeprom address 0x05 (Byte Write) */ - ret = i2c_start(Dev24C02+I2C_WRITE); // set device address and write mode - if ( ret ) { - /* failed to issue start condition, possibly no device found */ - i2c_stop(); - PORTB=0x00; // activate all 8 LED to show error */ - }else { - /* issuing start condition ok, device accessible */ - i2c_write(0x05); // write address = 5 - i2c_write(0x75); // ret=0 -> Ok, ret=1 -> no ACK - i2c_stop(); // set stop conditon = release bus - - /* write ok, read value back from eeprom address 0x05, wait until - the device is no longer busy from the previous write operation */ - i2c_start_wait(Dev24C02+I2C_WRITE); // set device address and write mode - i2c_write(0x05); // write address = 5 - i2c_rep_start(Dev24C02+I2C_READ); // set device address and read mode - ret = i2c_readNak(); // read one byte - i2c_stop(); - - PORTB = ~ret; // output byte on the LED's - - /* write 0x70,0x71,072,073 to eeprom address 0x00..0x03 (Page Write), - wait until the device is no longer busy from the previous write operation */ - i2c_start_wait(Dev24C02+I2C_WRITE); // set device address and write mode - i2c_write(0x00); // write start address = 0 - i2c_write(0x70); // write data to address 0 - i2c_write(0x71); // " " " " 1 - i2c_write(0x72); // " " " " 2 - i2c_write(0x74); // " " " " 3 - i2c_stop(); // set stop conditon = release bus - - /* write ok, read value back from eeprom address 0..3 (Sequencial Read), - wait until the device is no longer busy from the previous write operation */ - i2c_start_wait(Dev24C02+I2C_WRITE); // set device address and write mode - i2c_write(0x00); // write address = 0 - i2c_rep_start(Dev24C02+I2C_READ); // set device address and read mode - ret = i2c_readAck(); // read one byte form address 0 - ret = i2c_readAck(); // " " " " " 1 - ret = i2c_readAck(); // " " " " " 2 - ret = i2c_readNak(); // " " " " " 3 - i2c_stop(); // set stop condition = release bus - - PORTB = ~ret; // output byte on the LED's - } - - for(;;); -} diff --git a/src/lib-other/peter-fleury/i2cmaster/twimaster.c b/src/lib-other/peter-fleury/i2cmaster/twimaster.c deleted file mode 100644 index a3744ba..0000000 --- a/src/lib-other/peter-fleury/i2cmaster/twimaster.c +++ /dev/null @@ -1,202 +0,0 @@ -/************************************************************************* -* Title: I2C master library using hardware TWI interface -* Author: Peter Fleury http://jump.to/fleury -* File: $Id: twimaster.c,v 1.3 2005/07/02 11:14:21 Peter Exp $ -* Software: AVR-GCC 3.4.3 / avr-libc 1.2.3 -* Target: any AVR device with hardware TWI -* Usage: API compatible with I2C Software Library i2cmaster.h -**************************************************************************/ -#include -#include - -#include "i2cmaster.h" - - -/* define CPU frequency in Mhz here if not defined in Makefile */ -#ifndef F_CPU -#define F_CPU 4000000UL -#endif - -/* I2C clock in Hz */ -#define SCL_CLOCK 400000 // previously set to 100000L ::2012, Ben Blazak:: - - -/************************************************************************* - Initialization of the I2C bus interface. Need to be called only once -*************************************************************************/ -void i2c_init(void) -{ - /* initialize TWI clock: 100 kHz clock, TWPS = 0 => prescaler = 1 */ - - TWSR = 0; /* no prescaler */ - TWBR = ((F_CPU/SCL_CLOCK)-16)/2; /* must be > 10 for stable operation */ - -}/* i2c_init */ - - -/************************************************************************* - Issues a start condition and sends address and transfer direction. - return 0 = device accessible, 1= failed to access device -*************************************************************************/ -unsigned char i2c_start(unsigned char address) -{ - uint8_t twst; - - // send START condition - TWCR = (1< # src/lib-other Files taken from other projects ## links to original files * [pjrc] (http://pjrc.com/teensy/) - * [blinky] (http://pjrc.com/teensy/blinky.zip) * [usb_keyboard] (http://pjrc.com/teensy/usb_keyboard.zip) -* [peter-fleury] (http://homepage.hispeed.ch/peterfleury/) - * note: This code is licensed under the GNU GPL - (per [the author's web site] - (http://homepage.hispeed.ch/peterfleury/avr-software.html)). - The MIT License is compatible with GPL - (see [the Wikipedia entry] - (http://en.wikipedia.org/wiki/MIT_License), - and [the list of compatible licenses] - (http://www.gnu.org/licenses/license-list.html#GPLCompatibleLicenses) - on ). - * [i2cmaster] (http://homepage.hispeed.ch/peterfleury/i2cmaster.zip) - -* [arduino] (https://github.com/arduino) - * [arduino] (https://github.com/arduino/Arduino) - * .../twi.c and .../twi.h - * note: The version here is from the Ubuntu package, so it's probably - old. The (new) version from github has dependencies galore on random - other Arduino files, so it wasn't really usable. - ------------------------------------------------------------------------------- Copyright © 2012 Ben Blazak diff --git a/src/main.c b/src/main.c index 927381d..07c953c 100644 --- a/src/main.c +++ b/src/main.c @@ -52,7 +52,7 @@ int main(void) { if (counter == 0) _toggle_led3(); counter++; - if (counter >= 1000) + if (counter >= 250) counter = 0; /// static uint8_t current_layer = 0; diff --git a/src/makefile b/src/makefile index 37c0d91..3f585bf 100644 --- a/src/makefile +++ b/src/makefile @@ -18,7 +18,7 @@ SRC = $(shell find -maxdepth 1 -name '*.c') \ EXTRAINCDIRS = . -TEENSY_MAKE = $(MAKE) -f 'lib-other/pjrc/blinky/Makefile' \ +TEENSY_MAKE = $(MAKE) -f 'lib-other/pjrc/usb_keyboard/Makefile' \ TARGET='$(TARGET)' \ SRC='$(SRC)' \ EXTRAINCDIRS='$(EXTRAINCDIRS)' diff --git a/src/test/readme.md b/src/test/readme.md new file mode 100644 index 0000000..05488a9 --- /dev/null +++ b/src/test/readme.md @@ -0,0 +1,12 @@ +# src/test +Files used for testing (at some point) + +* I'm keeping these around for reference; they probably won't be maintained, + and are quite likely to become broken at some point in the future. + +------------------------------------------------------------------------------- + +Copyright © 2012 Ben Blazak +Released under The MIT License (MIT) (see "license.md") +Project located at + From 8b168bc88e8f46618e555ac3a506f7af0c5c5640 Mon Sep 17 00:00:00 2001 From: Ben Blazak Date: Wed, 11 Apr 2012 21:05:45 -0700 Subject: [PATCH 21/22] cleaned up :) and ready to merge --- readme.md | 38 +++- src/key-functions.c | 2 + src/keyboard/ergodox.c | 4 +- src/keyboard/ergodox.h | 1 + src/keyboard/ergodox/_circuit-diagram.svg | 211 +++++++++++++++------- src/keyboard/ergodox/mcp23018.c | 2 +- src/keyboard/ergodox/mcp23018.md | 18 +- src/keyboard/ergodox/teensy-2-0.md | 27 +-- src/main.c | 53 +++--- 9 files changed, 236 insertions(+), 120 deletions(-) diff --git a/readme.md b/readme.md index 3531a1f..11c62d7 100644 --- a/readme.md +++ b/readme.md @@ -4,12 +4,48 @@ [ergodox keyboard]: http://geekhack.org/showthread.php?22780-Interest-Check-Custom-split-ergo-keyboard -## dependencies +This project is definitely in beta, but I'll do my best to keep the 'stable' +branch working. Please see the source (and especially the accompanying '*.md' +files) for documentation. + + +## Notes + +### (2012-04-11) +As of now, it looks like we have a working 6-KRO keyboard firmware for a Teensy +2.0 with a MCP23018 I/O expander. It's scanning at ~167 Hz, most of which is +spent communicating over I²C. This should be fast enough, I think. +Slight improvements might be possible (without finding a microprocessor capable +of > 400 kHz I²C or using SPI, that is, which I imagine would speed things +up a lot - but it'd also be much less convenient). I'll attempt them if I see +the need. + +Also, layers are implemented, but untested, as no keymaps are written to use +them yet. Implementing on-keyboard hardware remapping seems like it'd be very +possible too, but I'd need to try it (and learn how to programmatically store +stuff in program space) to see if it'd work; and I'm not sure of a good way to +do the interface, since different people will likely have different keycap +layouts on the ergoDOX. + +Getting to N-KRO is a goal, but I honestly have no idea whether it'll be +accomplished. Ideally, I'd like a variable-KRO, where the keyboard is 6-KRO +till you press the 7th key (so if you're worried about compatibility, just +don't press more than 6 keys at a time). From what I've read, it might be +possible, but I just finished everything else (so I'm slightly tired), and the +USB spec is scary. + +Discussions about the project as a whole are going on at the forum page (linked +in the title) so if you have any imput (or want to participate in the group +buy!), please stop by. :) . + + +## Dependencies (for building from source) * See the PJRC [Getting Started] (http://pjrc.com/teensy/first_use.html) page for instructions on how to set up an AVR programming environment. This project uses C (not Arduino). + ------------------------------------------------------------------------------- Copyright © 2012 Ben Blazak diff --git a/src/key-functions.c b/src/key-functions.c index bc7a79a..ff5112b 100644 --- a/src/key-functions.c +++ b/src/key-functions.c @@ -14,6 +14,7 @@ #include "keyboard.h" + // ---------------------------------------------------------------------------- #if 0 // not being used right now @@ -36,6 +37,7 @@ static uint8_t _dec_current_layer(uint8_t * current_layer) { } #endif + // ---------------------------------------------------------------------------- void kbfun_press( diff --git a/src/keyboard/ergodox.c b/src/keyboard/ergodox.c index 250f205..12b5f32 100644 --- a/src/keyboard/ergodox.c +++ b/src/keyboard/ergodox.c @@ -33,9 +33,9 @@ uint8_t kb_init(void) { * - error: number of the function that failed */ uint8_t kb_update_matrix(bool matrix[KB_ROWS][KB_COLUMNS]) { - if (teensy_update_matrix(matrix)) // must be first + if (teensy_update_matrix(matrix)) return 1; - if (mcp23018_update_matrix(matrix)) // must be second + if (mcp23018_update_matrix(matrix)) return 2; return 0; // success diff --git a/src/keyboard/ergodox.h b/src/keyboard/ergodox.h index 77e0c76..13d096b 100644 --- a/src/keyboard/ergodox.h +++ b/src/keyboard/ergodox.h @@ -1,5 +1,6 @@ /* ---------------------------------------------------------------------------- * ergoDOX specific exports + * includes (for centralization) the public exports from all subfiles * ---------------------------------------------------------------------------- * Copyright (c) 2012 Ben Blazak * Released under The MIT License (MIT) (see "license.md") diff --git a/src/keyboard/ergodox/_circuit-diagram.svg b/src/keyboard/ergodox/_circuit-diagram.svg index a834901..3e09f78 100644 --- a/src/keyboard/ergodox/_circuit-diagram.svg +++ b/src/keyboard/ergodox/_circuit-diagram.svg @@ -12,7 +12,7 @@ inkscape:version="0.48.2 r9819" version="1.1" id="svg2" - height="367.06873" + height="398.98083" width="950.8382" sodipodi:docname="_circuit-diagram.svg" inkscape:export-filename="/home/ben/Desktop/programs/20120227--ergodox-firmware--for-the-ergodox-keyboard/src/test - circuit diagram/inkscape/_circuit-diagram.png" @@ -26,12 +26,12 @@ inkscape:pageopacity="1" inkscape:pageshadow="2" inkscape:zoom="1.4142136" - inkscape:cx="422.63041" - inkscape:cy="176.46238" + inkscape:cx="477.26232" + inkscape:cy="197.75046" inkscape:document-units="px" - inkscape:current-layer="layer1" + inkscape:current-layer="layer4" showgrid="true" - inkscape:snap-global="true" + inkscape:snap-global="false" inkscape:snap-bbox="false" inkscape:snap-nodes="false" inkscape:bbox-nodes="false" @@ -870,7 +870,7 @@ sodipodi:cy="185.44926" sodipodi:rx="80.96373" sodipodi:ry="82.024384" - d="m 49.497478,185.44926 a 80.96373,82.024384 0 1 1 -161.927458,0 l 80.963729,0 z" + d="m 49.497478,185.44926 c 0,45.30082 -36.248696,82.02439 -80.963729,82.02439 -44.715034,0 -80.963729,-36.72357 -80.963729,-82.02439 0,0 0,0 0,0 l 80.963729,0 z" sodipodi:start="0" sodipodi:end="3.1415927" transform="matrix(0,-0.11858905,0.11219624,0,469.59545,178.62704)" @@ -902,7 +902,7 @@ + LED 1 + LED 2 + LED 3 + - Please also see documentation (especially the notes) in the *.md files AREF + Teensy 2.0 + MCP23018 diff --git a/src/keyboard/ergodox/mcp23018.c b/src/keyboard/ergodox/mcp23018.c index eae2d1e..67d30be 100644 --- a/src/keyboard/ergodox/mcp23018.c +++ b/src/keyboard/ergodox/mcp23018.c @@ -99,7 +99,7 @@ uint8_t mcp23018_update_matrix(bool matrix[KB_ROWS][KB_COLUMNS]) { // if there was an error if (ret) { - // clear the matrix + // clear our part of the matrix for (uint8_t row=0x6; row<=0xB; row++) for (uint8_t col=0; col<=6; col++) matrix[row][col] = 0; diff --git a/src/keyboard/ergodox/mcp23018.md b/src/keyboard/ergodox/mcp23018.md index 1182ddc..7aa6db4 100644 --- a/src/keyboard/ergodox/mcp23018.md +++ b/src/keyboard/ergodox/mcp23018.md @@ -25,24 +25,26 @@ ### MCP32018 Pin Assignments - power_negative Vss(GND) +01---.---28o - o02 27o - column0 GPB0 +03 26o + power_negative Vss(GND) +01---.---28o NC + NC o02 27o GPA7 + column0 GPB0 +03 26o GPA6 column1 GPB1 +04 25+ GPA5 rowB column2 GPB2 +05 24+ GPA4 rowA column3 GPB3 +06 23+ GPA3 row9 column4 GPB4 +07 22+ GPA2 row8 column5 GPB5 +08 21+ GPA1 row7 column6 GPB6 +09 20+ GPA0 row6 - o10 19o - power_positive Vdd(Vcc) +11 18o - I2C SCL +12 17o + GPB7 o10 19o INTA + power_positive Vdd(Vcc) +11 18o INTB + I2C SCL +12 17o NC I2C SDA +13 16+ RESET (see note) - o14-------15+ ADDR (see note) + NC o14-------15+ ADDR (see note) * notes: * ADDR (pin15): Set slave address to `0b0100000` by connecting to Vss(GND). - (The user-defined bits are the three least significant). + * The user-defined bits are the three least significant + * I2C addresses are 7 bits long (the last bit in the byte is used for + indicating read/write) * RESET (pin16) must be externally biased. Since we're not going to trigger it ourselves, we can tie it high. * This is not noted in the I2C Pinout Description section of the MCP23018 diff --git a/src/keyboard/ergodox/teensy-2-0.md b/src/keyboard/ergodox/teensy-2-0.md index 326826f..f9f00a3 100644 --- a/src/keyboard/ergodox/teensy-2-0.md +++ b/src/keyboard/ergodox/teensy-2-0.md @@ -27,18 +27,21 @@ ### Teensy 2.0 Pin Assignments - power_negative GND +---.....---+ Vcc power_positive - column6 PB0 + + PF0 row0 - o + PF1 row1 - o + PF4 row2 - o o o + PF5 row3 - LED3 OC1C + + PF6 row4 - I2C SCL + + PF7 row5 - I2C SDA + + OC1B LED2 - column3 PD2 + + OC1A LED1 - column4 PD3 + + PB4 column0 - column1 PC6 + + PD7 column5 - column2 PC7 +-o-o-o-o-o-+ PD6 onboardLED + power_negative GND +---.....---+ Vcc power_positive + column6 PB0 + + PF0 row0 + PB1 o + PF1 row1 + PB2 o + PF4 row2 + PB3 o o o + PF5 row3 + (OC1C) LED3 PB7 + PE6 AREF + PF6 row4 + (SCL) I2C PD0 + + PF7 row5 + (SDA) I2C PD1 + + PB6 LED2 (OC1B) + column3 PD2 + + PB5 LED1 (OC1A) + column4 PD3 + + PB4 column0 + column1 PC6 + + PD7 column5 + column2 PC7 +-o-o-o-o-o-+ PD6 onboardLED + PD5 --/ | | | \-- PD4 + Vcc ----/ | \---- RST + GND-------/ * notes: * SCL and SDA: Need external pull-up resistors. Sometimes the Teensy diff --git a/src/main.c b/src/main.c index 07c953c..206d969 100644 --- a/src/main.c +++ b/src/main.c @@ -14,47 +14,34 @@ #include "lib/data-types.h" -// #include "keyboard.h" -//dbg -#define KEYBOARD_INCLUDE_PRIVATE -#include "keyboard/ergodox/teensy-2-0.h" -#include "keyboard/ergodox/mcp23018.h" #include "keyboard.h" -/// -#define DEBOUNCE_TIME 5 // in ms; see the spec for your keyswitches +// note: +// - see your keyswitch specification for the necessary value. for cherry mx +// switches, bounce time should be <= 5ms. it looks like most switches are +// speced between 5 and 8ms. +// - if timing is important, balance this value with the main() loop run time +// (~5ms, last i checked, nearly all of it in the i2c update() function) +#define DEBOUNCE_TIME 5 // in ms -//dbg -static void _toggle_led3(void) { - static bool led_on = false; - if (led_on) { - KB_LED3_OFF; - led_on = false; - } else { - KB_LED3_ON; - led_on = true; - } -} -/// int main(void) { kb_init(); // does controller initialization too + KB_LED1_ON; + KB_LED2_ON; + KB_LED3_ON; + usb_init(); while (!usb_configured()); _delay_ms(1000); // make sure the OS has had time to load drivers, etc. + KB_LED1_OFF; + KB_LED2_OFF; + KB_LED3_OFF; + for (;;) { - //dbg -// KB_LED1_ON; _delay_ms(200); KB_LED1_OFF; _delay_ms(200); //dbg - static int counter=0; - if (counter == 0) - _toggle_led3(); - counter++; - if (counter >= 250) - counter = 0; - /// static uint8_t current_layer = 0; // swap `kb_is_pressed` and `kb_was_pressed`, then update @@ -66,6 +53,10 @@ int main(void) { // call the appropriate function for each key, then send the report if // necessary + // - everything else is the key function's responsibility; see the + // keyboard layout file ("keyboard/ergodox/layout.c") for which key + // is assigned which function (per layer), and "key-functions.c" for + // their definitions for (uint8_t row=0; row Date: Wed, 11 Apr 2012 22:05:59 -0700 Subject: [PATCH 22/22] . --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 11c62d7..e2398a9 100644 --- a/readme.md +++ b/readme.md @@ -4,7 +4,7 @@ [ergodox keyboard]: http://geekhack.org/showthread.php?22780-Interest-Check-Custom-split-ergo-keyboard -This project is definitely in beta, but I'll do my best to keep the 'stable' +This project is definitely in beta, but I'll do my best to keep the 'master' branch working. Please see the source (and especially the accompanying '*.md' files) for documentation.