wrote kf__chord__*__progmem() :)

partial-rewrite
Ben Blazak 2013-04-01 01:49:36 -07:00
parent e036276dd0
commit 2964e68840
5 changed files with 75 additions and 79 deletions

View File

@ -59,9 +59,8 @@ void kb__led__delay__usb_init (void);
void kb__led__logical_on (char led);
void kb__led__logical_off (char led);
// -------
void kb__layout__exec_key ( bool pressed,
uint8_t row,
uint8_t column );
void kb__layout__exec_key_pointer (bool pressed, void * pointer);
void kb__layout__exec_key_location (bool pressed, uint8_t row, uint8_t column);
// ----------------------------------------------------------------------------
@ -240,8 +239,25 @@ void kb__layout__exec_key ( bool pressed,
// ----------------------------------------------------------------------------
// === kb__layout__exec_key ===
/** functions/kb__layout__exec_key/description
// === kb__layout__exec_key_pointer ===
/** functions/kb__layout__exec_key_pointer/description
* Perform a "press" or "release" of the key pointed to
*
* Arguments:
* - `pressed`:
* - `true`: Indicates that the key to be "executed" has been pressed
* - `false`: Indicates that the key to be "executed" has been released
* - `pointer`: A pointer to the key to execute
*
* Notes:
* - The pointer may be of any type, and to a value in any address space. It
* is up to the keyboard implementation to define this. Since this is the
* only `exec_key_pointer` function though, all the keys should probably be
* in the same address space, wherever they are.
*/
// === kb__layout__exec_key_location ===
/** functions/kb__layout__exec_key_location/description
* Perform the appropriate actions for a "press" or "release" of the key at the
* given position.
*

View File

@ -25,12 +25,13 @@
extern KEY_T layout[][KB__ROWS][KB__COLUMNS];
// ----------------------------------------------------------------------------
void kb__layout__exec_key_pointer(key_t * pointer) { // TODO
}
void kb__layout__exec_key( bool pressed,
int8_t layer,
int8_t row,
int8_t column ) {
// TODO
void kb__layout__exec_key_location( bool pressed, // TODO
int8_t layer,
int8_t row,
int8_t column ) {
// - check for key redefinition in the EEPROM
// - if there is one, execute it, according to the appropriate rules
// - lookup key in PROGMEM

View File

@ -34,23 +34,26 @@
2, &kf__press, KEY__LeftShift, \
&kf__press, value }; \
const uint16_t PROGMEM name##__release[] = { \
2, &kf__release, KEY__LeftShift, \
&kf__release, value }; \
2, &kf__release, value, \
&kf__release, KEY__LeftShift }; \
KEY_T name = { &kf__macro__progmem, &name##__press, \
&kf__macro__progmem, &name##__release }
// other `keys__` macros (in the `keys__` namespace for consistency)
#define KEYS__TWO_KEYS_CAPSLOCK_PRESS_RELEASE(name, value) \
const uint16_t PROGMEM name##__press[] = { \
2, &kf__two_keys_capslock, 1, \
&kf__press, value }; \
const uint16_t PROGMEM name##__release[] = { \
2, &kf__two_keys_capslock, 0, \
&kf__release, value }; \
KEY_T name = { &kf__macro__progmem, &name##__press, \
&kf__macro__progmem, &name##release }
// TODO: rewrite to reflect: kf__two_keys_capslock() -> kf__toggle_capslock() +
// kf__chord__progmem() (or some such thing)
// #define KEYS__TWO_KEYS_CAPSLOCK(name, value) \
// const uint16_t PROGMEM name##__press[] = { \
// 2, &kf__two_keys_capslock, 1, \
// &kf__press, value }; \
// const uint16_t PROGMEM name##__release[] = { \
// 2, &kf__two_keys_capslock, 0, \
// &kf__release, value }; \
// KEY_T name = { &kf__macro__progmem, &name##__press, \
// &kf__macro__progmem, &name##__release }
#define KEYS__TWO_KEYS_CAPSLOCK(name, value) KEYS__DEFAULT(name, value)
// ----------------------------------------------------------------------------
@ -76,10 +79,10 @@ KEYS__DEFAULT( Mute, KEY__Mute );
// special function
// --- Sh2KCapL
KEYS__TWO_KEYS_CAPSLOCK_PRESS_RELEASE( Sh2KCapL, KEY__LeftShift );
KEYS__TWO_KEYS_CAPSLOCK( Sh2KCapL, KEY__LeftShift );
// --- Sh2KCapR
KEYS__TWO_KEYS_CAPSLOCK_PRESS_RELEASE( Sh2KCapR, KEY__RightShift );
KEYS__TWO_KEYS_CAPSLOCK( Sh2KCapR, KEY__RightShift );
// --- Btldr
KEY_T Btldr = { &kf__jump_to_bootloader, 0, NULL, 0 };

View File

@ -8,6 +8,10 @@
* Some generally useful key-functions, and related definitions
*
* Prefix: `kf__`
*
* Notes:
* - Several of these functions depend on the fact that (on an AVR) pointers
* are 16-bit.
*/
@ -25,29 +29,17 @@ typedef void (*kf__function_pointer_t)(uint16_t value);
// ----------------------------------------------------------------------------
// basic
void kf__press (uint16_t keycode);
void kf__release (uint16_t keycode);
void kf__toggle (uint16_t keycode);
void kf__layer__push (uint16_t id__layer);
void kf__layer__pop (uint16_t id__ignore);
// void kf__macro__sram (uint16_t pointer); // TODO
void kf__macro__progmem (uint16_t pointer);
// void kf__macro__eeprom (uint16_t pointer); // TODO
void kf__press (uint16_t keycode);
void kf__release (uint16_t keycode);
void kf__toggle (uint16_t keycode);
void kf__layer__push (uint16_t id__layer);
void kf__layer__pop (uint16_t id__ignore);
// void kf__macro__sram (uint16_t pointer); // TODO
void kf__macro__progmem (uint16_t pointer);
// void kf__macro__eeprom (uint16_t pointer); // TODO
void kf__chord__press__progmem (uint16_t pointer); // TODO: write doc.
void kf__chord__release__progmem (uint16_t pointer); // TODO: write doc.
// TODO: chording
//
// - consider making a 'kf__chord(uint16_t pointer)' that takes a pointer to an
// array containing whatever's needed to specify [ which group of keys it
// belongs to; whether to increment or decrement the counter for that group;
// the threshold for action for that group; the action (possibly a
// layer/row/col tuple for a key to call exec on, or possible just a row/col,
// and a layer shift some other way, ...) ]
//
// - create a auto-resizing array ('flex_array'?) for use with this function,
// and probably with the the layer stack functions as well. IDs can be
// treated as array indices (the burden being on the user not to use indices
// that are too large...)
//
// TODO: kf__macro__eeprom
// - this should probably go into its own little place in 'lib'; it'll need a
// function to write the macro to memory, code to keep track of what's
@ -56,10 +48,6 @@ void kf__macro__progmem (uint16_t pointer);
// TODO: kf__macro__sram
// - is this necessary? will it be confusing (if we already have
// kf__macro__eeprom)? we should probably remove it.
//
// TODO: rewrite layouts to reflect
// - kf__two_keys_capslock() -> kf__toggle_capslock()
// - the removal of kf__send()
// device
void kf__jump_to_bootloader (uint16_t ignore);

View File

@ -12,12 +12,30 @@
#include <stdbool.h>
#include <stdint.h>
#include <avr/pgmspace.h>
#include "../../../../firmware/keyboard.h"
#include "../../../../firmware/lib/usb.h"
#include "../../../../firmware/lib/layout/layer-stack.h"
#include "../key-functions.h"
// ----------------------------------------------------------------------------
static void _chord__progmem(bool pressed, void * pointer) { // TODO: test
uint8_t * count = (uint8_t *) pgm_read_word( pointer );
uint16_t threshold = (uint16_t) pgm_read_word( pointer+2 );
void * key_pointer = (void *) pgm_read_word( pointer+4 );
if (pressed)
*count++;
if (*count == threshold)
kb__layout__exec_key_pointer(key_pointer);
if (!pressed)
*count--;
}
// ----------------------------------------------------------------------------
void kf__press(uint16_t keycode) {
usb__kb__set_key(true, keycode);
usb__kb__send_report();
@ -59,36 +77,6 @@ void kf__macro__progmem(uint16_t pointer) { // TODO: test
}
}
// TODO: write documentation for this function
// TODO: this is a mistakenly written function; i'm going to change it. what
// we really want is a way to generate a "press" above a certain
// threshold, and "release" going back the other way; this function would
// make that possible, since it's quite general, but difficult and
// space-consuming.
static void _chord__progmem(bool pressed, uint16_t pointer) { // TODO: test
#define funptr kf__function_pointer_t
uint8_t * count = (uint8_t *) pgm_read_word( pointer );
uint16_t threshold = (uint16_t) pgm_read_word( pointer+2 );
funptr function = (funptr) pgm_read_word( pointer+4 );
uint16_t argument = (uint16_t) pgm_read_word( pointer+6 );
uint16_t direction__comparison = (uint16_t) pgm_read_word( pointer+8 );
#undef funptr
char direction = ((char)(behavior >> 8));
char comparison = ((char)(behavior & 0xff));
if (pressed) *count++;
else *count--;
if ( (pressed && direction == 'p') ||
(!pressed && direction == 'r') )
if ( (comparison == '=' && *count == threshold) ||
(comparison == '<' && *count < threshold) ||
(comparison == '>' && *count > threshold) )
if (function)
(*function)();
}
void kf__chord__press__progmem(uint16_t pointer) {
_chord__progmem(true, pointer);
}