Skip to content

Commit

Permalink
Merge branch 'feature/benblazak#36-non-standard-shifted-keys' into neo2
Browse files Browse the repository at this point in the history
  • Loading branch information
tschulte committed Jun 26, 2014
2 parents 5aff6c4 + ed1e200 commit 2076d3e
Show file tree
Hide file tree
Showing 28 changed files with 1,677 additions and 351 deletions.
36 changes: 34 additions & 2 deletions firmware/keyboard.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* ----------------------------------------------------------------------------
* Copyright (c) 2012 Ben Blazak <[email protected]>
* Copyright (c) 2012, 2014 Ben Blazak <[email protected]>
* Released under The MIT License (see "doc/licenses/MIT.md")
* Project located at <https://github.com/benblazak/ergodox-firmware>
* ------------------------------------------------------------------------- */
Expand Down Expand Up @@ -50,13 +50,20 @@ void kb__led__all_set (float percent);
// -------
void kb__led__state__power_on (void);
void kb__led__state__ready (void);
void kb__led__delay__error (void);
void kb__led__delay__usb_init (void);

// layout
void kb__led__logical_on (char led);
void kb__led__logical_off (char led);
// -------
void kb__layout__exec_key (bool pressed, uint8_t row, uint8_t column);
void kb__layout__exec_key ( bool pressed,
uint8_t row,
uint8_t column );
void kb__layout__exec_key_layer ( bool pressed,
uint8_t layer,
uint8_t row,
uint8_t column );


// ----------------------------------------------------------------------------
Expand Down Expand Up @@ -217,6 +224,12 @@ void kb__layout__exec_key (bool pressed, uint8_t row, uint8_t column);
* keystrokes.
*/


// === kb__led__delay__error() ===
/** functions/kb__led__delay__error/description
* Signal a generic error
*/

// === kb__led__delay__usb_init() ===
/** functions/kb__led__delay__usb_init/description
* Delay for a total of ~1 second, to allow the host to load drivers and such.
Expand Down Expand Up @@ -273,3 +286,22 @@ void kb__layout__exec_key (bool pressed, uint8_t row, uint8_t column);
* etc. from `main()`.
*/

// === kb__layout__exec_key_layer ===
/** functions/kb__layout__exec_key_layer/description
* Perform the appropriate actions for a "press" or "release" of the key at the
* given position, on the given layer.
*
* Arguments:
* - `pressed`:
* - `true`: Indicates that the key to be "executed" has been pressed
* - `false`: Indicates that the key to be "executed" has been released
* - `layer`: The layer of the key to be "executed"
* - `row`: The row of the key to be "executed"
* - `column`: The column of the key to be "executed"
*
* Notes:
* - If the implementation does not support layers, the `layer` argument should
* be ignored, and this function will be equivalent to
* `kb__layout__exec_key()`.
*/

3 changes: 2 additions & 1 deletion firmware/keyboard/ergodox/controller.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ uint8_t kb__init(void) {
if (mcp23018__init()) // must be second
return 2;

eeprom_macro__init();
if (eeprom_macro__init())
return 3;

return 0; // success
}
Expand Down
8 changes: 4 additions & 4 deletions firmware/keyboard/ergodox/controller/mcp23018.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,6 @@
#error "Expecting different keyboard dimensions"
#endif

#if ( OPT__MCP23018__DRIVE_ROWS && OPT__MCP23018__DRIVE_COLUMNS ) \
|| !( OPT__MCP23018__DRIVE_ROWS || OPT__MCP23018__DRIVE_COLUMNS )
#error "MCP23018 pin drive direction incorrectly set"
#endif
/** macros/(group) pin drive direction/description
* Select which set of pins (rows or columns) will drive (alternate between
* hi-Z and drive low), and which will be inputs (hi-Z)
Expand All @@ -49,6 +45,10 @@
* - If the diode cathode is towards the circular solder pad, set
* `OPT__MCP23018__DRIVE_ROWS` to `1`
*/
#if ( OPT__MCP23018__DRIVE_ROWS && OPT__MCP23018__DRIVE_COLUMNS ) \
|| !( OPT__MCP23018__DRIVE_ROWS || OPT__MCP23018__DRIVE_COLUMNS )
#error "MCP23018 pin drive direction incorrectly set"
#endif

// ----------------------------------------------------------------------------

