abstracted layout access a little

partial-rewrite
Ben Blazak 2012-04-28 22:39:23 -07:00
parent c90908becd
commit 4e913361ac
8 changed files with 126 additions and 40 deletions

View File

@ -4,14 +4,49 @@
[ergodox keyboard]: http://geekhack.org/showthread.php?22780-Interest-Check-Custom-split-ergo-keyboard
## About this File
If you're viewing this on github, please note that directory links will only
work if you're viewing this from the directory, and file links will only work
if you're viewing this as a file. This is true for all the '.md' files here.
The limitation is due to the way github addresses directories and files, and
the fact that Markdown doesn't have any way (that I know of) to rewrite the
URLs as would be required.
## About this Project
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.
branch working. Please see the source (and especially the accompanying '.md'
files) for documentation. And [references.md] (references.md) contains lots of
good links, along with descriptions.
If you're just trying to compile, jump to the bottom of the file and read the
[Dependencies] (#dependencies-for-building-from-source) section. Once that's
taken care of, navigate to the [src] (src) directory, compile using Make, and
fire up your teensy loader to transfer the '.hex' file. Just to be safe, you
should also check the '.eep' file. If it's larger than 0 bytes, you need to
load it too.
If you're looking to hack on the source, or just feel like reading it, you
probably don't need much direction for a small project like this. I'll try to
write more later (for people who are new to AVR programming, like I was when I
started this project), but for now:
* [src/lib] (src/lib) is for generally useful stuff. The TWI and USB libraries
are in there, along with the file containing basic key press and release
functions.
* [src/keyboard] (src/keyboard) is for keyboard specific stuff. All the chip
initialization code is there, along with the layout files, the software
matrix to hardware matrix mapping, and hardware specific documentation.
* [src/main.c] (src/main.c) ties it all together.
Open issues and such are tracked [on github]
(/benblazak/ergodox-firmware/issues).
## Notes
### (2012-04-11)
### (2012-04-11) (first major release on branch 'main')
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.
@ -43,7 +78,9 @@ buy!), please stop by. :) .
* 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).
project uses C (not Arduino), and Make. I'm compiling with GNU tools under
Ubuntu, but other environments (especially [WinAVR]
(http://winavr.sourceforge.net/) under Windows) should work too.
* I also assume that you are using [git] (http://git-scm.com/) (for `make
clean`).

View File

@ -57,6 +57,11 @@
(on <http://gcc.gnu.org/>)
One of my main references.
* [The GNU C Preprocessor]
(http://tigcc.ticalc.org/doc/cpp.html#SEC27)
A modified version on a different site. Has a few really useful things that
I don't think I saw in the official documentation.
* [C Library Reference]
(http://www.cplusplus.com/reference/)
(on <http://cplusplus.com>)
@ -130,11 +135,13 @@
(http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=38417)
: tutorial by [Dean Camera] (http://fourwalledcubicle.com/AboutMe.php)
(on <http://www.avrfreaks.net/>)
The EEPROM is non-volatile data memory that you can write to if you like. I
don't really see the purpose, unless it feels conceptually cleaner to you,
because there's only 1024 bytes of it on the Teensy 2.0, while there's 2560
bytes of RAM, and 33256 bytes of flash (program memory), and it seems like
it'd be generally easier to use one of those.
The EEPROM is non-volatile data memory that can withstand 100,000 writes and
is byte accessible from within the program. On the Teensy 2.0 there's only
1,024 bytes of it though (compared to 32,256 bytes of flash, and 2,560 bytes
of RAM), so you have to use it sparingly. It's useful because flash
(program) memory is not really something that's meant to be written to (it
can only withstand 10,000 writes, and has to be written in pages using
instructions meant for the bootloader), and RAM is volatile.
* updated version available as a pdf at
[Four Walled Cubicle : AVR Articles]

View File

@ -11,13 +11,18 @@
#ifndef LAYOUT_h
#define LAYOUT_h
#include <avr/pgmspace.h>
#include "lib/_data-types.h"
#include "lib/_key-functions.h" // for `kbfun_funptr_t`
#include "matrix.h" // for number of rows and columns
// include the appropriate keyboard layout header;
// for number of layers
// include the appropriate keyboard layout header
// for:
// - number of layers
// - layout matrix definitions
// - possible non-default layout 'get' and 'set' definitions
#undef _str
#undef _expstr
#undef _inc
@ -29,12 +34,37 @@
#undef _expstr
#undef _inc
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];
// default layout 'get' functions
//
// these are for when the matrices are stored solely in RAM. they're
// here so layouts can redefine them if they with and use RAM, Flash,
// EEPROM, or any combination of those, while maintaining the same
// interface
//
// - 'set' functions are optional, and should be defined in the layout
// specific '.h'. they'll require the use of the EEPROM, possibly in
// clever conjunction with one of the other two memories (since the
// EEPROM is small)
//
// - to override these with real functions, set the macro equal to
// itself (e.g. `#define kb_layout_get kb_layout_get`) and provide
// function prototypes in the layout specific '.h'
#ifndef kb_layout_get
#define kb_layout_get(layer,row,column) \
(_kb_layout[layer][row][column])
#endif
#ifndef kb_layout_press_get
#define kb_layout_press_get(layer,row,column) \
(_kb_layout_press[layer][row][column])
#endif
#ifndef kb_layout_release_get
#define kb_layout_release_get(layer,row,column) \
(_kb_layout_release[layer][row][column])
#endif
#endif

View File

@ -32,8 +32,7 @@ To write a new one:
* The layout matricies could be moved to flash memory (program space,
instead of data space) in order to save RAM, but that doesn't seem
necessary at the moment. It would also be slightly slower, though that
probably shouldn't be a concern. It might be necessary (or convenient)
if one were trying to implement on-keyboard remaping.
probably shouldn't be a concern.
-------------------------------------------------------------------------------

View File

@ -9,6 +9,8 @@
* ------------------------------------------------------------------------- */
#include <avr/pgmspace.h>
#include "lib/_data-types.h"
#include "lib/_usb/keyboard-usage-page--short-names.h"
#include "lib/_key-functions.h"
@ -33,7 +35,7 @@
#endif
uint8_t kb_layout[KB_LAYERS][KB_ROWS][KB_COLUMNS] = {
uint8_t _kb_layout[KB_LAYERS][KB_ROWS][KB_COLUMNS] = {
{ // layer 0: default
// right hand
/* ---- 0 ---- ---- 1 ---- ---- 2 ---- ---- 3 ---- ---- 4 ---- ---- 5 ---- ---- 6 ---- */
@ -56,7 +58,7 @@ uint8_t kb_layout[KB_LAYERS][KB_ROWS][KB_COLUMNS] = {
}
};
kbfun_funptr_t kb_layout_press[KB_LAYERS][KB_ROWS][KB_COLUMNS] = {
kbfun_funptr_t _kb_layout_press[KB_LAYERS][KB_ROWS][KB_COLUMNS] = {
{ // layer 0: default
// right hand
/* ---- 0 ---- ---- 1 ---- ---- 2 ---- ---- 3 ---- ---- 4 ---- ---- 5 ---- ---- 6 ---- */
@ -79,7 +81,7 @@ kbfun_funptr_t kb_layout_press[KB_LAYERS][KB_ROWS][KB_COLUMNS] = {
}
};
kbfun_funptr_t kb_layout_release[KB_LAYERS][KB_ROWS][KB_COLUMNS] = {
kbfun_funptr_t _kb_layout_release[KB_LAYERS][KB_ROWS][KB_COLUMNS] = {
{ // layer 0: default
// right hand
/* ---- 0 ---- ---- 1 ---- ---- 2 ---- ---- 3 ---- ---- 4 ---- ---- 5 ---- ---- 6 ---- */

View File

@ -1,5 +1,7 @@
/* ----------------------------------------------------------------------------
* ergoDOX layout : QWERTY : exports
*
* Meant to be included (as the last header) from "../layout.h"
* ----------------------------------------------------------------------------
* Copyright (c) 2012 Ben Blazak <benblazak.dev@gmail.com>
* Released under The MIT License (MIT) (see "license.md")
@ -7,5 +9,10 @@
* ------------------------------------------------------------------------- */
#define KB_LAYERS 1 // must match what's defined in "layout*.c"
#define KB_LAYERS 1 // must match what's defined in the layout '.c' file
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];

View File

@ -50,12 +50,12 @@ int main(void) {
kb_update_matrix(*kb_is_pressed);
// call the appropriate function for each key, then send the report if
// necessary
// call the appropriate function for each key, then send the usb 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
// is assigned which function (per layer), and "lib/key-functions.c"
// for their definitions
for (uint8_t row=0; row<KB_ROWS; row++) {
for (uint8_t col=0; col<KB_COLUMNS; col++) {
bool is_pressed = (*kb_is_pressed)[row][col];
@ -63,18 +63,18 @@ int main(void) {
if (is_pressed != was_pressed) {
if (is_pressed) {
kbfun_funptr_t press_function =
kb_layout_press[current_layer][row][col];
kb_layout_press_get(current_layer, row, col);
if (press_function) {
(*press_function)(
&kb_layout[current_layer][row][col],
&kb_layout_get(current_layer, row, col),
&current_layer, &row, &col );
}
} else {
kbfun_funptr_t release_function =
kb_layout_release[current_layer][row][col];
kb_layout_release_get(current_layer, row, col);
if (release_function) {
(*release_function)(
&kb_layout[current_layer][row][col],
&kb_layout_get(current_layer, row, col),
&current_layer, &row, &col );
}
}

View File

@ -13,16 +13,20 @@
# -----------------------------------------------------------------------------
TARGET = firmware
FORMAT = ihex
BOARD = teensy-2-0 # see the libraries you're using for what's available
KEYBOARD = ergodox # see "src/keyboard" for what's available
LAYOUT = qwerty # see "src/keyboard/*/layout" for what's available
TARGET = firmware # the name we want for our program binary
FORMAT = ihex # the program binary's format
KEYBOARD = ergodox # keyboard model; see "src/keyboard" for what's available
LAYOUT = qwerty # keyboard layout; see "src/keyboard/*/layout" for what's
# available
MCU = atmega32u4 # processor type (for teensy 2.0); must match real life
BOARD = teensy-2-0 # see the libraries you're using for what's available
F_CPU = 16000000 # processor speed, in Hz
# firmware stuff
SRC = $(wildcard *.c)
# keyboard and layout stuff
# --- remove whitespace
# --- remove whitespace from vars
KEYBOARD := $(strip $(KEYBOARD))
LAYOUT := $(strip $(LAYOUT))
# --- include stuff
@ -41,9 +45,9 @@ SRC += $(wildcard lib/*/*/*.c)
OBJ = $(SRC:%.c=%.o)
CFLAGS = -mmcu=atmega32u4 # processor type (teensy 2.0); must match real
CFLAGS = -mmcu=$(MCU) # processor type (teensy 2.0); must match real
# life
CFLAGS += -DF_CPU=16000000 # processor frequency; must match initialization
CFLAGS += -DF_CPU=$(F_CPU) # processor frequency; must match initialization
# in source
CFLAGS += -I. # search for includes in the current directory
# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
@ -81,7 +85,7 @@ OBJCOPY = avr-objcopy
SIZE = avr-size
# remove extraneous whitespace
# remove whitespace from some of the variables
TARGET := $(strip $(TARGET))
FORMAT := $(strip $(FORMAT))