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).
partial-rewrite
Ben Blazak 2012-06-20 16:56:24 -07:00
parent 9f357ede2a
commit d1fa583bb3
5 changed files with 185 additions and 135 deletions

View File

@ -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 )
// ----------------------------------------------------------------------------
};

View File

@ -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,

View File

@ -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_ );
}

View File

@ -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

View File

@ -11,6 +11,7 @@
#include <util/delay.h>
#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<KB_ROWS; row++) {
for (uint8_t col=0; col<KB_COLUMNS; col++) {
@ -57,39 +63,25 @@ int main(void) {
bool was_pressed = (*kb_was_pressed)[row][col];
if (is_pressed != was_pressed) {
uint8_t layer = ( (is_pressed)
? current_layers[row][col]
: pressed_layers[row][col] );
if (is_pressed) {
uint8_t layer = current_layers[row][col];
if (is_pressed)
pressed_layers[row][col] = layer;
kbfun_funptr_t press_function =
kb_layout_press_get(layer, row, col);
if (press_function) {
(*press_function)(
kb_layout_get(layer, row, col),
true, &current_layer,
&current_layers, &pressed_layers,
&row, &col );
}
} else {
uint8_t layer = pressed_layers[row][col];
kbfun_funptr_t release_function =
kb_layout_release_get(layer, row, col);
if (release_function) {
(*release_function)(
kb_layout_get(layer, row, col),
false, &current_layer,
&current_layers, &pressed_layers,
&row, &col );
}
}
usb_keyboard_send();
_delay_ms(KB_DEBOUNCE_TIME);
_kbfun_exec_key(
is_pressed, 0, layer,
&row, &col, &current_layer,
&current_layers, &pressed_layers );
}
}
}
// send the USB report (even if nothing's changed)
usb_keyboard_send();
_delay_ms(KB_DEBOUNCE_TIME);
// update LEDs
if (keyboard_leds & (1<<0)) { kb_led_num_on(); }
else { kb_led_num_off(); }