Expand Down
8 changes: 4 additions & 4 deletions firmware/keyboard/ergodox/controller/teensy-2-0.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,6 @@
#error "Expecting different keyboard dimensions"
#endif

#if ( OPT__TEENSY__DRIVE_ROWS && OPT__TEENSY__DRIVE_COLUMNS ) \
|| !( OPT__TEENSY__DRIVE_ROWS || OPT__TEENSY__DRIVE_COLUMNS )
#error "Teensy pin drive direction incorrectly set"
#endif
/** macros/(group) pin drive direction/description
* Select which set of pins (rows or columns) will drive (alternate between
* hi-Z and drive low), and which will be inputs (hi-Z)
Expand All @@ -54,6 +50,10 @@
* - If the diode cathode is towards the circular solder pad, set
* `OPT__TEENSY__DRIVE_ROWS` to `1`
*/
#if ( OPT__TEENSY__DRIVE_ROWS && OPT__TEENSY__DRIVE_COLUMNS ) \
|| !( OPT__TEENSY__DRIVE_ROWS || OPT__TEENSY__DRIVE_COLUMNS )
#error "Teensy pin drive direction incorrectly set"
#endif

// ----------------------------------------------------------------------------

Expand Down
1 change: 1 addition & 0 deletions firmware/keyboard/ergodox/layout/fragments/includes.part.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "../../../../../firmware/lib/timer.h"
#include "../../../../../firmware/lib/usb.h"
#include "../../../../../firmware/lib/usb/usage-page/keyboard.h"
#include "../../../../../firmware/lib/layout/eeprom-macro.h"
#include "../../../../../firmware/lib/layout/key-functions.h"
#include "../../../../../firmware/lib/layout/layer-stack.h"
#include "../../../../../firmware/keyboard.h"
Expand Down
117 changes: 81 additions & 36 deletions firmware/keyboard/ergodox/layout/fragments/matrix-control.part.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,59 +12,104 @@
*/


