From bdcd4484beff65bffa8f4fa1ca63c9da0c346e10 Mon Sep 17 00:00:00 2001 From: Ben Blazak Date: Sun, 3 Jun 2012 23:46:21 -0700 Subject: [PATCH 01/28] added a layout layer; layout's still kind of a mess... layout includes function keys, some symbols, and a few things from the default layer --- src/keyboard/ergodox/layout/qwerty.c | 129 +++++++++++++++++++++++++-- src/keyboard/ergodox/layout/qwerty.h | 2 +- src/lib/key-functions.c | 46 +++++----- src/lib/key-functions.h | 6 ++ 4 files changed, 152 insertions(+), 31 deletions(-) diff --git a/src/keyboard/ergodox/layout/qwerty.c b/src/keyboard/ergodox/layout/qwerty.c index 65ce0d4..51d04e1 100644 --- a/src/keyboard/ergodox/layout/qwerty.c +++ b/src/keyboard/ergodox/layout/qwerty.c @@ -19,13 +19,21 @@ #include "../layout.h" +// aliases +#define f_press &kbfun_press +#define f_relea &kbfun_release +#define f_l_inc &kbfun_layer_inc +#define f_l_dec &kbfun_layer_dec + + // error check: everything below assumes these dimensions -#if KB_LAYERS != 1 || KB_ROWS != 12 || KB_COLUMNS != 7 +#if KB_LAYERS != 2 || KB_ROWS != 12 || KB_COLUMNS != 7 #error "Expecting different keyboard dimensions" #endif uint8_t PROGMEM _kb_layout[KB_LAYERS][KB_ROWS][KB_COLUMNS] = { +// ---------------------------------------------------------------------------- LAYER( // layer 0: default // unused 0, @@ -33,7 +41,7 @@ uint8_t PROGMEM _kb_layout[KB_LAYERS][KB_ROWS][KB_COLUMNS] = { _grave, _1, _2, _3, _4, _5, _equal, _tab, _Q, _W, _E, _R, _T, _esc, _capsLock, _A, _S, _D, _F, _G, -_shiftL, _Z, _X, _C, _V, _B, _ctrlL, +_shiftL, _Z, _X, _C, _V, _B, 0/*inc*/, _guiL, _arrowL, _arrowU, _arrowD, _arrowR, _bs, _del, _ctrlL, @@ -42,20 +50,131 @@ _guiL, _arrowL, _arrowU, _arrowD, _arrowR, _backslash, _6, _7, _8, _9, _0, _dash, _bracketL, _Y, _U, _I, _O, _P, _bracketR, _H, _J, _K, _L, _semicolon, _quote, - _ctrlR, _N, _M, _comma, _period, _slash, _shiftR, + 0/*inc*/, _N, _M, _comma, _period, _slash, _shiftR, _arrowL, _arrowD, _arrowU, _arrowR, _guiR, _space, _ctrlR, _enter, +_altR, _pageU, _pageD ), +// ---------------------------------------------------------------------------- + LAYER( // layer 1: function and symbol keys +// unused +0, +// left hand +0, _F1, _F2, _F3, _F4, _F5, _F11, +0, _braceL_kp, _braceR_kp, _bracketL, _bracketR, 0, _esc, +0, _semicolon, _slash, _dash, 0, _colon_kp, +0, 0, 0, 0, 0, 0, 0/*dec*/, +0, _arrowL, _arrowU, _arrowD, _arrowR, + _bs, + _del, _ctrlL, + _end, _home, _altL, +// right hand + _F12, _F6, _F7, _F8, _F9, _F10, 0, + 0, 0, _dash, _lt_kp, _gt_kp, _currencyUnit, 0, + _backslash, 0, _parenL_kp, _parenR_kp, _equal, 0, + 0/*dec*/, _mul_kp, 0, 0, 0, 0, 0, + _arrowL, _arrowD, _arrowU, _arrowR, 0, + _space, +_ctrlR, _enter, _altR, _pageU, _pageD ) +// ---------------------------------------------------------------------------- }; kbfun_funptr_t PROGMEM _kb_layout_press[KB_LAYERS][KB_ROWS][KB_COLUMNS] = { - LAYER_SET_ALL(NULL, &kbfun_press) // layer 0: default +// ---------------------------------------------------------------------------- + LAYER( // layer 0: default +// unused +NULL, +// left hand +f_press,f_press,f_press,f_press,f_press,f_press,f_press, +f_press,f_press,f_press,f_press,f_press,f_press,f_press, +f_press,f_press,f_press,f_press,f_press,f_press, +f_press,f_press,f_press,f_press,f_press,f_press,f_l_inc, +f_press,f_press,f_press,f_press,f_press, + f_press, + f_press, f_press, + f_press,f_press,f_press, +// right hand + f_press,f_press,f_press,f_press,f_press,f_press,f_press, + f_press,f_press,f_press,f_press,f_press,f_press,f_press, + f_press,f_press,f_press,f_press,f_press,f_press, + f_l_inc,f_press,f_press,f_press,f_press,f_press,f_press, + f_press,f_press,f_press,f_press,f_press, + f_press, +f_press, f_press, +f_press,f_press,f_press ), +// ---------------------------------------------------------------------------- + LAYER( // layer 1: function and symbol keys +// unused +NULL, +// left hand +f_press,f_press,f_press,f_press,f_press,f_press,f_press, +f_press,f_press,f_press,f_press,f_press,f_press,f_press, +f_press,f_press,f_press,f_press,f_press,f_press, +f_press,f_press,f_press,f_press,f_press,f_press, NULL, +f_press,f_press,f_press,f_press,f_press, + f_press, + f_press, f_press, + f_press,f_press,f_press, +// right hand + f_press,f_press,f_press,f_press,f_press,f_press,f_press, + f_press,f_press,f_press,f_press,f_press,f_press,f_press, + f_press,f_press,f_press,f_press,f_press,f_press, + NULL,f_press,f_press,f_press,f_press,f_press,f_press, + f_press,f_press,f_press,f_press,f_press, + f_press, +f_press, f_press, +f_press,f_press,f_press ) +// ---------------------------------------------------------------------------- }; kbfun_funptr_t PROGMEM _kb_layout_release[KB_LAYERS][KB_ROWS][KB_COLUMNS] = { - LAYER_SET_ALL(NULL, &kbfun_release) // layer 0: default +// ---------------------------------------------------------------------------- + LAYER( // layer 0: default +// unused +NULL, +// left hand +f_relea,f_relea,f_relea,f_relea,f_relea,f_relea,f_relea, +f_relea,f_relea,f_relea,f_relea,f_relea,f_relea,f_relea, +f_relea,f_relea,f_relea,f_relea,f_relea,f_relea, +f_relea,f_relea,f_relea,f_relea,f_relea,f_relea, NULL, +f_relea,f_relea,f_relea,f_relea,f_relea, + f_relea, + f_relea, f_relea, + f_relea,f_relea,f_relea, +// right hand + f_relea,f_relea,f_relea,f_relea,f_relea,f_relea,f_relea, + f_relea,f_relea,f_relea,f_relea,f_relea,f_relea,f_relea, + f_relea,f_relea,f_relea,f_relea,f_relea,f_relea, + NULL,f_relea,f_relea,f_relea,f_relea,f_relea,f_relea, + f_relea,f_relea,f_relea,f_relea,f_relea, + f_relea, +f_relea, f_relea, +f_relea,f_relea,f_relea ), +// ---------------------------------------------------------------------------- + LAYER( // layer 1: function and symbol keys +// unused +NULL, +// left hand +f_relea,f_relea,f_relea,f_relea,f_relea,f_relea,f_relea, +f_relea,f_relea,f_relea,f_relea,f_relea,f_relea,f_relea, +f_relea,f_relea,f_relea,f_relea,f_relea,f_relea, +f_relea,f_relea,f_relea,f_relea,f_relea,f_relea,f_l_dec, +f_relea,f_relea,f_relea,f_relea,f_relea, + f_relea, + f_relea, f_relea, + f_relea,f_relea,f_relea, +// right hand + f_relea,f_relea,f_relea,f_relea,f_relea,f_relea,f_relea, + f_relea,f_relea,f_relea,f_relea,f_relea,f_relea,f_relea, + f_relea,f_relea,f_relea,f_relea,f_relea,f_relea, + f_l_dec,f_relea,f_relea,f_relea,f_relea,f_relea,f_relea, + f_relea,f_relea,f_relea,f_relea,f_relea, + f_relea, +f_relea, f_relea, +f_relea,f_relea,f_relea ) +// ---------------------------------------------------------------------------- }; diff --git a/src/keyboard/ergodox/layout/qwerty.h b/src/keyboard/ergodox/layout/qwerty.h index a94f2c5..097927a 100644 --- a/src/keyboard/ergodox/layout/qwerty.h +++ b/src/keyboard/ergodox/layout/qwerty.h @@ -13,7 +13,7 @@ #include "../led.h" - #define KB_LAYERS 1 // must match what's defined in "qwerty.c" + #define KB_LAYERS 2 // must match what's defined in "qwerty.c" #define kb_led_num_on() _led_1_on() #define kb_led_num_off() _led_1_off() diff --git a/src/lib/key-functions.c b/src/lib/key-functions.c index de037ef..38119d6 100644 --- a/src/lib/key-functions.c +++ b/src/lib/key-functions.c @@ -19,31 +19,6 @@ #include "key-functions.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 ) { @@ -116,3 +91,24 @@ void kbfun_release( } } +void kbfun_layer_inc( + uint8_t keycode, uint8_t * current_layer, + uint8_t * row, uint8_t * col ) { + + if (*current_layer < (KB_LAYERS-1)) + (*current_layer)++; + // else do nothing +} + +void kbfun_layer_dec( + uint8_t keycode, uint8_t * current_layer, + uint8_t * row, uint8_t * col ) { + + if (*current_layer > 0) + (*current_layer)--; + // else do nothing +} + + +// ---------------------------------------------------------------------------- + diff --git a/src/lib/key-functions.h b/src/lib/key-functions.h index 9437251..fa4a819 100644 --- a/src/lib/key-functions.h +++ b/src/lib/key-functions.h @@ -22,6 +22,12 @@ void kbfun_release( uint8_t keycode, uint8_t * current_layer, uint8_t * row, uint8_t * col ); + void kbfun_layer_inc( + uint8_t keycode, uint8_t * current_layer, + uint8_t * row, uint8_t * col ); + void kbfun_layer_dec( + uint8_t keycode, uint8_t * current_layer, + uint8_t * row, uint8_t * col ); #endif From f5bd07c45c7a6e918324932a2113287f1282d803 Mon Sep 17 00:00:00 2001 From: Ben Blazak Date: Mon, 4 Jun 2012 00:09:15 -0700 Subject: [PATCH 02/28] added convenience target 'dist-hex' to makefile --- src/makefile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/makefile b/src/makefile index f120b12..bea17a9 100644 --- a/src/makefile +++ b/src/makefile @@ -122,6 +122,10 @@ clean: @echo --- cleaning --- cd .. ; git clean -dX # remove ignored files and directories +# availability: linux +dist-hex: clean all + mv firmware.hex 'ergodox-firmware--$(shell git branch -l | grep '*' | cut -c 3-)--$(shell date +'%Y%m%d_%H%M%S').hex' + # ----------------------------------------------------------------------------- .SECONDARY: From ce13bf38933739b8b5c709ea555d7d91763cde34 Mon Sep 17 00:00:00 2001 From: Ben Blazak Date: Wed, 6 Jun 2012 12:26:36 -0700 Subject: [PATCH 03/28] created a contrib folder --- contrib/readme.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 contrib/readme.md diff --git a/contrib/readme.md b/contrib/readme.md new file mode 100644 index 0000000..ff0a5fb --- /dev/null +++ b/contrib/readme.md @@ -0,0 +1,2 @@ +This directory is for projects closely related to the firmware. + From 471a92834cdcbda957c11ddab1d6f1d6e8835dcd Mon Sep 17 00:00:00 2001 From: Ben Blazak Date: Sun, 10 Jun 2012 20:48:24 -0700 Subject: [PATCH 04/28] starting some changes on layer handling and key functions --- src/lib/key-functions.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/lib/key-functions.c b/src/lib/key-functions.c index 38119d6..9d55bd5 100644 --- a/src/lib/key-functions.c +++ b/src/lib/key-functions.c @@ -91,6 +91,13 @@ void kbfun_release( } } +// TODO: +// - allocate 10 layers, by default (overrideable in the map specific .h) +// - implement having different keys using different layers +// - implement two shifts => capslock +// - implement layer lock key combos (make a function to switch to a specific +// layer) + void kbfun_layer_inc( uint8_t keycode, uint8_t * current_layer, uint8_t * row, uint8_t * col ) { From 5569cecd2b86d58d30fcd849abd14ed744e0425c Mon Sep 17 00:00:00 2001 From: Ben Blazak Date: Sun, 10 Jun 2012 20:53:21 -0700 Subject: [PATCH 05/28] changed default number of layers to 10 --- src/keyboard/ergodox/layout.h | 8 +++++++- src/keyboard/ergodox/layout/qwerty.h | 2 -- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/keyboard/ergodox/layout.h b/src/keyboard/ergodox/layout.h index 7454dff..0cf5fee 100644 --- a/src/keyboard/ergodox/layout.h +++ b/src/keyboard/ergodox/layout.h @@ -20,7 +20,7 @@ // include the appropriate keyboard layout header // for: - // - number of layers + // - possible non-default number of layers // - possible non-default layout matrix definitions // - possible non-default layout 'get' and 'set' definitions #undef _str @@ -35,6 +35,12 @@ #undef _inc + // default number of layers + #ifndef KB_LAYERS + #define KB_LAYERS 10 + #endif + + // default layout 'get' macros and `extern` matrix declarations // // these are for when the matrices are stored solely in Flash. layouts diff --git a/src/keyboard/ergodox/layout/qwerty.h b/src/keyboard/ergodox/layout/qwerty.h index 097927a..950b5db 100644 --- a/src/keyboard/ergodox/layout/qwerty.h +++ b/src/keyboard/ergodox/layout/qwerty.h @@ -13,8 +13,6 @@ #include "../led.h" - #define KB_LAYERS 2 // must match what's defined in "qwerty.c" - #define kb_led_num_on() _led_1_on() #define kb_led_num_off() _led_1_off() #define kb_led_caps_on() _led_2_on() From 3322844ed08869a4d04e3b39b7453d59c20a56b0 Mon Sep 17 00:00:00 2001 From: Ben Blazak Date: Mon, 11 Jun 2012 03:27:34 -0700 Subject: [PATCH 06/28] bugfix (mostly): changed the way layers are handled before, if you pressed a key, then shifted layers, then released it, the first layer's press() would be called, and the 2nd layer's release() would be called, causing keys to stick, and probably other errors. now, the layer that the key was on when it was pressed is kept track of, and the proper release() is called. also, layers can be shifted per key now, instead of just for the whole board at once i also changed how keyboard-private includes are handled. "private" stuff is now in its own file, instead of being nested in an extra `#ifdef`. and i think that's it. i'm pretty tired right now, so there may be errors, but it seemed to work all right with cursory tests. --- src/keyboard/ergodox.c | 5 +- src/keyboard/ergodox.h | 1 - src/keyboard/ergodox/layout.h | 3 +- src/keyboard/ergodox/layout/qwerty.c | 68 ++++++------- src/keyboard/ergodox/matrix--private.h | 96 +++++++++++++++++++ src/keyboard/ergodox/matrix.c | 1 + src/keyboard/ergodox/matrix.h | 88 ----------------- .../{mcp23018.h => mcp23018--private.h} | 18 ++-- src/keyboard/ergodox/mcp23018.c | 3 +- src/keyboard/ergodox/teensy-2-0--private.h | 19 ++++ src/keyboard/ergodox/teensy-2-0.c | 2 +- src/keyboard/ergodox/teensy-2-0.h | 11 --- src/lib/key-functions.c | 57 +++++------ src/lib/key-functions.h | 48 +++++++--- src/main.c | 31 ++++-- 15 files changed, 237 insertions(+), 214 deletions(-) create mode 100644 src/keyboard/ergodox/matrix--private.h rename src/keyboard/ergodox/{mcp23018.h => mcp23018--private.h} (62%) create mode 100644 src/keyboard/ergodox/teensy-2-0--private.h diff --git a/src/keyboard/ergodox.c b/src/keyboard/ergodox.c index 12b5f32..a55bfb9 100644 --- a/src/keyboard/ergodox.c +++ b/src/keyboard/ergodox.c @@ -9,10 +9,9 @@ #include "lib/data-types.h" -#define KEYBOARD_INCLUDE_PRIVATE #include "ergodox/matrix.h" -#include "ergodox/mcp23018.h" -#include "ergodox/teensy-2-0.h" +#include "ergodox/mcp23018--private.h" +#include "ergodox/teensy-2-0--private.h" /* returns diff --git a/src/keyboard/ergodox.h b/src/keyboard/ergodox.h index 5174f31..00ba51e 100644 --- a/src/keyboard/ergodox.h +++ b/src/keyboard/ergodox.h @@ -16,7 +16,6 @@ #include "ergodox/layout.h" // number of layers, layout #include "ergodox/led.h" // logical led controls #include "ergodox/matrix.h" // kb dimensions, matrix status - #include "ergodox/mcp23018.h" // (nothing right now) #include "ergodox/teensy-2-0.h" // LED controls diff --git a/src/keyboard/ergodox/layout.h b/src/keyboard/ergodox/layout.h index 0cf5fee..e58eb51 100644 --- a/src/keyboard/ergodox/layout.h +++ b/src/keyboard/ergodox/layout.h @@ -15,8 +15,7 @@ #include "lib/data-types.h" #include "lib/key-functions.h" // for `kbfun_funptr_t` - #include "matrix.h" // for number of rows and columns, and layout - // to matrix macros + #include "matrix.h" // for number of rows and columns // include the appropriate keyboard layout header // for: diff --git a/src/keyboard/ergodox/layout/qwerty.c b/src/keyboard/ergodox/layout/qwerty.c index 51d04e1..ea8a8ac 100644 --- a/src/keyboard/ergodox/layout/qwerty.c +++ b/src/keyboard/ergodox/layout/qwerty.c @@ -14,8 +14,8 @@ #include "lib/usb/usage-page/keyboard--short-names.h" #include "lib/key-functions.h" -#define KEYBOARD_INCLUDE_PRIVATE #include "../matrix.h" +#include "../matrix--private.h" #include "../layout.h" @@ -26,12 +26,6 @@ #define f_l_dec &kbfun_layer_dec -// error check: everything below assumes these dimensions -#if KB_LAYERS != 2 || KB_ROWS != 12 || KB_COLUMNS != 7 - #error "Expecting different keyboard dimensions" -#endif - - uint8_t PROGMEM _kb_layout[KB_LAYERS][KB_ROWS][KB_COLUMNS] = { // ---------------------------------------------------------------------------- LAYER( // layer 0: default @@ -41,7 +35,7 @@ uint8_t PROGMEM _kb_layout[KB_LAYERS][KB_ROWS][KB_COLUMNS] = { _grave, _1, _2, _3, _4, _5, _equal, _tab, _Q, _W, _E, _R, _T, _esc, _capsLock, _A, _S, _D, _F, _G, -_shiftL, _Z, _X, _C, _V, _B, 0/*inc*/, +_shiftL, _Z, _X, _C, _V, _B, 0, _guiL, _arrowL, _arrowU, _arrowD, _arrowR, _bs, _del, _ctrlL, @@ -50,7 +44,7 @@ _guiL, _arrowL, _arrowU, _arrowD, _arrowR, _backslash, _6, _7, _8, _9, _0, _dash, _bracketL, _Y, _U, _I, _O, _P, _bracketR, _H, _J, _K, _L, _semicolon, _quote, - 0/*inc*/, _N, _M, _comma, _period, _slash, _shiftR, + 0, _N, _M, _comma, _period, _slash, _shiftR, _arrowL, _arrowD, _arrowU, _arrowR, _guiR, _space, _ctrlR, _enter, @@ -63,17 +57,17 @@ _altR, _pageU, _pageD ), 0, _F1, _F2, _F3, _F4, _F5, _F11, 0, _braceL_kp, _braceR_kp, _bracketL, _bracketR, 0, _esc, 0, _semicolon, _slash, _dash, 0, _colon_kp, -0, 0, 0, 0, 0, 0, 0/*dec*/, +0, 0, 0, 0, 0, 0, 0, 0, _arrowL, _arrowU, _arrowD, _arrowR, _bs, _del, _ctrlL, _end, _home, _altL, // right hand - _F12, _F6, _F7, _F8, _F9, _F10, 0, - 0, 0, _dash, _lt_kp, _gt_kp, _currencyUnit, 0, - _backslash, 0, _parenL_kp, _parenR_kp, _equal, 0, - 0/*dec*/, _mul_kp, 0, 0, 0, 0, 0, - _arrowL, _arrowD, _arrowU, _arrowR, 0, + _F12, _F6, _F7, _F8, _F9, _F10, 0, + 0, 0, _dash, _lt_kp, _gt_kp, _currencyUnit, 0, + _backslash, 0, _parenL_kp, _parenR_kp, _equal, 0, + 0, _mul_kp, 0, 0, 0, 0, 0, + _arrowL, _arrowD, _arrowU, _arrowR, 0, _space, _ctrlR, _enter, _altR, _pageU, _pageD ) @@ -139,28 +133,6 @@ NULL, f_relea,f_relea,f_relea,f_relea,f_relea,f_relea,f_relea, f_relea,f_relea,f_relea,f_relea,f_relea,f_relea,f_relea, f_relea,f_relea,f_relea,f_relea,f_relea,f_relea, -f_relea,f_relea,f_relea,f_relea,f_relea,f_relea, NULL, -f_relea,f_relea,f_relea,f_relea,f_relea, - f_relea, - f_relea, f_relea, - f_relea,f_relea,f_relea, -// right hand - f_relea,f_relea,f_relea,f_relea,f_relea,f_relea,f_relea, - f_relea,f_relea,f_relea,f_relea,f_relea,f_relea,f_relea, - f_relea,f_relea,f_relea,f_relea,f_relea,f_relea, - NULL,f_relea,f_relea,f_relea,f_relea,f_relea,f_relea, - f_relea,f_relea,f_relea,f_relea,f_relea, - f_relea, -f_relea, f_relea, -f_relea,f_relea,f_relea ), -// ---------------------------------------------------------------------------- - LAYER( // layer 1: function and symbol keys -// unused -NULL, -// left hand -f_relea,f_relea,f_relea,f_relea,f_relea,f_relea,f_relea, -f_relea,f_relea,f_relea,f_relea,f_relea,f_relea,f_relea, -f_relea,f_relea,f_relea,f_relea,f_relea,f_relea, f_relea,f_relea,f_relea,f_relea,f_relea,f_relea,f_l_dec, f_relea,f_relea,f_relea,f_relea,f_relea, f_relea, @@ -174,6 +146,28 @@ f_relea,f_relea,f_relea,f_relea,f_relea, f_relea,f_relea,f_relea,f_relea,f_relea, f_relea, f_relea, f_relea, +f_relea,f_relea,f_relea ), +// ---------------------------------------------------------------------------- + LAYER( // layer 1: function and symbol keys +// unused +NULL, +// left hand +f_relea,f_relea,f_relea,f_relea,f_relea,f_relea,f_relea, +f_relea,f_relea,f_relea,f_relea,f_relea,f_relea,f_relea, +f_relea,f_relea,f_relea,f_relea,f_relea,f_relea, +f_relea,f_relea,f_relea,f_relea,f_relea,f_relea, NULL, +f_relea,f_relea,f_relea,f_relea,f_relea, + f_relea, + f_relea, f_relea, + f_relea,f_relea,f_relea, +// right hand + f_relea,f_relea,f_relea,f_relea,f_relea,f_relea,f_relea, + f_relea,f_relea,f_relea,f_relea,f_relea,f_relea,f_relea, + f_relea,f_relea,f_relea,f_relea,f_relea,f_relea, + NULL,f_relea,f_relea,f_relea,f_relea,f_relea,f_relea, + f_relea,f_relea,f_relea,f_relea,f_relea, + f_relea, +f_relea, f_relea, f_relea,f_relea,f_relea ) // ---------------------------------------------------------------------------- }; diff --git a/src/keyboard/ergodox/matrix--private.h b/src/keyboard/ergodox/matrix--private.h new file mode 100644 index 0000000..3094eca --- /dev/null +++ b/src/keyboard/ergodox/matrix--private.h @@ -0,0 +1,96 @@ +/* ---------------------------------------------------------------------------- + * ergoDOX: keyboard matrix specific exports : private + * ---------------------------------------------------------------------------- + * Copyright (c) 2012 Ben Blazak + * Released under The MIT License (MIT) (see "license.md") + * Project located at + * ------------------------------------------------------------------------- */ + + +#ifndef MATRIX_h_PRIVATE + #define MATRIX_h_PRIVATE + + /* mapping from spatial position to matrix position + * - spatial position: where the key is spatially, relative to other + * keys both on the keyboard and in the layout + * - matrix position: the coordinate in the matrix to which a key is + * scanned by the update functions + * + * - location numbers are in the format `row##column`, where both 'row' + * and 'column' are single digit hex numbers corresponding to the + * matrix position (which also corresponds to the row and column pin + * labels used in the teensy and mcp23018 files) + * - coordinates not listed are unused + * + * --- other info ----------------------------------------------------- + * rows x columns = positions; assigned, unassigned + * per hand: 6 x 7 = 42; 38, 4 + * total: 12 x 7 = 84; 76, 8 + * + * left hand : cols 0..6, rows 6..B + * right hand : cols 0..6, rows 0..5 + * -------------------------------------------------------------------- + */ + #define LAYER( \ + /* for unused positions */ \ + na, \ + \ + /* left hand, spatial positions */ \ + kB6,kB5,kB4,kB3,kB2,kB1,kB0, \ + kA6,kA5,kA4,kA3,kA2,kA1,kA0, \ + k96,k95,k94,k93,k92,k91, \ + k86,k85,k84,k83,k82,k81,k80, \ + k76,k75,k74,k73,k72, \ + k64, \ + k63, k60, \ + k65,k62,k61, \ + \ + /* right hand, spatial positions */ \ + k50,k51,k52,k53,k54,k55,k56, \ + k40,k41,k42,k43,k44,k45,k46, \ + k31,k32,k33,k34,k35,k36, \ + k20,k21,k22,k23,k24,k25,k26, \ + k12,k13,k14,k15,k16, \ + k04, \ + k00, k03, \ + k01,k02,k05 ) \ + \ + /* matrix positions */ \ + { { k00,k01,k02,k03,k04,k05, na,}, \ + { na, na,k12,k13,k14,k15,k16,}, \ + { k20,k21,k22,k23,k24,k25,k26,}, \ + { na,k31,k32,k33,k34,k35,k36,}, \ + { k40,k41,k42,k43,k44,k45,k46,}, \ + { k50,k51,k52,k53,k54,k55,k56,}, \ + { k60,k61,k62,k63,k64,k65, na,}, \ + { na, na,k72,k73,k74,k75,k76,}, \ + { k80,k81,k82,k83,k84,k85,k86,}, \ + { na,k91,k92,k93,k94,k95,k96,}, \ + { kA0,kA1,kA2,kA3,kA4,kA5,kA6,}, \ + { kB0,kB1,kB2,kB3,kB4,kB5,kB6 } } + + + #define LAYER_SET_ALL(na, kxx) \ + LAYER( \ + na, \ + \ + kxx,kxx,kxx,kxx,kxx,kxx,kxx, \ + kxx,kxx,kxx,kxx,kxx,kxx,kxx, \ + kxx,kxx,kxx,kxx,kxx,kxx, \ + kxx,kxx,kxx,kxx,kxx,kxx,kxx, \ + kxx,kxx,kxx,kxx,kxx, \ + kxx, \ + kxx, kxx, \ + kxx,kxx,kxx, \ + \ + kxx,kxx,kxx,kxx,kxx,kxx,kxx, \ + kxx,kxx,kxx,kxx,kxx,kxx,kxx, \ + kxx,kxx,kxx,kxx,kxx,kxx, \ + kxx,kxx,kxx,kxx,kxx,kxx,kxx, \ + kxx,kxx,kxx,kxx,kxx, \ + kxx, \ + kxx, kxx, \ + kxx,kxx,kxx ) + +#endif + diff --git a/src/keyboard/ergodox/matrix.c b/src/keyboard/ergodox/matrix.c index 3a1f9e7..d5e6b93 100644 --- a/src/keyboard/ergodox/matrix.c +++ b/src/keyboard/ergodox/matrix.c @@ -10,6 +10,7 @@ #include "lib/data-types.h" #include "matrix.h" +#include "matrix--private.h" static bool _kb_is_pressed[KB_ROWS][KB_COLUMNS]; diff --git a/src/keyboard/ergodox/matrix.h b/src/keyboard/ergodox/matrix.h index ce499b5..600f311 100644 --- a/src/keyboard/ergodox/matrix.h +++ b/src/keyboard/ergodox/matrix.h @@ -18,93 +18,5 @@ extern bool (*kb_is_pressed)[KB_ROWS][KB_COLUMNS]; extern bool (*kb_was_pressed)[KB_ROWS][KB_COLUMNS]; - - #ifdef KEYBOARD_INCLUDE_PRIVATE - - /* mapping from spatial position to matrix position - * - spatial position: where the key is spatially, relative to - * other keys both on the keyboard and in the layout - * - matrix position: the coordinate in the matrix to which - * a key is scanned by the update functions - * - * - location numbers are in the format `row##column`, where - * both 'row' and 'column' are single digit hex numbers - * corresponding to the matrix position (which also - * corresponds to the row and column pin labels used in the - * teensy and mcp23018 files) - * - coordinates not listed are unused - * - * --- other info --------------------------------------------- - * rows x columns = positions; assigned, unassigned - * per hand: 6 x 7 = 42; 38, 4 - * total: 12 x 7 = 84; 76, 8 - * - * left hand : cols 0..6, rows 6..B - * right hand : cols 0..6, rows 0..5 - * ------------------------------------------------------------ - */ - #define LAYER( \ - /* for unused positions */ \ - na, \ - \ - /* left hand, spatial positions */ \ - kB6,kB5,kB4,kB3,kB2,kB1,kB0, \ - kA6,kA5,kA4,kA3,kA2,kA1,kA0, \ - k96,k95,k94,k93,k92,k91, \ - k86,k85,k84,k83,k82,k81,k80, \ - k76,k75,k74,k73,k72, \ - k64, \ - k63, k60, \ - k65,k62,k61, \ - \ - /* right hand, spatial positions */ \ - k50,k51,k52,k53,k54,k55,k56, \ - k40,k41,k42,k43,k44,k45,k46, \ - k31,k32,k33,k34,k35,k36, \ - k20,k21,k22,k23,k24,k25,k26, \ - k12,k13,k14,k15,k16, \ - k04, \ - k00, k03, \ - k01,k02,k05 ) \ - \ - /* matrix positions */ \ - { { k00,k01,k02,k03,k04,k05, na,}, \ - { na, na,k12,k13,k14,k15,k16,}, \ - { k20,k21,k22,k23,k24,k25,k26,}, \ - { na,k31,k32,k33,k34,k35,k36,}, \ - { k40,k41,k42,k43,k44,k45,k46,}, \ - { k50,k51,k52,k53,k54,k55,k56,}, \ - { k60,k61,k62,k63,k64,k65, na,}, \ - { na, na,k72,k73,k74,k75,k76,}, \ - { k80,k81,k82,k83,k84,k85,k86,}, \ - { na,k91,k92,k93,k94,k95,k96,}, \ - { kA0,kA1,kA2,kA3,kA4,kA5,kA6,}, \ - { kB0,kB1,kB2,kB3,kB4,kB5,kB6 } } - - - #define LAYER_SET_ALL(na, kxx) \ - LAYER( \ - na, \ - \ - kxx,kxx,kxx,kxx,kxx,kxx,kxx, \ - kxx,kxx,kxx,kxx,kxx,kxx,kxx, \ - kxx,kxx,kxx,kxx,kxx,kxx, \ - kxx,kxx,kxx,kxx,kxx,kxx,kxx, \ - kxx,kxx,kxx,kxx,kxx, \ - kxx, \ - kxx, kxx, \ - kxx,kxx,kxx, \ - \ - kxx,kxx,kxx,kxx,kxx,kxx,kxx, \ - kxx,kxx,kxx,kxx,kxx,kxx,kxx, \ - kxx,kxx,kxx,kxx,kxx,kxx, \ - kxx,kxx,kxx,kxx,kxx,kxx,kxx, \ - kxx,kxx,kxx,kxx,kxx, \ - kxx, \ - kxx, kxx, \ - kxx,kxx,kxx ) - - #endif - #endif diff --git a/src/keyboard/ergodox/mcp23018.h b/src/keyboard/ergodox/mcp23018--private.h similarity index 62% rename from src/keyboard/ergodox/mcp23018.h rename to src/keyboard/ergodox/mcp23018--private.h index ef29523..a48b9b4 100644 --- a/src/keyboard/ergodox/mcp23018.h +++ b/src/keyboard/ergodox/mcp23018--private.h @@ -1,5 +1,5 @@ /* ---------------------------------------------------------------------------- - * ergoDOX controller: MCP23018 specific exports + * ergoDOX controller: MCP23018 specific exports : private * ---------------------------------------------------------------------------- * Copyright (c) 2012 Ben Blazak * Released under The MIT License (MIT) (see "license.md") @@ -7,20 +7,16 @@ * ------------------------------------------------------------------------- */ -#ifndef MCP23018_h - #define MCP23018_h +#ifndef MCP23018_h_PRIVATE + #define MCP23018_h_PRIVATE #include "lib/data-types.h" + #include "matrix.h" - #ifdef KEYBOARD_INCLUDE_PRIVATE + #define MCP23018_TWI_ADDRESS 0b0100000 - #define MCP23018_TWI_ADDRESS 0b0100000 - - uint8_t mcp23018_init(void); - uint8_t mcp23018_update_matrix( - bool matrix[KB_ROWS][KB_COLUMNS] ); - - #endif + uint8_t mcp23018_init(void); + uint8_t mcp23018_update_matrix( bool matrix[KB_ROWS][KB_COLUMNS] ); #endif diff --git a/src/keyboard/ergodox/mcp23018.c b/src/keyboard/ergodox/mcp23018.c index ca960a1..793d332 100644 --- a/src/keyboard/ergodox/mcp23018.c +++ b/src/keyboard/ergodox/mcp23018.c @@ -11,9 +11,8 @@ #include "lib/data-types.h" #include "lib/twi.h" // `TWI_FREQ` defined in "teensy-2-0.c" -#define KEYBOARD_INCLUDE_PRIVATE #include "matrix.h" -#include "mcp23018.h" +#include "mcp23018--private.h" // register addresses (see "mcp23018.md") diff --git a/src/keyboard/ergodox/teensy-2-0--private.h b/src/keyboard/ergodox/teensy-2-0--private.h new file mode 100644 index 0000000..231e608 --- /dev/null +++ b/src/keyboard/ergodox/teensy-2-0--private.h @@ -0,0 +1,19 @@ +/* ---------------------------------------------------------------------------- + * ergoDOX controller: Teensy 2.0 specific exports : private + * ---------------------------------------------------------------------------- + * Copyright (c) 2012 Ben Blazak + * Released under The MIT License (MIT) (see "license.md") + * Project located at + * ------------------------------------------------------------------------- */ + + +#ifndef TEENSY_2_0_h_PRIVATE + #define TEENSY_2_0_h_PRIVATE + + #include "matrix.h" + + uint8_t teensy_init(void); + uint8_t teensy_update_matrix( bool matrix[KB_ROWS][KB_COLUMNS] ); + +#endif + diff --git a/src/keyboard/ergodox/teensy-2-0.c b/src/keyboard/ergodox/teensy-2-0.c index f09d033..74b68cf 100644 --- a/src/keyboard/ergodox/teensy-2-0.c +++ b/src/keyboard/ergodox/teensy-2-0.c @@ -13,9 +13,9 @@ #define TWI_FREQ 400000 #include "lib/twi.h" -#define KEYBOARD_INCLUDE_PRIVATE #include "matrix.h" #include "teensy-2-0.h" +#include "teensy-2-0--private.h" // processor frequency (from ) diff --git a/src/keyboard/ergodox/teensy-2-0.h b/src/keyboard/ergodox/teensy-2-0.h index 048072d..c43714f 100644 --- a/src/keyboard/ergodox/teensy-2-0.h +++ b/src/keyboard/ergodox/teensy-2-0.h @@ -13,8 +13,6 @@ #include // for the register macros #include "lib/data-types.h" - #include "matrix.h" - // LED control #define _led_1_on() (DDRB |= (1<<6)) @@ -53,14 +51,5 @@ _led_3_set_percent(n); \ } while(0) - - #ifdef KEYBOARD_INCLUDE_PRIVATE - - uint8_t teensy_init(void); - uint8_t teensy_update_matrix( - bool matrix[KB_ROWS][KB_COLUMNS] ); - - #endif - #endif diff --git a/src/lib/key-functions.c b/src/lib/key-functions.c index 9d55bd5..53c6011 100644 --- a/src/lib/key-functions.c +++ b/src/lib/key-functions.c @@ -19,16 +19,13 @@ #include "key-functions.h" -void kbfun_press( - uint8_t keycode, uint8_t * current_layer, - uint8_t * row, uint8_t * col ) { - +void kbfun_press( KBFUN_FUNCTION_ARGS ) { // no-op - if (keycode == 0) + if (keycode_ == 0) return; // modifier keys - switch (keycode) { + switch (keycode_) { case KEY_LeftControl: keyboard_modifier_keys |= (1<<0); return; case KEY_LeftShift: keyboard_modifier_keys |= (1<<1); @@ -50,21 +47,18 @@ void kbfun_press( // all others for (uint8_t i=0; i<6; i++) if (keyboard_keys[i] == 0) { - keyboard_keys[i] = keycode; - break; + keyboard_keys[i] = keycode_; + return; } } -void kbfun_release( - uint8_t keycode, uint8_t * current_layer, - uint8_t * row, uint8_t * col ) { - +void kbfun_release( KBFUN_FUNCTION_ARGS ) { // no-op - if (keycode == 0) + if (keycode_ == 0) return; // modifier keys - switch (keycode) { + switch (keycode_) { case KEY_LeftControl: keyboard_modifier_keys &= ~(1<<0); return; case KEY_LeftShift: keyboard_modifier_keys &= ~(1<<1); @@ -85,37 +79,30 @@ void kbfun_release( // all others for (uint8_t i=0; i<6; i++) - if (keyboard_keys[i] == keycode) { + if (keyboard_keys[i] == keycode_) { keyboard_keys[i] = 0; - break; + return; } } // TODO: -// - allocate 10 layers, by default (overrideable in the map specific .h) -// - implement having different keys using different layers // - implement two shifts => capslock // - implement layer lock key combos (make a function to switch to a specific // layer) -void kbfun_layer_inc( - uint8_t keycode, uint8_t * current_layer, - uint8_t * row, uint8_t * col ) { - - if (*current_layer < (KB_LAYERS-1)) - (*current_layer)++; - // else do nothing +void kbfun_layer_inc( KBFUN_FUNCTION_ARGS ) { + for (uint8_t row=0; row 0) - (*current_layer)--; - // else do nothing +void kbfun_layer_dec( KBFUN_FUNCTION_ARGS ) { + for (uint8_t row=0; row 0) + ((*current_layers_)[row][col])--; + // else do nothing } - -// ---------------------------------------------------------------------------- - diff --git a/src/lib/key-functions.h b/src/lib/key-functions.h index fa4a819..b709474 100644 --- a/src/lib/key-functions.h +++ b/src/lib/key-functions.h @@ -12,22 +12,40 @@ #include "lib/data-types.h" - typedef void (*kbfun_funptr_t)( - uint8_t, uint8_t *, - uint8_t *, uint8_t * ); + // -------------------------------------------------------------------- + // include the appropriate 'matrix.h' + // ------- + // we're not simply including 'keyboard.h' here because this header is + // meant to be included by 'keyboard/layout/*.c', which is indirectly + // included by 'keyboard.h'; and that would lead to a circular include, + // which gcc might (depending on the order of include statements it + // encounters) deal with by processing this file before 'matrix.h', + // which would give us undefined macros here + #undef _str + #undef _expstr + #undef _inc + #define _str(s) #s // stringify + #define _expstr(s) _str(s) // expand -> stringify + #define _inc _expstr(keyboard/MAKEFILE_KEYBOARD/matrix.h) // inc(lude) + #include _inc + #undef _str + #undef _expstr + #undef _inc + // -------------------------------------------------------------------- - 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_layer_inc( - uint8_t keycode, uint8_t * current_layer, - uint8_t * row, uint8_t * col ); - void kbfun_layer_dec( - uint8_t keycode, uint8_t * current_layer, - uint8_t * row, uint8_t * col ); + + #define KBFUN_FUNCTION_ARGS \ + uint8_t keycode_, \ + uint8_t (*current_layers_)[KB_ROWS][KB_COLUMNS], \ + uint8_t (*pressed_layers_)[KB_ROWS][KB_COLUMNS], \ + uint8_t * row_, uint8_t * col_ + + typedef void (*kbfun_funptr_t)( KBFUN_FUNCTION_ARGS ); + + void kbfun_press ( KBFUN_FUNCTION_ARGS ); + void kbfun_release ( KBFUN_FUNCTION_ARGS ); + void kbfun_layer_inc ( KBFUN_FUNCTION_ARGS ); + void kbfun_layer_dec ( KBFUN_FUNCTION_ARGS ); #endif diff --git a/src/main.c b/src/main.c index eaa76d4..340873a 100644 --- a/src/main.c +++ b/src/main.c @@ -27,7 +27,10 @@ int main(void) { kb_led_state_ready(); for (;;) { - static uint8_t current_layer = 0; + // the current layer for each key + static uint8_t current_layers[KB_ROWS][KB_COLUMNS]; + // the layer each key was on when it was last pressed + static uint8_t pressed_layers[KB_ROWS][KB_COLUMNS]; // swap `kb_is_pressed` and `kb_was_pressed`, then update bool (*temp)[KB_ROWS][KB_COLUMNS] = kb_was_pressed; @@ -36,32 +39,44 @@ int main(void) { kb_update_matrix(*kb_is_pressed); - // call the appropriate function for each key, then send the usb report - // if necessary + // call the appropriate function for each key(press|release), 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 "lib/key-functions.c" // for their definitions + // - anything passed to the key function by reference may be changed + // after the call for (uint8_t row=0; row Date: Mon, 11 Jun 2012 16:11:56 -0700 Subject: [PATCH 07/28] makefile now generates a .map --- .gitignore | 3 ++- src/makefile | 14 +++++++++++--- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index b7bdca1..5f82de9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,10 @@ *~ *.swp -*.hex *.eep *.elf +*.hex +*.map *.o *.o.dep diff --git a/src/makefile b/src/makefile index bea17a9..367fa3e 100644 --- a/src/makefile +++ b/src/makefile @@ -76,7 +76,9 @@ CFLAGS += -fdata-sections # / section in the output file if the # unused code. # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -LDFLAGS = -Wl,--relax # for some linker optimizations +LDFLAGS = -Wl,-Map=$(strip $(TARGET)).map,--cref # generate a link map, with + # a cross reference table +LDFLAGS += -Wl,--relax # for some linker optimizations LDFLAGS += -Wl,--gc-sections # discard unused functions and data # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @@ -123,8 +125,14 @@ clean: cd .. ; git clean -dX # remove ignored files and directories # availability: linux -dist-hex: clean all - mv firmware.hex 'ergodox-firmware--$(shell git branch -l | grep '*' | cut -c 3-)--$(shell date +'%Y%m%d_%H%M%S').hex' +dist: clean all + name='ergodox-firmware'; \ + branch='$(shell git branch -l | grep '*' | cut -c 3-)'; \ + date='$(shell date +'%Y%m%d_%H%M%S')'; \ + \ + zip "$$name--$$branch--$$date.zip" "$(TARGET).hex" "$(TARGET).map"; \ + \ + make clean # ----------------------------------------------------------------------------- From 5260e7104da1e48838a899a30b3057bca4b11532 Mon Sep 17 00:00:00 2001 From: Ben Blazak Date: Tue, 12 Jun 2012 14:12:50 -0700 Subject: [PATCH 08/28] modified how dist is build; changed .gitignore hierarchy there is now a toplevel makefile for making dist, so that we can keep the project build systems separate (in src and contrib/UI*), and then build dist from the root dir --- .gitignore | 10 +--------- makefile | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/.gitignore | 7 +++++++ src/makefile | 14 ++----------- 4 files changed, 63 insertions(+), 21 deletions(-) create mode 100644 makefile create mode 100644 src/.gitignore diff --git a/.gitignore b/.gitignore index 5f82de9..d77864a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,10 +1,2 @@ -*~ -*.swp - -*.eep -*.elf -*.hex -*.map -*.o -*.o.dep +*.zip diff --git a/makefile b/makefile new file mode 100644 index 0000000..4372346 --- /dev/null +++ b/makefile @@ -0,0 +1,53 @@ +# ----------------------------------------------------------------------------- +# makefile for the ergoDOX project +# +# This should produce a single file (probably in an archive format) for +# distribution, containing everything people will need to use the software. +# +# AVAILABILITY: This is unabashedly dependant on various Unix commands, and +# therefore probably won't work in a Windows environment. I'm sorry. I don't +# know a good portable way to write it. +# +# TODO: +# - include doc files (and maybe render them in html) +# - include the UI stuff (once it's done) +# ----------------------------------------------------------------------------- +# Copyright (c) 2012 Ben Blazak +# Released under The MIT License (MIT) (see "license.md") +# Project located at +# ----------------------------------------------------------------------------- + + +# the base name of the file or package to distribute +NAME := ergodox-firmware +# the branch of the git repo we're currently on +BRANCH := $(shell git branch -l | grep '*' | cut -c 3-) +# a version identifier +VERSION := $(shell date +'%Y%m%d_%H%M%S') + +# name to use for the final distribution file or package +TARGET = $(NAME)--$(BRANCH)--$(VERSION) + +# ----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- + +.PHONY: all clean dist + +all: dist + +clean: + git clean -dX # remove ignored files and directories + +dist: src contrib/UI + +# ----------------------------------------------------------------------------- + +.PHONY: src contrib/UI + +src: + cd src; $(MAKE) all + zip '$(TARGET)' src/*.hex src/*.elf src/*.map + +contrib/UI: + # nothing yet + diff --git a/src/.gitignore b/src/.gitignore new file mode 100644 index 0000000..ec1ee50 --- /dev/null +++ b/src/.gitignore @@ -0,0 +1,7 @@ +*.eep +*.elf +*.hex +*.map +*.o +*.o.dep + diff --git a/src/makefile b/src/makefile index 367fa3e..07e03ee 100644 --- a/src/makefile +++ b/src/makefile @@ -1,5 +1,5 @@ # ----------------------------------------------------------------------------- -# makefile for the ergoDOX project +# makefile for the ergoDOX firmware # # - .h file dependencies are automatically generated # @@ -122,17 +122,7 @@ all: $(TARGET).hex $(TARGET).eep clean: @echo @echo --- cleaning --- - cd .. ; git clean -dX # remove ignored files and directories - -# availability: linux -dist: clean all - name='ergodox-firmware'; \ - branch='$(shell git branch -l | grep '*' | cut -c 3-)'; \ - date='$(shell date +'%Y%m%d_%H%M%S')'; \ - \ - zip "$$name--$$branch--$$date.zip" "$(TARGET).hex" "$(TARGET).map"; \ - \ - make clean + git clean -dX # remove ignored files and directories # ----------------------------------------------------------------------------- From 973cac3240865aa0585fcd03a5aed8f2d8d296f0 Mon Sep 17 00:00:00 2001 From: Ben Blazak Date: Tue, 12 Jun 2012 16:11:18 -0700 Subject: [PATCH 09/28] (more makefile modifications) --- .gitignore | 2 -- makefile | 40 ++++++++++++++++++++++++---------------- src/makefile | 32 ++++++++++++++++---------------- 3 files changed, 40 insertions(+), 34 deletions(-) delete mode 100644 .gitignore diff --git a/.gitignore b/.gitignore deleted file mode 100644 index d77864a..0000000 --- a/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -*.zip - diff --git a/makefile b/makefile index 4372346..2d03791 100644 --- a/makefile +++ b/makefile @@ -4,9 +4,9 @@ # This should produce a single file (probably in an archive format) for # distribution, containing everything people will need to use the software. # -# AVAILABILITY: This is unabashedly dependant on various Unix commands, and -# therefore probably won't work in a Windows environment. I'm sorry. I don't -# know a good portable way to write it. +# DEPENDENCIES: This is unabashedly dependant on various Unix commands, and +# therefore probably won't work in a Windows environment. I'm sorry... I +# don't know a good portable way to write it. # # TODO: # - include doc files (and maybe render them in html) @@ -23,10 +23,13 @@ NAME := ergodox-firmware # the branch of the git repo we're currently on BRANCH := $(shell git branch -l | grep '*' | cut -c 3-) # a version identifier -VERSION := $(shell date +'%Y%m%d_%H%M%S') +VERSION := $(shell git log -n 1 | grep 'commit' | cut -c 8-14)--$(shell date +'%Y%m%dT%H%M%S') # name to use for the final distribution file or package -TARGET = $(NAME)--$(BRANCH)--$(VERSION) +TARGET := $(NAME)--$(BRANCH)--$(VERSION) + +# the build dir +BUILD := build # ----------------------------------------------------------------------------- # ----------------------------------------------------------------------------- @@ -37,17 +40,22 @@ all: dist clean: git clean -dX # remove ignored files and directories + -rm -r '$(BUILD)' -dist: src contrib/UI - -# ----------------------------------------------------------------------------- - -.PHONY: src contrib/UI - -src: +dist: + # set up the build dir + -rm -r '$(BUILD)/$(TARGET)'* + -mkdir -p '$(BUILD)/$(TARGET)' + # make all subprojects cd src; $(MAKE) all - zip '$(TARGET)' src/*.hex src/*.elf src/*.map - -contrib/UI: - # nothing yet + # copy stuff to build dir + # --- from src + ( cd src; \ + cp firmware.hex firmware.eep firmware.map \ + '../$(BUILD)/$(TARGET)' ) + # make into a zip archive + ( cd '$(BUILD)/$(TARGET)'; \ + zip '../$(TARGET).zip' \ + -r * .* \ + -x '..*' ) diff --git a/src/makefile b/src/makefile index 07e03ee..ccdc7ec 100644 --- a/src/makefile +++ b/src/makefile @@ -13,18 +13,18 @@ # ----------------------------------------------------------------------------- -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 +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 +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) +SRC := $(wildcard *.c) # keyboard and layout stuff # --- remove whitespace from vars KEYBOARD := $(strip $(KEYBOARD)) @@ -48,7 +48,7 @@ SRC += $(wildcard lib-other/*/*/*.c) OBJ = $(SRC:%.c=%.o) -CFLAGS = -mmcu=$(MCU) # processor type (teensy 2.0); must match real +CFLAGS := -mmcu=$(MCU) # processor type (teensy 2.0); must match real # life CFLAGS += -DF_CPU=$(F_CPU) # processor frequency; must match initialization # in source @@ -76,7 +76,7 @@ CFLAGS += -fdata-sections # / section in the output file if the # unused code. # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -LDFLAGS = -Wl,-Map=$(strip $(TARGET)).map,--cref # generate a link map, with +LDFLAGS := -Wl,-Map=$(strip $(TARGET)).map,--cref # generate a link map, with # a cross reference table LDFLAGS += -Wl,--relax # for some linker optimizations LDFLAGS += -Wl,--gc-sections # discard unused functions and data @@ -85,14 +85,14 @@ LDFLAGS += -Wl,--gc-sections # discard unused functions and data GENDEPFLAGS += -MMD -MP -MF $@.dep # generate dependency files -CC = avr-gcc -OBJCOPY = avr-objcopy -SIZE = avr-size +CC := avr-gcc +OBJCOPY := avr-objcopy +SIZE := avr-size # remove whitespace from some of the variables -TARGET := $(strip $(TARGET)) -FORMAT := $(strip $(FORMAT)) +TARGET := $(strip $(TARGET)) +FORMAT := $(strip $(FORMAT)) # ----------------------------------------------------------------------------- # ----------------------------------------------------------------------------- From 7404ca3c02c5fa31dfe9746b685ed19bcfb5f276 Mon Sep 17 00:00:00 2001 From: Ben Blazak Date: Thu, 14 Jun 2012 11:38:49 -0700 Subject: [PATCH 10/28] (changed low level led macro names) --- src/keyboard/ergodox/layout/qwerty.h | 12 +++--- src/keyboard/ergodox/led.h | 19 +++++----- src/keyboard/ergodox/teensy-2-0.c | 2 +- src/keyboard/ergodox/teensy-2-0.h | 56 ++++++++++++++-------------- 4 files changed, 45 insertions(+), 44 deletions(-) diff --git a/src/keyboard/ergodox/layout/qwerty.h b/src/keyboard/ergodox/layout/qwerty.h index 950b5db..a424938 100644 --- a/src/keyboard/ergodox/layout/qwerty.h +++ b/src/keyboard/ergodox/layout/qwerty.h @@ -13,12 +13,12 @@ #include "../led.h" - #define kb_led_num_on() _led_1_on() - #define kb_led_num_off() _led_1_off() - #define kb_led_caps_on() _led_2_on() - #define kb_led_caps_off() _led_2_off() - #define kb_led_scroll_on() _led_3_on() - #define kb_led_scroll_off() _led_3_off() + #define kb_led_num_on() _kb_led_1_on() + #define kb_led_num_off() _kb_led_1_off() + #define kb_led_caps_on() _kb_led_2_on() + #define kb_led_caps_off() _kb_led_2_off() + #define kb_led_scroll_on() _kb_led_3_on() + #define kb_led_scroll_off() _kb_led_3_off() #endif diff --git a/src/keyboard/ergodox/led.h b/src/keyboard/ergodox/led.h index 78ddf00..1a5ff89 100644 --- a/src/keyboard/ergodox/led.h +++ b/src/keyboard/ergodox/led.h @@ -4,8 +4,9 @@ * you should also include this file for low-level led macros, as it will * always include the file(s) containing those * - * - low level led macros should all start with '_led_' - * - public led macros should start with 'kb_led_' + * - low level LED macros (that have to be shared, but aren't really public) + * should all start with '_kb_led_' + * - public LED macros should start with 'kb_led_' * ---------------------------------------------------------------------------- * Copyright (c) 2012 Ben Blazak * Released under The MIT License (MIT) (see "license.md") @@ -22,23 +23,23 @@ #define kb_led_state_power_on() do { \ - _led_all_set_percent(0.05); \ - _led_all_on(); \ + _kb_led_all_set_percent(0.05); \ + _kb_led_all_on(); \ } while(0) // note: need to delay for a total of ~1 second #define kb_led_delay_usb_init() do { \ - _led_1_set_percent(0.5); \ + _kb_led_1_set_percent(0.5); \ _delay_ms(333); \ - _led_2_set_percent(0.5); \ + _kb_led_2_set_percent(0.5); \ _delay_ms(333); \ - _led_3_set_percent(0.5); \ + _kb_led_3_set_percent(0.5); \ _delay_ms(333); \ } while(0) #define kb_led_state_ready() do { \ - _led_all_off(); \ - _led_all_set_percent(0.5); \ + _kb_led_all_off(); \ + _kb_led_all_set_percent(0.5); \ } while(0) #endif diff --git a/src/keyboard/ergodox/teensy-2-0.c b/src/keyboard/ergodox/teensy-2-0.c index 74b68cf..3f037f0 100644 --- a/src/keyboard/ergodox/teensy-2-0.c +++ b/src/keyboard/ergodox/teensy-2-0.c @@ -123,7 +123,7 @@ uint8_t teensy_init(void) { PORTD &= ~(1<<6); // set D(6) internal pull-up disabled // keyboard LEDs (see "PWM on ports OC1(A|B|C)" in "teensy-2-0.md") - _led_all_off(); // (just to put the pins in a known state) + _kb_led_all_off(); // (just to put the pins in a known state) TCCR1A = 0b10101001; // set and configure fast PWM TCCR1B = 0b00001001; // set and configure fast PWM diff --git a/src/keyboard/ergodox/teensy-2-0.h b/src/keyboard/ergodox/teensy-2-0.h index c43714f..65fa67d 100644 --- a/src/keyboard/ergodox/teensy-2-0.h +++ b/src/keyboard/ergodox/teensy-2-0.h @@ -15,40 +15,40 @@ // LED control - #define _led_1_on() (DDRB |= (1<<6)) - #define _led_1_off() (DDRB &= ~(1<<6)) - #define _led_1_set(n) (OCR1B = (uint8_t)(n)) - #define _led_1_set_percent(n) (OCR1B = (uint8_t)((n) * 0xFF)) + #define _kb_led_1_on() (DDRB |= (1<<6)) + #define _kb_led_1_off() (DDRB &= ~(1<<6)) + #define _kb_led_1_set(n) (OCR1B = (uint8_t)(n)) + #define _kb_led_1_set_percent(n) (OCR1B = (uint8_t)((n) * 0xFF)) // - #define _led_2_on() (DDRB |= (1<<5)) - #define _led_2_off() (DDRB &= ~(1<<5)) - #define _led_2_set(n) (OCR1A = (uint8_t)(n)) - #define _led_2_set_percent(n) (OCR1A = (uint8_t)((n) * 0xFF)) + #define _kb_led_2_on() (DDRB |= (1<<5)) + #define _kb_led_2_off() (DDRB &= ~(1<<5)) + #define _kb_led_2_set(n) (OCR1A = (uint8_t)(n)) + #define _kb_led_2_set_percent(n) (OCR1A = (uint8_t)((n) * 0xFF)) // - #define _led_3_on() (DDRB |= (1<<7)) - #define _led_3_off() (DDRB &= ~(1<<7)) - #define _led_3_set(n) (OCR1C = (uint8_t)(n)) - #define _led_3_set_percent(n) (OCR1C = (uint8_t)((n) * 0xFF)) + #define _kb_led_3_on() (DDRB |= (1<<7)) + #define _kb_led_3_off() (DDRB &= ~(1<<7)) + #define _kb_led_3_set(n) (OCR1C = (uint8_t)(n)) + #define _kb_led_3_set_percent(n) (OCR1C = (uint8_t)((n) * 0xFF)) // --- - #define _led_all_on() do { \ - _led_1_on(); \ - _led_2_on(); \ - _led_3_on(); \ + #define _kb_led_all_on() do { \ + _kb_led_1_on(); \ + _kb_led_2_on(); \ + _kb_led_3_on(); \ } while(0) - #define _led_all_off() do { \ - _led_1_off(); \ - _led_2_off(); \ - _led_3_off(); \ + #define _kb_led_all_off() do { \ + _kb_led_1_off(); \ + _kb_led_2_off(); \ + _kb_led_3_off(); \ } while(0) - #define _led_all_set(n) do { \ - _led_1_set(n); \ - _led_2_set(n); \ - _led_3_set(n); \ + #define _kb_led_all_set(n) do { \ + _kb_led_1_set(n); \ + _kb_led_2_set(n); \ + _kb_led_3_set(n); \ } while(0) - #define _led_all_set_percent(n) do { \ - _led_1_set_percent(n); \ - _led_2_set_percent(n); \ - _led_3_set_percent(n); \ + #define _kb_led_all_set_percent(n) do { \ + _kb_led_1_set_percent(n); \ + _kb_led_2_set_percent(n); \ + _kb_led_3_set_percent(n); \ } while(0) #endif From 223f03ac749a9596c4e8d6d0184e6015c2f7f6f6 Mon Sep 17 00:00:00 2001 From: Ben Blazak Date: Thu, 14 Jun 2012 16:01:34 -0700 Subject: [PATCH 11/28] wrote kbfun for 2 shifts => capslock; other kbfun mods --- src/lib/key-functions.c | 137 ++++++++++++++++++++++++++-------------- src/lib/key-functions.h | 2 +- src/main.c | 2 + 3 files changed, 94 insertions(+), 47 deletions(-) diff --git a/src/lib/key-functions.c b/src/lib/key-functions.c index 53c6011..48517b6 100644 --- a/src/lib/key-functions.c +++ b/src/lib/key-functions.c @@ -18,78 +18,102 @@ #include "key-functions.h" +// ---------------------------------------------------------------------------- -void kbfun_press( KBFUN_FUNCTION_ARGS ) { +/* + * Generate a normal keypress or keyrelease + * + * Arguments + * - keycode: the keycode to use + * - pressed: whether to generate a keypress (true) or keyrelease (false) + * + * Note + * - Because of the way USB does things, what this actually does is either add + * or remove 'keycode' from the list of currently pressed keys + */ +static void _press_release(uint8_t keycode, bool pressed) { // no-op - if (keycode_ == 0) + if (keycode == 0) return; // modifier keys - switch (keycode_) { - case KEY_LeftControl: keyboard_modifier_keys |= (1<<0); + switch (keycode) { + case KEY_LeftControl: (pressed) + ? (keyboard_modifier_keys |= (1<<0)) + : (keyboard_modifier_keys &= ~(1<<0)); return; - case KEY_LeftShift: keyboard_modifier_keys |= (1<<1); + case KEY_LeftShift: (pressed) + ? (keyboard_modifier_keys |= (1<<1)) + : (keyboard_modifier_keys &= ~(1<<1)); return; - case KEY_LeftAlt: keyboard_modifier_keys |= (1<<2); + case KEY_LeftAlt: (pressed) + ? (keyboard_modifier_keys |= (1<<2)) + : (keyboard_modifier_keys &= ~(1<<2)); return; - case KEY_LeftGUI: keyboard_modifier_keys |= (1<<3); + case KEY_LeftGUI: (pressed) + ? (keyboard_modifier_keys |= (1<<3)) + : (keyboard_modifier_keys &= ~(1<<3)); return; - case KEY_RightControl: keyboard_modifier_keys |= (1<<4); + case KEY_RightControl: (pressed) + ? (keyboard_modifier_keys |= (1<<4)) + : (keyboard_modifier_keys &= ~(1<<4)); return; - case KEY_RightShift: keyboard_modifier_keys |= (1<<5); + case KEY_RightShift: (pressed) + ? (keyboard_modifier_keys |= (1<<5)) + : (keyboard_modifier_keys &= ~(1<<5)); return; - case KEY_RightAlt: keyboard_modifier_keys |= (1<<6); + case KEY_RightAlt: (pressed) + ? (keyboard_modifier_keys |= (1<<6)) + : (keyboard_modifier_keys &= ~(1<<6)); return; - case KEY_RightGUI: keyboard_modifier_keys |= (1<<7); + case KEY_RightGUI: (pressed) + ? (keyboard_modifier_keys |= (1<<7)) + : (keyboard_modifier_keys &= ~(1<<7)); return; } // all others - for (uint8_t i=0; i<6; i++) - if (keyboard_keys[i] == 0) { - keyboard_keys[i] = keycode_; - return; + for (uint8_t i=0; i<6; i++) { + if (pressed) { + if (keyboard_keys[i] == 0) { + keyboard_keys[i] = keycode; + return; + } + } else { + if (keyboard_keys[i] == keycode) { + keyboard_keys[i] = 0; + return; + } } + } } +// ---------------------------------------------------------------------------- + +/* + * - press + * - generate a normal keypress + */ +void kbfun_press( KBFUN_FUNCTION_ARGS ) { + _press_release(keycode_, true); +} + +/* + * - release + * - generate a normal keyrelease + */ void kbfun_release( KBFUN_FUNCTION_ARGS ) { - // no-op - if (keycode_ == 0) - return; - - // modifier keys - switch (keycode_) { - case KEY_LeftControl: keyboard_modifier_keys &= ~(1<<0); - return; - case KEY_LeftShift: keyboard_modifier_keys &= ~(1<<1); - return; - case KEY_LeftAlt: keyboard_modifier_keys &= ~(1<<2); - return; - case KEY_LeftGUI: keyboard_modifier_keys &= ~(1<<3); - return; - case KEY_RightControl: keyboard_modifier_keys &= ~(1<<4); - return; - case KEY_RightShift: keyboard_modifier_keys &= ~(1<<5); - return; - case KEY_RightAlt: keyboard_modifier_keys &= ~(1<<6); - return; - case KEY_RightGUI: keyboard_modifier_keys &= ~(1<<7); - return; - } - - // all others - for (uint8_t i=0; i<6; i++) - if (keyboard_keys[i] == keycode_) { - keyboard_keys[i] = 0; - return; - } + _press_release(keycode_, false); } // TODO: -// - implement two shifts => capslock // - implement layer lock key combos (make a function to switch to a specific // layer) +/* + * - next layer + * - layer increment (for all keys) + */ void kbfun_layer_inc( KBFUN_FUNCTION_ARGS ) { for (uint8_t row=0; row capslock + * - when assigned to two keys (e.g. the physical left and right shift keys), + * pressing and holding down one of them makes the second toggle capslock + */ +void kbfun_2_keys_capslock_press_release( KBFUN_FUNCTION_ARGS ) { + static uint8_t keys_pressed = 0; + + if (!pressed_) keys_pressed--; + + _press_release(keycode_, pressed_); + if (keys_pressed == 1) + _press_release(KEY_CapsLock, pressed_); + + if (pressed_) keys_pressed++; +} + diff --git a/src/lib/key-functions.h b/src/lib/key-functions.h index b709474..7b80874 100644 --- a/src/lib/key-functions.h +++ b/src/lib/key-functions.h @@ -35,7 +35,7 @@ #define KBFUN_FUNCTION_ARGS \ - uint8_t keycode_, \ + uint8_t keycode_, bool pressed_, \ uint8_t (*current_layers_)[KB_ROWS][KB_COLUMNS], \ uint8_t (*pressed_layers_)[KB_ROWS][KB_COLUMNS], \ uint8_t * row_, uint8_t * col_ diff --git a/src/main.c b/src/main.c index 340873a..56ea6b5 100644 --- a/src/main.c +++ b/src/main.c @@ -64,6 +64,7 @@ int main(void) { if (press_function) { (*press_function)( kb_layout_get(current_layer, row, col), + true, ¤t_layers, &pressed_layers, &row, &col ); } @@ -75,6 +76,7 @@ int main(void) { if (release_function) { (*release_function)( kb_layout_get(pressed_layer, row, col), + false, ¤t_layers, &pressed_layers, &row, &col ); } From 28e198ee7219f492cc3b3d4a033acbc675d214b5 Mon Sep 17 00:00:00 2001 From: Ben Blazak Date: Thu, 14 Jun 2012 22:02:57 -0700 Subject: [PATCH 12/28] added set layer function; more lib/keyfunctions* changes --- src/lib/key-functions.c | 80 ++++++++++++++++++++++++++++++++--------- src/lib/key-functions.h | 7 ++-- src/main.c | 6 ++-- 3 files changed, 72 insertions(+), 21 deletions(-) diff --git a/src/lib/key-functions.c b/src/lib/key-functions.c index 48517b6..2210948 100644 --- a/src/lib/key-functions.c +++ b/src/lib/key-functions.c @@ -16,8 +16,12 @@ #include "lib/usb/usage-page/keyboard.h" #include "keyboard.h" -#include "key-functions.h" +#include "key-functions.h" // includes the appropriate keyboard 'matrix.h' +#include "key-functions--private.h" + +// ---------------------------------------------------------------------------- +// private functions // ---------------------------------------------------------------------------- /* @@ -29,9 +33,10 @@ * * Note * - Because of the way USB does things, what this actually does is either add - * or remove 'keycode' from the list of currently pressed keys + * or remove 'keycode' from the list of currently pressed keys, to be sent at + * the end of the current cycle (see main.c) */ -static void _press_release(uint8_t keycode, bool pressed) { +void _press_release(uint8_t keycode, bool pressed) { // no-op if (keycode == 0) return; @@ -88,6 +93,44 @@ static void _press_release(uint8_t keycode, bool pressed) { } } +/* + * Set current layer + * - Sets any keys currently set to the overall current layer to the new layer, + * and then sets the overall current layer + * + * Arguments + * - value: the new layer value + * - current_layer: (a pointer to) the overall current layer (see main.c) + * - current_layers_: (a pointer to a matrix of) the current layer for each key + * (see main.c and lib/key-functions.h) + * + * Note + * - Leaving all non-current layer values alone allows changing layers while + * maintaining a possibly enabled layer mask (as might be used to implement + * firmware enabled numlock) + */ +void _layer_set_current( + uint8_t value, + uint8_t * current_layer, + uint8_t * current_layers_[KB_ROWS][KB_COLUMNS] ) { + + // don't switch to out-of-bounds layers + if (!( (0 <= *current_layer) && (*current_layer < KB_LAYERS) )) + return; + + for (uint8_t row=0; row 0) - ((*current_layers_)[row][col])--; - // else do nothing + _layer_set_current( + (*current_layer_)-1, + current_layer_, + current_layers_ ); } /* diff --git a/src/lib/key-functions.h b/src/lib/key-functions.h index 7b80874..db6e548 100644 --- a/src/lib/key-functions.h +++ b/src/lib/key-functions.h @@ -35,10 +35,13 @@ #define KBFUN_FUNCTION_ARGS \ - uint8_t keycode_, bool pressed_, \ + uint8_t keycode_, \ + bool pressed_, \ + uint8_t * current_layer_, \ uint8_t (*current_layers_)[KB_ROWS][KB_COLUMNS], \ uint8_t (*pressed_layers_)[KB_ROWS][KB_COLUMNS], \ - uint8_t * row_, uint8_t * col_ + uint8_t * row_, \ + uint8_t * col_ typedef void (*kbfun_funptr_t)( KBFUN_FUNCTION_ARGS ); diff --git a/src/main.c b/src/main.c index 56ea6b5..8fcb09f 100644 --- a/src/main.c +++ b/src/main.c @@ -27,6 +27,8 @@ int main(void) { kb_led_state_ready(); for (;;) { + // the overall current layer + static uint8_t current layer; // the current layer for each key static uint8_t current_layers[KB_ROWS][KB_COLUMNS]; // the layer each key was on when it was last pressed @@ -64,7 +66,7 @@ int main(void) { if (press_function) { (*press_function)( kb_layout_get(current_layer, row, col), - true, + true, ¤t_layer, ¤t_layers, &pressed_layers, &row, &col ); } @@ -76,7 +78,7 @@ int main(void) { if (release_function) { (*release_function)( kb_layout_get(pressed_layer, row, col), - false, + false, ¤t_layer, ¤t_layers, &pressed_layers, &row, &col ); } From d1f17133c92c7cfa390fb1f2b8e2ca2f493b4586 Mon Sep 17 00:00:00 2001 From: Ben Blazak Date: Thu, 14 Jun 2012 22:03:47 -0700 Subject: [PATCH 13/28] added lib/key-functions private header --- src/lib/key-functions--private.h | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 src/lib/key-functions--private.h diff --git a/src/lib/key-functions--private.h b/src/lib/key-functions--private.h new file mode 100644 index 0000000..d1988e5 --- /dev/null +++ b/src/lib/key-functions--private.h @@ -0,0 +1,23 @@ +/* ---------------------------------------------------------------------------- + * key functions: private + * + * Things to be used only by keyfunctions. Exported any layouts would like to + * use these functions to help define their own. + * ---------------------------------------------------------------------------- + * Copyright (c) 2012 Ben Blazak + * Released under The MIT License (MIT) (see "license.md") + * Project located at + * ------------------------------------------------------------------------- */ + + +#ifndef KEY_FUNCTIONS_h_PRIVATE + #define KEY_FUNCTIONS_h_PRIVATE + + void _press_release(uint8_t keycode, bool pressed); + void _layer_set_current( + uint8_t value, + uint8_t * current_layer, + uint8_t * current_layers_[KB_ROWS][KB_COLUMNS] ); + +#endif + From 068a3546f66006c5ca616fe821ca9efe4d0b489e Mon Sep 17 00:00:00 2001 From: Ben Blazak Date: Fri, 15 Jun 2012 14:36:50 -0700 Subject: [PATCH 14/28] bug fixes, mostly; and other things - addition to references.md - keymap modification - now using 2 shifts => capslock - the previous capslock key -> tab - the previous tab key -> left bracket - bug and omission fixes; notably: - _is_pressed() no longer changes the value of `keyboard_modifier_keys`, lol - kbfun_2_keys_capslock_press_release() now works. (capslock doesn't register if left or right shift is pressed, so the shift state has to be stored, cleared, capslock pressed, and shift state restored) - main() no longer locally overwrites the value of `current_layer` before sending it to the kbfun. (i didn't realize i was using the same variable name for two different things) - improvements - kbfun_layer_inc() and ...dec() are now variable --- references.md | 11 +++ src/keyboard/ergodox/layout/qwerty.c | 19 +++-- src/lib/key-functions--private.h | 3 +- src/lib/key-functions.c | 116 +++++++++++++++++++++------ src/lib/key-functions.h | 10 ++- src/main.c | 16 ++-- 6 files changed, 128 insertions(+), 47 deletions(-) diff --git a/references.md b/references.md index c6b899c..c8c3bdb 100644 --- a/references.md +++ b/references.md @@ -377,6 +377,17 @@ ## Miscellaneous +### Keyboard Testing Tools + +* [Understanding Rollover] + (http://gadzikowski.com/nkeyrollover.html) + Includes 3 different tests (2 of which are web based) to see which keys are + actually registering as pressed. + + * mentioned on the [Default:NKey Rollover] + (http://geekhack.org/showwiki.php?title=NKey+Rollover+-+Overview+Testing+Methodology+and+Results) + page (on ) + ### Typical Keyboard Information * [Keyboard Scan Rates] diff --git a/src/keyboard/ergodox/layout/qwerty.c b/src/keyboard/ergodox/layout/qwerty.c index ea8a8ac..8169a27 100644 --- a/src/keyboard/ergodox/layout/qwerty.c +++ b/src/keyboard/ergodox/layout/qwerty.c @@ -19,11 +19,14 @@ #include "../layout.h" +#include "../../../lib/key-functions.h" // aliases #define f_press &kbfun_press #define f_relea &kbfun_release +#define f_l_set &kbfun_layer_set #define f_l_inc &kbfun_layer_inc #define f_l_dec &kbfun_layer_dec +#define f_2kcap &kbfun_2_keys_capslock_press_release uint8_t PROGMEM _kb_layout[KB_LAYERS][KB_ROWS][KB_COLUMNS] = { @@ -33,9 +36,9 @@ uint8_t PROGMEM _kb_layout[KB_LAYERS][KB_ROWS][KB_COLUMNS] = { 0, // left hand _grave, _1, _2, _3, _4, _5, _equal, -_tab, _Q, _W, _E, _R, _T, _esc, -_capsLock, _A, _S, _D, _F, _G, -_shiftL, _Z, _X, _C, _V, _B, 0, +_bracketL, _Q, _W, _E, _R, _T, _esc, +_tab, _A, _S, _D, _F, _G, +_shiftL, _Z, _X, _C, _V, _B, 1, _guiL, _arrowL, _arrowU, _arrowD, _arrowR, _bs, _del, _ctrlL, @@ -44,7 +47,7 @@ _guiL, _arrowL, _arrowU, _arrowD, _arrowR, _backslash, _6, _7, _8, _9, _0, _dash, _bracketL, _Y, _U, _I, _O, _P, _bracketR, _H, _J, _K, _L, _semicolon, _quote, - 0, _N, _M, _comma, _period, _slash, _shiftR, + 1, _N, _M, _comma, _period, _slash, _shiftR, _arrowL, _arrowD, _arrowU, _arrowR, _guiR, _space, _ctrlR, _enter, @@ -84,7 +87,7 @@ NULL, f_press,f_press,f_press,f_press,f_press,f_press,f_press, f_press,f_press,f_press,f_press,f_press,f_press,f_press, f_press,f_press,f_press,f_press,f_press,f_press, -f_press,f_press,f_press,f_press,f_press,f_press,f_l_inc, +f_2kcap,f_press,f_press,f_press,f_press,f_press,f_l_inc, f_press,f_press,f_press,f_press,f_press, f_press, f_press, f_press, @@ -93,7 +96,7 @@ f_press,f_press,f_press,f_press,f_press, f_press,f_press,f_press,f_press,f_press,f_press,f_press, f_press,f_press,f_press,f_press,f_press,f_press,f_press, f_press,f_press,f_press,f_press,f_press,f_press, - f_l_inc,f_press,f_press,f_press,f_press,f_press,f_press, + f_l_inc,f_press,f_press,f_press,f_press,f_press,f_2kcap, f_press,f_press,f_press,f_press,f_press, f_press, f_press, f_press, @@ -133,7 +136,7 @@ NULL, f_relea,f_relea,f_relea,f_relea,f_relea,f_relea,f_relea, f_relea,f_relea,f_relea,f_relea,f_relea,f_relea,f_relea, f_relea,f_relea,f_relea,f_relea,f_relea,f_relea, -f_relea,f_relea,f_relea,f_relea,f_relea,f_relea,f_l_dec, +f_2kcap,f_relea,f_relea,f_relea,f_relea,f_relea,f_l_dec, f_relea,f_relea,f_relea,f_relea,f_relea, f_relea, f_relea, f_relea, @@ -142,7 +145,7 @@ f_relea,f_relea,f_relea,f_relea,f_relea, f_relea,f_relea,f_relea,f_relea,f_relea,f_relea,f_relea, f_relea,f_relea,f_relea,f_relea,f_relea,f_relea,f_relea, f_relea,f_relea,f_relea,f_relea,f_relea,f_relea, - f_l_dec,f_relea,f_relea,f_relea,f_relea,f_relea,f_relea, + f_l_dec,f_relea,f_relea,f_relea,f_relea,f_relea,f_2kcap, f_relea,f_relea,f_relea,f_relea,f_relea, f_relea, f_relea, f_relea, diff --git a/src/lib/key-functions--private.h b/src/lib/key-functions--private.h index d1988e5..9d14aaa 100644 --- a/src/lib/key-functions--private.h +++ b/src/lib/key-functions--private.h @@ -17,7 +17,8 @@ void _layer_set_current( uint8_t value, uint8_t * current_layer, - uint8_t * current_layers_[KB_ROWS][KB_COLUMNS] ); + uint8_t (*current_layers_)[KB_ROWS][KB_COLUMNS] ); + bool _is_pressed(uint8_t keycode); #endif diff --git a/src/lib/key-functions.c b/src/lib/key-functions.c index 2210948..dd8e88a 100644 --- a/src/lib/key-functions.c +++ b/src/lib/key-functions.c @@ -101,7 +101,7 @@ void _press_release(uint8_t keycode, bool pressed) { * Arguments * - value: the new layer value * - current_layer: (a pointer to) the overall current layer (see main.c) - * - current_layers_: (a pointer to a matrix of) the current layer for each key + * - current_layers: (a pointer to a matrix of) the current layer for each key * (see main.c and lib/key-functions.h) * * Note @@ -112,87 +112,151 @@ void _press_release(uint8_t keycode, bool pressed) { void _layer_set_current( uint8_t value, uint8_t * current_layer, - uint8_t * current_layers_[KB_ROWS][KB_COLUMNS] ) { + uint8_t (*current_layers)[KB_ROWS][KB_COLUMNS] ) { // don't switch to out-of-bounds layers - if (!( (0 <= *current_layer) && (*current_layer < KB_LAYERS) )) + if ( value < 0 || value >= KB_LAYERS ) return; for (uint8_t row=0; row capslock - * - when assigned to two keys (e.g. the physical left and right shift keys), - * pressing and holding down one of them makes the second toggle capslock + * Two keys => capslock + * - When assigned to two keys (e.g. the physical left and right shift keys) + * (in both the press and release matrices), pressing and holding down one of + * the keys will make the second toggle capslock + * + * Note + * - If either of the shifts are pressed when the second key is pressed, they + * wil be released so that capslock will register properly when pressed. + * Capslock will then be pressed and released, and the original state of the + * shifts will be restored */ +#include "../lib/usb/usage-page/keyboard.h" void kbfun_2_keys_capslock_press_release( KBFUN_FUNCTION_ARGS ) { - static uint8_t keys_pressed = 0; + static uint8_t keys_pressed; + static bool lshift_pressed; + static bool rshift_pressed; if (!pressed_) keys_pressed--; + // take care of the key that was actually pressed _press_release(keycode_, pressed_); - if (keys_pressed == 1) - _press_release(KEY_CapsLock, pressed_); + + // take care of capslock (only on the press of the 2nd key) + if (keys_pressed == 1 && pressed_) { + // save the state of left and right shift + lshift_pressed = _is_pressed(KEY_LeftShift); + rshift_pressed = _is_pressed(KEY_RightShift); + // disable both + _press_release(KEY_LeftShift, false); + _press_release(KEY_RightShift, false); + + // press capslock, then release it + _press_release(KEY_CapsLock, true); + usb_keyboard_send(); + _press_release(KEY_CapsLock, false); + usb_keyboard_send(); + + // restore the state of left and right shift + if (lshift_pressed) + _press_release(KEY_LeftShift, true); + if (rshift_pressed) + _press_release(KEY_RightShift, true); + } if (pressed_) keys_pressed++; } diff --git a/src/lib/key-functions.h b/src/lib/key-functions.h index db6e548..14ef916 100644 --- a/src/lib/key-functions.h +++ b/src/lib/key-functions.h @@ -45,10 +45,12 @@ typedef void (*kbfun_funptr_t)( KBFUN_FUNCTION_ARGS ); - void kbfun_press ( KBFUN_FUNCTION_ARGS ); - void kbfun_release ( KBFUN_FUNCTION_ARGS ); - void kbfun_layer_inc ( KBFUN_FUNCTION_ARGS ); - void kbfun_layer_dec ( KBFUN_FUNCTION_ARGS ); + void kbfun_press ( KBFUN_FUNCTION_ARGS ); + void kbfun_release ( KBFUN_FUNCTION_ARGS ); + void kbfun_layer_set ( KBFUN_FUNCTION_ARGS ); + void kbfun_layer_inc ( KBFUN_FUNCTION_ARGS ); + void kbfun_layer_dec ( KBFUN_FUNCTION_ARGS ); + void kbfun_2_keys_capslock_press_release ( KBFUN_FUNCTION_ARGS ); #endif diff --git a/src/main.c b/src/main.c index 8fcb09f..052ba29 100644 --- a/src/main.c +++ b/src/main.c @@ -28,7 +28,7 @@ int main(void) { for (;;) { // the overall current layer - static uint8_t current layer; + static uint8_t current_layer; // the current layer for each key static uint8_t current_layers[KB_ROWS][KB_COLUMNS]; // the layer each key was on when it was last pressed @@ -59,25 +59,25 @@ int main(void) { if (is_pressed != was_pressed) { if (is_pressed) { - uint8_t current_layer = current_layers[row][col]; - pressed_layers[row][col] = current_layer; + uint8_t layer = current_layers[row][col]; + pressed_layers[row][col] = layer; kbfun_funptr_t press_function = - kb_layout_press_get(current_layer, row, col); + kb_layout_press_get(layer, row, col); if (press_function) { (*press_function)( - kb_layout_get(current_layer, row, col), + kb_layout_get(layer, row, col), true, ¤t_layer, ¤t_layers, &pressed_layers, &row, &col ); } } else { - uint8_t pressed_layer = pressed_layers[row][col]; + uint8_t layer = pressed_layers[row][col]; kbfun_funptr_t release_function = - kb_layout_release_get(pressed_layer, row, col); + kb_layout_release_get(layer, row, col); if (release_function) { (*release_function)( - kb_layout_get(pressed_layer, row, col), + kb_layout_get(layer, row, col), false, ¤t_layer, ¤t_layers, &pressed_layers, &row, &col ); From fe545d83d677814eca3caeca09327874e3a7bbf4 Mon Sep 17 00:00:00 2001 From: Ben Blazak Date: Fri, 15 Jun 2012 16:39:33 -0700 Subject: [PATCH 15/28] test: using indices to an array of fn ptrs in layout matrices so that _kb_layout_press... and ...release... are of type uint8_t instead of kbfun_funptr_t (saving 1 byte per key per layer per matrix = 40% of the total layout size). this brings the total firmware size with 10 layers to 6574 bytes instead of 8302 bytes. the teensy 2.0 has 32256 bytes of flash. i'm going to revert to the old way. partly because the space savings don't seem consequential compared to what we have to work with. mostly because doing it with an array separates the function pointer to macro (or const var) correlation in qwerty.c, and because i then have to extern the _kb_layout_functions[6] array in layout.h (or qwerty.h). also, using an enum instead of macros with manually assigned numbers corresponding to the array indices would be more error prone, i think, because (since it has to be visible outside qwerty.c) it would have to be declared in a header. hopefully all that makes sense. i'm in a bit of a hurry. but look at the code: i think, even with a bit of formatting help, it'd still look less clean --- src/keyboard/ergodox/layout.h | 26 ++++++++++----- src/keyboard/ergodox/layout/qwerty.c | 47 ++++++++++++++++++---------- 2 files changed, 48 insertions(+), 25 deletions(-) diff --git a/src/keyboard/ergodox/layout.h b/src/keyboard/ergodox/layout.h index e58eb51..c5c9a0f 100644 --- a/src/keyboard/ergodox/layout.h +++ b/src/keyboard/ergodox/layout.h @@ -71,23 +71,33 @@ #endif #ifndef kb_layout_press_get - extern kbfun_funptr_t PROGMEM \ + extern kbfun_funptr_t PROGMEM _kb_layout_functions[6]; + extern uint8_t PROGMEM \ _kb_layout_press[KB_LAYERS][KB_ROWS][KB_COLUMNS]; #define kb_layout_press_get(layer,row,column) \ - ( (kbfun_funptr_t) \ - pgm_read_word(&( \ - _kb_layout_press[layer][row][column] )) ) + ( (kbfun_funptr_t) \ + pgm_read_word(&( \ + _kb_layout_functions[ \ + ( (uint8_t) \ + pgm_read_byte(&( \ + _kb_layout_press[layer][row][column] \ + )) ) ] )) ) #endif #ifndef kb_layout_release_get - extern kbfun_funptr_t PROGMEM \ + extern kbfun_funptr_t PROGMEM _kb_layout_functions[6]; + extern uint8_t PROGMEM \ _kb_layout_release[KB_LAYERS][KB_ROWS][KB_COLUMNS]; #define kb_layout_release_get(layer,row,column) \ - ( (kbfun_funptr_t) \ - pgm_read_word(&( \ - _kb_layout_release[layer][row][column] )) ) + ( (kbfun_funptr_t) \ + pgm_read_word(&( \ + _kb_layout_functions[ \ + ( (uint8_t) \ + pgm_read_byte(&( \ + _kb_layout_release[layer][row][column] \ + )) ) ] )) ) #endif diff --git a/src/keyboard/ergodox/layout/qwerty.c b/src/keyboard/ergodox/layout/qwerty.c index 8169a27..3b5d3c8 100644 --- a/src/keyboard/ergodox/layout/qwerty.c +++ b/src/keyboard/ergodox/layout/qwerty.c @@ -19,14 +19,27 @@ #include "../layout.h" -#include "../../../lib/key-functions.h" // aliases -#define f_press &kbfun_press -#define f_relea &kbfun_release -#define f_l_set &kbfun_layer_set -#define f_l_inc &kbfun_layer_inc -#define f_l_dec &kbfun_layer_dec -#define f_2kcap &kbfun_2_keys_capslock_press_release +// #define f_press &kbfun_press +// #define f_relea &kbfun_release +// #define f_l_set &kbfun_layer_set +// #define f_l_inc &kbfun_layer_inc +// #define f_l_dec &kbfun_layer_dec +// #define f_2kcap &kbfun_2_keys_capslock_press_release +kbfun_funptr_t PROGMEM _kb_layout_functions[6] = { + &kbfun_press, + &kbfun_release, + &kbfun_layer_set, + &kbfun_layer_inc, + &kbfun_layer_dec, + &kbfun_2_keys_capslock_press_release +}; +#define f_press 0 +#define f_relea 1 +#define f_l_set 2 +#define f_l_inc 3 +#define f_l_dec 4 +#define f_2kcap 5 uint8_t PROGMEM _kb_layout[KB_LAYERS][KB_ROWS][KB_COLUMNS] = { @@ -78,11 +91,11 @@ _altR, _pageU, _pageD ) }; -kbfun_funptr_t PROGMEM _kb_layout_press[KB_LAYERS][KB_ROWS][KB_COLUMNS] = { +uint8_t PROGMEM _kb_layout_press[KB_LAYERS][KB_ROWS][KB_COLUMNS] = { // ---------------------------------------------------------------------------- LAYER( // layer 0: default // unused -NULL, + 0, // left hand f_press,f_press,f_press,f_press,f_press,f_press,f_press, f_press,f_press,f_press,f_press,f_press,f_press,f_press, @@ -104,12 +117,12 @@ f_press,f_press,f_press ), // ---------------------------------------------------------------------------- LAYER( // layer 1: function and symbol keys // unused -NULL, + 0, // left hand f_press,f_press,f_press,f_press,f_press,f_press,f_press, f_press,f_press,f_press,f_press,f_press,f_press,f_press, f_press,f_press,f_press,f_press,f_press,f_press, -f_press,f_press,f_press,f_press,f_press,f_press, NULL, +f_press,f_press,f_press,f_press,f_press,f_press, 0, f_press,f_press,f_press,f_press,f_press, f_press, f_press, f_press, @@ -118,7 +131,7 @@ f_press,f_press,f_press,f_press,f_press, f_press,f_press,f_press,f_press,f_press,f_press,f_press, f_press,f_press,f_press,f_press,f_press,f_press,f_press, f_press,f_press,f_press,f_press,f_press,f_press, - NULL,f_press,f_press,f_press,f_press,f_press,f_press, + 0,f_press,f_press,f_press,f_press,f_press,f_press, f_press,f_press,f_press,f_press,f_press, f_press, f_press, f_press, @@ -127,11 +140,11 @@ f_press,f_press,f_press ) }; -kbfun_funptr_t PROGMEM _kb_layout_release[KB_LAYERS][KB_ROWS][KB_COLUMNS] = { +uint8_t PROGMEM _kb_layout_release[KB_LAYERS][KB_ROWS][KB_COLUMNS] = { // ---------------------------------------------------------------------------- LAYER( // layer 0: default // unused -NULL, + 0, // left hand f_relea,f_relea,f_relea,f_relea,f_relea,f_relea,f_relea, f_relea,f_relea,f_relea,f_relea,f_relea,f_relea,f_relea, @@ -153,12 +166,12 @@ f_relea,f_relea,f_relea ), // ---------------------------------------------------------------------------- LAYER( // layer 1: function and symbol keys // unused -NULL, + 0, // left hand f_relea,f_relea,f_relea,f_relea,f_relea,f_relea,f_relea, f_relea,f_relea,f_relea,f_relea,f_relea,f_relea,f_relea, f_relea,f_relea,f_relea,f_relea,f_relea,f_relea, -f_relea,f_relea,f_relea,f_relea,f_relea,f_relea, NULL, +f_relea,f_relea,f_relea,f_relea,f_relea,f_relea, 0, f_relea,f_relea,f_relea,f_relea,f_relea, f_relea, f_relea, f_relea, @@ -167,7 +180,7 @@ f_relea,f_relea,f_relea,f_relea,f_relea, f_relea,f_relea,f_relea,f_relea,f_relea,f_relea,f_relea, f_relea,f_relea,f_relea,f_relea,f_relea,f_relea,f_relea, f_relea,f_relea,f_relea,f_relea,f_relea,f_relea, - NULL,f_relea,f_relea,f_relea,f_relea,f_relea,f_relea, + 0,f_relea,f_relea,f_relea,f_relea,f_relea,f_relea, f_relea,f_relea,f_relea,f_relea,f_relea, f_relea, f_relea, f_relea, From 33b6cf6f4746b136aefe3d5edbd99b9536b67b84 Mon Sep 17 00:00:00 2001 From: Ben Blazak Date: Fri, 15 Jun 2012 16:50:02 -0700 Subject: [PATCH 16/28] (reverting after test) i did want to save the test code though --- src/keyboard/ergodox/layout.h | 26 +++++---------- src/keyboard/ergodox/layout/qwerty.c | 47 ++++++++++------------------ 2 files changed, 25 insertions(+), 48 deletions(-) diff --git a/src/keyboard/ergodox/layout.h b/src/keyboard/ergodox/layout.h index c5c9a0f..e58eb51 100644 --- a/src/keyboard/ergodox/layout.h +++ b/src/keyboard/ergodox/layout.h @@ -71,33 +71,23 @@ #endif #ifndef kb_layout_press_get - extern kbfun_funptr_t PROGMEM _kb_layout_functions[6]; - extern uint8_t PROGMEM \ + extern kbfun_funptr_t PROGMEM \ _kb_layout_press[KB_LAYERS][KB_ROWS][KB_COLUMNS]; #define kb_layout_press_get(layer,row,column) \ - ( (kbfun_funptr_t) \ - pgm_read_word(&( \ - _kb_layout_functions[ \ - ( (uint8_t) \ - pgm_read_byte(&( \ - _kb_layout_press[layer][row][column] \ - )) ) ] )) ) + ( (kbfun_funptr_t) \ + pgm_read_word(&( \ + _kb_layout_press[layer][row][column] )) ) #endif #ifndef kb_layout_release_get - extern kbfun_funptr_t PROGMEM _kb_layout_functions[6]; - extern uint8_t PROGMEM \ + extern kbfun_funptr_t PROGMEM \ _kb_layout_release[KB_LAYERS][KB_ROWS][KB_COLUMNS]; #define kb_layout_release_get(layer,row,column) \ - ( (kbfun_funptr_t) \ - pgm_read_word(&( \ - _kb_layout_functions[ \ - ( (uint8_t) \ - pgm_read_byte(&( \ - _kb_layout_release[layer][row][column] \ - )) ) ] )) ) + ( (kbfun_funptr_t) \ + pgm_read_word(&( \ + _kb_layout_release[layer][row][column] )) ) #endif diff --git a/src/keyboard/ergodox/layout/qwerty.c b/src/keyboard/ergodox/layout/qwerty.c index 3b5d3c8..8169a27 100644 --- a/src/keyboard/ergodox/layout/qwerty.c +++ b/src/keyboard/ergodox/layout/qwerty.c @@ -19,27 +19,14 @@ #include "../layout.h" +#include "../../../lib/key-functions.h" // aliases -// #define f_press &kbfun_press -// #define f_relea &kbfun_release -// #define f_l_set &kbfun_layer_set -// #define f_l_inc &kbfun_layer_inc -// #define f_l_dec &kbfun_layer_dec -// #define f_2kcap &kbfun_2_keys_capslock_press_release -kbfun_funptr_t PROGMEM _kb_layout_functions[6] = { - &kbfun_press, - &kbfun_release, - &kbfun_layer_set, - &kbfun_layer_inc, - &kbfun_layer_dec, - &kbfun_2_keys_capslock_press_release -}; -#define f_press 0 -#define f_relea 1 -#define f_l_set 2 -#define f_l_inc 3 -#define f_l_dec 4 -#define f_2kcap 5 +#define f_press &kbfun_press +#define f_relea &kbfun_release +#define f_l_set &kbfun_layer_set +#define f_l_inc &kbfun_layer_inc +#define f_l_dec &kbfun_layer_dec +#define f_2kcap &kbfun_2_keys_capslock_press_release uint8_t PROGMEM _kb_layout[KB_LAYERS][KB_ROWS][KB_COLUMNS] = { @@ -91,11 +78,11 @@ _altR, _pageU, _pageD ) }; -uint8_t PROGMEM _kb_layout_press[KB_LAYERS][KB_ROWS][KB_COLUMNS] = { +kbfun_funptr_t PROGMEM _kb_layout_press[KB_LAYERS][KB_ROWS][KB_COLUMNS] = { // ---------------------------------------------------------------------------- LAYER( // layer 0: default // unused - 0, +NULL, // left hand f_press,f_press,f_press,f_press,f_press,f_press,f_press, f_press,f_press,f_press,f_press,f_press,f_press,f_press, @@ -117,12 +104,12 @@ f_press,f_press,f_press ), // ---------------------------------------------------------------------------- LAYER( // layer 1: function and symbol keys // unused - 0, +NULL, // left hand f_press,f_press,f_press,f_press,f_press,f_press,f_press, f_press,f_press,f_press,f_press,f_press,f_press,f_press, f_press,f_press,f_press,f_press,f_press,f_press, -f_press,f_press,f_press,f_press,f_press,f_press, 0, +f_press,f_press,f_press,f_press,f_press,f_press, NULL, f_press,f_press,f_press,f_press,f_press, f_press, f_press, f_press, @@ -131,7 +118,7 @@ f_press,f_press,f_press,f_press,f_press, f_press,f_press,f_press,f_press,f_press,f_press,f_press, f_press,f_press,f_press,f_press,f_press,f_press,f_press, f_press,f_press,f_press,f_press,f_press,f_press, - 0,f_press,f_press,f_press,f_press,f_press,f_press, + NULL,f_press,f_press,f_press,f_press,f_press,f_press, f_press,f_press,f_press,f_press,f_press, f_press, f_press, f_press, @@ -140,11 +127,11 @@ f_press,f_press,f_press ) }; -uint8_t PROGMEM _kb_layout_release[KB_LAYERS][KB_ROWS][KB_COLUMNS] = { +kbfun_funptr_t PROGMEM _kb_layout_release[KB_LAYERS][KB_ROWS][KB_COLUMNS] = { // ---------------------------------------------------------------------------- LAYER( // layer 0: default // unused - 0, +NULL, // left hand f_relea,f_relea,f_relea,f_relea,f_relea,f_relea,f_relea, f_relea,f_relea,f_relea,f_relea,f_relea,f_relea,f_relea, @@ -166,12 +153,12 @@ f_relea,f_relea,f_relea ), // ---------------------------------------------------------------------------- LAYER( // layer 1: function and symbol keys // unused - 0, +NULL, // left hand f_relea,f_relea,f_relea,f_relea,f_relea,f_relea,f_relea, f_relea,f_relea,f_relea,f_relea,f_relea,f_relea,f_relea, f_relea,f_relea,f_relea,f_relea,f_relea,f_relea, -f_relea,f_relea,f_relea,f_relea,f_relea,f_relea, 0, +f_relea,f_relea,f_relea,f_relea,f_relea,f_relea, NULL, f_relea,f_relea,f_relea,f_relea,f_relea, f_relea, f_relea, f_relea, @@ -180,7 +167,7 @@ f_relea,f_relea,f_relea,f_relea,f_relea, f_relea,f_relea,f_relea,f_relea,f_relea,f_relea,f_relea, f_relea,f_relea,f_relea,f_relea,f_relea,f_relea,f_relea, f_relea,f_relea,f_relea,f_relea,f_relea,f_relea, - 0,f_relea,f_relea,f_relea,f_relea,f_relea,f_relea, + NULL,f_relea,f_relea,f_relea,f_relea,f_relea,f_relea, f_relea,f_relea,f_relea,f_relea,f_relea, f_relea, f_relea, f_relea, From 9f357ede2a01bd62f326c2f01145ae608e67402e Mon Sep 17 00:00:00 2001 From: Ben Blazak Date: Sat, 16 Jun 2012 23:21:20 -0700 Subject: [PATCH 17/28] ((removed something i'd forgotten)) --- src/keyboard/ergodox/layout/qwerty.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/keyboard/ergodox/layout/qwerty.c b/src/keyboard/ergodox/layout/qwerty.c index 8169a27..da162f1 100644 --- a/src/keyboard/ergodox/layout/qwerty.c +++ b/src/keyboard/ergodox/layout/qwerty.c @@ -19,7 +19,6 @@ #include "../layout.h" -#include "../../../lib/key-functions.h" // aliases #define f_press &kbfun_press #define f_relea &kbfun_release From d1fa583bb3e46e102859a9c8359a28500ab06ae7 Mon Sep 17 00:00:00 2001 From: Ben Blazak Date: Wed, 20 Jun 2012 16:56:24 -0700 Subject: [PATCH 18/28] mostly kbfun*() changes and additions - changed KBFUN_FUNCTION_ARGS again - changed kbfun's - condensed `kbfun_press()` and `kbfun_release()` to `kbfun_press_release()` - added `kbfun_toggle()`, which toggles keycodes on or off - added `kbfun_layer_inc_dec_press_release()` which is like ...press_release(), except it increments the layer first (and decrements it on keyrelease) - added `_kbfun_exec_key()` (which is a public kbfun*(), but not for assignment to keycodes) for convenience. used by main(), and currently 1 of the kbfun*()s. it doesn't save a lot of code, but i think it makes things slightly easier to read. not quite as elegant a solution as i'd like, but it might have to do - changed keymap accordingly - changed main() - now using `_kbfun_exec_key()` (instead of essentially inlining the code) - now sending the USB report once every cycle. i was sending once for every keypress (lol, by mistake: what i meant to do was only send it if any keys had been pressed). --- src/keyboard/ergodox/layout/qwerty.c | 133 ++++++++++++++------------- src/lib/key-functions--private.h | 2 +- src/lib/key-functions.c | 99 +++++++++++++++----- src/lib/key-functions.h | 24 +++-- src/main.c | 62 ++++++------- 5 files changed, 185 insertions(+), 135 deletions(-) diff --git a/src/keyboard/ergodox/layout/qwerty.c b/src/keyboard/ergodox/layout/qwerty.c index da162f1..8055010 100644 --- a/src/keyboard/ergodox/layout/qwerty.c +++ b/src/keyboard/ergodox/layout/qwerty.c @@ -20,12 +20,13 @@ // aliases -#define f_press &kbfun_press -#define f_relea &kbfun_release +#define f_prrel &kbfun_press_release +#define f_toggl &kbfun_toggle #define f_l_set &kbfun_layer_set #define f_l_inc &kbfun_layer_inc #define f_l_dec &kbfun_layer_dec #define f_2kcap &kbfun_2_keys_capslock_press_release +#define f_lidpr &kbfun_layer_inc_dec_press_release uint8_t PROGMEM _kb_layout[KB_LAYERS][KB_ROWS][KB_COLUMNS] = { @@ -83,45 +84,45 @@ kbfun_funptr_t PROGMEM _kb_layout_press[KB_LAYERS][KB_ROWS][KB_COLUMNS] = { // unused NULL, // left hand -f_press,f_press,f_press,f_press,f_press,f_press,f_press, -f_press,f_press,f_press,f_press,f_press,f_press,f_press, -f_press,f_press,f_press,f_press,f_press,f_press, -f_2kcap,f_press,f_press,f_press,f_press,f_press,f_l_inc, -f_press,f_press,f_press,f_press,f_press, - f_press, - f_press, f_press, - f_press,f_press,f_press, +f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, +f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, +f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, +f_2kcap,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_l_inc, +f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, + f_prrel, + f_prrel, f_prrel, + f_prrel,f_prrel,f_prrel, // right hand - f_press,f_press,f_press,f_press,f_press,f_press,f_press, - f_press,f_press,f_press,f_press,f_press,f_press,f_press, - f_press,f_press,f_press,f_press,f_press,f_press, - f_l_inc,f_press,f_press,f_press,f_press,f_press,f_2kcap, - f_press,f_press,f_press,f_press,f_press, - f_press, -f_press, f_press, -f_press,f_press,f_press ), + f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, + f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, + f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, + f_l_inc,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_2kcap, + f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, + f_prrel, +f_prrel, f_prrel, +f_prrel,f_prrel,f_prrel ), // ---------------------------------------------------------------------------- LAYER( // layer 1: function and symbol keys // unused NULL, // left hand -f_press,f_press,f_press,f_press,f_press,f_press,f_press, -f_press,f_press,f_press,f_press,f_press,f_press,f_press, -f_press,f_press,f_press,f_press,f_press,f_press, -f_press,f_press,f_press,f_press,f_press,f_press, NULL, -f_press,f_press,f_press,f_press,f_press, - f_press, - f_press, f_press, - f_press,f_press,f_press, +f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, +f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, +f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, +f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, NULL, +f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, + f_prrel, + f_prrel, f_prrel, + f_prrel,f_prrel,f_prrel, // right hand - f_press,f_press,f_press,f_press,f_press,f_press,f_press, - f_press,f_press,f_press,f_press,f_press,f_press,f_press, - f_press,f_press,f_press,f_press,f_press,f_press, - NULL,f_press,f_press,f_press,f_press,f_press,f_press, - f_press,f_press,f_press,f_press,f_press, - f_press, -f_press, f_press, -f_press,f_press,f_press ) + f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, + f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, + f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, + NULL,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, + f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, + f_prrel, +f_prrel, f_prrel, +f_prrel,f_prrel,f_prrel ) // ---------------------------------------------------------------------------- }; @@ -132,45 +133,45 @@ kbfun_funptr_t PROGMEM _kb_layout_release[KB_LAYERS][KB_ROWS][KB_COLUMNS] = { // unused NULL, // left hand -f_relea,f_relea,f_relea,f_relea,f_relea,f_relea,f_relea, -f_relea,f_relea,f_relea,f_relea,f_relea,f_relea,f_relea, -f_relea,f_relea,f_relea,f_relea,f_relea,f_relea, -f_2kcap,f_relea,f_relea,f_relea,f_relea,f_relea,f_l_dec, -f_relea,f_relea,f_relea,f_relea,f_relea, - f_relea, - f_relea, f_relea, - f_relea,f_relea,f_relea, +f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, +f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, +f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, +f_2kcap,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_l_dec, +f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, + f_prrel, + f_prrel, f_prrel, + f_prrel,f_prrel,f_prrel, // right hand - f_relea,f_relea,f_relea,f_relea,f_relea,f_relea,f_relea, - f_relea,f_relea,f_relea,f_relea,f_relea,f_relea,f_relea, - f_relea,f_relea,f_relea,f_relea,f_relea,f_relea, - f_l_dec,f_relea,f_relea,f_relea,f_relea,f_relea,f_2kcap, - f_relea,f_relea,f_relea,f_relea,f_relea, - f_relea, -f_relea, f_relea, -f_relea,f_relea,f_relea ), + f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, + f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, + f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, + f_l_dec,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_2kcap, + f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, + f_prrel, +f_prrel, f_prrel, +f_prrel,f_prrel,f_prrel ), // ---------------------------------------------------------------------------- LAYER( // layer 1: function and symbol keys // unused NULL, // left hand -f_relea,f_relea,f_relea,f_relea,f_relea,f_relea,f_relea, -f_relea,f_relea,f_relea,f_relea,f_relea,f_relea,f_relea, -f_relea,f_relea,f_relea,f_relea,f_relea,f_relea, -f_relea,f_relea,f_relea,f_relea,f_relea,f_relea, NULL, -f_relea,f_relea,f_relea,f_relea,f_relea, - f_relea, - f_relea, f_relea, - f_relea,f_relea,f_relea, +f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, +f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, +f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, +f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, NULL, +f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, + f_prrel, + f_prrel, f_prrel, + f_prrel,f_prrel,f_prrel, // right hand - f_relea,f_relea,f_relea,f_relea,f_relea,f_relea,f_relea, - f_relea,f_relea,f_relea,f_relea,f_relea,f_relea,f_relea, - f_relea,f_relea,f_relea,f_relea,f_relea,f_relea, - NULL,f_relea,f_relea,f_relea,f_relea,f_relea,f_relea, - f_relea,f_relea,f_relea,f_relea,f_relea, - f_relea, -f_relea, f_relea, -f_relea,f_relea,f_relea ) + f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, + f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, + f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, + NULL,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, + f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, + f_prrel, +f_prrel, f_prrel, +f_prrel,f_prrel,f_prrel ) // ---------------------------------------------------------------------------- }; diff --git a/src/lib/key-functions--private.h b/src/lib/key-functions--private.h index 9d14aaa..beaeb80 100644 --- a/src/lib/key-functions--private.h +++ b/src/lib/key-functions--private.h @@ -13,7 +13,7 @@ #ifndef KEY_FUNCTIONS_h_PRIVATE #define KEY_FUNCTIONS_h_PRIVATE - void _press_release(uint8_t keycode, bool pressed); + void _press_release(bool pressed, uint8_t keycode); void _layer_set_current( uint8_t value, uint8_t * current_layer, diff --git a/src/lib/key-functions.c b/src/lib/key-functions.c index dd8e88a..5fa4405 100644 --- a/src/lib/key-functions.c +++ b/src/lib/key-functions.c @@ -16,10 +16,39 @@ #include "lib/usb/usage-page/keyboard.h" #include "keyboard.h" -#include "key-functions.h" // includes the appropriate keyboard 'matrix.h' +#include "key-functions.h" #include "key-functions--private.h" +// ---------------------------------------------------------------------------- +// public functions not for key(press|release) +// ---------------------------------------------------------------------------- + +/* + * Exec key + * - Execute the keypress or keyrelease function (if it exists) of the key at + * the current possition. Pass the keycode at the current position, and pass + * all other arguments as received + */ +void _kbfun_exec_key( KBFUN_FUNCTION_ARGS ) { + kbfun_funptr_t key_function = + ( (pressed_) + ? kb_layout_press_get(layer_, *row_, *col_) + : kb_layout_release_get(layer_, *row_, *col_) ); + + if (key_function) + (*key_function)( + pressed_, + kb_layout_get(layer_, *row_, *col_), + layer_, + row_, + col_, + current_layer_, + current_layers_, + pressed_layers_ ); +} + + // ---------------------------------------------------------------------------- // private functions // ---------------------------------------------------------------------------- @@ -36,7 +65,7 @@ * or remove 'keycode' from the list of currently pressed keys, to be sent at * the end of the current cycle (see main.c) */ -void _press_release(uint8_t keycode, bool pressed) { +void _press_release(bool pressed, uint8_t keycode) { // no-op if (keycode == 0) return; @@ -165,19 +194,22 @@ bool _is_pressed(uint8_t keycode) { // ---------------------------------------------------------------------------- /* - * Press - * - Generate a normal keypress + * Press|Release + * - Generate a normal keypress or keyrelease */ -void kbfun_press( KBFUN_FUNCTION_ARGS ) { - _press_release(keycode_, true); +void kbfun_press_release( KBFUN_FUNCTION_ARGS ) { + _press_release(pressed_, keycode_); } /* - * Release - * - Generate a normal keyrelease + * Toggle + * - Toggle the key on or off */ -void kbfun_release( KBFUN_FUNCTION_ARGS ) { - _press_release(keycode_, false); +void kbfun_toggle( KBFUN_FUNCTION_ARGS ) { + if (_is_pressed(keycode_)) + _press_release(false, keycode_); + else + _press_release(true, keycode_); } /* @@ -191,8 +223,8 @@ void kbfun_layer_set( KBFUN_FUNCTION_ARGS ) { /* * Increase layer - * - Increment layer by the value specified in the keymap (for all non-masked - * keys) + * - Increment the current layer by the value specified in the keymap (for all + * non-masked keys) */ void kbfun_layer_inc( KBFUN_FUNCTION_ARGS ) { _layer_set_current( @@ -203,8 +235,8 @@ void kbfun_layer_inc( KBFUN_FUNCTION_ARGS ) { /* * Decrease layer - * - Decrement layer by the value specified in the keymap (for all non-masked - * keys) + * - Decrement the current layer by the value specified in the keymap (for all + * non-masked keys) */ void kbfun_layer_dec( KBFUN_FUNCTION_ARGS ) { _layer_set_current( @@ -217,7 +249,7 @@ void kbfun_layer_dec( KBFUN_FUNCTION_ARGS ) { * Two keys => capslock * - When assigned to two keys (e.g. the physical left and right shift keys) * (in both the press and release matrices), pressing and holding down one of - * the keys will make the second toggle capslock + * the keys will make the second key toggle capslock * * Note * - If either of the shifts are pressed when the second key is pressed, they @@ -225,7 +257,6 @@ void kbfun_layer_dec( KBFUN_FUNCTION_ARGS ) { * Capslock will then be pressed and released, and the original state of the * shifts will be restored */ -#include "../lib/usb/usage-page/keyboard.h" void kbfun_2_keys_capslock_press_release( KBFUN_FUNCTION_ARGS ) { static uint8_t keys_pressed; static bool lshift_pressed; @@ -234,7 +265,7 @@ void kbfun_2_keys_capslock_press_release( KBFUN_FUNCTION_ARGS ) { if (!pressed_) keys_pressed--; // take care of the key that was actually pressed - _press_release(keycode_, pressed_); + _press_release(pressed_, keycode_); // take care of capslock (only on the press of the 2nd key) if (keys_pressed == 1 && pressed_) { @@ -242,22 +273,44 @@ void kbfun_2_keys_capslock_press_release( KBFUN_FUNCTION_ARGS ) { lshift_pressed = _is_pressed(KEY_LeftShift); rshift_pressed = _is_pressed(KEY_RightShift); // disable both - _press_release(KEY_LeftShift, false); - _press_release(KEY_RightShift, false); + _press_release(false, KEY_LeftShift); + _press_release(false, KEY_RightShift); // press capslock, then release it - _press_release(KEY_CapsLock, true); + _press_release(true, KEY_CapsLock); usb_keyboard_send(); - _press_release(KEY_CapsLock, false); + _press_release(false, KEY_CapsLock); usb_keyboard_send(); // restore the state of left and right shift if (lshift_pressed) - _press_release(KEY_LeftShift, true); + _press_release(true, KEY_LeftShift); if (rshift_pressed) - _press_release(KEY_RightShift, true); + _press_release(true, KEY_RightShift); } if (pressed_) keys_pressed++; } +/* + * Layer (inc|dec), key (press|release) + * - Increment (for press) or decrement (for release) the current layer by the + * value specified in the keymap (for all non-masked keys), and press or + * release the key in the same position on that new layer + */ +void kbfun_layer_inc_dec_press_release( KBFUN_FUNCTION_ARGS ) { + // switch layers + _layer_set_current( + ( (pressed_) + ? (*current_layer_) + keycode_ + : (*current_layer_) - keycode_ ), + current_layer_, + current_layers_ ); + + // exececute second key (in the same position) + _kbfun_exec_key( + pressed_, 0, layer_+keycode_, + row_, col_, current_layer_, + current_layers_, pressed_layers_ ); +} + diff --git a/src/lib/key-functions.h b/src/lib/key-functions.h index 14ef916..42d87c2 100644 --- a/src/lib/key-functions.h +++ b/src/lib/key-functions.h @@ -35,22 +35,26 @@ #define KBFUN_FUNCTION_ARGS \ - uint8_t keycode_, \ bool pressed_, \ + uint8_t keycode_, \ + uint8_t layer_, \ + uint8_t * row_, \ + uint8_t * col_, \ uint8_t * current_layer_, \ uint8_t (*current_layers_)[KB_ROWS][KB_COLUMNS], \ - uint8_t (*pressed_layers_)[KB_ROWS][KB_COLUMNS], \ - uint8_t * row_, \ - uint8_t * col_ + uint8_t (*pressed_layers_)[KB_ROWS][KB_COLUMNS] typedef void (*kbfun_funptr_t)( KBFUN_FUNCTION_ARGS ); - void kbfun_press ( KBFUN_FUNCTION_ARGS ); - void kbfun_release ( KBFUN_FUNCTION_ARGS ); - void kbfun_layer_set ( KBFUN_FUNCTION_ARGS ); - void kbfun_layer_inc ( KBFUN_FUNCTION_ARGS ); - void kbfun_layer_dec ( KBFUN_FUNCTION_ARGS ); - void kbfun_2_keys_capslock_press_release ( KBFUN_FUNCTION_ARGS ); + void _kbfun_exec_key ( KBFUN_FUNCTION_ARGS ); + + void kbfun_press_release (KBFUN_FUNCTION_ARGS); + void kbfun_toggle (KBFUN_FUNCTION_ARGS); + void kbfun_layer_set (KBFUN_FUNCTION_ARGS); + void kbfun_layer_inc (KBFUN_FUNCTION_ARGS); + void kbfun_layer_dec (KBFUN_FUNCTION_ARGS); + void kbfun_2_keys_capslock_press_release (KBFUN_FUNCTION_ARGS); + void kbfun_layer_inc_dec_press_release (KBFUN_FUNCTION_ARGS); #endif diff --git a/src/main.c b/src/main.c index 052ba29..78ec964 100644 --- a/src/main.c +++ b/src/main.c @@ -11,6 +11,7 @@ #include #include "lib-other/pjrc/usb_keyboard/usb_keyboard.h" #include "lib/data-types.h" +#include "lib/key-functions.h" #include "keyboard.h" @@ -41,15 +42,20 @@ int main(void) { kb_update_matrix(*kb_is_pressed); - // call the appropriate function for each key(press|release), 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 "lib/key-functions.c" - // for their definitions - // - anything passed to the key function by reference may be changed - // after the call + // this loop is responsible to + // - "execute" keys when they change state (call `_kbfun_exec_key()`, + // which will call the appropriate function with the appropriate + // keycode argument from the kb_layout* matrices) + // - keep track of which layers the keys were on when they were pressed + // (so they can be released using the function from that layer) + // + // note + // - 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) + // - see "lib/key-functions.c" for the function definitions + // - anything passed to the key function by reference is fair game for + // that function to modify for (uint8_t row=0; row Date: Thu, 21 Jun 2012 20:42:56 -0700 Subject: [PATCH 19/28] separated kbfun_layer_inc_exec() and ...dec_exec() also added another layer to _kb_layout_release[][][], mostly NULL, but including at least one of each available kbfun*(). this way, all the functions appear to be used, and none of them get optimised out by the compiler --- src/keyboard/ergodox/layout/qwerty.c | 22 ++++++++- src/lib/key-functions.c | 72 +++++++++++++++++++--------- src/lib/key-functions.h | 3 +- 3 files changed, 72 insertions(+), 25 deletions(-) diff --git a/src/keyboard/ergodox/layout/qwerty.c b/src/keyboard/ergodox/layout/qwerty.c index 8055010..8061a42 100644 --- a/src/keyboard/ergodox/layout/qwerty.c +++ b/src/keyboard/ergodox/layout/qwerty.c @@ -25,8 +25,9 @@ #define f_l_set &kbfun_layer_set #define f_l_inc &kbfun_layer_inc #define f_l_dec &kbfun_layer_dec +#define f_l_iex &kbfun_layer_inc_exec +#define f_l_dex &kbfun_layer_dec_exec #define f_2kcap &kbfun_2_keys_capslock_press_release -#define f_lidpr &kbfun_layer_inc_dec_press_release uint8_t PROGMEM _kb_layout[KB_LAYERS][KB_ROWS][KB_COLUMNS] = { @@ -171,7 +172,24 @@ f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, f_prrel, f_prrel, f_prrel, -f_prrel,f_prrel,f_prrel ) +f_prrel,f_prrel,f_prrel ), +// ---------------------------------------------------------------------------- + LAYER( // layer 2: nothing (just making sure unused functions don't + // get compiled out) +// unused +NULL, +// other +f_prrel, NULL, NULL, NULL, NULL, NULL, NULL, +f_toggl, NULL, NULL, NULL, NULL, NULL, NULL, +f_l_set, NULL, NULL, NULL, NULL, NULL, NULL, +f_l_inc, NULL, NULL, NULL, NULL, NULL, NULL, +f_l_dec, NULL, NULL, NULL, NULL, NULL, NULL, +f_l_iex, NULL, NULL, NULL, NULL, NULL, NULL, +f_l_dex, NULL, NULL, NULL, NULL, NULL, NULL, +f_2kcap, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL ) // ---------------------------------------------------------------------------- }; diff --git a/src/lib/key-functions.c b/src/lib/key-functions.c index 5fa4405..ea16367 100644 --- a/src/lib/key-functions.c +++ b/src/lib/key-functions.c @@ -245,6 +245,56 @@ void kbfun_layer_dec( KBFUN_FUNCTION_ARGS ) { current_layers_ ); } +/* + * Increase layer, Execute key + * - Increment the current layer by the value specified in the keymap (for all + * non-masked keys), and execute (usually press|release) the key in the same + * position on that new layer + * + * Note + * - Meant to be paired with `kbfun_layer_dec_exec()` + */ +void kbfun_layer_inc_exec( KBFUN_FUNCTION_ARGS ) { + // switch layers + _layer_set_current( + (*current_layer_) + keycode_, + current_layer_, + current_layers_ ); + + // exececute second key (in the same position) + // - `layer_+keycode_` will be constant (under normal circumstances) + // between the press and release + _kbfun_exec_key( + pressed_, 0, layer_+keycode_, + row_, col_, current_layer_, + current_layers_, pressed_layers_ ); +} + +/* + * Decrease layer, Execute key + * - Decrement the current layer by the value specified in the keymap (for all + * non-masked keys), and execute (usually press|release) the key in the same + * position on that new layer + * + * Note + * - Meant to be paired with `kbfun_layer_inc_exec()` + */ +void kbfun_layer_dec_exec( KBFUN_FUNCTION_ARGS ) { + // switch layers + _layer_set_current( + (*current_layer_) - keycode_, + current_layer_, + current_layers_ ); + + // exececute second key (in the same position) + // - `layer_+keycode_` will be constant (under normal circumstances) + // between the press and release + _kbfun_exec_key( + pressed_, 0, layer_+keycode_, + row_, col_, current_layer_, + current_layers_, pressed_layers_ ); +} + /* * Two keys => capslock * - When assigned to two keys (e.g. the physical left and right shift keys) @@ -292,25 +342,3 @@ void kbfun_2_keys_capslock_press_release( KBFUN_FUNCTION_ARGS ) { if (pressed_) keys_pressed++; } -/* - * Layer (inc|dec), key (press|release) - * - Increment (for press) or decrement (for release) the current layer by the - * value specified in the keymap (for all non-masked keys), and press or - * release the key in the same position on that new layer - */ -void kbfun_layer_inc_dec_press_release( KBFUN_FUNCTION_ARGS ) { - // switch layers - _layer_set_current( - ( (pressed_) - ? (*current_layer_) + keycode_ - : (*current_layer_) - keycode_ ), - current_layer_, - current_layers_ ); - - // exececute second key (in the same position) - _kbfun_exec_key( - pressed_, 0, layer_+keycode_, - row_, col_, current_layer_, - current_layers_, pressed_layers_ ); -} - diff --git a/src/lib/key-functions.h b/src/lib/key-functions.h index 42d87c2..5ccb545 100644 --- a/src/lib/key-functions.h +++ b/src/lib/key-functions.h @@ -53,8 +53,9 @@ void kbfun_layer_set (KBFUN_FUNCTION_ARGS); void kbfun_layer_inc (KBFUN_FUNCTION_ARGS); void kbfun_layer_dec (KBFUN_FUNCTION_ARGS); + void kbfun_layer_inc_exec (KBFUN_FUNCTION_ARGS); + void kbfun_layer_dec_exec (KBFUN_FUNCTION_ARGS); void kbfun_2_keys_capslock_press_release (KBFUN_FUNCTION_ARGS); - void kbfun_layer_inc_dec_press_release (KBFUN_FUNCTION_ARGS); #endif From 49e3b5208a24091cd82efe5fe4d4d38f2af0b061 Mon Sep 17 00:00:00 2001 From: Ben Blazak Date: Thu, 21 Jun 2012 22:09:26 -0700 Subject: [PATCH 20/28] (small bug/typo fix) --- src/keyboard/ergodox/layout/qwerty.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/keyboard/ergodox/layout/qwerty.c b/src/keyboard/ergodox/layout/qwerty.c index 8061a42..6546e14 100644 --- a/src/keyboard/ergodox/layout/qwerty.c +++ b/src/keyboard/ergodox/layout/qwerty.c @@ -189,7 +189,7 @@ f_l_dex, NULL, NULL, NULL, NULL, NULL, NULL, f_2kcap, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL ) + NULL, NULL, NULL, NULL, NULL, NULL ) // ---------------------------------------------------------------------------- }; From 6e087c7dd42bafb2e71d32e957d0f910ecfd6f30 Mon Sep 17 00:00:00 2001 From: Ben Blazak Date: Fri, 22 Jun 2012 17:43:12 -0700 Subject: [PATCH 21/28] removed `kbfun_layer_set()` since it was redundant it had no effective difference from `kbfun_layer_inc()`, because values in the keycode matrix can only be positive (of type uint8_t) --- src/keyboard/ergodox/layout/qwerty.c | 3 +-- src/lib/key-functions.c | 9 --------- src/lib/key-functions.h | 1 - 3 files changed, 1 insertion(+), 12 deletions(-) diff --git a/src/keyboard/ergodox/layout/qwerty.c b/src/keyboard/ergodox/layout/qwerty.c index 6546e14..fb7d859 100644 --- a/src/keyboard/ergodox/layout/qwerty.c +++ b/src/keyboard/ergodox/layout/qwerty.c @@ -22,7 +22,6 @@ // aliases #define f_prrel &kbfun_press_release #define f_toggl &kbfun_toggle -#define f_l_set &kbfun_layer_set #define f_l_inc &kbfun_layer_inc #define f_l_dec &kbfun_layer_dec #define f_l_iex &kbfun_layer_inc_exec @@ -181,12 +180,12 @@ NULL, // other f_prrel, NULL, NULL, NULL, NULL, NULL, NULL, f_toggl, NULL, NULL, NULL, NULL, NULL, NULL, -f_l_set, NULL, NULL, NULL, NULL, NULL, NULL, f_l_inc, NULL, NULL, NULL, NULL, NULL, NULL, f_l_dec, NULL, NULL, NULL, NULL, NULL, NULL, f_l_iex, NULL, NULL, NULL, NULL, NULL, NULL, f_l_dex, NULL, NULL, NULL, NULL, NULL, NULL, f_2kcap, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL ) diff --git a/src/lib/key-functions.c b/src/lib/key-functions.c index ea16367..b7dc621 100644 --- a/src/lib/key-functions.c +++ b/src/lib/key-functions.c @@ -212,15 +212,6 @@ void kbfun_toggle( KBFUN_FUNCTION_ARGS ) { _press_release(true, keycode_); } -/* - * Set layer - * - Set layer to the value specified in the keymap (using the value as a - * number instead of a keycode) - */ -void kbfun_layer_set( KBFUN_FUNCTION_ARGS ) { - _layer_set_current( keycode_, current_layer_, current_layers_ ); -} - /* * Increase layer * - Increment the current layer by the value specified in the keymap (for all diff --git a/src/lib/key-functions.h b/src/lib/key-functions.h index 5ccb545..a9728d8 100644 --- a/src/lib/key-functions.h +++ b/src/lib/key-functions.h @@ -50,7 +50,6 @@ void kbfun_press_release (KBFUN_FUNCTION_ARGS); void kbfun_toggle (KBFUN_FUNCTION_ARGS); - void kbfun_layer_set (KBFUN_FUNCTION_ARGS); void kbfun_layer_inc (KBFUN_FUNCTION_ARGS); void kbfun_layer_dec (KBFUN_FUNCTION_ARGS); void kbfun_layer_inc_exec (KBFUN_FUNCTION_ARGS); From 039aba752b1c18a5303d7232d3a293a272d232f3 Mon Sep 17 00:00:00 2001 From: Ben Blazak Date: Thu, 5 Jul 2012 15:48:18 -0700 Subject: [PATCH 22/28] added numpad (and a private key-function for layer masking) tested on breadboard. appears to work! --- src/keyboard/ergodox/layout/qwerty.c | 161 +++++++++++++++++-------- src/keyboard/ergodox/matrix--private.h | 96 --------------- src/keyboard/ergodox/matrix.c | 1 - src/keyboard/ergodox/matrix.h | 84 +++++++++++++ src/lib/key-functions--private.h | 4 + src/lib/key-functions.c | 94 +++++++++++++-- src/lib/key-functions.h | 1 + src/lib/usb/TODO.c | 10 +- 8 files changed, 298 insertions(+), 153 deletions(-) delete mode 100644 src/keyboard/ergodox/matrix--private.h diff --git a/src/keyboard/ergodox/layout/qwerty.c b/src/keyboard/ergodox/layout/qwerty.c index fb7d859..c29878f 100644 --- a/src/keyboard/ergodox/layout/qwerty.c +++ b/src/keyboard/ergodox/layout/qwerty.c @@ -15,7 +15,6 @@ #include "lib/key-functions.h" #include "../matrix.h" -#include "../matrix--private.h" #include "../layout.h" @@ -27,60 +26,84 @@ #define f_l_iex &kbfun_layer_inc_exec #define f_l_dex &kbfun_layer_dec_exec #define f_2kcap &kbfun_2_keys_capslock_press_release +#define f_lm_nu &kbfun_layermask_numpad_press_release uint8_t PROGMEM _kb_layout[KB_LAYERS][KB_ROWS][KB_COLUMNS] = { // ---------------------------------------------------------------------------- - LAYER( // layer 0: default + MATRIX_LAYER( // layer 0: default // unused 0, // left hand -_grave, _1, _2, _3, _4, _5, _equal, -_bracketL, _Q, _W, _E, _R, _T, _esc, -_tab, _A, _S, _D, _F, _G, -_shiftL, _Z, _X, _C, _V, _B, 1, -_guiL, _arrowL, _arrowU, _arrowD, _arrowR, - _bs, - _del, _ctrlL, - _end, _home, _altL, -// right hand - _backslash, _6, _7, _8, _9, _0, _dash, - _bracketL, _Y, _U, _I, _O, _P, _bracketR, - _H, _J, _K, _L, _semicolon, _quote, - 1, _N, _M, _comma, _period, _slash, _shiftR, - _arrowL, _arrowD, _arrowU, _arrowR, _guiR, - _space, -_ctrlR, _enter, -_altR, _pageU, _pageD ), -// ---------------------------------------------------------------------------- - LAYER( // layer 1: function and symbol keys -// unused -0, -// left hand -0, _F1, _F2, _F3, _F4, _F5, _F11, -0, _braceL_kp, _braceR_kp, _bracketL, _bracketR, 0, _esc, -0, _semicolon, _slash, _dash, 0, _colon_kp, -0, 0, 0, 0, 0, 0, 0, -0, _arrowL, _arrowU, _arrowD, _arrowR, + _grave, _1, _2, _3, _4, _5, _equal, +_bracketL, _Q, _W, _E, _R, _T, _esc, + _tab, _A, _S, _D, _F, _G, + _shiftL, _Z, _X, _C, _V, _B, 1, + _guiL, _arrowL, _arrowU, _arrowD, _arrowR, _bs, - _del, _ctrlL, - _end, _home, _altL, + _del, _ctrlL, + _end, _home, _altL, // right hand - _F12, _F6, _F7, _F8, _F9, _F10, 0, - 0, 0, _dash, _lt_kp, _gt_kp, _currencyUnit, 0, - _backslash, 0, _parenL_kp, _parenR_kp, _equal, 0, - 0, _mul_kp, 0, 0, 0, 0, 0, - _arrowL, _arrowD, _arrowU, _arrowR, 0, + _backslash, _6, _7, _8, _9, _0, _dash, + _bracketL, _Y, _U, _I, _O, _P, _bracketR, + _H, _J, _K, _L, _semicolon, _quote, + 1, _N, _M, _comma, _period, _slash, _shiftR, + _arrowL, _arrowD, _arrowU, _arrowR, _guiR, _space, _ctrlR, _enter, -_altR, _pageU, _pageD ) + _altR, _pageU, _pageD ), +// ---------------------------------------------------------------------------- + MATRIX_LAYER( // layer 1: function and symbol keys +// unused +0, +// left hand +0, _F1, _F2, _F3, _F4, _F5, _F11, +0, _braceL_kp, _braceR_kp, _bracketL, _bracketR, 0, _esc, +0, _semicolon, _slash, _dash, 0, _colon_kp, +2, 0, 0, 0, 0, 0, 0, +0, _arrowL, _arrowU, _arrowD, _arrowR, + _bs, + _del, _ctrlL, + _end, _home, _altL, +// right hand + _F12, _F6, _F7, _F8, _F9, _F10, 0, + 0, 0, _dash, _lt_kp, _gt_kp, _currencyUnit, 0, + _backslash, 0, _parenL_kp, _parenR_kp, _equal, 0, + 0, _mul_kp, 0, 0, 0, 0, 0, + _arrowL, _arrowD, _arrowU, _arrowR, 0, + _space, +_ctrlR, _enter, + _altR, _pageU, _pageD ), +// ---------------------------------------------------------------------------- + MATRIX_LAYER( // layer 2: numpad +// unused +0, +// left hand +0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, + 0, + 0, 0, + 0, 0, 0, +// right hand +//------- ------- ------- ------- ------- ------- ------- + 0, 0, _7_kp, _8_kp, _9_kp, _div_kp, 0, + 0, 0, _4_kp, _5_kp, _6_kp, _mul_kp, 0, + 0, _1_kp, _2_kp, _3_kp, _sub_kp, 0, + 0, 0, _0_kp, _period, 0, _add_kp, 0, + 0, 0, 0, 0, 0, + 0, +0, 0, +0, 0, 0 ) // ---------------------------------------------------------------------------- }; kbfun_funptr_t PROGMEM _kb_layout_press[KB_LAYERS][KB_ROWS][KB_COLUMNS] = { // ---------------------------------------------------------------------------- - LAYER( // layer 0: default + MATRIX_LAYER( // layer 0: default // unused NULL, // left hand @@ -102,14 +125,14 @@ f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, f_prrel, f_prrel, f_prrel,f_prrel,f_prrel ), // ---------------------------------------------------------------------------- - LAYER( // layer 1: function and symbol keys + MATRIX_LAYER( // layer 1: function and symbol keys // unused NULL, // left hand f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, -f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, NULL, +f_lm_nu,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, NULL, f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, f_prrel, f_prrel, f_prrel, @@ -122,14 +145,36 @@ f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, f_prrel, f_prrel, f_prrel, -f_prrel,f_prrel,f_prrel ) +f_prrel,f_prrel,f_prrel ), +// ---------------------------------------------------------------------------- + MATRIX_LAYER( // layer 2: numpad +// unused +NULL, +// left hand + NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, + NULL, + NULL, NULL, + NULL, NULL, NULL, +// right hand + NULL, NULL,f_prrel,f_prrel,f_prrel,f_prrel, NULL, + NULL, NULL,f_prrel,f_prrel,f_prrel,f_prrel, NULL, + NULL,f_prrel,f_prrel,f_prrel,f_prrel, NULL, + NULL, NULL,f_prrel,f_prrel,f_prrel,f_prrel, NULL, + NULL, NULL, NULL, NULL, NULL, + NULL, + NULL, NULL, + NULL, NULL, NULL ) // ---------------------------------------------------------------------------- }; kbfun_funptr_t PROGMEM _kb_layout_release[KB_LAYERS][KB_ROWS][KB_COLUMNS] = { // ---------------------------------------------------------------------------- - LAYER( // layer 0: default + MATRIX_LAYER( // layer 0: default // unused NULL, // left hand @@ -151,14 +196,14 @@ f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, f_prrel, f_prrel, f_prrel,f_prrel,f_prrel ), // ---------------------------------------------------------------------------- - LAYER( // layer 1: function and symbol keys + MATRIX_LAYER( // layer 1: function and symbol keys // unused NULL, // left hand f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, -f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, NULL, +f_lm_nu,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, NULL, f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, f_prrel, f_prrel, f_prrel, @@ -173,8 +218,30 @@ f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, f_prrel, f_prrel, f_prrel,f_prrel,f_prrel ), // ---------------------------------------------------------------------------- - LAYER( // layer 2: nothing (just making sure unused functions don't - // get compiled out) + MATRIX_LAYER( // layer 2: numpad +// unused +NULL, +// left hand + NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, + NULL, + NULL, NULL, + NULL, NULL, NULL, +// right hand + NULL, NULL,f_prrel,f_prrel,f_prrel,f_prrel, NULL, + NULL, NULL,f_prrel,f_prrel,f_prrel,f_prrel, NULL, + NULL,f_prrel,f_prrel,f_prrel,f_prrel, NULL, + NULL, NULL,f_prrel,f_prrel,f_prrel,f_prrel, NULL, + NULL, NULL, NULL, NULL, NULL, + NULL, + NULL, NULL, + NULL, NULL, NULL ), +// ---------------------------------------------------------------------------- + MATRIX_LAYER( // layer 3: nothing (just making sure unused functions + // don't get compiled out) // unused NULL, // other @@ -185,7 +252,7 @@ f_l_dec, NULL, NULL, NULL, NULL, NULL, NULL, f_l_iex, NULL, NULL, NULL, NULL, NULL, NULL, f_l_dex, NULL, NULL, NULL, NULL, NULL, NULL, f_2kcap, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, +f_lm_nu, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL ) diff --git a/src/keyboard/ergodox/matrix--private.h b/src/keyboard/ergodox/matrix--private.h deleted file mode 100644 index 3094eca..0000000 --- a/src/keyboard/ergodox/matrix--private.h +++ /dev/null @@ -1,96 +0,0 @@ -/* ---------------------------------------------------------------------------- - * ergoDOX: keyboard matrix specific exports : private - * ---------------------------------------------------------------------------- - * Copyright (c) 2012 Ben Blazak - * Released under The MIT License (MIT) (see "license.md") - * Project located at - * ------------------------------------------------------------------------- */ - - -#ifndef MATRIX_h_PRIVATE - #define MATRIX_h_PRIVATE - - /* mapping from spatial position to matrix position - * - spatial position: where the key is spatially, relative to other - * keys both on the keyboard and in the layout - * - matrix position: the coordinate in the matrix to which a key is - * scanned by the update functions - * - * - location numbers are in the format `row##column`, where both 'row' - * and 'column' are single digit hex numbers corresponding to the - * matrix position (which also corresponds to the row and column pin - * labels used in the teensy and mcp23018 files) - * - coordinates not listed are unused - * - * --- other info ----------------------------------------------------- - * rows x columns = positions; assigned, unassigned - * per hand: 6 x 7 = 42; 38, 4 - * total: 12 x 7 = 84; 76, 8 - * - * left hand : cols 0..6, rows 6..B - * right hand : cols 0..6, rows 0..5 - * -------------------------------------------------------------------- - */ - #define LAYER( \ - /* for unused positions */ \ - na, \ - \ - /* left hand, spatial positions */ \ - kB6,kB5,kB4,kB3,kB2,kB1,kB0, \ - kA6,kA5,kA4,kA3,kA2,kA1,kA0, \ - k96,k95,k94,k93,k92,k91, \ - k86,k85,k84,k83,k82,k81,k80, \ - k76,k75,k74,k73,k72, \ - k64, \ - k63, k60, \ - k65,k62,k61, \ - \ - /* right hand, spatial positions */ \ - k50,k51,k52,k53,k54,k55,k56, \ - k40,k41,k42,k43,k44,k45,k46, \ - k31,k32,k33,k34,k35,k36, \ - k20,k21,k22,k23,k24,k25,k26, \ - k12,k13,k14,k15,k16, \ - k04, \ - k00, k03, \ - k01,k02,k05 ) \ - \ - /* matrix positions */ \ - { { k00,k01,k02,k03,k04,k05, na,}, \ - { na, na,k12,k13,k14,k15,k16,}, \ - { k20,k21,k22,k23,k24,k25,k26,}, \ - { na,k31,k32,k33,k34,k35,k36,}, \ - { k40,k41,k42,k43,k44,k45,k46,}, \ - { k50,k51,k52,k53,k54,k55,k56,}, \ - { k60,k61,k62,k63,k64,k65, na,}, \ - { na, na,k72,k73,k74,k75,k76,}, \ - { k80,k81,k82,k83,k84,k85,k86,}, \ - { na,k91,k92,k93,k94,k95,k96,}, \ - { kA0,kA1,kA2,kA3,kA4,kA5,kA6,}, \ - { kB0,kB1,kB2,kB3,kB4,kB5,kB6 } } - - - #define LAYER_SET_ALL(na, kxx) \ - LAYER( \ - na, \ - \ - kxx,kxx,kxx,kxx,kxx,kxx,kxx, \ - kxx,kxx,kxx,kxx,kxx,kxx,kxx, \ - kxx,kxx,kxx,kxx,kxx,kxx, \ - kxx,kxx,kxx,kxx,kxx,kxx,kxx, \ - kxx,kxx,kxx,kxx,kxx, \ - kxx, \ - kxx, kxx, \ - kxx,kxx,kxx, \ - \ - kxx,kxx,kxx,kxx,kxx,kxx,kxx, \ - kxx,kxx,kxx,kxx,kxx,kxx,kxx, \ - kxx,kxx,kxx,kxx,kxx,kxx, \ - kxx,kxx,kxx,kxx,kxx,kxx,kxx, \ - kxx,kxx,kxx,kxx,kxx, \ - kxx, \ - kxx, kxx, \ - kxx,kxx,kxx ) - -#endif - diff --git a/src/keyboard/ergodox/matrix.c b/src/keyboard/ergodox/matrix.c index d5e6b93..3a1f9e7 100644 --- a/src/keyboard/ergodox/matrix.c +++ b/src/keyboard/ergodox/matrix.c @@ -10,7 +10,6 @@ #include "lib/data-types.h" #include "matrix.h" -#include "matrix--private.h" static bool _kb_is_pressed[KB_ROWS][KB_COLUMNS]; diff --git a/src/keyboard/ergodox/matrix.h b/src/keyboard/ergodox/matrix.h index 600f311..1903a8f 100644 --- a/src/keyboard/ergodox/matrix.h +++ b/src/keyboard/ergodox/matrix.h @@ -18,5 +18,89 @@ extern bool (*kb_is_pressed)[KB_ROWS][KB_COLUMNS]; extern bool (*kb_was_pressed)[KB_ROWS][KB_COLUMNS]; + + /* mapping from spatial position to matrix position + * - spatial position: where the key is spatially, relative to other + * keys both on the keyboard and in the layout + * - matrix position: the coordinate in the matrix to which a key is + * scanned by the update functions + * + * - location numbers are in the format `row##column`, where both 'row' + * and 'column' are single digit hex numbers corresponding to the + * matrix position (which also corresponds to the row and column pin + * labels used in the teensy and mcp23018 files) + * - coordinates not listed are unused + * + * --- other info ----------------------------------------------------- + * rows x columns = positions; assigned, unassigned + * per hand: 6 x 7 = 42; 38, 4 + * total: 12 x 7 = 84; 76, 8 + * + * left hand : cols 0..6, rows 6..B + * right hand : cols 0..6, rows 0..5 + * -------------------------------------------------------------------- + */ + #define MATRIX_LAYER( \ + /* for unused positions */ \ + na, \ + \ + /* left hand, spatial positions */ \ + kB6,kB5,kB4,kB3,kB2,kB1,kB0, \ + kA6,kA5,kA4,kA3,kA2,kA1,kA0, \ + k96,k95,k94,k93,k92,k91, \ + k86,k85,k84,k83,k82,k81,k80, \ + k76,k75,k74,k73,k72, \ + k64, \ + k63, k60, \ + k65,k62,k61, \ + \ + /* right hand, spatial positions */ \ + k50,k51,k52,k53,k54,k55,k56, \ + k40,k41,k42,k43,k44,k45,k46, \ + k31,k32,k33,k34,k35,k36, \ + k20,k21,k22,k23,k24,k25,k26, \ + k12,k13,k14,k15,k16, \ + k04, \ + k00, k03, \ + k01,k02,k05 ) \ + \ + /* matrix positions */ \ + { { k00,k01,k02,k03,k04,k05, na,}, \ + { na, na,k12,k13,k14,k15,k16,}, \ + { k20,k21,k22,k23,k24,k25,k26,}, \ + { na,k31,k32,k33,k34,k35,k36,}, \ + { k40,k41,k42,k43,k44,k45,k46,}, \ + { k50,k51,k52,k53,k54,k55,k56,}, \ + { k60,k61,k62,k63,k64,k65, na,}, \ + { na, na,k72,k73,k74,k75,k76,}, \ + { k80,k81,k82,k83,k84,k85,k86,}, \ + { na,k91,k92,k93,k94,k95,k96,}, \ + { kA0,kA1,kA2,kA3,kA4,kA5,kA6,}, \ + { kB0,kB1,kB2,kB3,kB4,kB5,kB6 } } + + + #define MATRIX_LAYER_SET_ALL(na, kxx) \ + LAYER( \ + na, \ + \ + kxx,kxx,kxx,kxx,kxx,kxx,kxx, \ + kxx,kxx,kxx,kxx,kxx,kxx,kxx, \ + kxx,kxx,kxx,kxx,kxx,kxx, \ + kxx,kxx,kxx,kxx,kxx,kxx,kxx, \ + kxx,kxx,kxx,kxx,kxx, \ + kxx, \ + kxx, kxx, \ + kxx,kxx,kxx, \ + \ + kxx,kxx,kxx,kxx,kxx,kxx,kxx, \ + kxx,kxx,kxx,kxx,kxx,kxx,kxx, \ + kxx,kxx,kxx,kxx,kxx,kxx, \ + kxx,kxx,kxx,kxx,kxx,kxx,kxx, \ + kxx,kxx,kxx,kxx,kxx, \ + kxx, \ + kxx, kxx, \ + kxx,kxx,kxx ) + + #endif diff --git a/src/lib/key-functions--private.h b/src/lib/key-functions--private.h index beaeb80..ee9c979 100644 --- a/src/lib/key-functions--private.h +++ b/src/lib/key-functions--private.h @@ -18,6 +18,10 @@ uint8_t value, uint8_t * current_layer, uint8_t (*current_layers_)[KB_ROWS][KB_COLUMNS] ); + void _layer_set_mask( + uint8_t layer, + bool positions[KB_ROWS][KB_COLUMNS], + uint8_t (*current_layers)[KB_ROWS][KB_COLUMNS] ); bool _is_pressed(uint8_t keycode); #endif diff --git a/src/lib/key-functions.c b/src/lib/key-functions.c index b7dc621..ded56a6 100644 --- a/src/lib/key-functions.c +++ b/src/lib/key-functions.c @@ -21,7 +21,7 @@ // ---------------------------------------------------------------------------- -// public functions not for key(press|release) +// public functions (not for keys) // ---------------------------------------------------------------------------- /* @@ -128,7 +128,7 @@ void _press_release(bool pressed, uint8_t keycode) { * and then sets the overall current layer * * Arguments - * - value: the new layer value + * - layer: the new layer value * - current_layer: (a pointer to) the overall current layer (see main.c) * - current_layers: (a pointer to a matrix of) the current layer for each key * (see main.c and lib/key-functions.h) @@ -139,21 +139,40 @@ void _press_release(bool pressed, uint8_t keycode) { * firmware enabled numlock) */ void _layer_set_current( - uint8_t value, + uint8_t layer, uint8_t * current_layer, uint8_t (*current_layers)[KB_ROWS][KB_COLUMNS] ) { // don't switch to out-of-bounds layers - if ( value < 0 || value >= KB_LAYERS ) + if ( layer < 0 || layer >= KB_LAYERS ) return; for (uint8_t row=0; row= KB_LAYERS ) + return; + + for (uint8_t row=0; row Date: Thu, 5 Jul 2012 17:10:18 -0700 Subject: [PATCH 23/28] added a jump to bootloader key-function --- src/keyboard/ergodox/layout/qwerty.c | 24 ++++++++++---------- src/lib/key-functions.c | 33 +++++++++++++++++++++++++++- src/lib/key-functions.h | 1 + 3 files changed, 46 insertions(+), 12 deletions(-) diff --git a/src/keyboard/ergodox/layout/qwerty.c b/src/keyboard/ergodox/layout/qwerty.c index c29878f..c77cdf8 100644 --- a/src/keyboard/ergodox/layout/qwerty.c +++ b/src/keyboard/ergodox/layout/qwerty.c @@ -27,6 +27,8 @@ #define f_l_dex &kbfun_layer_dec_exec #define f_2kcap &kbfun_2_keys_capslock_press_release #define f_lm_nu &kbfun_layermask_numpad_press_release +#define f_btldr &kbfun_jump_to_bootloader + uint8_t PROGMEM _kb_layout[KB_LAYERS][KB_ROWS][KB_COLUMNS] = { @@ -57,14 +59,14 @@ _ctrlR, _enter, // unused 0, // left hand -0, _F1, _F2, _F3, _F4, _F5, _F11, -0, _braceL_kp, _braceR_kp, _bracketL, _bracketR, 0, _esc, -0, _semicolon, _slash, _dash, 0, _colon_kp, -2, 0, 0, 0, 0, 0, 0, -0, _arrowL, _arrowU, _arrowD, _arrowR, - _bs, - _del, _ctrlL, - _end, _home, _altL, +-1, _F1, _F2, _F3, _F4, _F5, _F11, + 0, _braceL_kp, _braceR_kp, _bracketL, _bracketR, 0, _esc, + 0, _semicolon, _slash, _dash, 0, _colon_kp, + 2, 0, 0, 0, 0, 0, 0, + 0, _arrowL, _arrowU, _arrowD, _arrowR, + _bs, + _del, _ctrlL, + _end, _home, _altL, // right hand _F12, _F6, _F7, _F8, _F9, _F10, 0, 0, 0, _dash, _lt_kp, _gt_kp, _currencyUnit, 0, @@ -129,7 +131,7 @@ f_prrel,f_prrel,f_prrel ), // unused NULL, // left hand -f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, +f_btldr,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, f_lm_nu,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, NULL, @@ -200,7 +202,7 @@ f_prrel,f_prrel,f_prrel ), // unused NULL, // left hand -f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, + NULL,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, f_lm_nu,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, NULL, @@ -253,7 +255,7 @@ f_l_iex, NULL, NULL, NULL, NULL, NULL, NULL, f_l_dex, NULL, NULL, NULL, NULL, NULL, NULL, f_2kcap, NULL, NULL, NULL, NULL, NULL, NULL, f_lm_nu, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, +f_btldr, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL ) // ---------------------------------------------------------------------------- diff --git a/src/lib/key-functions.c b/src/lib/key-functions.c index ded56a6..541c12a 100644 --- a/src/lib/key-functions.c +++ b/src/lib/key-functions.c @@ -11,6 +11,7 @@ * ------------------------------------------------------------------------- */ +#include #include "lib-other/pjrc/usb_keyboard/usb_keyboard.h" #include "lib/data-types.h" #include "lib/usb/usage-page/keyboard.h" @@ -364,7 +365,6 @@ void kbfun_2_keys_capslock_press_release( KBFUN_FUNCTION_ARGS ) { * to the overall current layer when the second is released (even if the * first is still pressed) */ -#include "usb/usage-page/keyboard.h" void kbfun_layermask_numpad_press_release( KBFUN_FUNCTION_ARGS ) { // define layer mask bool layer_mask[KB_ROWS][KB_COLUMNS] = MATRIX_LAYER( @@ -411,3 +411,34 @@ void kbfun_layermask_numpad_press_release( KBFUN_FUNCTION_ARGS ) { _layer_set_mask(*current_layer_, layer_mask, current_layers_); } + +// ---------------------------------------------------------------------------- +// public functions (device specific) +// ---------------------------------------------------------------------------- + +void kbfun_jump_to_bootloader( KBFUN_FUNCTION_ARGS ) { + + // from PJRC (slightly modified) + // +#if MAKEFILE_BOARD == teensy-2-0 + // --- for all Teensy boards + cli(); + + // disable watchdog, if enabled + // disable all peripherals + UDCON = 1; + USBCON = (1< Date: Fri, 6 Jul 2012 00:35:01 -0700 Subject: [PATCH 24/28] added linked lists in lib/data-types --- src/lib/data-types.h | 1 + src/lib/data-types/linked-list.c | 156 +++++++++++++++++++++++++++++++ src/lib/data-types/linked-list.h | 86 +++++++++++++++++ 3 files changed, 243 insertions(+) create mode 100644 src/lib/data-types/linked-list.c create mode 100644 src/lib/data-types/linked-list.h diff --git a/src/lib/data-types.h b/src/lib/data-types.h index 453dca1..434cc97 100644 --- a/src/lib/data-types.h +++ b/src/lib/data-types.h @@ -12,6 +12,7 @@ #include #include + #include "data-types/linked-list.h" #define bool _Bool #define true ((bool)1) diff --git a/src/lib/data-types/linked-list.c b/src/lib/data-types/linked-list.c new file mode 100644 index 0000000..ec14c1e --- /dev/null +++ b/src/lib/data-types/linked-list.c @@ -0,0 +1,156 @@ +/* ---------------------------------------------------------------------------- + * linked list + * ---------------------------------------------------------------------------- + * Copyright (c) 2012 Ben Blazak + * Released under The MIT License (MIT) (see "license.md") + * Project located at + * ------------------------------------------------------------------------- */ + + +#include +#include "lib/data-types.h" + +#include "linked-list.h" + + +// convenience macros (undefined later) +#define _NEW_STRUCT_POINTER(type, name) \ + struct type * name = (struct type *) malloc(sizeof(struct type)) + + +struct linked_list * linked_list_new(void) { + _NEW_STRUCT_POINTER(linked_list, list); + if (!list) return NULL; + + list->head = NULL; + list->tail = NULL; + + list->number_of_elements = 0; + return list; +} + +struct linked_list * linked_list_add_head( + struct linked_list * list, + LINKED_LIST_DATA_TYPE data ) { + + _NEW_STRUCT_POINTER(linked_list_node, node); + if (!node) return NULL; + + node->data = data; + node->next = list->head; + list->head = node; + if (list->number_of_elements == 0) + list->tail = node; + + list->number_of_elements++; + return list; +} + +struct linked_list * linked_list_add_tail( + struct linked_list * list, + LINKED_LIST_DATA_TYPE data ) { + + _NEW_STRUCT_POINTER(linked_list_node, node); + if (!node) return NULL; + + node->data = data; + node->next = NULL; + if (list->number_of_elements == 0) + list->head = node; + else + list->tail->next = node; + list->tail = node; + + list->number_of_elements++; + return list; +} + +LINKED_LIST_DATA_TYPE linked_list_pop_head(struct linked_list * list) { + if (list->number_of_elements == 0) + return 0; + + struct linked_list_node node = { + .data = list->head->data, + .next = list->head->next + }; + + free(list->head); + + if (list->number_of_elements == 1) { + list->head = NULL; + list->tail = NULL; + } else { + list->head = node.next; + } + + list->number_of_elements--; + return node.data; +} + +// note: this function is inefficient for singly linked lists: it has O(n) time +// instead of O(1) time like most of the other functions. but it's not needed +// for implementing stacks or queues, so i don't anticipate it being used all +// that much. it's here for completeness. +LINKED_LIST_DATA_TYPE linked_list_pop_tail(struct linked_list * list) { + if (list->number_of_elements == 0) + return 0; + + struct linked_list_node node = { + .data = list->tail->data, + .next = list->tail->next + }; + + free(list->tail); + + if (list->number_of_elements == 1) { + list->head = NULL; + list->tail = NULL; + } else { + list->tail = list->head; + for (uint8_t i=2; i<(list->number_of_elements); i++) + list->tail = list->tail->next; + list->tail->next = NULL; + } + + list->number_of_elements--; + return node.data; +} + +LINKED_LIST_DATA_TYPE linked_list_read( + struct linked_list * list, + uint8_t position ) { + + if (position < 1 || position > (list->number_of_elements)) + return 0; + + struct linked_list_node * node = list->head; + for (uint8_t i=1; inext; + + return node->data; +} + +struct linked_list * linked_list_copy(struct linked_list * list) { + _NEW_STRUCT_POINTER(linked_list, copy); + + for (uint8_t i=1; i<=(list->number_of_elements); i++) + linked_list_add_tail(copy, linked_list_read(list, i)); + + return copy; +} + + +// note: this is implemented inefficiently (using ...pop_head(), which does +// extra work). but that makes things simpler, and i don't anticipate using it +// all that often. +void linked_list_free(struct linked_list * list) { + while ((list->number_of_elements) > 0) + linked_list_pop_head(list); + + free(list); +} + + +// convenience macros (undefined here) +#undef _NEW_STRUCT_POINTER + diff --git a/src/lib/data-types/linked-list.h b/src/lib/data-types/linked-list.h new file mode 100644 index 0000000..9a918e7 --- /dev/null +++ b/src/lib/data-types/linked-list.h @@ -0,0 +1,86 @@ +/* ---------------------------------------------------------------------------- + * linked list : exports + * + * Includes aliases to treat the list as a queue or stack. + * ---------------------------------------------------------------------------- + * Copyright (c) 2012 Ben Blazak + * Released under The MIT License (MIT) (see "license.md") + * Project located at + * ------------------------------------------------------------------------- */ + + +#ifndef LINKED_LIST_h + #define LINKED_LIST_h + + #include "lib/data-types.h" + + + // default list data type + #ifndef LINKED_LIST_DATA_TYPE + #define LINKED_LIST_DATA_TYPE uint8_t + #endif + + + // structs + struct linked_list_node { + LINKED_LIST_DATA_TYPE data; + struct linked_list_node * next; + }; + + struct linked_list{ + uint8_t number_of_elements; + struct linked_list_node * head; + struct linked_list_node * tail; + }; + + // functions + struct linked_list * linked_list_new(void); + struct linked_list * linked_list_add_head( + struct linked_list * list, + LINKED_LIST_DATA_TYPE data ); + struct linked_list * linked_list_add_tail( + struct linked_list * list, + LINKED_LIST_DATA_TYPE data ); + LINKED_LIST_DATA_TYPE linked_list_pop_head(struct linked_list * list); + LINKED_LIST_DATA_TYPE linked_list_pop_tail(struct linked_list * list); + LINKED_LIST_DATA_TYPE linked_list_read( + struct linked_list * list, + uint8_t position ); + struct linked_list * linked_list_copy(struct linked_list * list); + void linked_list_free(struct linked_list * list); + + + // typedefs, for user code + typedef struct linked_list * linked_list_t; + typedef struct linked_list_node * linked_list_node_t; + + // aliases, for user code + #define list_t linked_list_t + #define list_new linked_list_new + #define list_push linked_list_add_head + #define list_append linked_list_add_tail + #define list_pop linked_list_pop_head + #define list_pop_tail linked_list_pop_tail + #define list_read linked_list_read + #define list_copy linked_list_copy + #define list_free linked_list_free + + #define queue_t list_t + #define queue_new list_new + #define queue_append list_append + #define queue_pop list_pop + #define queue_read list_read + #define queue_copy list_copy + #define queue_free list_free + + #define stack_t list_t + #define stack_new list_new + #define stack_push list_push + #define stack_pop list_pop + #define stack_read list_read + #define stack_copy list_copy + #define stack_free list_free + + +#endif + From 4c23dbaf59e58b456818ab286101012a2bbf52fc Mon Sep 17 00:00:00 2001 From: Ben Blazak Date: Fri, 6 Jul 2012 01:52:54 -0700 Subject: [PATCH 25/28] updated the ergodox circuit diagram svg --- src/keyboard/ergodox/circuit-diagram.svg | 42 ++++++++++++------------ 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/src/keyboard/ergodox/circuit-diagram.svg b/src/keyboard/ergodox/circuit-diagram.svg index ce67d59..8c0c41e 100644 --- a/src/keyboard/ergodox/circuit-diagram.svg +++ b/src/keyboard/ergodox/circuit-diagram.svg @@ -14,7 +14,7 @@ id="svg2" height="398.98083" width="950.8382" - sodipodi:docname="_circuit-diagram.svg" + 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" inkscape:export-xdpi="150" inkscape:export-ydpi="150"> @@ -26,8 +26,8 @@ inkscape:pageopacity="1" inkscape:pageshadow="2" inkscape:zoom="1.4142136" - inkscape:cx="477.26232" - inkscape:cy="197.75046" + inkscape:cx="422.99272" + inkscape:cy="193.57419" inkscape:document-units="px" inkscape:current-layer="layer7" showgrid="true" @@ -1924,22 +1924,22 @@ sodipodi:nodetypes="ccccccccccccc" /> + sodipodi:nodetypes="ccszzcc" /> PWM PWM PWM Date: Sat, 7 Jul 2012 21:49:47 -0700 Subject: [PATCH 26/28] working on linked-lists (going to remove some functions) --- src/lib/data-types.h | 5 +- src/lib/data-types/linked-list.c | 242 ++++++++++++++++++++++++++----- src/lib/data-types/linked-list.h | 80 ++++------ 3 files changed, 233 insertions(+), 94 deletions(-) diff --git a/src/lib/data-types.h b/src/lib/data-types.h index 434cc97..4c625a4 100644 --- a/src/lib/data-types.h +++ b/src/lib/data-types.h @@ -10,13 +10,10 @@ #ifndef DATA_TYPES_h #define DATA_TYPES_h + #include #include #include #include "data-types/linked-list.h" - #define bool _Bool - #define true ((bool)1) - #define false ((bool)0) - #endif diff --git a/src/lib/data-types/linked-list.c b/src/lib/data-types/linked-list.c index ec14c1e..9528132 100644 --- a/src/lib/data-types/linked-list.c +++ b/src/lib/data-types/linked-list.c @@ -1,5 +1,10 @@ /* ---------------------------------------------------------------------------- * linked list + * + * Notes: + * - When 'position' is used, it referes to the position of the node in the + * list, not the node's offset. E.g. the node with position == 1 is the + * first node in the list. * ---------------------------------------------------------------------------- * Copyright (c) 2012 Ben Blazak * Released under The MIT License (MIT) (see "license.md") @@ -13,13 +18,22 @@ #include "linked-list.h" -// convenience macros (undefined later) -#define _NEW_STRUCT_POINTER(type, name) \ - struct type * name = (struct type *) malloc(sizeof(struct type)) +// local macros (undefined later) +#define _NEW_POINTER(type, name) type * name = (type *) malloc(sizeof(type)) +#define _list_t linked_list_t +#define _node_t linked_list_node_t +#define _data_t LINKED_LIST_DATA_TYPE -struct linked_list * linked_list_new(void) { - _NEW_STRUCT_POINTER(linked_list, list); +/* + * new() + * + * Returns + * - success: a pointer to a new linked list + * - failure: NULL + */ +_list_t * linked_list_new(void) { + _NEW_POINTER(_list_t, list); if (!list) return NULL; list->head = NULL; @@ -29,11 +43,15 @@ struct linked_list * linked_list_new(void) { return list; } -struct linked_list * linked_list_add_head( - struct linked_list * list, - LINKED_LIST_DATA_TYPE data ) { - - _NEW_STRUCT_POINTER(linked_list_node, node); +/* + * add_head() + * + * Returns + * - success: the pointer to the list that was passed + * - failure: NULL + */ +_list_t * linked_list_add_head(_list_t * list, _data_t data) { + _NEW_POINTER(_node_t, node); if (!node) return NULL; node->data = data; @@ -46,11 +64,15 @@ struct linked_list * linked_list_add_head( return list; } -struct linked_list * linked_list_add_tail( - struct linked_list * list, - LINKED_LIST_DATA_TYPE data ) { - - _NEW_STRUCT_POINTER(linked_list_node, node); +/* + * add_tail() + * + * Returns + * - success: the pointer to the list that was passed + * - failure: NULL + */ +_list_t * linked_list_add_tail(_list_t * list, _data_t data) { + _NEW_POINTER(_node_t, node); if (!node) return NULL; node->data = data; @@ -65,11 +87,18 @@ struct linked_list * linked_list_add_tail( return list; } -LINKED_LIST_DATA_TYPE linked_list_pop_head(struct linked_list * list) { +/* + * pop_head() + * + * Returns + * - success: the data element of the first node of the list + * - failure: (_data_t) 0 + */ +_data_t linked_list_pop_head(_list_t * list) { if (list->number_of_elements == 0) - return 0; + return (_data_t) 0; - struct linked_list_node node = { + _node_t node = { .data = list->head->data, .next = list->head->next }; @@ -87,15 +116,24 @@ LINKED_LIST_DATA_TYPE linked_list_pop_head(struct linked_list * list) { return node.data; } -// note: this function is inefficient for singly linked lists: it has O(n) time -// instead of O(1) time like most of the other functions. but it's not needed -// for implementing stacks or queues, so i don't anticipate it being used all -// that much. it's here for completeness. -LINKED_LIST_DATA_TYPE linked_list_pop_tail(struct linked_list * list) { +/* + * pop_tail() + * + * Returns + * - success: the data element of the last node of the list + * - failure: (_data_t) 0 + * + * Note + * - This function is inefficient for singly linked lists: it has O(n) time + * instead of O(1) time like most of the other functions. But it's not + * needed for implementing stacks or queues, so i don't anticipate it being + * used all that much. It's here for completeness. + */ +_data_t linked_list_pop_tail(_list_t * list) { if (list->number_of_elements == 0) - return 0; + return (_data_t) 0; - struct linked_list_node node = { + _node_t node = { .data = list->tail->data, .next = list->tail->next }; @@ -116,22 +154,62 @@ LINKED_LIST_DATA_TYPE linked_list_pop_tail(struct linked_list * list) { return node.data; } -LINKED_LIST_DATA_TYPE linked_list_read( - struct linked_list * list, - uint8_t position ) { - +/* + * read() + * + * Returns + * - success: the data element at the given position + * - failure: (_data_t) 0 + */ +_data_t linked_list_read(_list_t * list, uint8_t position) { if (position < 1 || position > (list->number_of_elements)) - return 0; + return (_data_t) 0; - struct linked_list_node * node = list->head; + _node_t * node = list->head; for (uint8_t i=1; inext; return node->data; } -struct linked_list * linked_list_copy(struct linked_list * list) { - _NEW_STRUCT_POINTER(linked_list, copy); +/* + * insert() + * - Insert a new node containing the given data such that it occupies the + * given position in the list. + * + * Returns + * - success: the pointer to the list that was passed + * - failure: NULL + */ +_list_t * linked_list_insert(_list_t * list, _data_t data, uint8_t position) { + if (position < 1 || position > (list->number_of_elements)+1) + return NULL; + + _NEW_POINTER(_node_t, new); + if (!new) return NULL; + + _node_t * prev = list->head; + for (uint8_t i=0; inext; + + new->data = data; + new->next = prev->next; + prev->next = new; + + list->number_of_elements++; + return list; +} + +/* + * copy() + * + * Returns + * - success: a new pointer to a copy of the list who's pointer was passed + * - failure: NULL + */ +_list_t * linked_list_copy(_list_t * list) { + _NEW_POINTER(_list_t, copy); + if (!copy) return NULL; for (uint8_t i=1; i<=(list->number_of_elements); i++) linked_list_add_tail(copy, linked_list_read(list, i)); @@ -139,18 +217,102 @@ struct linked_list * linked_list_copy(struct linked_list * list) { return copy; } - -// note: this is implemented inefficiently (using ...pop_head(), which does -// extra work). but that makes things simpler, and i don't anticipate using it -// all that often. -void linked_list_free(struct linked_list * list) { +/* + * free() + * - Free the memory allocated to all the nodes, then free the memory allocated + * to the list. + * + * Note + * - This is implemented inefficiently (using pop_head(), which does extra + * work). But that makes things simpler, and i don't anticipate using it all + * that often. + */ +void linked_list_free(_list_t * list) { while ((list->number_of_elements) > 0) linked_list_pop_head(list); free(list); } +/* + * slice_copy() + * - Return the (copied) sublist + * + * Arguments + * - start_position: + * - the position of the first element to include in the slice + * - or '0' for the beginning of the list + * - end_position: + * - the position of the last element to include in the slice + * - or '0' for the end of the list + * + * Returns + * - success: a copy of the portion of the list indicated + * - failure: NULL + */ +_list_t * linked_list_slice_copy ( + _list_t * list, + uint8_t start_position, + uint8_t end_position ) { -// convenience macros (undefined here) -#undef _NEW_STRUCT_POINTER + if ( start_position > end_position || + end_position > (list->number_of_elements) ) + return NULL; + + if (start_position == 0) + start_position = 1; + if (end_position == 0) + end_position = list->number_of_elements; + + _NEW_POINTER(_list_t, shallow_slice); + if (!shallow_slice) return NULL; + + shallow_slice->number_of_elements = end_position - start_position + 1; + shallow_slice->head = list->head; + for (uint8_t i=1; ihead = shallow_slice->head->next; + shallow_slice->tail = shallow_slice->head; + for (uint8_t i=1; i<(shallow_slice->number_of_elements); i++) + shallow_slice->tail = shallow_slice->tail->next; + + return linked_list_copy(shallow_slice); +} + +/* + * slice() + */ +_list_t * linked_list_slice ( + _list_t * list, + uint8_t start_position, + uint8_t end_position ) { + // TODO +} + +/* + * remove() + */ +_list_t * linked_list_remove(_list_t * list, uint8_t position) { + // TODO +} + +/* + * find_first() + */ +uint8_t linked_list_find_first(_list_t * list, _data_t data) { + // TODO +} + +/* + * reverse() + */ +_list_t * linked_list_reverse(_list_t * list) { + // TODO +} + + +// local macros (undefined here) +#undef _NEW_POINTER +#undef _list_t +#undef _node_t +#undef _data_t diff --git a/src/lib/data-types/linked-list.h b/src/lib/data-types/linked-list.h index 9a918e7..56bcb88 100644 --- a/src/lib/data-types/linked-list.h +++ b/src/lib/data-types/linked-list.h @@ -1,7 +1,5 @@ /* ---------------------------------------------------------------------------- * linked list : exports - * - * Includes aliases to treat the list as a queue or stack. * ---------------------------------------------------------------------------- * Copyright (c) 2012 Ben Blazak * Released under The MIT License (MIT) (see "license.md") @@ -15,7 +13,7 @@ #include "lib/data-types.h" - // default list data type + // default data type for the list #ifndef LINKED_LIST_DATA_TYPE #define LINKED_LIST_DATA_TYPE uint8_t #endif @@ -27,60 +25,42 @@ struct linked_list_node * next; }; - struct linked_list{ + struct linked_list { uint8_t number_of_elements; struct linked_list_node * head; struct linked_list_node * tail; }; + // typedefs + typedef struct linked_list linked_list_t; + typedef struct linked_list_node linked_list_node_t; + // functions - struct linked_list * linked_list_new(void); - struct linked_list * linked_list_add_head( - struct linked_list * list, - LINKED_LIST_DATA_TYPE data ); - struct linked_list * linked_list_add_tail( - struct linked_list * list, - LINKED_LIST_DATA_TYPE data ); - LINKED_LIST_DATA_TYPE linked_list_pop_head(struct linked_list * list); - LINKED_LIST_DATA_TYPE linked_list_pop_tail(struct linked_list * list); - LINKED_LIST_DATA_TYPE linked_list_read( - struct linked_list * list, - uint8_t position ); - struct linked_list * linked_list_copy(struct linked_list * list); - void linked_list_free(struct linked_list * list); - - - // typedefs, for user code - typedef struct linked_list * linked_list_t; - typedef struct linked_list_node * linked_list_node_t; - - // aliases, for user code - #define list_t linked_list_t - #define list_new linked_list_new - #define list_push linked_list_add_head - #define list_append linked_list_add_tail - #define list_pop linked_list_pop_head - #define list_pop_tail linked_list_pop_tail - #define list_read linked_list_read - #define list_copy linked_list_copy - #define list_free linked_list_free - - #define queue_t list_t - #define queue_new list_new - #define queue_append list_append - #define queue_pop list_pop - #define queue_read list_read - #define queue_copy list_copy - #define queue_free list_free - - #define stack_t list_t - #define stack_new list_new - #define stack_push list_push - #define stack_pop list_pop - #define stack_read list_read - #define stack_copy list_copy - #define stack_free list_free + #define _list_t linked_list_t + #define _data_t LINKED_LIST_DATA_TYPE + _list_t * linked_list_new (void); + _list_t * linked_list_add_head (_list_t * list, _data_t data); + _list_t * linked_list_add_tail (_list_t * list, _data_t data); + _data_t linked_list_pop_head (_list_t * list); + _data_t linked_list_pop_tail (_list_t * list); + _data_t linked_list_read (_list_t * list, uint8_t position); + _list_t * linked_list_insert ( _list_t * list, + uint8_t position, + _data_t data ); + _list_t * linked_list_copy (_list_t * list); + void linked_list_free (_list_t * list); + _list_t * linked_list_slice_copy ( _list_t * list, + uint8_t start_position, + uint8_t end_position ); + _list_t * linked_list_slice ( _list_t * list, + uint8_t start_position, + uint8_t end_position ); + _list_t * linked_list_remove (_list_t * list, uint8_t position); + uint8_t linked_list_find_first (_list_t * list, _data_t data); + _list_t * linked_list_reverse (_list_t * list); + #undef _list_t + #undef _data_t #endif From 018b76342347b6e7bfa6a9efc5e65c7605119e6d Mon Sep 17 00:00:00 2001 From: Ben Blazak Date: Sun, 8 Jul 2012 17:54:23 -0700 Subject: [PATCH 27/28] changed numpad functions; linked-lists, etc. in progress - the numpad functions are reorganized, and there are more of them now, so the numpad can be treated either as something that's toggled or something that's locked - the numpad functions may need to be split into a separate file, to keep things pretty. i'll look into it later. - the linked-list functions are being written so that hopefully i can change the concept of how layers (with transitions and masking) are handled. they're incomplete in this check in because i took a break to fix the numpad functions for dox --- src/keyboard/ergodox/layout/qwerty.c | 22 +- src/lib/data-types/linked-list.c | 292 ++++++++++++--------------- src/lib/data-types/linked-list.h | 17 +- src/lib/key-functions.c | 164 ++++++++++----- src/lib/key-functions.h | 20 +- 5 files changed, 272 insertions(+), 243 deletions(-) diff --git a/src/keyboard/ergodox/layout/qwerty.c b/src/keyboard/ergodox/layout/qwerty.c index c77cdf8..1e5490d 100644 --- a/src/keyboard/ergodox/layout/qwerty.c +++ b/src/keyboard/ergodox/layout/qwerty.c @@ -26,7 +26,9 @@ #define f_l_iex &kbfun_layer_inc_exec #define f_l_dex &kbfun_layer_dec_exec #define f_2kcap &kbfun_2_keys_capslock_press_release -#define f_lm_nu &kbfun_layermask_numpad_press_release +#define f_np_to &kbfun_layermask_numpad_toggle +#define f_np_on &kbfun_layermask_numpad_on +#define f_np_of &kbfun_layermask_numpad_off #define f_btldr &kbfun_jump_to_bootloader @@ -69,7 +71,7 @@ _ctrlR, _enter, _end, _home, _altL, // right hand _F12, _F6, _F7, _F8, _F9, _F10, 0, - 0, 0, _dash, _lt_kp, _gt_kp, _currencyUnit, 0, + 2, 0, _dash, _lt_kp, _gt_kp, _currencyUnit, 0, _backslash, 0, _parenL_kp, _parenR_kp, _equal, 0, 0, _mul_kp, 0, 0, 0, 0, 0, _arrowL, _arrowD, _arrowU, _arrowR, 0, @@ -134,14 +136,14 @@ NULL, f_btldr,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, -f_lm_nu,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, NULL, +f_np_on,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, NULL, f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, f_prrel, f_prrel, f_prrel, f_prrel,f_prrel,f_prrel, // right hand f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, - f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, + f_np_to,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, NULL,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, @@ -205,14 +207,14 @@ NULL, NULL,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, -f_lm_nu,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, NULL, +f_np_of,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, NULL, f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, f_prrel, f_prrel, f_prrel, f_prrel,f_prrel,f_prrel, // right hand f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, - f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, + NULL,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, NULL,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, @@ -254,10 +256,10 @@ f_l_dec, NULL, NULL, NULL, NULL, NULL, NULL, f_l_iex, NULL, NULL, NULL, NULL, NULL, NULL, f_l_dex, NULL, NULL, NULL, NULL, NULL, NULL, f_2kcap, NULL, NULL, NULL, NULL, NULL, NULL, -f_lm_nu, NULL, NULL, NULL, NULL, NULL, NULL, -f_btldr, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL ) +f_np_to, NULL, NULL, NULL, NULL, NULL, NULL, +f_np_on, NULL, NULL, NULL, NULL, NULL, NULL, +f_np_of, NULL, NULL, NULL, NULL, NULL, NULL, +f_btldr, NULL, NULL, NULL, NULL, NULL ) // ---------------------------------------------------------------------------- }; diff --git a/src/lib/data-types/linked-list.c b/src/lib/data-types/linked-list.c index 9528132..20f7141 100644 --- a/src/lib/data-types/linked-list.c +++ b/src/lib/data-types/linked-list.c @@ -39,63 +39,154 @@ _list_t * linked_list_new(void) { list->head = NULL; list->tail = NULL; - list->number_of_elements = 0; + list->length = 0; return list; } /* - * add_head() + * insert() + * + * Arguments + * - index: the index of the position that the new node will occupy. if index + * is negative, we set index += length (as in Python). so: + * - 0 => the first node in the list + * - 1 => the second node in the list + * - -1 => the last node in the list + * - -2 => the second from the last node in the list + * - '0' is undefined (returns 'failure') + * - out of bounds positions wrap around, so: + * - [length] => 0 => the first node in the list + * - -[length+1] => -1 => the last node in the list * * Returns * - success: the pointer to the list that was passed * - failure: NULL */ -_list_t * linked_list_add_head(_list_t * list, _data_t data) { +_list_t * linked_list_insert(_list_t * list, _data_t data, int index) { _NEW_POINTER(_node_t, node); if (!node) return NULL; node->data = data; - node->next = list->head; - list->head = node; - if (list->number_of_elements == 0) - list->tail = node; - list->number_of_elements++; - return list; -} - -/* - * add_tail() - * - * Returns - * - success: the pointer to the list that was passed - * - failure: NULL - */ -_list_t * linked_list_add_tail(_list_t * list, _data_t data) { - _NEW_POINTER(_node_t, node); - if (!node) return NULL; - - node->data = data; - node->next = NULL; - if (list->number_of_elements == 0) + if (list->length == 0) { + // insert as only node (no others exist yet) list->head = node; - else - list->tail->next = node; - list->tail = node; + list->tail = node; + node->next = NULL; + } else { + // find positive, in-bounds index + index = index % list->length; + if (index < 0) + index += list->length; - list->number_of_elements++; + if (index == 0) { + // insert as first node + node->next = list->head; + list->head = node; + } else if (index == list->length-1) { + // insert as last node + list->tail->next = node; + list->tail = node; + node->next = NULL; + } else { + // insert as other node + _node_t * previous = list->head; + for (int i=1; inext; + node->next = previous->next; + previous->next = node; + } + } + + list->length++; return list; } +/* + * peek() + * + * Arguments + * - index: [see 'insert()'] + * + * Returns + * - success: the data field of the node at the given index + * - failure: (_data_t) 0 + */ +_data_t linked_list_peek(_list_t * list, int index) { + // if: no nodes exist + if (list->length == 0) + return (_data_t) 0; + + // find positive, in-bounds index + index = index % list->length; + if (index < 0) + index += list->length; + + // if: last node + if (index == list->length-1) + return list->tail->data; + + // else + _node_t * node = list->head; + for (int i=0; inext; + return node->data; +} + +/* + * pop() + * + * Arguments + * - index: [see 'insert()'] + * + * Returns + * - success: the data field of the node at the given index + * - failure: (_data_t) 0 + */ +// TODO +_data_t linked_list_pop(_list_t * list, int index) { + // if: no nodes exist + if (list->length == 0) + return (_data_t) 0; + + // find positive, in-bounds index + index = index % list->length; + if (index < 0) + index += list->length; + + // vars + _data_t data; + _node_t * node; + + if (index == 0) { + // pop first node + data = list->head->data; + node = list->head; + list->head = node->next; + } else { + // find the index-1'th node, then pop the next one + _node_t * previous; + previous = list->head; + for (int i=1; inext; + data = previous->next->data; + node = previous->next; + previous->next = node->next; + } + + free(node); + return data; +} + /* * pop_head() * * Returns - * - success: the data element of the first node of the list + * - success: the data field of the first node of the list * - failure: (_data_t) 0 */ _data_t linked_list_pop_head(_list_t * list) { - if (list->number_of_elements == 0) + if (list->length == 0) return (_data_t) 0; _node_t node = { @@ -105,14 +196,14 @@ _data_t linked_list_pop_head(_list_t * list) { free(list->head); - if (list->number_of_elements == 1) { + if (list->length == 1) { list->head = NULL; list->tail = NULL; } else { list->head = node.next; } - list->number_of_elements--; + list->length--; return node.data; } @@ -120,7 +211,7 @@ _data_t linked_list_pop_head(_list_t * list) { * pop_tail() * * Returns - * - success: the data element of the last node of the list + * - success: the data field of the last node of the list * - failure: (_data_t) 0 * * Note @@ -130,7 +221,7 @@ _data_t linked_list_pop_head(_list_t * list) { * used all that much. It's here for completeness. */ _data_t linked_list_pop_tail(_list_t * list) { - if (list->number_of_elements == 0) + if (list->length == 0) return (_data_t) 0; _node_t node = { @@ -140,66 +231,20 @@ _data_t linked_list_pop_tail(_list_t * list) { free(list->tail); - if (list->number_of_elements == 1) { + if (list->length == 1) { list->head = NULL; list->tail = NULL; } else { list->tail = list->head; - for (uint8_t i=2; i<(list->number_of_elements); i++) + for (uint8_t i=2; i<(list->length); i++) list->tail = list->tail->next; list->tail->next = NULL; } - list->number_of_elements--; + list->length--; return node.data; } -/* - * read() - * - * Returns - * - success: the data element at the given position - * - failure: (_data_t) 0 - */ -_data_t linked_list_read(_list_t * list, uint8_t position) { - if (position < 1 || position > (list->number_of_elements)) - return (_data_t) 0; - - _node_t * node = list->head; - for (uint8_t i=1; inext; - - return node->data; -} - -/* - * insert() - * - Insert a new node containing the given data such that it occupies the - * given position in the list. - * - * Returns - * - success: the pointer to the list that was passed - * - failure: NULL - */ -_list_t * linked_list_insert(_list_t * list, _data_t data, uint8_t position) { - if (position < 1 || position > (list->number_of_elements)+1) - return NULL; - - _NEW_POINTER(_node_t, new); - if (!new) return NULL; - - _node_t * prev = list->head; - for (uint8_t i=0; inext; - - new->data = data; - new->next = prev->next; - prev->next = new; - - list->number_of_elements++; - return list; -} - /* * copy() * @@ -211,7 +256,7 @@ _list_t * linked_list_copy(_list_t * list) { _NEW_POINTER(_list_t, copy); if (!copy) return NULL; - for (uint8_t i=1; i<=(list->number_of_elements); i++) + for (uint8_t i=1; i<=(list->length); i++) linked_list_add_tail(copy, linked_list_read(list, i)); return copy; @@ -228,87 +273,12 @@ _list_t * linked_list_copy(_list_t * list) { * that often. */ void linked_list_free(_list_t * list) { - while ((list->number_of_elements) > 0) + while ((list->length) > 0) linked_list_pop_head(list); free(list); } -/* - * slice_copy() - * - Return the (copied) sublist - * - * Arguments - * - start_position: - * - the position of the first element to include in the slice - * - or '0' for the beginning of the list - * - end_position: - * - the position of the last element to include in the slice - * - or '0' for the end of the list - * - * Returns - * - success: a copy of the portion of the list indicated - * - failure: NULL - */ -_list_t * linked_list_slice_copy ( - _list_t * list, - uint8_t start_position, - uint8_t end_position ) { - - if ( start_position > end_position || - end_position > (list->number_of_elements) ) - return NULL; - - if (start_position == 0) - start_position = 1; - if (end_position == 0) - end_position = list->number_of_elements; - - _NEW_POINTER(_list_t, shallow_slice); - if (!shallow_slice) return NULL; - - shallow_slice->number_of_elements = end_position - start_position + 1; - shallow_slice->head = list->head; - for (uint8_t i=1; ihead = shallow_slice->head->next; - shallow_slice->tail = shallow_slice->head; - for (uint8_t i=1; i<(shallow_slice->number_of_elements); i++) - shallow_slice->tail = shallow_slice->tail->next; - - return linked_list_copy(shallow_slice); -} - -/* - * slice() - */ -_list_t * linked_list_slice ( - _list_t * list, - uint8_t start_position, - uint8_t end_position ) { - // TODO -} - -/* - * remove() - */ -_list_t * linked_list_remove(_list_t * list, uint8_t position) { - // TODO -} - -/* - * find_first() - */ -uint8_t linked_list_find_first(_list_t * list, _data_t data) { - // TODO -} - -/* - * reverse() - */ -_list_t * linked_list_reverse(_list_t * list) { - // TODO -} - // local macros (undefined here) #undef _NEW_POINTER diff --git a/src/lib/data-types/linked-list.h b/src/lib/data-types/linked-list.h index 56bcb88..a73ea82 100644 --- a/src/lib/data-types/linked-list.h +++ b/src/lib/data-types/linked-list.h @@ -26,7 +26,7 @@ }; struct linked_list { - uint8_t number_of_elements; + uint8_t length; struct linked_list_node * head; struct linked_list_node * tail; }; @@ -38,27 +38,16 @@ // functions #define _list_t linked_list_t #define _data_t LINKED_LIST_DATA_TYPE + // TODO _list_t * linked_list_new (void); _list_t * linked_list_add_head (_list_t * list, _data_t data); _list_t * linked_list_add_tail (_list_t * list, _data_t data); _data_t linked_list_pop_head (_list_t * list); _data_t linked_list_pop_tail (_list_t * list); _data_t linked_list_read (_list_t * list, uint8_t position); - _list_t * linked_list_insert ( _list_t * list, - uint8_t position, - _data_t data ); _list_t * linked_list_copy (_list_t * list); void linked_list_free (_list_t * list); - - _list_t * linked_list_slice_copy ( _list_t * list, - uint8_t start_position, - uint8_t end_position ); - _list_t * linked_list_slice ( _list_t * list, - uint8_t start_position, - uint8_t end_position ); - _list_t * linked_list_remove (_list_t * list, uint8_t position); - uint8_t linked_list_find_first (_list_t * list, _data_t data); - _list_t * linked_list_reverse (_list_t * list); + // /TODO #undef _list_t #undef _data_t diff --git a/src/lib/key-functions.c b/src/lib/key-functions.c index 541c12a..c7f2e2c 100644 --- a/src/lib/key-functions.c +++ b/src/lib/key-functions.c @@ -353,64 +353,130 @@ void kbfun_2_keys_capslock_press_release( KBFUN_FUNCTION_ARGS ) { if (pressed_) keys_pressed++; } -/* - * Activate Numpad - * - Sets num-lock (on for press, off for release) and shifts (without changing - * the overall current layer) the layer of the keys specified in this - * function to the value specified in the keymap + +// TODO: maybe the numpad functions (and other logical sets of functions?) need +// to be in (a) seaparate file(s). +/* ---------------------------------------------------------------------------- + * Numpad functions + * - Functions to implement an embedded numpad * - * Note - * - If a more than one layer mask of this type is used at the same time, the + * Notes + * - The numpad is toggled by shifting (without changing the overall current + * layer) the layer of the keys specified in this function to the value + * specified in the keymap + * - When the numpad is toggled, the numlock is set to on (for active) or off + * (for inactive) as well + * - All these functions cooperate, but if more than one layer mask of this + * type is used (by a different set of functions) at the same time, the * second will override the first, and any keys covered by both will be reset - * to the overall current layer when the second is released (even if the - * first is still pressed) - */ -void kbfun_layermask_numpad_press_release( KBFUN_FUNCTION_ARGS ) { - // define layer mask - bool layer_mask[KB_ROWS][KB_COLUMNS] = MATRIX_LAYER( - // unused - 0, + * to the overall current layer when either is released (even if the other is + * still pressed) + * ------------------------------------------------------------------------- */ - // left hand - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 0, - 0, 0, - 0, 0, 0, +// prefix function (undefined later) +// - to keep these names reasonable in this block, and obviously not global +// outside it +// - 'L' is for 'local' +#define L(name) _kbfun_layermask_numpad__##name - // right hand - 0, 0, 1, 1, 1, 1, 0, - 0, 0, 1, 1, 1, 1, 0, - 0, 1, 1, 1, 1, 0, - 0, 0, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, - 0, - 0, 0, - 0, 0, 0 ); +// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . - // set numlock - if ( // if pressed and numlock off - (pressed_ && !(keyboard_leds & (1<<0))) || - // if released and numlock on - (!pressed_ && (keyboard_leds & (1<<0))) ) { +// vars +static bool L(numpad_activated) = false; +static bool L(layer_mask)[KB_ROWS][KB_COLUMNS] = + MATRIX_LAYER( + // unused + 0, - // toggle numlock - _press_release(true, KEYPAD_NumLock_Clear); - usb_keyboard_send(); - _press_release(false, KEYPAD_NumLock_Clear); - usb_keyboard_send(); - } + // left hand + 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, + 0, 0, + 0, 0, 0, - // set layer mask - if (pressed_) - _layer_set_mask(keycode_, layer_mask, current_layers_); - else - _layer_set_mask(*current_layer_, layer_mask, current_layers_); + // right hand + 0, 0, 1, 1, 1, 1, 0, + 0, 0, 1, 1, 1, 1, 0, + 0, 1, 1, 1, 1, 0, + 0, 0, 1, 1, 1, 1, 0, + 0, 0, 0, 0, 0, + 0, + 0, 0, + 0, 0, 0 ); + +// functions +static inline void L(toggle_numlock)(void) { + _press_release(true, KEYPAD_NumLock_Clear); + usb_keyboard_send(); + _press_release(false, KEYPAD_NumLock_Clear); + usb_keyboard_send(); } +static void L(toggle_numpad)( + uint8_t numpad_layer, + uint8_t current_layer, + uint8_t (*current_layers)[KB_ROWS][KB_COLUMNS] ) { + + if (L(numpad_activated)) { + // deactivate numpad + _layer_set_mask(current_layer, L(layer_mask), current_layers); + L(numpad_activated) = false; + + // if: numlock on + if (keyboard_leds & (1<<0)) + L(toggle_numlock)(); + } else { + // activate numpad + _layer_set_mask(numpad_layer, L(layer_mask), current_layers); + L(numpad_activated) = true; + + // if: numlock off + if (!(keyboard_leds & (1<<0))) + L(toggle_numlock)(); + } +} + +// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + +/* + * Numpad toggle + * - Toggles the numpad and sets numlock on (for active) or off (for inactive) + * with it, if it's not already in that state + */ +void kbfun_layermask_numpad_toggle( KBFUN_FUNCTION_ARGS ) { + L(toggle_numpad)(keycode_, *current_layer_, current_layers_); +} + +/* + * Numpad on + * - Set the numpad on (along with numlock, if it's not already) + */ +void kbfun_layermask_numpad_on( KBFUN_FUNCTION_ARGS ) { + if (!L(numpad_activated)) + L(toggle_numpad)(keycode_, *current_layer_, current_layers_); +} + +/* + * Numpad off + * - Set the numpad off (along with numlock, if it's not already) + */ +void kbfun_layermask_numpad_off( KBFUN_FUNCTION_ARGS ) { + if (L(numpad_activated)) + L(toggle_numpad)(keycode_, *current_layer_, current_layers_); +} + +// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + +// prefix function (undefined here) +#undef L + +/* ---------------------------------------------------------------------------- + * ------------------------------------------------------------------------- */ + // ---------------------------------------------------------------------------- // public functions (device specific) diff --git a/src/lib/key-functions.h b/src/lib/key-functions.h index b0e1740..b6e87ce 100644 --- a/src/lib/key-functions.h +++ b/src/lib/key-functions.h @@ -48,15 +48,17 @@ void _kbfun_exec_key ( KBFUN_FUNCTION_ARGS ); - void kbfun_press_release (KBFUN_FUNCTION_ARGS); - void kbfun_toggle (KBFUN_FUNCTION_ARGS); - void kbfun_layer_inc (KBFUN_FUNCTION_ARGS); - void kbfun_layer_dec (KBFUN_FUNCTION_ARGS); - void kbfun_layer_inc_exec (KBFUN_FUNCTION_ARGS); - void kbfun_layer_dec_exec (KBFUN_FUNCTION_ARGS); - void kbfun_2_keys_capslock_press_release (KBFUN_FUNCTION_ARGS); - void kbfun_layermask_numpad_press_release (KBFUN_FUNCTION_ARGS); - void kbfun_jump_to_bootloader (KBFUN_FUNCTION_ARGS); + void kbfun_press_release (KBFUN_FUNCTION_ARGS); + void kbfun_toggle (KBFUN_FUNCTION_ARGS); + void kbfun_layer_inc (KBFUN_FUNCTION_ARGS); + void kbfun_layer_dec (KBFUN_FUNCTION_ARGS); + void kbfun_layer_inc_exec (KBFUN_FUNCTION_ARGS); + void kbfun_layer_dec_exec (KBFUN_FUNCTION_ARGS); + void kbfun_2_keys_capslock_press_release (KBFUN_FUNCTION_ARGS); + void kbfun_layermask_numpad_toggle (KBFUN_FUNCTION_ARGS); + void kbfun_layermask_numpad_on (KBFUN_FUNCTION_ARGS); + void kbfun_layermask_numpad_off (KBFUN_FUNCTION_ARGS); + void kbfun_jump_to_bootloader (KBFUN_FUNCTION_ARGS); #endif From a31b0fa507fdea523d6416674946b02387ed72d4 Mon Sep 17 00:00:00 2001 From: Ben Blazak Date: Wed, 11 Jul 2012 16:06:08 -0700 Subject: [PATCH 28/28] modified docs a little about row/col assignments and linked-list stuff still in progress --- src/keyboard/ergodox/circuit-diagram.svg | 12 ++- src/keyboard/ergodox/mcp23018.md | 5 ++ src/keyboard/ergodox/teensy-2-0.md | 5 ++ src/lib/data-types/linked-list.c | 106 +++++++---------------- 4 files changed, 47 insertions(+), 81 deletions(-) diff --git a/src/keyboard/ergodox/circuit-diagram.svg b/src/keyboard/ergodox/circuit-diagram.svg index 8c0c41e..da586fb 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="398.98083" + height="416.48083" 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,8 +26,8 @@ inkscape:pageopacity="1" inkscape:pageshadow="2" inkscape:zoom="1.4142136" - inkscape:cx="422.99272" - inkscape:cy="193.57419" + inkscape:cx="464.65225" + inkscape:cy="203.44926" inkscape:document-units="px" inkscape:current-layer="layer7" showgrid="true" @@ -2693,7 +2693,11 @@ sodipodi:role="line" id="tspan3445" x="37.24189" - y="388.43091">- Please also see documentation (especially the notes) in the *.md files + y="388.43091">- Please also see documentation (especially the notes) in the *.md files- Row and column assignments are to matrix positions, not physical positions length == 0) @@ -164,100 +163,55 @@ _data_t linked_list_pop(_list_t * list, int index) { node = list->head; list->head = node->next; } else { - // find the index-1'th node, then pop the next one + // find the index-1'th node _node_t * previous; previous = list->head; for (int i=1; inext; + + // if: last node + if (index == list->length-1) + list->tail = previous; + + // pop the node at index data = previous->next->data; node = previous->next; previous->next = node->next; } free(node); + + list->length--; return data; } /* - * pop_head() - * - * Returns - * - success: the data field of the first node of the list - * - failure: (_data_t) 0 + * find() + * TODO */ -_data_t linked_list_pop_head(_list_t * list) { - if (list->length == 0) - return (_data_t) 0; - - _node_t node = { - .data = list->head->data, - .next = list->head->next - }; - - free(list->head); - - if (list->length == 1) { - list->head = NULL; - list->tail = NULL; - } else { - list->head = node.next; - } - - list->length--; - return node.data; -} - -/* - * pop_tail() - * - * Returns - * - success: the data field of the last node of the list - * - failure: (_data_t) 0 - * - * Note - * - This function is inefficient for singly linked lists: it has O(n) time - * instead of O(1) time like most of the other functions. But it's not - * needed for implementing stacks or queues, so i don't anticipate it being - * used all that much. It's here for completeness. - */ -_data_t linked_list_pop_tail(_list_t * list) { - if (list->length == 0) - return (_data_t) 0; - - _node_t node = { - .data = list->tail->data, - .next = list->tail->next - }; - - free(list->tail); - - if (list->length == 1) { - list->head = NULL; - list->tail = NULL; - } else { - list->tail = list->head; - for (uint8_t i=2; i<(list->length); i++) - list->tail = list->tail->next; - list->tail->next = NULL; - } - - list->length--; - return node.data; -} +// TODO /* * copy() * * Returns - * - success: a new pointer to a copy of the list who's pointer was passed + * - success: a new pointer to a (deep) copy of the list that was passed * - failure: NULL */ _list_t * linked_list_copy(_list_t * list) { _NEW_POINTER(_list_t, copy); if (!copy) return NULL; - for (uint8_t i=1; i<=(list->length); i++) - linked_list_add_tail(copy, linked_list_read(list, i)); + bool error; + _node_t * node = list->head; + for (uint8_t i=0; i<(list->length); i++) { + error = ! linked_list_insert(copy, node->data, -1); + if (error) { + linked_list_free(copy); + return NULL; + } + node = node->next; + } return copy; } @@ -266,16 +220,14 @@ _list_t * linked_list_copy(_list_t * list) { * free() * - Free the memory allocated to all the nodes, then free the memory allocated * to the list. - * - * Note - * - This is implemented inefficiently (using pop_head(), which does extra - * work). But that makes things simpler, and i don't anticipate using it all - * that often. */ void linked_list_free(_list_t * list) { - while ((list->length) > 0) - linked_list_pop_head(list); - + _node_t * node; + for (uint8_t i=0; i<(list->length); i++) { + node = list->head; + list->head = list->head->next; + free(node); + } free(list); }