diff --git a/src/TODO b/src/TODO deleted file mode 100644 index d398be1..0000000 --- a/src/TODO +++ /dev/null @@ -1,2 +0,0 @@ -- make new branch and update for fredrick's new PCB (pre-prototype) - diff --git a/src/keyboard.h b/src/keyboard.h deleted file mode 100644 index 6a472b4..0000000 --- a/src/keyboard.h +++ /dev/null @@ -1,22 +0,0 @@ -/* ---------------------------------------------------------------------------- - * keyboard specific exports - * - * Different keyboards are included by modifying a variable in the makefile. - * ---------------------------------------------------------------------------- - * Copyright (c) 2012 Ben Blazak - * Released under The MIT License (MIT) (see "license.md") - * Project located at - * ------------------------------------------------------------------------- */ - - -#undef _str -#undef _expstr -#undef _inc -#define _str(s) #s // stringify -#define _expstr(s) _str(s) // expand -> stringify -#define _inc _expstr(keyboard/MAKEFILE_KEYBOARD.h) // inc(lude) -#include _inc -#undef _str -#undef _expstr -#undef _inc - diff --git a/src/keyboard/ergodox/matrix.c b/src/keyboard/controller.h similarity index 56% rename from src/keyboard/ergodox/matrix.c rename to src/keyboard/controller.h index 564d857..217abf1 100644 --- a/src/keyboard/ergodox/matrix.c +++ b/src/keyboard/controller.h @@ -1,5 +1,8 @@ /* ---------------------------------------------------------------------------- - * ergoDOX: keyboard matrix specific code + * controller specific exports + * + * Files for different keyboards are used by modifying a variable in the + * Makefile * ---------------------------------------------------------------------------- * Copyright (c) 2012 Ben Blazak * Released under The MIT License (MIT) (see "license.md") @@ -7,14 +10,7 @@ * ------------------------------------------------------------------------- */ -#include "lib/data-types/common.h" - -#include "matrix.h" - - -static bool _kb_is_pressed[KB_ROWS][KB_COLUMNS]; -static bool _kb_was_pressed[KB_ROWS][KB_COLUMNS]; - -bool (*kb_is_pressed)[KB_ROWS][KB_COLUMNS] = &_kb_is_pressed; -bool (*kb_was_pressed)[KB_ROWS][KB_COLUMNS] = &_kb_was_pressed; +#include "src/lib/conditional-include.h" +#define INCLUDE EXP_STR( ./MAKEFILE_KEYBOARD/controller.h ) +#include INCLUDE diff --git a/src/keyboard/ergodox.h b/src/keyboard/ergodox.h deleted file mode 100644 index df27410..0000000 --- a/src/keyboard/ergodox.h +++ /dev/null @@ -1,36 +0,0 @@ -/* ---------------------------------------------------------------------------- - * ergoDOX specific exports - * includes (for centralization) the public exports from all subfiles - * ---------------------------------------------------------------------------- - * Copyright (c) 2012 Ben Blazak - * Released under The MIT License (MIT) (see "license.md") - * Project located at - * ------------------------------------------------------------------------- */ - - -#ifndef ERGODOX_h - #define ERGODOX_h - - #include "lib/data-types/common.h" - - #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/teensy-2-0.h" // LED controls - - - // note: - // - see your keyswitch specification for the necessary value. for - // cherry mx switches, the switch bounce time is speced to be <= 5ms. - // it looks like most switches are speced to be between 5 and 8 ms. - // - if timing is important, balance this value with the main() loop - // run time (~5ms, last i checked, nearly all of it in the i2c - // update() function) - #define KB_DEBOUNCE_TIME 5 // in ms - - - uint8_t kb_init(void); - uint8_t kb_update_matrix(bool matrix[KB_ROWS][KB_COLUMNS]); - -#endif - diff --git a/src/keyboard/ergodox.c b/src/keyboard/ergodox/controller.c similarity index 77% rename from src/keyboard/ergodox.c rename to src/keyboard/ergodox/controller.c index ce01457..44178fd 100644 --- a/src/keyboard/ergodox.c +++ b/src/keyboard/ergodox/controller.c @@ -1,5 +1,5 @@ /* ---------------------------------------------------------------------------- - * ergoDOX specific code: tying it all together + * ergoDOX : controller specific code * ---------------------------------------------------------------------------- * Copyright (c) 2012 Ben Blazak * Released under The MIT License (MIT) (see "license.md") @@ -7,12 +7,13 @@ * ------------------------------------------------------------------------- */ -#include "lib/data-types/common.h" - -#include "ergodox/matrix.h" -#include "ergodox/mcp23018--private.h" -#include "ergodox/teensy-2-0--private.h" +#include +#include +#include "./matrix.h" +#include "./controller/mcp23018--functions.h" +#include "./controller/teensy-2-0--functions.h" +// ---------------------------------------------------------------------------- /* returns * - success: 0 diff --git a/src/keyboard/ergodox/controller.h b/src/keyboard/ergodox/controller.h new file mode 100644 index 0000000..5eb9eb7 --- /dev/null +++ b/src/keyboard/ergodox/controller.h @@ -0,0 +1,27 @@ +/* ---------------------------------------------------------------------------- + * ergoDOX : controller specific exports + * ---------------------------------------------------------------------------- + * Copyright (c) 2012 Ben Blazak + * Released under The MIT License (MIT) (see "license.md") + * Project located at + * ------------------------------------------------------------------------- */ + + +#ifndef KEYBOARD__ERGODOX__CONTROLLER_h + #define KEYBOARD__ERGODOX__CONTROLLER_h + + #include + #include + #include "./matrix.h" + + // -------------------------------------------------------------------- + + #include "./controller/teensy-2-0--led.h" + + // -------------------------------------------------------------------- + + uint8_t kb_init(void); + uint8_t kb_update_matrix(bool matrix[KB_ROWS][KB_COLUMNS]); + +#endif + diff --git a/src/keyboard/ergodox/mcp23018--private.h b/src/keyboard/ergodox/controller/mcp23018--functions.h similarity index 59% rename from src/keyboard/ergodox/mcp23018--private.h rename to src/keyboard/ergodox/controller/mcp23018--functions.h index 8533ebf..f3e934f 100644 --- a/src/keyboard/ergodox/mcp23018--private.h +++ b/src/keyboard/ergodox/controller/mcp23018--functions.h @@ -1,5 +1,5 @@ /* ---------------------------------------------------------------------------- - * ergoDOX controller: MCP23018 specific exports : private + * ergoDOX : controller : MCP23018 specific exports : functions * ---------------------------------------------------------------------------- * Copyright (c) 2012 Ben Blazak * Released under The MIT License (MIT) (see "license.md") @@ -7,14 +7,19 @@ * ------------------------------------------------------------------------- */ -#ifndef MCP23018_h_PRIVATE - #define MCP23018_h_PRIVATE +#ifndef KEYBOARD__ERGODOX__CONTROLLER__MCP23018__FUNCTIONS_h + #define KEYBOARD__ERGODOX__CONTROLLER__MCP23018__FUNCTIONS_h - #include "lib/data-types/common.h" - #include "matrix.h" + #include + #include + #include "../matrix.h" + + // -------------------------------------------------------------------- #define MCP23018_TWI_ADDRESS 0b0100000 + // -------------------------------------------------------------------- + uint8_t mcp23018_init(void); uint8_t mcp23018_update_matrix( bool matrix[KB_ROWS][KB_COLUMNS] ); diff --git a/src/keyboard/ergodox/mcp23018.c b/src/keyboard/ergodox/controller/mcp23018.c similarity index 90% rename from src/keyboard/ergodox/mcp23018.c rename to src/keyboard/ergodox/controller/mcp23018.c index d8cd616..f9faf49 100644 --- a/src/keyboard/ergodox/mcp23018.c +++ b/src/keyboard/ergodox/controller/mcp23018.c @@ -1,5 +1,5 @@ /* ---------------------------------------------------------------------------- - * ergoDOX controller: MCP23018 specific code + * ergoDOX : controller: MCP23018 specific code * ---------------------------------------------------------------------------- * Copyright (c) 2012 Ben Blazak * Released under The MIT License (MIT) (see "license.md") @@ -7,13 +7,14 @@ * ------------------------------------------------------------------------- */ +#include +#include #include -#include "lib/data-types/common.h" -#include "lib/twi.h" // `TWI_FREQ` defined in "teensy-2-0.c" - -#include "matrix.h" -#include "mcp23018--private.h" +#include "src/lib/twi.h" // `TWI_FREQ` defined in "teensy-2-0.c" +#include "../matrix.h" +#include "./mcp23018--functions.h" +// ---------------------------------------------------------------------------- // register addresses (see "mcp23018.md") #define IODIRA 0x00 // i/o direction register @@ -29,6 +30,7 @@ #define TWI_ADDR_WRITE ( (MCP23018_TWI_ADDRESS<<1) | TW_WRITE ) #define TWI_ADDR_READ ( (MCP23018_TWI_ADDRESS<<1) | TW_READ ) +// ---------------------------------------------------------------------------- /* returns: * - success: 0 diff --git a/src/keyboard/ergodox/mcp23018.md b/src/keyboard/ergodox/controller/mcp23018.md similarity index 100% rename from src/keyboard/ergodox/mcp23018.md rename to src/keyboard/ergodox/controller/mcp23018.md diff --git a/src/keyboard/ergodox/controller/teensy-2-0--functions.h b/src/keyboard/ergodox/controller/teensy-2-0--functions.h new file mode 100644 index 0000000..341b4bf --- /dev/null +++ b/src/keyboard/ergodox/controller/teensy-2-0--functions.h @@ -0,0 +1,23 @@ +/* ---------------------------------------------------------------------------- + * ergoDOX : controller : Teensy 2.0 specific exports : functions + * ---------------------------------------------------------------------------- + * Copyright (c) 2012 Ben Blazak + * Released under The MIT License (MIT) (see "license.md") + * Project located at + * ------------------------------------------------------------------------- */ + + +#ifndef KEYBOARD__ERGODOX__CONTROLLER__TEENSY_2_0__FUNCTIONS_h + #define KEYBOARD__ERGODOX__CONTROLLER__TEENSY_2_0__FUNCTIONS_h + + #include + #include + #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.h b/src/keyboard/ergodox/controller/teensy-2-0--led.h similarity index 75% rename from src/keyboard/ergodox/teensy-2-0.h rename to src/keyboard/ergodox/controller/teensy-2-0--led.h index 1202830..3718873 100644 --- a/src/keyboard/ergodox/teensy-2-0.h +++ b/src/keyboard/ergodox/controller/teensy-2-0--led.h @@ -1,5 +1,5 @@ /* ---------------------------------------------------------------------------- - * ergoDOX controller: Teensy 2.0 specific exports + * ergoDOX : controller : Teensy 2.0 specific exports : LED control * ---------------------------------------------------------------------------- * Copyright (c) 2012 Ben Blazak * Released under The MIT License (MIT) (see "license.md") @@ -7,48 +7,52 @@ * ------------------------------------------------------------------------- */ -#ifndef TEENSY_2_0_h - #define TEENSY_2_0_h +#ifndef KEYBOARD__ERGODOX__CONTROLLER__TEENSY_2_0__LED_h + #define KEYBOARD__ERGODOX__CONTROLLER__TEENSY_2_0__LED_h + #include #include // for the register macros - #include "lib/data-types/common.h" + // -------------------------------------------------------------------- - // LED control #define _kb_led_1_on() (DDRB |= (1<<5)) #define _kb_led_1_off() (DDRB &= ~(1<<5)) #define _kb_led_1_set(n) (OCR1A = (uint8_t)(n)) #define _kb_led_1_set_percent(n) (OCR1A = (uint8_t)((n) * 0xFF)) - // + #define _kb_led_2_on() (DDRB |= (1<<6)) #define _kb_led_2_off() (DDRB &= ~(1<<6)) #define _kb_led_2_set(n) (OCR1B = (uint8_t)(n)) #define _kb_led_2_set_percent(n) (OCR1B = (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 _kb_led_all_on() do { \ _kb_led_1_on(); \ _kb_led_2_on(); \ _kb_led_3_on(); \ } while(0) + #define _kb_led_all_off() do { \ - _kb_led_1_off(); \ - _kb_led_2_off(); \ - _kb_led_3_off(); \ + _kb_led_1_off(); \ + _kb_led_2_off(); \ + _kb_led_3_off(); \ } while(0) + #define _kb_led_all_set(n) do { \ - _kb_led_1_set(n); \ - _kb_led_2_set(n); \ - _kb_led_3_set(n); \ + _kb_led_1_set(n); \ + _kb_led_2_set(n); \ + _kb_led_3_set(n); \ } while(0) + #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); \ + _kb_led_1_set_percent(n); \ + _kb_led_2_set_percent(n); \ + _kb_led_3_set_percent(n); \ } while(0) #endif diff --git a/src/keyboard/ergodox/teensy-2-0.c b/src/keyboard/ergodox/controller/teensy-2-0.c similarity index 72% rename from src/keyboard/ergodox/teensy-2-0.c rename to src/keyboard/ergodox/controller/teensy-2-0.c index 577ddcc..acf7019 100644 --- a/src/keyboard/ergodox/teensy-2-0.c +++ b/src/keyboard/ergodox/controller/teensy-2-0.c @@ -1,5 +1,5 @@ /* ---------------------------------------------------------------------------- - * ergoDOX controller: Teensy 2.0 specific code + * ergoDOX : controller: Teensy 2.0 specific code * ---------------------------------------------------------------------------- * Copyright (c) 2012 Ben Blazak * Released under The MIT License (MIT) (see "license.md") @@ -7,16 +7,19 @@ * ------------------------------------------------------------------------- */ +// for "lib/twi.h" +#define TWI_FREQ 400000 + +#include +#include #include #include -#include "lib/data-types/common.h" -#define TWI_FREQ 400000 -#include "lib/twi.h" - -#include "matrix.h" -#include "teensy-2-0.h" -#include "teensy-2-0--private.h" +#include "src/lib/twi.h" +#include "../matrix.h" +#include "./teensy-2-0--functions.h" +#include "./teensy-2-0--led.h" +// ---------------------------------------------------------------------------- // processor frequency (from ) #define CPU_PRESCALE(n) (CLKPR = 0x80, CLKPR = (n)) @@ -39,47 +42,48 @@ * - note: if you change pin assignments, please be sure to update * "teensy-2-0.md", and the '.svg' circuit diagram. */ + // --- helpers +#define _teensypin_write(register, operation, pin_letter, pin_number) \ + ((register##pin_letter) operation (1<<(pin_number))) #define teensypin_write(register, operation, pin) do { \ _teensypin_write(register, operation, pin); \ - _delay_us(1); /* allow pins time to stabalize */ \ + _delay_us(1); /* allow pins time to stabilize */ \ } while(0) -#define _teensypin_write(register, operation, pin_letter, pin_number) \ - ((register##pin_letter) operation (1<<(pin_number))) -#define teensypin_read(pin) \ - _teensypin_read(pin) -#define _teensypin_read(pin_letter, pin_number) \ +#define _teensypin_read(pin_letter, pin_number) \ ((PIN##pin_letter) & (1<<(pin_number))) +#define teensypin_read(pin) \ + _teensypin_read(pin) -#define teensypin_write_all_unused(register, operation) \ - do { \ - teensypin_write(register, operation, UNUSED_0); \ - teensypin_write(register, operation, UNUSED_1); \ - teensypin_write(register, operation, UNUSED_2); \ - teensypin_write(register, operation, UNUSED_3); \ - teensypin_write(register, operation, UNUSED_4); } \ +#define teensypin_write_all_unused(register, operation) \ + do { \ + teensypin_write(register, operation, UNUSED_0); \ + teensypin_write(register, operation, UNUSED_1); \ + teensypin_write(register, operation, UNUSED_2); \ + teensypin_write(register, operation, UNUSED_3); \ + teensypin_write(register, operation, UNUSED_4); } \ while(0) -#define teensypin_write_all_row(register, operation) \ - do { \ - teensypin_write(register, operation, ROW_0); \ - teensypin_write(register, operation, ROW_1); \ - teensypin_write(register, operation, ROW_2); \ - teensypin_write(register, operation, ROW_3); \ - teensypin_write(register, operation, ROW_4); \ - teensypin_write(register, operation, ROW_5); } \ +#define teensypin_write_all_row(register, operation) \ + do { \ + teensypin_write(register, operation, ROW_0); \ + teensypin_write(register, operation, ROW_1); \ + teensypin_write(register, operation, ROW_2); \ + teensypin_write(register, operation, ROW_3); \ + teensypin_write(register, operation, ROW_4); \ + teensypin_write(register, operation, ROW_5); } \ while(0) -#define teensypin_write_all_column(register, operation) \ - do { \ - teensypin_write(register, operation, COLUMN_0); \ - teensypin_write(register, operation, COLUMN_1); \ - teensypin_write(register, operation, COLUMN_2); \ - teensypin_write(register, operation, COLUMN_3); \ - teensypin_write(register, operation, COLUMN_4); \ - teensypin_write(register, operation, COLUMN_5); \ - teensypin_write(register, operation, COLUMN_6); } \ +#define teensypin_write_all_column(register, operation) \ + do { \ + teensypin_write(register, operation, COLUMN_0); \ + teensypin_write(register, operation, COLUMN_1); \ + teensypin_write(register, operation, COLUMN_2); \ + teensypin_write(register, operation, COLUMN_3); \ + teensypin_write(register, operation, COLUMN_4); \ + teensypin_write(register, operation, COLUMN_5); \ + teensypin_write(register, operation, COLUMN_6); } \ while(0) #define SET |= @@ -109,12 +113,17 @@ #define COLUMN_5 D, 3 #define COLUMN_6 C, 6 +// ---------------------------------------------------------------------------- /* returns * - success: 0 */ uint8_t teensy_init(void) { - CPU_PRESCALE(CPU_16MHz); // speed should match F_CPU in makefile + // CPU speed : should match F_CPU in makefile + #if F_CPU != 16000000 + #error "Expecting different CPU frequency" + #endif + CPU_PRESCALE(CPU_16MHz); // onboard LED // (tied to GND for hardware convenience) diff --git a/src/keyboard/ergodox/teensy-2-0.md b/src/keyboard/ergodox/controller/teensy-2-0.md similarity index 100% rename from src/keyboard/ergodox/teensy-2-0.md rename to src/keyboard/ergodox/controller/teensy-2-0.md diff --git a/src/keyboard/ergodox/layout.h b/src/keyboard/ergodox/layout.h index 125f34d..51e3d75 100644 --- a/src/keyboard/ergodox/layout.h +++ b/src/keyboard/ergodox/layout.h @@ -1,5 +1,5 @@ /* ---------------------------------------------------------------------------- - * ergoDOX layout : exports + * ergoDOX : layout exports * * Different layouts are included by modifying a variable in the makefile. * ---------------------------------------------------------------------------- @@ -8,121 +8,16 @@ * Project located at * ------------------------------------------------------------------------- */ -#ifndef LAYOUT_h - #define LAYOUT_h - #include - #include "lib/data-types/common.h" - #include "lib/key-functions.h" // for `kbfun_funptr_t` +#ifndef KEYBOARD__ERGODOX__LAYOUT_h + #define KEYBOARD__ERGODOX__LAYOUT_h - #include "matrix.h" // for number of rows and columns + // -------------------------------------------------------------------- // include the appropriate keyboard layout header - // for: - // - possible non-default number of layers - // - possible non-default layout matrix definitions - // - possible non-default layout 'get' and 'set' definitions - #undef _str - #undef _expstr - #undef _inc - #define _str(s) #s // stringify - #define _expstr(s) _str(s) // expand -> stringify - #define _inc _expstr(layout/MAKEFILE_KEYBOARD_LAYOUT.h) // inc(lude) - #include _inc - #undef _str - #undef _expstr - #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 - // may redefine them if they wish and use RAM, EEPROM, or any - // combination of the three, as long as they maintain the same - // interface. - // - // - if the macro is overridden, the matrix declaration must be too, - // and vice versa. - // - // - 'set' functions are optional, and should be defined in the layout - // specific '.h'. they'll require the use of the EEPROM, possibly in - // clever conjunction with one of the other two memories (since the - // EEPROM is small). custom key functions will also need to be - // written. - // - // - to override these macros with real functions, set the macro equal - // to itself (e.g. `#define kb_layout_get kb_layout_get`) and provide - // function prototypes in the layout specific '.h' - - #ifndef kb_layout_get - extern uint8_t PROGMEM \ - _kb_layout[KB_LAYERS][KB_ROWS][KB_COLUMNS]; - - #define kb_layout_get(layer,row,column) \ - ( (uint8_t) \ - pgm_read_byte(&( \ - _kb_layout[layer][row][column] )) ) - #endif - - #ifndef kb_layout_press_get - 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_press[layer][row][column] )) ) - #endif - - #ifndef kb_layout_release_get - 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_release[layer][row][column] )) ) - - #endif - - - // default logical LED macros (all defined to nothing) - #ifndef kb_led_num_on - #define kb_led_num_on() - #endif - #ifndef kb_led_num_off - #define kb_led_num_off() - #endif - #ifndef kb_led_caps_on - #define kb_led_caps_on() - #endif - #ifndef kb_led_caps_off - #define kb_led_caps_off() - #endif - #ifndef kb_led_scroll_on - #define kb_led_scroll_on() - #endif - #ifndef kb_led_scroll_off - #define kb_led_scroll_off() - #endif - #ifndef kb_led_compose_on - #define kb_led_compose_on() - #endif - #ifndef kb_led_compose_off - #define kb_led_compose_off() - #endif - #ifndef kb_led_kana_on - #define kb_led_kana_on() - #endif - #ifndef kb_led_kana_off - #define kb_led_kana_off() - #endif + #include "src/lib/conditional-include.h" + #define INCLUDE EXP_STR( ./layout/MAKEFILE_KEYBOARD_LAYOUT.h ) + #include INCLUDE #endif diff --git a/src/keyboard/ergodox/layout.md b/src/keyboard/ergodox/layout.md index 732fac7..dade59a 100644 --- a/src/keyboard/ergodox/layout.md +++ b/src/keyboard/ergodox/layout.md @@ -3,33 +3,22 @@ Different layouts are included by modifying a variable in the makefile. To write a new one: -* You must implement everything defined in [layout.h] (layout.h). Take a look - at existing layouts in the 'layout' subdir. - * Currently, see [qwerty.c] (layout/qwerty.c) and [qwerty.h] - (layout/qwerty.h). The latter is only important if you want more than - one layer. And I still need to write the functions to make that possible - (though that shouldn't be hard, I just haven't gotten to it yet). But - (at least for the QWERTY and Dvorak layouts I'd really like to include) - if you indicate it clealy in the layout, and provide complete - initializations for `kb_layout[][][]`, `kb_layout_press[][][]`, and - `kb_layout_release[][][]`, I'll make sure it gets working. -* The number of layers must be defined in the layout *.h file. +* Create new layout files under [layout] (layout) (see [qwerty.h] + (layout/qwerty.h) and [qwerty.c] (layout/qwerty.c)). * Use `0` for no-operation (unused) keys, and `NULL` for no-operation (unused) functions. -* See [matrix.md] (matrix.md) for how the key matrix maps to hardware. +* See [matrix/mapping.h] (matrix/mapping.h) for how the key matrix maps to + hardware. * See [keyboard-usage-page--short-names.h] (../../lib/_usb/keyboard-usage-page--short-names.h) for available keycodes. -* See [key-functions.c] (../../lib/_key-functions.c) for what functions keys +* See [key-functions.c] (../../lib/key-functions.c) for what functions keys can call. -* See [_defaults.h] (layout/_defaults.h) for default function layers and - aliases. ## notes -* Each full layer takes 420 bytes of memory, wherever it's stored. (The matrix - size is 12x7, keycodes are 1 byte each, and function pointers are 2 bytes - each.) +* Each full layer takes 420 bytes of memory (the matrix size is 12x7, keycodes + are 1 byte each, and function pointers are 2 bytes each). ------------------------------------------------------------------------------- diff --git a/src/keyboard/ergodox/layout/default--led-control.h b/src/keyboard/ergodox/layout/default--led-control.h new file mode 100644 index 0000000..a977340 --- /dev/null +++ b/src/keyboard/ergodox/layout/default--led-control.h @@ -0,0 +1,86 @@ +/* ---------------------------------------------------------------------------- + * ergoDOX : layout : default LED control + * ---------------------------------------------------------------------------- + * Copyright (c) 2012 Ben Blazak + * Released under The MIT License (MIT) (see "license.md") + * Project located at + * ------------------------------------------------------------------------- */ + + +#ifndef KEYBOARD__ERGODOX__LAYOUT__DEFAULT__LED_CONTROL_h + #define KEYBOARD__ERGODOX__LAYOUT__DEFAULT__LED_CONTROL_h + + // -------------------------------------------------------------------- + + /* + * state and delay macros + */ + + #ifndef kb_led_state_power_on + #define kb_led_state_power_on() do { \ + _kb_led_all_set_percent(0.05); \ + _kb_led_all_on(); \ + } while(0) + #endif + + // note: need to delay for a total of ~1 second + #ifndef kb_led_delay_usb_init + #define kb_led_delay_usb_init() do { \ + _kb_led_1_set_percent(0.5); \ + _delay_ms(333); \ + _kb_led_2_set_percent(0.5); \ + _delay_ms(333); \ + _kb_led_3_set_percent(0.5); \ + _delay_ms(333); \ + } while(0) + #endif + + #ifndef kb_led_state_ready + #define kb_led_state_ready() do { \ + _kb_led_all_off(); \ + _kb_led_all_set_percent(0.5); \ + } while(0) + #endif + + + /* + * logical LED macros + * - unused macros should be defined to nothing + * - they all are here, because they really need to be specified in + * the layout specific file + */ + + #ifndef kb_led_num_on + #define kb_led_num_on() + #endif + #ifndef kb_led_num_off + #define kb_led_num_off() + #endif + #ifndef kb_led_caps_on + #define kb_led_caps_on() + #endif + #ifndef kb_led_caps_off + #define kb_led_caps_off() + #endif + #ifndef kb_led_scroll_on + #define kb_led_scroll_on() + #endif + #ifndef kb_led_scroll_off + #define kb_led_scroll_off() + #endif + #ifndef kb_led_compose_on + #define kb_led_compose_on() + #endif + #ifndef kb_led_compose_off + #define kb_led_compose_off() + #endif + #ifndef kb_led_kana_on + #define kb_led_kana_on() + #endif + #ifndef kb_led_kana_off + #define kb_led_kana_off() + #endif + + +#endif + diff --git a/src/keyboard/ergodox/layout/default--matrix-control.h b/src/keyboard/ergodox/layout/default--matrix-control.h new file mode 100644 index 0000000..247f0b0 --- /dev/null +++ b/src/keyboard/ergodox/layout/default--matrix-control.h @@ -0,0 +1,80 @@ +/* ---------------------------------------------------------------------------- + * ergoDOX : layout : default matrix control + * ---------------------------------------------------------------------------- + * Copyright (c) 2012 Ben Blazak + * Released under The MIT License (MIT) (see "license.md") + * Project located at + * ------------------------------------------------------------------------- */ + + +#ifndef KEYBOARD__ERGODOX__LAYOUT__DEFAULT__MATRIX_CONTROL_h + #define KEYBOARD__ERGODOX__LAYOUT__DEFAULT__MATRIX_CONTROL_h + + #include + #include + #include "src/lib/key-functions/public.h" + #include "../matrix.h" + + // -------------------------------------------------------------------- + + #ifndef KB_LAYERS + #define KB_LAYERS 10 + #endif + + // -------------------------------------------------------------------- + + /* + * matrix 'get' macros, and `extern` matrix declarations + * + * These are written for when the matrices are stored solely in Flash. + * Layouts may redefine them if they wish and use Flash, RAM, EEPROM, + * or any combination of the three, as long as they maintain the same + * interface. + * + * - If the macro is overridden, the matrix declaration must be too, + * and vice versa. + * + * - 'set' functions are optional, and should be defined in the layout + * specific '.h'. They'll require the use of the EEPROM, possibly in + * clever conjunction with one of the other two memories (since the + * EEPROM is small). Custom key functions will also need to be + * written. + * + * - To override these macros with real functions, set the macro equal + * to itself (e.g. `#define kb_layout_get kb_layout_get`) and provide + * function prototypes, in the layout specific '.h' + */ + + #ifndef kb_layout_get + extern uint8_t PROGMEM \ + _kb_layout[KB_LAYERS][KB_ROWS][KB_COLUMNS]; + + #define kb_layout_get(layer,row,column) \ + ( (uint8_t) \ + pgm_read_byte(&( \ + _kb_layout[layer][row][column] )) ) + #endif + + #ifndef kb_layout_press_get + 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_press[layer][row][column] )) ) + #endif + + #ifndef kb_layout_release_get + 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_release[layer][row][column] )) ) + + #endif + +#endif + diff --git a/src/keyboard/ergodox/layout/qwerty.c b/src/keyboard/ergodox/layout/qwerty.c index 8e1dcc5..f8d5dd7 100644 --- a/src/keyboard/ergodox/layout/qwerty.c +++ b/src/keyboard/ergodox/layout/qwerty.c @@ -1,7 +1,7 @@ /* ---------------------------------------------------------------------------- * ergoDOX layout : QWERTY * - * This is an overly basic implementation. It needs to be replaced. + * TODO: This is a temporary version. It will be replaced later. * ---------------------------------------------------------------------------- * Copyright (c) 2012 Ben Blazak * Released under The MIT License (MIT) (see "license.md") @@ -9,33 +9,40 @@ * ------------------------------------------------------------------------- */ +#include +#include #include -#include "lib/data-types/common.h" -#include "lib/usb/usage-page/keyboard--short-names.h" -#include "lib/key-functions.h" - +#include "src/lib/usb/usage-page/keyboard--short-names.h" +#include "src/lib/key-functions/public.h" #include "../matrix.h" #include "../layout.h" +// ---------------------------------------------------------------------------- +// ---------------------------------------------------------------------------- // aliases +// --- basic #define f_prrel &kbfun_press_release #define f_toggl &kbfun_toggle #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 +// --- device +#define f_btldr &kbfun_jump_to_bootloader +// --- numpad #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 - +// --- special +#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 +// ---------------------------------------------------------------------------- +// ---------------------------------------------------------------------------- uint8_t PROGMEM _kb_layout[KB_LAYERS][KB_ROWS][KB_COLUMNS] = { -// ---------------------------------------------------------------------------- - MATRIX_LAYER( // layer 0: default + // -------------------------------------------------------------------- + KB_MATRIX_LAYER( // layout: layer 0: default // unused 0, // left hand @@ -56,8 +63,8 @@ _bracketL, _Q, _W, _E, _R, _T, _esc, 0, _space, _ctrlR, 0, _enter, _altR, _pageU, _pageD ), -// ---------------------------------------------------------------------------- - MATRIX_LAYER( // layer 1: function and symbol keys + // -------------------------------------------------------------------- + KB_MATRIX_LAYER( // layout: layer 1: function and symbol keys // unused 0, // left hand @@ -78,8 +85,8 @@ _ctrlR, 0, _enter, 0, _space, _ctrlR, 0, _enter, _altR, _pageU, _pageD ), -// ---------------------------------------------------------------------------- - MATRIX_LAYER( // layer 2: numpad + // -------------------------------------------------------------------- + KB_MATRIX_LAYER( // layout: layer 2: numpad // unused 0, // left hand @@ -92,7 +99,6 @@ _ctrlR, 0, _enter, 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, @@ -101,13 +107,14 @@ _ctrlR, 0, _enter, 0, 0, 0, 0, 0, 0, 0, 0 ) -// ---------------------------------------------------------------------------- + // -------------------------------------------------------------------- }; +// ---------------------------------------------------------------------------- kbfun_funptr_t PROGMEM _kb_layout_press[KB_LAYERS][KB_ROWS][KB_COLUMNS] = { -// ---------------------------------------------------------------------------- - MATRIX_LAYER( // layer 0: default + // -------------------------------------------------------------------- + KB_MATRIX_LAYER( // press: layer 0: default // unused NULL, // left hand @@ -128,8 +135,8 @@ f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, NULL,f_prrel, f_prrel, NULL,f_prrel, f_prrel,f_prrel,f_prrel ), -// ---------------------------------------------------------------------------- - MATRIX_LAYER( // layer 1: function and symbol keys + // -------------------------------------------------------------------- + KB_MATRIX_LAYER( // press: layer 1: function and symbol keys // unused NULL, // left hand @@ -150,8 +157,8 @@ f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, NULL,f_prrel, f_prrel, NULL,f_prrel, f_prrel,f_prrel,f_prrel ), -// ---------------------------------------------------------------------------- - MATRIX_LAYER( // layer 2: numpad + // -------------------------------------------------------------------- + KB_MATRIX_LAYER( // press: layer 2: numpad // unused NULL, // left hand @@ -172,13 +179,14 @@ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL ) -// ---------------------------------------------------------------------------- + // -------------------------------------------------------------------- }; +// ---------------------------------------------------------------------------- kbfun_funptr_t PROGMEM _kb_layout_release[KB_LAYERS][KB_ROWS][KB_COLUMNS] = { -// ---------------------------------------------------------------------------- - MATRIX_LAYER( // layer 0: default + // -------------------------------------------------------------------- + KB_MATRIX_LAYER( // release: layer 0: default // unused NULL, // left hand @@ -199,8 +207,8 @@ f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, NULL,f_prrel, f_prrel, NULL,f_prrel, f_prrel,f_prrel,f_prrel ), -// ---------------------------------------------------------------------------- - MATRIX_LAYER( // layer 1: function and symbol keys + // -------------------------------------------------------------------- + KB_MATRIX_LAYER( // release: layer 1: function and symbol keys // unused NULL, // left hand @@ -221,8 +229,8 @@ f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, NULL,f_prrel, f_prrel, NULL,f_prrel, f_prrel,f_prrel,f_prrel ), -// ---------------------------------------------------------------------------- - MATRIX_LAYER( // layer 2: numpad + // -------------------------------------------------------------------- + KB_MATRIX_LAYER( // release: layer 2: numpad // unused NULL, // left hand @@ -243,9 +251,10 @@ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL ), -// ---------------------------------------------------------------------------- - MATRIX_LAYER( // layer 3: nothing (just making sure unused functions - // don't get compiled out) + // -------------------------------------------------------------------- + KB_MATRIX_LAYER( // release: layer 3: nothing (just making sure unused + // functions don't get compiled + // out) // unused NULL, // other @@ -259,6 +268,6 @@ f_2kcap, NULL, NULL, NULL, NULL, NULL, NULL, NULL, f_np_to, NULL, NULL, NULL, NULL, NULL, NULL, NULL, f_np_on, NULL, NULL, NULL, NULL, NULL, NULL, NULL, f_np_of, NULL, NULL, NULL, NULL, NULL, NULL, NULL ) -// ---------------------------------------------------------------------------- + // -------------------------------------------------------------------- }; diff --git a/src/keyboard/ergodox/layout/qwerty.h b/src/keyboard/ergodox/layout/qwerty.h index a424938..dd0fa66 100644 --- a/src/keyboard/ergodox/layout/qwerty.h +++ b/src/keyboard/ergodox/layout/qwerty.h @@ -1,5 +1,5 @@ /* ---------------------------------------------------------------------------- - * ergoDOX layout : QWERTY : exports + * ergoDOX : layout : QWERTY : exports * ---------------------------------------------------------------------------- * Copyright (c) 2012 Ben Blazak * Released under The MIT License (MIT) (see "license.md") @@ -7,11 +7,12 @@ * ------------------------------------------------------------------------- */ -#ifndef LAYOUT_QWERTY_h - #define LAYOUT_QWERTY_h +#ifndef KEYBOARD__ERGODOX__LAYOUT__QWERTY_h + #define KEYBOARD__ERGODOX__LAYOUT__QWERTY_h - #include "../led.h" + #include "../controller.h" + // -------------------------------------------------------------------- #define kb_led_num_on() _kb_led_1_on() #define kb_led_num_off() _kb_led_1_off() @@ -20,5 +21,10 @@ #define kb_led_scroll_on() _kb_led_3_on() #define kb_led_scroll_off() _kb_led_3_off() + // -------------------------------------------------------------------- + + #include "./default--led-control.h" + #include "./default--matrix-control.h" + #endif diff --git a/src/keyboard/ergodox/led.h b/src/keyboard/ergodox/led.h deleted file mode 100644 index 1a5ff89..0000000 --- a/src/keyboard/ergodox/led.h +++ /dev/null @@ -1,46 +0,0 @@ -/* ---------------------------------------------------------------------------- - * led stuff that isn't microprocessor or layout specific - * - * 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 (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") - * Project located at - * ------------------------------------------------------------------------- */ - - -#ifndef LED_h - #define LED_h - - #include - - #include "teensy-2-0.h" // for low-level led macros - - - #define kb_led_state_power_on() do { \ - _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 { \ - _kb_led_1_set_percent(0.5); \ - _delay_ms(333); \ - _kb_led_2_set_percent(0.5); \ - _delay_ms(333); \ - _kb_led_3_set_percent(0.5); \ - _delay_ms(333); \ - } while(0) - - #define kb_led_state_ready() do { \ - _kb_led_all_off(); \ - _kb_led_all_set_percent(0.5); \ - } while(0) - -#endif - diff --git a/src/keyboard/ergodox/matrix.h b/src/keyboard/ergodox/matrix.h index ee9c9ea..2442ced 100644 --- a/src/keyboard/ergodox/matrix.h +++ b/src/keyboard/ergodox/matrix.h @@ -1,5 +1,5 @@ /* ---------------------------------------------------------------------------- - * ergoDOX: keyboard matrix specific exports + * ergoDOX : matrix specific exports * ---------------------------------------------------------------------------- * Copyright (c) 2012 Ben Blazak * Released under The MIT License (MIT) (see "license.md") @@ -7,17 +7,15 @@ * ------------------------------------------------------------------------- */ -#ifndef MATRIX_h - #define MATRIX_h +#ifndef KEYBOARD__ERGODOX__MATRIX_h + #define KEYBOARD__ERGODOX__MATRIX_h - #include "lib/data-types/common.h" + // -------------------------------------------------------------------- #define KB_ROWS 12 // must match real life #define KB_COLUMNS 7 // must match real life - extern bool (*kb_is_pressed)[KB_ROWS][KB_COLUMNS]; - 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 @@ -42,7 +40,7 @@ * right hand : cols 0..6, rows 0..5 * -------------------------------------------------------------------- */ - #define MATRIX_LAYER( \ + #define KB_MATRIX_LAYER( \ /* for unused positions */ \ na, \ \ @@ -81,7 +79,7 @@ { kB0,kB1,kB2,kB3,kB4,kB5,kB6 } } - #define MATRIX_LAYER_SET_ALL(na, kxx) \ + #define KB_MATRIX_LAYER_SET_ALL(na, kxx) \ LAYER( \ na, \ \ @@ -103,6 +101,5 @@ kxx,kxx,kxx, \ kxx,kxx,kxx ) \ - #endif diff --git a/src/keyboard/layout.h b/src/keyboard/layout.h new file mode 100644 index 0000000..d8edaed --- /dev/null +++ b/src/keyboard/layout.h @@ -0,0 +1,16 @@ +/* ---------------------------------------------------------------------------- + * layout specific exports + * + * Files for different keyboards are used by modifying a variable in the + * Makefile + * ---------------------------------------------------------------------------- + * Copyright (c) 2012 Ben Blazak + * Released under The MIT License (MIT) (see "license.md") + * Project located at + * ------------------------------------------------------------------------- */ + + +#include "src/lib/conditional-include.h" +#define INCLUDE EXP_STR( ./MAKEFILE_KEYBOARD/layout.h ) +#include INCLUDE + diff --git a/src/keyboard/matrix.h b/src/keyboard/matrix.h new file mode 100644 index 0000000..1dadb9a --- /dev/null +++ b/src/keyboard/matrix.h @@ -0,0 +1,16 @@ +/* ---------------------------------------------------------------------------- + * matrix specific exports + * + * Files for different keyboards are used by modifying a variable in the + * Makefile + * ---------------------------------------------------------------------------- + * Copyright (c) 2012 Ben Blazak + * Released under The MIT License (MIT) (see "license.md") + * Project located at + * ------------------------------------------------------------------------- */ + + +#include "src/lib/conditional-include.h" +#define INCLUDE EXP_STR( ./MAKEFILE_KEYBOARD/matrix.h ) +#include INCLUDE + diff --git a/src/lib/data-types/common.h b/src/lib/conditional-include.h similarity index 73% rename from src/lib/data-types/common.h rename to src/lib/conditional-include.h index 8f537da..67ff6d5 100644 --- a/src/lib/data-types/common.h +++ b/src/lib/conditional-include.h @@ -1,5 +1,5 @@ /* ---------------------------------------------------------------------------- - * Common data types + * Macros to help with conditional includes * ---------------------------------------------------------------------------- * Copyright (c) 2012 Ben Blazak * Released under The MIT License (MIT) (see "license.md") @@ -7,12 +7,7 @@ * ------------------------------------------------------------------------- */ -#ifndef DATA_TYPES_COMMON_h - #define DATA_TYPES_COMMON_h - - #include - #include - #include - -#endif +#undef INCLUDE +#define STR(s) #s // stringify +#define EXP_STR(s) STR(s) // expand -> stringify diff --git a/src/lib/data-types/linked-list.c b/src/lib/data-types/linked-list.c index 3244a1d..8924e23 100644 --- a/src/lib/data-types/linked-list.c +++ b/src/lib/data-types/linked-list.c @@ -7,11 +7,12 @@ * ------------------------------------------------------------------------- */ +#include +#include #include -#include "lib/data-types/common.h" - -#include "linked-list.h" +#include "./linked-list.h" +// ---------------------------------------------------------------------------- // local macros (undefined later) #define _NEW_POINTER(type, name) type * name = (type *) malloc(sizeof(type)) @@ -19,6 +20,7 @@ #define _node_t linked_list_node_t #define _data_t LINKED_LIST_DATA_TYPE +// ---------------------------------------------------------------------------- /* * new() @@ -225,6 +227,7 @@ void linked_list_free(_list_t * list) { free(list); } +// ---------------------------------------------------------------------------- // 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 525dcb9..c8327c5 100644 --- a/src/lib/data-types/linked-list.h +++ b/src/lib/data-types/linked-list.h @@ -10,14 +10,16 @@ #ifndef DATA_TYPES_LINKED_LIST_h #define DATA_TYPES_LINKED_LIST_h - #include "lib/data-types/common.h" + #include + // -------------------------------------------------------------------- // default data type for the list #ifndef LINKED_LIST_DATA_TYPE #define LINKED_LIST_DATA_TYPE uint8_t #endif + // -------------------------------------------------------------------- // structs struct linked_list_node { @@ -26,7 +28,7 @@ }; struct linked_list { - uint8_t length; // 'uint8_t' to save ram + uint8_t length; // 'uint8_t' to save memory struct linked_list_node * head; struct linked_list_node * tail; }; diff --git a/src/lib/data-types/list.h b/src/lib/data-types/list.h index be63a24..9bd6a84 100644 --- a/src/lib/data-types/list.h +++ b/src/lib/data-types/list.h @@ -10,13 +10,14 @@ #ifndef DATA_TYPES_LIST_h #define DATA_TYPES_LIST_h + // for "linked-list.h" #ifdef LIST_DATA_TYPE #define LINKED_LIST_DATA_TYPE LIST_DATA_TYPE #endif - #include "linked-list.h" - typedef linked_list_t * list_t; - typedef linked_list_node_t * list_node_t; + #include "./linked-list.h" + + // -------------------------------------------------------------------- #define list_new linked_list_new #define list_insert linked_list_insert @@ -25,5 +26,10 @@ #define list_copy linked_list_copy #define list_free linked_list_free + // -------------------------------------------------------------------- + + typedef linked_list_t * list_t; + typedef linked_list_node_t * list_node_t; + #endif diff --git a/src/lib/data-types/queue.h b/src/lib/data-types/queue.h index c3049f5..32354f2 100644 --- a/src/lib/data-types/queue.h +++ b/src/lib/data-types/queue.h @@ -10,13 +10,14 @@ #ifndef DATA_TYPES_QUEUE_h #define DATA_TYPES_QUEUE_h + // for "linked-list.h" #ifdef QUEUE_DATA_TYPE #define LINKED_LIST_DATA_TYPE QUEUE_DATA_TYPE #endif - #include "linked-list.h" - typedef linked_list_t * queue_t; - typedef linked_list_node_t * queue_node_t; + #include "./linked-list.h" + + // -------------------------------------------------------------------- #define queue_new linked_list_new #define queue_append(list, data) linked_list_insert(list, -1, data) @@ -25,5 +26,10 @@ #define queue_copy linked_list_copy #define queue_free linked_list_free + // -------------------------------------------------------------------- + + typedef linked_list_t * queue_t; + typedef linked_list_node_t * queue_node_t; + #endif diff --git a/src/lib/data-types/stack.h b/src/lib/data-types/stack.h index 46c9407..532caa5 100644 --- a/src/lib/data-types/stack.h +++ b/src/lib/data-types/stack.h @@ -10,13 +10,14 @@ #ifndef DATA_TYPES_STACK_h #define DATA_TYPES_STACK_h + // for "linked-list.h" #ifdef STACK_DATA_TYPE #define LINKED_LIST_DATA_TYPE STACK_DATA_TYPE #endif - #include "linked-list.h" - typedef linked_list_t * stack_t; - typedef linked_list_node_t * stack_node_t; + #include "./linked-list.h" + + // -------------------------------------------------------------------- #define stack_new linked_list_new #define stack_push(list, data) linked_list_insert(list, 0, data) @@ -25,5 +26,10 @@ #define stack_copy linked_list_copy #define stack_free linked_list_free + // -------------------------------------------------------------------- + + typedef linked_list_t * stack_t; + typedef linked_list_node_t * stack_node_t; + #endif diff --git a/src/lib/key-functions.c b/src/lib/key-functions.c deleted file mode 100644 index 72b1ea9..0000000 --- a/src/lib/key-functions.c +++ /dev/null @@ -1,510 +0,0 @@ -/* ---------------------------------------------------------------------------- - * key functions: code - * - * These functions may do.. pretty much anything rational that thay like. If - * they want keycodes to be sent to the host in an aggrate report, they're - * responsible for modifying the appropriate report variables. - * ---------------------------------------------------------------------------- - * Copyright (c) 2012 Ben Blazak - * Released under The MIT License (MIT) (see "license.md") - * Project located at - * ------------------------------------------------------------------------- */ - - -#include -#include "lib-other/pjrc/usb_keyboard/usb_keyboard.h" -#include "lib/data-types/common.h" -#include "lib/usb/usage-page/keyboard.h" -#include "keyboard.h" - -#include "key-functions.h" -#include "key-functions--private.h" - - -// ---------------------------------------------------------------------------- -// public functions (not for keys) -// ---------------------------------------------------------------------------- - -/* - * 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 -// ---------------------------------------------------------------------------- - -/* - * 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, to be sent at - * the end of the current cycle (see main.c) - */ -void _press_release(bool pressed, uint8_t keycode) { - // no-op - if (keycode == 0) - return; - - // modifier keys - switch (keycode) { - case KEY_LeftControl: (pressed) - ? (keyboard_modifier_keys |= (1<<0)) - : (keyboard_modifier_keys &= ~(1<<0)); - return; - case KEY_LeftShift: (pressed) - ? (keyboard_modifier_keys |= (1<<1)) - : (keyboard_modifier_keys &= ~(1<<1)); - return; - case KEY_LeftAlt: (pressed) - ? (keyboard_modifier_keys |= (1<<2)) - : (keyboard_modifier_keys &= ~(1<<2)); - return; - case KEY_LeftGUI: (pressed) - ? (keyboard_modifier_keys |= (1<<3)) - : (keyboard_modifier_keys &= ~(1<<3)); - return; - case KEY_RightControl: (pressed) - ? (keyboard_modifier_keys |= (1<<4)) - : (keyboard_modifier_keys &= ~(1<<4)); - return; - case KEY_RightShift: (pressed) - ? (keyboard_modifier_keys |= (1<<5)) - : (keyboard_modifier_keys &= ~(1<<5)); - return; - case KEY_RightAlt: (pressed) - ? (keyboard_modifier_keys |= (1<<6)) - : (keyboard_modifier_keys &= ~(1<<6)); - return; - 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 (pressed) { - if (keyboard_keys[i] == 0) { - keyboard_keys[i] = keycode; - return; - } - } else { - if (keyboard_keys[i] == keycode) { - keyboard_keys[i] = 0; - return; - } - } - } -} - -/* - * 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 - * - 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) - * - * 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 layer, - uint8_t * current_layer, - uint8_t (*current_layers)[KB_ROWS][KB_COLUMNS] ) { - - // don't switch to out-of-bounds layers - if ( layer < 0 || layer >= KB_LAYERS ) - return; - - for (uint8_t row=0; row= KB_LAYERS ) - return; - - for (uint8_t row=0; row 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 key 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 - */ -void kbfun_2_keys_capslock_press_release( KBFUN_FUNCTION_ARGS ) { - 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(pressed_, keycode_); - - // 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(false, KEY_LeftShift); - _press_release(false, KEY_RightShift); - - // press capslock, then release it - _press_release(true, KEY_CapsLock); - usb_keyboard_send(); - _press_release(false, KEY_CapsLock); - usb_keyboard_send(); - - // restore the state of left and right shift - if (lshift_pressed) - _press_release(true, KEY_LeftShift); - if (rshift_pressed) - _press_release(true, KEY_RightShift); - } - - if (pressed_) keys_pressed++; -} - - -// 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 - * - * 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 either is released (even if the other is - * still pressed) - * ------------------------------------------------------------------------- */ - -// 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 - -// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . - -// vars -static bool L(numpad_activated) = false; -static bool L(layer_mask)[KB_ROWS][KB_COLUMNS] = - MATRIX_LAYER( - // 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, 0, 0, - - // 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, 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) -// ---------------------------------------------------------------------------- - -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< - * Released under The MIT License (MIT) (see "license.md") - * Project located at - * ------------------------------------------------------------------------- */ - - -#ifndef KEY_FUNCTIONS_h - #define KEY_FUNCTIONS_h - - #include "lib/data-types/common.h" - - // -------------------------------------------------------------------- - // 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 - // -------------------------------------------------------------------- - - - #define KBFUN_FUNCTION_ARGS \ - 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] - - typedef void (*kbfun_funptr_t)( 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_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 - diff --git a/src/lib/key-functions/private.c b/src/lib/key-functions/private.c new file mode 100644 index 0000000..6d72fee --- /dev/null +++ b/src/lib/key-functions/private.c @@ -0,0 +1,173 @@ +/* ---------------------------------------------------------------------------- + * key functions : private : code + * ---------------------------------------------------------------------------- + * Copyright (c) 2012 Ben Blazak + * Released under The MIT License (MIT) (see "license.md") + * Project located at + * ------------------------------------------------------------------------- */ + + +#include +#include +#include "src/lib-other/pjrc/usb_keyboard/usb_keyboard.h" +#include "src/lib/usb/usage-page/keyboard.h" +#include "src/keyboard/layout.h" +#include "src/keyboard/matrix.h" +#include "./public.h" + +// ---------------------------------------------------------------------------- + +/* + * 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, to be sent at + * the end of the current cycle (see main.c) + */ +void _kbfun_press_release(bool pressed, uint8_t keycode) { + // no-op + if (keycode == 0) + return; + + // modifier keys + switch (keycode) { + case KEY_LeftControl: (pressed) + ? (keyboard_modifier_keys |= (1<<0)) + : (keyboard_modifier_keys &= ~(1<<0)); + return; + case KEY_LeftShift: (pressed) + ? (keyboard_modifier_keys |= (1<<1)) + : (keyboard_modifier_keys &= ~(1<<1)); + return; + case KEY_LeftAlt: (pressed) + ? (keyboard_modifier_keys |= (1<<2)) + : (keyboard_modifier_keys &= ~(1<<2)); + return; + case KEY_LeftGUI: (pressed) + ? (keyboard_modifier_keys |= (1<<3)) + : (keyboard_modifier_keys &= ~(1<<3)); + return; + case KEY_RightControl: (pressed) + ? (keyboard_modifier_keys |= (1<<4)) + : (keyboard_modifier_keys &= ~(1<<4)); + return; + case KEY_RightShift: (pressed) + ? (keyboard_modifier_keys |= (1<<5)) + : (keyboard_modifier_keys &= ~(1<<5)); + return; + case KEY_RightAlt: (pressed) + ? (keyboard_modifier_keys |= (1<<6)) + : (keyboard_modifier_keys &= ~(1<<6)); + return; + 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 (pressed) { + if (keyboard_keys[i] == 0) { + keyboard_keys[i] = keycode; + return; + } + } else { + if (keyboard_keys[i] == keycode) { + keyboard_keys[i] = 0; + return; + } + } + } +} + +/* + * 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 + * - 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) + * + * 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 _kbfun_layer_set_current( + uint8_t layer, + uint8_t * current_layer, + uint8_t (*current_layers)[KB_ROWS][KB_COLUMNS] ) { + + // don't switch to out-of-bounds layers + if ( layer < 0 || layer >= KB_LAYERS ) + return; + + for (uint8_t row=0; row= KB_LAYERS ) + return; + + for (uint8_t row=0; row * Released under The MIT License (MIT) (see "license.md") @@ -10,19 +10,23 @@ * ------------------------------------------------------------------------- */ -#ifndef KEY_FUNCTIONS_h_PRIVATE - #define KEY_FUNCTIONS_h_PRIVATE +#ifndef LIB__KEY_FUNCTIONS__INTERNAL_h + #define LIB__KEY_FUNCTIONS__INTERNAL_h - void _press_release(bool pressed, uint8_t keycode); - void _layer_set_current( + #include "./public.h" + + // -------------------------------------------------------------------- + + void _kbfun_press_release(bool pressed, uint8_t keycode); + void _kbfun_layer_set_current( uint8_t value, uint8_t * current_layer, uint8_t (*current_layers_)[KB_ROWS][KB_COLUMNS] ); - void _layer_set_mask( + void _kbfun_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); + bool _kbfun_is_pressed(uint8_t keycode); #endif diff --git a/src/lib/key-functions/public.h b/src/lib/key-functions/public.h new file mode 100644 index 0000000..fd9b824 --- /dev/null +++ b/src/lib/key-functions/public.h @@ -0,0 +1,55 @@ +/* ---------------------------------------------------------------------------- + * key functions : public exports + * ---------------------------------------------------------------------------- + * Copyright (c) 2012 Ben Blazak + * Released under The MIT License (MIT) (see "license.md") + * Project located at + * ------------------------------------------------------------------------- */ + + +#ifndef LIB__KEY_FUNCTIONS__COMMON_h + #define LIB__KEY_FUNCTIONS__COMMON_h + + #include + #include + #include "src/keyboard/matrix.h" + + // -------------------------------------------------------------------- + + #define KBFUN_FUNCTION_ARGS \ + 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] + + // -------------------------------------------------------------------- + + typedef void (*kbfun_funptr_t)( KBFUN_FUNCTION_ARGS ); + + // -------------------------------------------------------------------- + + // basic + 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 ); + + // device + void kbfun_jump_to_bootloader ( KBFUN_FUNCTION_ARGS ); + + // numpad + void kbfun_layermask_numpad_toggle ( KBFUN_FUNCTION_ARGS ); + void kbfun_layermask_numpad_on ( KBFUN_FUNCTION_ARGS ); + void kbfun_layermask_numpad_off ( KBFUN_FUNCTION_ARGS ); + + // special + 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 ); + +#endif + diff --git a/src/lib/key-functions/public/basic.c b/src/lib/key-functions/public/basic.c new file mode 100644 index 0000000..f229def --- /dev/null +++ b/src/lib/key-functions/public/basic.c @@ -0,0 +1,57 @@ +/* ---------------------------------------------------------------------------- + * key functions : basic : code + * ---------------------------------------------------------------------------- + * Copyright (c) 2012 Ben Blazak + * Released under The MIT License (MIT) (see "license.md") + * Project located at + * ------------------------------------------------------------------------- */ + + +#include "../public.h" +#include "../private.h" + +// ---------------------------------------------------------------------------- + +/* + * Press|Release + * - Generate a normal keypress or keyrelease + */ +void kbfun_press_release( KBFUN_FUNCTION_ARGS ) { + _kbfun_press_release(pressed_, keycode_); +} + +/* + * Toggle + * - Toggle the key pressed or unpressed + */ +void kbfun_toggle( KBFUN_FUNCTION_ARGS ) { + if (_kbfun_is_pressed(keycode_)) + _kbfun_press_release(false, keycode_); + else + _kbfun_press_release(true, keycode_); +} + +/* + * Increase layer + * - Increment the current layer by the value specified in the keymap (for all + * non-masked keys) + */ +void kbfun_layer_inc( KBFUN_FUNCTION_ARGS ) { + _kbfun_layer_set_current( + (*current_layer_) + keycode_, + current_layer_, + current_layers_ ); +} + +/* + * Decrease layer + * - Decrement the current layer by the value specified in the keymap (for all + * non-masked keys) + */ +void kbfun_layer_dec( KBFUN_FUNCTION_ARGS ) { + _kbfun_layer_set_current( + (*current_layer_) - keycode_, + current_layer_, + current_layers_ ); +} + diff --git a/src/lib/key-functions/public/device.c b/src/lib/key-functions/public/device.c new file mode 100644 index 0000000..bab6164 --- /dev/null +++ b/src/lib/key-functions/public/device.c @@ -0,0 +1,52 @@ +/* ---------------------------------------------------------------------------- + * key functions : device specific : code + * ---------------------------------------------------------------------------- + * Copyright (c) 2012 Ben Blazak + * Released under The MIT License (MIT) (see "license.md") + * Project located at + * ------------------------------------------------------------------------- */ + + +#include +#include +#include "../public.h" + +// ---------------------------------------------------------------------------- +#if MAKEFILE_BOARD == teensy-2-0 +// ---------------------------------------------------------------------------- + +// from PJRC (slightly modified) +// +void kbfun_jump_to_bootloader( KBFUN_FUNCTION_ARGS ) { + // --- for all Teensy boards --- + + cli(); + + // disable watchdog, if enabled + // disable all peripherals + UDCON = 1; + USBCON = (1< + * Released under The MIT License (MIT) (see "license.md") + * Project located at + * ------------------------------------------------------------------------- */ + + +#include +#include +#include "src/lib-other/pjrc/usb_keyboard/usb_keyboard.h" +#include "src/lib/usb/usage-page/keyboard.h" +#include "src/keyboard/matrix.h" +#include "../public.h" +#include "../private.h" + + +// ---------------------------------------------------------------------------- +// vars +// ---------------------------------------------------------------------------- + +static bool _numpad_activated = false; + +static bool _layer_mask[KB_ROWS][KB_COLUMNS] = + KB_MATRIX_LAYER( + // 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, 0, 0, + + // 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, 0, 0 ); + + +// ---------------------------------------------------------------------------- +// private functions +// ---------------------------------------------------------------------------- + +static inline void _toggle_numlock(void) { + _kbfun_press_release(true, KEYPAD_NumLock_Clear); + usb_keyboard_send(); + _kbfun_press_release(false, KEYPAD_NumLock_Clear); + usb_keyboard_send(); +} + +static void _toggle_numpad( + uint8_t numpad_layer, + uint8_t current_layer, + uint8_t (*current_layers)[KB_ROWS][KB_COLUMNS] ) { + + if (_numpad_activated) { + // deactivate numpad + _kbfun_layer_set_mask( + current_layer, _layer_mask, current_layers ); + _numpad_activated = false; + + // if: numlock on + if (keyboard_leds & (1<<0)) + _toggle_numlock(); + } else { + // activate numpad + _kbfun_layer_set_mask( + numpad_layer, _layer_mask, current_layers ); + _numpad_activated = true; + + // if: numlock off + if (!(keyboard_leds & (1<<0))) + _toggle_numlock(); + } +} + + +// ---------------------------------------------------------------------------- +// public functions +// ---------------------------------------------------------------------------- + +/* + * 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 ) { + _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 (!_numpad_activated) + _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 (_numpad_activated) + _toggle_numpad(keycode_, *current_layer_, current_layers_); +} + diff --git a/src/lib/key-functions/public/special.c b/src/lib/key-functions/public/special.c new file mode 100644 index 0000000..a9d9d4b --- /dev/null +++ b/src/lib/key-functions/public/special.c @@ -0,0 +1,118 @@ +/* ---------------------------------------------------------------------------- + * key functions : special : code + * ---------------------------------------------------------------------------- + * Copyright (c) 2012 Ben Blazak + * Released under The MIT License (MIT) (see "license.md") + * Project located at + * ------------------------------------------------------------------------- */ + + +#include +#include +#include "src/lib-other/pjrc/usb_keyboard/usb_keyboard.h" +#include "src/lib/usb/usage-page/keyboard.h" +#include "src/main.h" +#include "../public.h" +#include "../private.h" + +// ---------------------------------------------------------------------------- + +/* + * 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 + _kbfun_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 + main_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 + _kbfun_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 + main_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) + * (in both the press and release matrices), pressing and holding down one of + * the keys will make the second key 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 + */ +void kbfun_2_keys_capslock_press_release( KBFUN_FUNCTION_ARGS ) { + 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 + _kbfun_press_release(pressed_, keycode_); + + // 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 = _kbfun_is_pressed(KEY_LeftShift); + rshift_pressed = _kbfun_is_pressed(KEY_RightShift); + // disable both + _kbfun_press_release(false, KEY_LeftShift); + _kbfun_press_release(false, KEY_RightShift); + + // press capslock, then release it + _kbfun_press_release(true, KEY_CapsLock); + usb_keyboard_send(); + _kbfun_press_release(false, KEY_CapsLock); + usb_keyboard_send(); + + // restore the state of left and right shift + if (lshift_pressed) + _kbfun_press_release(true, KEY_LeftShift); + if (rshift_pressed) + _kbfun_press_release(true, KEY_RightShift); + } + + if (pressed_) keys_pressed++; +} + diff --git a/src/lib/key-functions/readme.md b/src/lib/key-functions/readme.md new file mode 100644 index 0000000..6e49659 --- /dev/null +++ b/src/lib/key-functions/readme.md @@ -0,0 +1,12 @@ +# src/lib/key-functions + +These functions may do.. pretty much anything rational that they like. If they +want keycodes to be sent to the host in an aggregate report, they're responsible +for modifying the appropriate report variables. + +------------------------------------------------------------------------------- + +Copyright © 2012 Ben Blazak +Released under The MIT License (MIT) (see "license.md") +Project located at + diff --git a/src/lib/twi.h b/src/lib/twi.h index 6221bd5..af3e59f 100644 --- a/src/lib/twi.h +++ b/src/lib/twi.h @@ -10,14 +10,7 @@ * ------------------------------------------------------------------------- */ -#undef _str -#undef _expstr -#undef _inc -#define _str(s) #s // stringify -#define _expstr(s) _str(s) // expand -> stringify -#define _inc _expstr(twi/MAKEFILE_BOARD.h) // inc(lude) -#include _inc -#undef _str -#undef _expstr -#undef _inc +#include "src/lib/conditional-include.h" +#define INCLUDE EXP_STR( ./twi/MAKEFILE_BOARD.h ) +#include INCLUDE diff --git a/src/lib/twi/teensy-2-0.c b/src/lib/twi/teensy-2-0.c index 7c3ed69..c956b38 100644 --- a/src/lib/twi/teensy-2-0.c +++ b/src/lib/twi/teensy-2-0.c @@ -21,10 +21,17 @@ * ------------------------------------------------------------------------- */ -#include -#include "lib/twi.h" +// ---------------------------------------------------------------------------- +// conditional compile +#if MAKEFILE_BOARD == teensy-2-0 +// ---------------------------------------------------------------------------- +#include +#include "./teensy-2-0.h" + +// ---------------------------------------------------------------------------- + void twi_init(void) { // set the prescaler value to 0 TWSR &= ~( (1< // ---------------------------------------------------------------------------- diff --git a/src/lib/usb/usage-page/keyboard--short-names.h b/src/lib/usb/usage-page/keyboard--short-names.h index c611e14..d666b21 100644 --- a/src/lib/usb/usage-page/keyboard--short-names.h +++ b/src/lib/usb/usage-page/keyboard--short-names.h @@ -17,7 +17,7 @@ // ---------------------------------------------------------------------------- -#include "keyboard.h" +#include "./keyboard.h" // ---------------------------------------------------------------------------- diff --git a/src/main.c b/src/main.c index 339c9a6..429ea0b 100644 --- a/src/main.c +++ b/src/main.c @@ -8,14 +8,46 @@ * ------------------------------------------------------------------------- */ +#include +#include #include -#include "lib-other/pjrc/usb_keyboard/usb_keyboard.h" -#include "lib/data-types/common.h" -#include "lib/key-functions.h" +#include "src/lib-other/pjrc/usb_keyboard/usb_keyboard.h" +#include "src/lib/key-functions/public.h" +#include "src/keyboard/controller.h" +#include "src/keyboard/layout.h" +#include "src/keyboard/matrix.h" -#include "keyboard.h" +// ---------------------------------------------------------------------------- +/* + * 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 main_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_ ); +} + +// ---------------------------------------------------------------------------- + +/* + * main() + */ int main(void) { kb_init(); // does controller initialization too @@ -28,6 +60,13 @@ int main(void) { kb_led_state_ready(); for (;;) { + // matrix of keys currently pressed + static bool _kb_is_pressed[KB_ROWS][KB_COLUMNS]; + static bool (*kb_is_pressed)[KB_ROWS][KB_COLUMNS] = &_kb_is_pressed; + // matrix of keys previously pressed + static bool _kb_was_pressed[KB_ROWS][KB_COLUMNS]; + static bool (*kb_was_pressed)[KB_ROWS][KB_COLUMNS] = &_kb_was_pressed; + // the overall current layer static uint8_t current_layer; // the current layer for each key @@ -43,9 +82,9 @@ int main(void) { kb_update_matrix(*kb_is_pressed); // this loop is responsible to - // - "execute" keys when they change state (call `_kbfun_exec_key()`, + // - "execute" keys when they change state (call `main_exec_key()`, // which will call the appropriate function with the appropriate - // keycode argument from the kb_layout* matrices) + // 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) // @@ -70,7 +109,7 @@ int main(void) { if (is_pressed) pressed_layers[row][col] = layer; - _kbfun_exec_key( + main_exec_key( is_pressed, 0, layer, &row, &col, ¤t_layer, ¤t_layers, &pressed_layers ); diff --git a/src/keyboard/ergodox/teensy-2-0--private.h b/src/main.h similarity index 65% rename from src/keyboard/ergodox/teensy-2-0--private.h rename to src/main.h index 231e608..78e6453 100644 --- a/src/keyboard/ergodox/teensy-2-0--private.h +++ b/src/main.h @@ -1,5 +1,5 @@ /* ---------------------------------------------------------------------------- - * ergoDOX controller: Teensy 2.0 specific exports : private + * main() : functions that may be useful externally * ---------------------------------------------------------------------------- * Copyright (c) 2012 Ben Blazak * Released under The MIT License (MIT) (see "license.md") @@ -7,13 +7,12 @@ * ------------------------------------------------------------------------- */ -#ifndef TEENSY_2_0_h_PRIVATE - #define TEENSY_2_0_h_PRIVATE +#ifndef MAIN_h + #define MAIN_h - #include "matrix.h" + #include "lib/key-functions/public.h" - uint8_t teensy_init(void); - uint8_t teensy_update_matrix( bool matrix[KB_ROWS][KB_COLUMNS] ); + void main_exec_key( KBFUN_FUNCTION_ARGS ); #endif diff --git a/src/makefile b/src/makefile index ccdc7ec..e2d6d83 100644 --- a/src/makefile +++ b/src/makefile @@ -23,6 +23,9 @@ 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 +KB_DEBOUNCE_TIME := 5 # in ms; see keyswitch spec for necessary value; 5ms + # should be good for cherry mx switches + # firmware stuff SRC := $(wildcard *.c) # keyboard and layout stuff @@ -32,12 +35,14 @@ LAYOUT := $(strip $(LAYOUT)) # --- include stuff SRC += $(wildcard keyboard/$(KEYBOARD)*.c) SRC += $(wildcard keyboard/$(KEYBOARD)/*.c) +SRC += $(wildcard keyboard/$(KEYBOARD)/controller/*.c) SRC += $(wildcard keyboard/$(KEYBOARD)/layout/$(LAYOUT)*.c) # library stuff # - add more "*/*/..."s as necessary to compile everything. # - parts of the stuff under "lib" may not be necessary, depending on other # options, but it's all included here. hopefully any unnecessary stuff gets # compiled out. else, the makefile will have to become more complicated. + SRC += $(wildcard lib/*.c) SRC += $(wildcard lib/*/*.c) SRC += $(wildcard lib/*/*/*.c) @@ -48,15 +53,17 @@ SRC += $(wildcard lib-other/*/*/*.c) OBJ = $(SRC:%.c=%.o) +# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . CFLAGS := -mmcu=$(MCU) # processor type (teensy 2.0); must match real # life CFLAGS += -DF_CPU=$(F_CPU) # processor frequency; must match initialization # in source -CFLAGS += -I. # search for includes in the current directory +CFLAGS += -I.. # search for includes in the toplevel directory # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . CFLAGS += -DMAKEFILE_BOARD='$(strip $(BOARD))' CFLAGS += -DMAKEFILE_KEYBOARD='$(strip $(KEYBOARD))' CFLAGS += -DMAKEFILE_KEYBOARD_LAYOUT='$(strip $(LAYOUT))' +CFLAGS += -DKB_DEBOUNCE_TIME='$(strip $(KB_DEBOUNCE_TIME))' # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . CFLAGS += -std=gnu99 # use C99 plus GCC extensions CFLAGS += -Os # optimize for size @@ -83,6 +90,7 @@ LDFLAGS += -Wl,--gc-sections # discard unused functions and data # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . GENDEPFLAGS += -MMD -MP -MF $@.dep # generate dependency files +# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . CC := avr-gcc