/** functions/kb__layout__exec_key/description
* Assumptions:
* - All arguments are valid.
*
* Implementation notes:
* - The default layer is layer 0.
* - This function is only responsible for layer resolution (which includes the
* handling of transparent keys). Everything else, it passes to
* `kb__layout__exec_key_layer()`.
*/
void kb__layout__exec_key(bool pressed, uint8_t row, uint8_t column) {

// if we press a key, we need to keep track of the layer it was pressed on,
// so we can release it on the same layer
// - if the release is transparent, search through the layer stack for a
// non-transparent release in the same position, as normal
// - to keep track of the layer a key was pressed on, so we can release on
// the same layer
static uint8_t pressed_layer[OPT__KB__ROWS][OPT__KB__COLUMNS];

void (*function)(void);
uint8_t layer;
void (*function)(void);

// - add 1 to the stack size because we spend the first iteration checking
// to see if we need to release on a previously stored layer
// - add 1 to the stack size in order to peek out of bounds on the last
// iteration (if we get that far), so that layer 0 is our default (see
// the documentation for ".../firmware/lib/layout/layer-stack.h")
for (uint8_t i=0; i < layer_stack__size()+1+1; i++) { // i = offset+1
if (i == 0)
if (!pressed)
layer = pressed_layer[row][column];
else
continue;
else
layer = layer_stack__peek(i-1);
// handle the case that a key is released, and the layer it was pressed on
// has a non-transparent release function in the given location

if (! pressed) {
layer = pressed_layer[row][column];
function = (void (*)(void))
pgm_read_word( &( layout[ layer ]
[ row ]
[ column ]
[ (pressed) ? 0 : 1 ] ) );

if (function == &KF(transp))
function = NULL;
pgm_read_word( &( layout[ layer ]
[ row ]
[ column ]
[ !pressed ] ) );

if (function) {
if (pressed)
pressed_layer[row][column] = layer;
if (function != &KF(transp)) {
kb__layout__exec_key_layer( pressed, layer, row, column );
return;
}
}

flags.tick_keypresses = (pressed) ? true : false; // set default
// otherwise, search through the layer stack for a layer with a
// non-transparent key-function in the given location

(*function)();
// - altogether, unless we find a non-transparent key-function earlier, we
// want to peek at offsets `0` through `layer_stack__size()`. this will
// cause us to peek out of bounds on the last iteration, so that layer 0
// will be the default (see the documentation for
// ".../lib/layout/layer-stack")
for (uint8_t i=0; i <= layer_stack__size(); i++) {
layer = layer_stack__peek(i);
function = (void (*)(void))
pgm_read_word( &( layout[ layer ]
[ row ]
[ column ]
[ !pressed ] ) );

// TODO: *always* tick keypresses
// TODO: instead of this, set a flag for the type of key pressed,
// and any functions that execute can check it, and conditionally
// reschedule themselves to run later, if they so desire
if (flags.tick_keypresses)
timer___tick_keypresses();
if (function != &KF(transp)) {
if (pressed)
pressed_layer[row][column] = layer;

kb__layout__exec_key_layer( pressed, layer, row, column );
return;
}
}

// if we get here, there was a transparent key in layer 0; do nothing
}

/** functions/kb__layout__exec_key_layer/description
* Assumptions:
* - All arguments are valid.
*
* TODO:
* - take care of the recording and such of macros :)
* - need to ignore layer-shift keys when recording
*/
void kb__layout__exec_key_layer( bool pressed,
uint8_t layer,
uint8_t row,
uint8_t column ) {

void (*function)(void) = (void (*)(void))
pgm_read_word( &( layout[ layer ]
[ row ]
[ column ]
[ !pressed ] ) );
if (! function) return;

// set default values
// - the key-function will not be able to see the values set previously
// - any function scheduled to run will be able to see the values set
// by the immediately preceding function; but that may change in the
// future, so it shouldn't be relied on. if functions need to
// communicate with each other, they should share a file-local or global
// variable.
flags[0].key_type.sticky = false;
flags[0].key_type.layer_shift = false;
flags[0].key_type.layer_lock = false;

(*function)();

if (pressed)
timer___tick_keypresses();
}

37 changes: 27 additions & 10 deletions firmware/keyboard/ergodox/layout/fragments/variables.part.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,34 @@ static layout_t layout PROGMEM;
/** variables/flags/description
* A collection of flags pertaining to the operation of `...exec_key()`
*
* Notes:
* - These should be set within key-functions, but only read inside
* `...exec_key()`. The ability to read them outside that function should
* not be counted on.
*
* Struct members:
* - `tick_keypresses`: A predicate indicating whether or not to "tick"
* keypresses on this run of the function (see the documentation in
* ".../firmware/lib/timer.h" for more precisely what this means)
* - This is useful for defining things like sticky keys, if, e.g., you
* want to make it so that you can press more than one and have none of
* them release until the press of the next normal key.
* - `key_type`: To indicate the type of key most recently pressed
* - More than one type flag may be set (e.g. a key may be both a
* layer-shift key and a sticky key).
* - `key_type.sticky`
* - `key_type.layer_shift`
* - `key_type.layer_lock`
*
* Terms:
* - A "sticky key" is one which, once pressed, remains pressed in software
* (whether or not the user holds it down) ... TODO
*
* TODO:
* - finish terms
* - change other code (in "./matrix-control.part.h") to actually use the fact
* that we have 2 of these now (so that there is an "old" version, and a
* version to update)
*/
static struct {
bool tick_keypresses : 1;
} flags = {
.tick_keypresses = true,
};
struct {
bool sticky : 1;
bool layer_shift : 1;
bool layer_lock : 1;
} key_type;
} flags[2];

2 changes: 1 addition & 1 deletion firmware/keyboard/ergodox/layout/qwerty--ben.c
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ shL2kcap, z, x, c, v, b, lpupo2l2,
transp, transp, transp,
// right hand ..... ......... ......... ......... ......... ......... .........
F12, F6, F7, F8, F9, F10, power,
lpo2l2, nop, undersc, lessThan, grtrThan, dollar, volumeU,
lpo2l2, caret, undersc, lessThan, grtrThan, dollar, volumeU,
bkslash, 1, parenL, parenR, equal, volumeD,
lpupo3l3, asterisk, 2, 3, 4, 5, mute,
transp, transp, transp, transp, transp,
Expand Down
3 changes: 0 additions & 3 deletions firmware/keyboard/ergodox/layout/test.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,6 @@
* A layout for testing newly build boards
*
* Implements the "layout" section of '.../firmware/keyboard.h'
*
* TODO:
* - update, if i change the semantics `kb__layout__exec_key()`
*/


Expand Down
Loading

0 comments on commit 2076d3e

Please sign in to comment.