(in the middle of a lot of misc changes)
parent
4628061b53
commit
d3e9291d49
|
@ -139,10 +139,23 @@
|
|||
Yes. The memory manager keeps track of the size of allocations - and the
|
||||
pointer you pass to `free()` is cast to `void *` before deallocation anyway.
|
||||
|
||||
* [Why exactly should I not call free() on variables not allocated by malloc()?]
|
||||
(http://stackoverflow.com/questions/2688377/why-exactly-should-i-not-call-free-on-variables-not-allocated-by-malloc)
|
||||
But it's not safe to call `free()` on non-`malloc()`ed things.
|
||||
|
||||
* [Why do we need C Unions?]
|
||||
(http://stackoverflow.com/questions/252552/why-do-we-need-c-unions)
|
||||
Some good examples of what Unions are good for.
|
||||
|
||||
* [C preprocessor, recursive macros]
|
||||
(http://stackoverflow.com/questions/5641836/c-preprocessor-recursive-macros)
|
||||
I'm not entirely sure I understand what's going on... but be it known that
|
||||
function like macros that expand into other function like macros are tricky
|
||||
business.
|
||||
|
||||
* [Declaring and Using Bit Fields in Structures]
|
||||
(http://publib.boulder.ibm.com/infocenter/macxhelp/v6v81/index.jsp?topic=%2Fcom.ibm.vacpp6m.doc%2Flanguage%2Fref%2Fclrc03defbitf.htm)
|
||||
|
||||
### C++ Stuff
|
||||
|
||||
* [Google C++ Style Guide]
|
||||
|
|
|
@ -20,11 +20,12 @@
|
|||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <avr/pgmspace.h>
|
||||
#include "../../../../../firmware/keyboard.h"
|
||||
#include "../../../../../firmware/lib/data-types/list.h"
|
||||
#include "../../../../../firmware/lib/usb.h"
|
||||
#include "../../../../../firmware/lib/usb/usage-page/keyboard.h"
|
||||
#include "../../../../../firmware/lib/layout/key-functions.h"
|
||||
#include "../../../../../firmware/lib/layout/layer-stack.h"
|
||||
#include "../../../../../firmware/keyboard.h"
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
|
@ -41,7 +42,7 @@
|
|||
/** macros/K/description
|
||||
* Expand into a "key" suitable for putting into the layout matrix
|
||||
*/
|
||||
#define K(name) { &P(name), &R(name) }
|
||||
#define K(name) { &keys__press__##name, &keys__release__##name }
|
||||
|
||||
/** macros/KF/description
|
||||
* Expand `name` into the corresponding "key_functions" function name
|
||||
|
@ -79,7 +80,7 @@ void KF(nop) (void) {}
|
|||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
/** typedefs/_key_t/description
|
||||
/** types/_key_t/description
|
||||
* The type we will use for our "key"s
|
||||
*
|
||||
* Notes:
|
||||
|
@ -92,7 +93,7 @@ void KF(nop) (void) {}
|
|||
*/
|
||||
typedef void (*_key_t[2])(void);
|
||||
|
||||
/** typedefs/_layout_t/description
|
||||
/** types/_layout_t/description
|
||||
* The type we will use for our layout matrix
|
||||
*
|
||||
* Notes:
|
||||
|
@ -101,26 +102,25 @@ typedef void (*_key_t[2])(void);
|
|||
*/
|
||||
typedef const _key_t _layout_t[][OPT__KB__ROWS][OPT__KB__COLUMNS];
|
||||
|
||||
/** variables/layout/description
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
/** variables/_layout/description
|
||||
* The variable containing our layout matrix
|
||||
*/
|
||||
static _layout_t PROGMEM _layout;
|
||||
|
||||
/** variables/sticky_key/description
|
||||
* A pointer to the release function of the last sticky key pressed
|
||||
/** variables/_flags/description
|
||||
* A collection of flags pertaining to the operation of `...exec_key()`
|
||||
*
|
||||
* The function pointed to by this should be executed directly after executing
|
||||
* the "press" function of the next key pressed.
|
||||
*
|
||||
* Notes:
|
||||
* - In order for things to work right, sticky keys should either execute this
|
||||
* stored function themselves before placing their own "release" function
|
||||
* value here, or else save the value that's here and call it as part of
|
||||
* their own "release" function. If this isn't done, and the key pressed
|
||||
* directly before this was a sticky key as well, then the previous sticky
|
||||
* key will never be released.
|
||||
* Struct members:
|
||||
* - stick_current: TODO: probably just want 'tick_keypresses'?
|
||||
*/
|
||||
static void (*_sticky_key)(void);
|
||||
static struct {
|
||||
bool stick_current : 1;
|
||||
bool stick_press : 1;
|
||||
bool stick_release : 1;
|
||||
bool unstick_all : 1;
|
||||
} _flags;
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
|
|
@ -23,14 +23,16 @@
|
|||
|
||||
void kb__layout__exec_key(bool pressed, uint8_t row, uint8_t column) {
|
||||
|
||||
// keep track of the layer the key was pressed on, so we can release it on
|
||||
// the same layer
|
||||
// if we press a key, we need to keep track of the layer it was pressed on,
|
||||
// so we can release it on the same layer
|
||||
// - if the release is transparent, search through the layer stack for a
|
||||
// non-transparent release in the same position, as normal
|
||||
// - don't need to initialize, since we'll only read from positions that
|
||||
// we've previously set
|
||||
static uint8_t pressed_layer[OPT__KB__ROWS][OPT__KB__COLUMNS];
|
||||
|
||||
// TODO: keep track of sticky keys
|
||||
|
||||
void (*function)(void);
|
||||
uint8_t layer;
|
||||
|
||||
|
@ -58,10 +60,11 @@ void kb__layout__exec_key(bool pressed, uint8_t row, uint8_t column) {
|
|||
|
||||
(*function)();
|
||||
|
||||
if (pressed && _sticky_key) {
|
||||
(*_sticky_key)();
|
||||
_sticky_key = NULL;
|
||||
}
|
||||
// TODO: implement sticky keys
|
||||
// if (pressed && _sticky_key) {
|
||||
// (*_sticky_key)();
|
||||
// _sticky_key = NULL;
|
||||
// }
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
* Meant to be included *only* by the layout using it.
|
||||
*/
|
||||
|
||||
// TODO: make a KF for windows/mac style unicode input
|
||||
|
||||
// TODO: write a chordmak (or asetniop) layout, on top of a standard colemak
|
||||
// layout, using chained sticky keys for the modifiers
|
||||
|
||||
|
@ -22,6 +24,7 @@
|
|||
// - sticky keys
|
||||
// - macros
|
||||
// - chorded keys
|
||||
// - timed keys
|
||||
// - layers
|
||||
// - making layouts
|
||||
// - changing the meaning of the LEDs
|
||||
|
@ -88,16 +91,10 @@
|
|||
* (only) functions may be defined as follows (using the example `lpupo1l1`
|
||||
* from above):
|
||||
*
|
||||
* #define keys__press__lpu1l1 keys__press__lpupo1l1
|
||||
* #define keys__press__lpu1l1 P(lpupo1l1)
|
||||
* #define keys__release__lpu1l1 KF(nop)
|
||||
* #define keys__press__lpo1l1 R(lpupo1l1)
|
||||
* #define keys__release__lpo1l1 KF(nop)
|
||||
*
|
||||
* - Also note that writing `#define keys__press__lpu1l1 P(lpupo1l1)` will
|
||||
* not work. My guess is that this has something to do with the fact that,
|
||||
* if things are being expanded within the layout definition, the left hand
|
||||
* side "press" function names will themselves have been expanded by the
|
||||
* `P()` macro; but I'm not really sure why that makes a difference.
|
||||
*/
|
||||
#define KEYS__LAYER__PUSH_POP(ID, LAYER) \
|
||||
void P(lpupo##ID##l##LAYER) (void) { layer_stack__push(0, ID, LAYER); } \
|
||||
|
@ -213,61 +210,61 @@ void R(btldr) (void) {}
|
|||
// them if they're inconvenient
|
||||
|
||||
KEYS__LAYER__PUSH_POP(0, 0);
|
||||
#define keys__press__lpu0l0 keys__press__lpupo0l0
|
||||
#define keys__press__lpu0l0 P(lpupo0l0)
|
||||
#define keys__release__lpu0l0 KF(nop)
|
||||
#define keys__press__lpo0l0 R(lpupo0l0)
|
||||
#define keys__release__lpo0l0 KF(nop)
|
||||
|
||||
KEYS__LAYER__PUSH_POP(1, 1);
|
||||
#define keys__press__lpu1l1 keys__press__lpupo1l1
|
||||
#define keys__press__lpu1l1 P(lpupo1l1)
|
||||
#define keys__release__lpu1l1 KF(nop)
|
||||
#define keys__press__lpo1l1 R(lpupo1l1)
|
||||
#define keys__release__lpo1l1 KF(nop)
|
||||
|
||||
KEYS__LAYER__PUSH_POP(2, 2);
|
||||
#define keys__press__lpu2l2 keys__press__lpupo2l2
|
||||
#define keys__press__lpu2l2 P(lpupo2l2)
|
||||
#define keys__release__lpu2l2 KF(nop)
|
||||
#define keys__press__lpo2l2 R(lpupo2l2)
|
||||
#define keys__release__lpo2l2 KF(nop)
|
||||
|
||||
KEYS__LAYER__PUSH_POP(3, 3);
|
||||
#define keys__press__lpu3l3 keys__press__lpupo3l3
|
||||
#define keys__press__lpu3l3 P(lpupo3l3)
|
||||
#define keys__release__lpu3l3 KF(nop)
|
||||
#define keys__press__lpo3l3 R(lpupo3l3)
|
||||
#define keys__release__lpo3l3 KF(nop)
|
||||
|
||||
KEYS__LAYER__PUSH_POP(4, 4);
|
||||
#define keys__press__lpu4l4 keys__press__lpupo4l4
|
||||
#define keys__press__lpu4l4 P(lpupo4l4)
|
||||
#define keys__release__lpu4l4 KF(nop)
|
||||
#define keys__press__lpo4l4 R(lpupo4l4)
|
||||
#define keys__release__lpo4l4 KF(nop)
|
||||
|
||||
KEYS__LAYER__PUSH_POP(5, 5);
|
||||
#define keys__press__lpu5l5 keys__press__lpupo5l5
|
||||
#define keys__press__lpu5l5 P(lpupo5l5)
|
||||
#define keys__release__lpu5l5 KF(nop)
|
||||
#define keys__press__lpo5l5 R(lpupo5l5)
|
||||
#define keys__release__lpo5l5 KF(nop)
|
||||
|
||||
KEYS__LAYER__PUSH_POP(6, 6);
|
||||
#define keys__press__lpu6l6 keys__press__lpupo6l6
|
||||
#define keys__press__lpu6l6 P(lpupo6l6)
|
||||
#define keys__release__lpu6l6 KF(nop)
|
||||
#define keys__press__lpo6l6 R(lpupo6l6)
|
||||
#define keys__release__lpo6l6 KF(nop)
|
||||
|
||||
KEYS__LAYER__PUSH_POP(7, 7);
|
||||
#define keys__press__lpu7l7 keys__press__lpupo7l7
|
||||
#define keys__press__lpu7l7 P(lpupo7l7)
|
||||
#define keys__release__lpu7l7 KF(nop)
|
||||
#define keys__press__lpo7l7 R(lpupo7l7)
|
||||
#define keys__release__lpo7l7 KF(nop)
|
||||
|
||||
KEYS__LAYER__PUSH_POP(8, 8);
|
||||
#define keys__press__lpu8l8 keys__press__lpupo8l8
|
||||
#define keys__press__lpu8l8 P(lpupo8l8)
|
||||
#define keys__release__lpu8l8 KF(nop)
|
||||
#define keys__press__lpo8l8 R(lpupo8l8)
|
||||
#define keys__release__lpo8l8 KF(nop)
|
||||
|
||||
KEYS__LAYER__PUSH_POP(9, 9);
|
||||
#define keys__press__lpu9l9 keys__press__lpupo9l9
|
||||
#define keys__press__lpu9l9 P(lpupo9l9)
|
||||
#define keys__release__lpu9l9 KF(nop)
|
||||
#define keys__press__lpo9l9 R(lpupo9l9)
|
||||
#define keys__release__lpo9l9 KF(nop)
|
||||
|
|
|
@ -4,6 +4,9 @@
|
|||
* Project located at <https://github.com/benblazak/ergodox-firmware>
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
// TODO: change from using pointers to everything, to just using the things
|
||||
// (since they're structs anyway)
|
||||
|
||||
/** description
|
||||
* An interface to a simple linked-list that can be used to implement lists,
|
||||
* queues, stacks, and things
|
||||
|
@ -77,7 +80,6 @@ typedef struct list__list_t {
|
|||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
list__list_t * list__new (void);
|
||||
void * list__insert ( list__list_t * list,
|
||||
int8_t index,
|
||||
void * node );
|
||||
|
@ -100,16 +102,16 @@ void list__free (list__list_t * list);
|
|||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// typedefs -------------------------------------------------------------------
|
||||
// types ----------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// === list__node_t ===
|
||||
/** typedefs/list__node_t/description
|
||||
/** types/list__node_t/description
|
||||
* The type of a "node", for the purposes of this library
|
||||
*/
|
||||
|
||||
// === list__list_t ===
|
||||
/** typedefs/list__list_t/description
|
||||
/** types/list__list_t/description
|
||||
* Simple struct to define and keep track of our list
|
||||
*/
|
||||
|
||||
|
@ -118,15 +120,6 @@ void list__free (list__list_t * list);
|
|||
// functions ------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// === list__new() ===
|
||||
/** functions/list__new/description
|
||||
* Allocate a new (empty) list
|
||||
*
|
||||
* Returns:
|
||||
* - success: A pointer to the new list
|
||||
* - failure: `NULL`
|
||||
*/
|
||||
|
||||
// === list__insert() ===
|
||||
/** functions/list__insert/description
|
||||
* Insert `node` at position `index % list->length`
|
||||
|
@ -211,7 +204,7 @@ void list__free (list__list_t * list);
|
|||
|
||||
// === list__free() ===
|
||||
/** functions/list__free/description
|
||||
* Free all node pointers in `list`, then free `list`
|
||||
* Free all node pointers in `list`
|
||||
*
|
||||
* Arguments:
|
||||
* - `list`: A pointer to the list to be operated on
|
||||
|
|
|
@ -20,17 +20,6 @@
|
|||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
list__list_t * list__new(void) {
|
||||
list__list_t * list = malloc( sizeof(list__list_t) );
|
||||
if (!list) return NULL;
|
||||
|
||||
list->head = NULL;
|
||||
list->tail = NULL;
|
||||
list->length = 0;
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
void * list__insert(list__list_t * list, int8_t index, void * node) {
|
||||
if (!node) return NULL;
|
||||
|
||||
|
@ -171,7 +160,6 @@ void list__free(list__list_t * list) {
|
|||
list->head = N(list->head)->next;
|
||||
free(node);
|
||||
}
|
||||
free(list);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,9 @@
|
|||
* Prefixes: `timer__`, `timer___`
|
||||
*/
|
||||
|
||||
// TODO: make macros for defining timers; make groups for function
|
||||
// documentation; make notes for all extra information
|
||||
|
||||
|
||||
#ifndef ERGODOX_FIRMWARE__LIB__TIMER__H
|
||||
#define ERGODOX_FIRMWARE__LIB__TIMER__H
|
||||
|
|
|
@ -5,14 +5,10 @@
|
|||
* ------------------------------------------------------------------------- */
|
||||
|
||||
/** description
|
||||
* Implements the timer interface defined in ".../firmware/lib/timer.h" for the
|
||||
* ATMega32U4
|
||||
* Implements the device specific portion of the timer interface defined in
|
||||
* ".../firmware/lib/timer.h" for the ATMega32U4
|
||||
*
|
||||
* See the accompanying '.md' file for further documentation.
|
||||
*
|
||||
* Notes:
|
||||
* - Not all of this code is device-specific, but the parts that aren't are
|
||||
* trivial enough that it's not worth separating them.
|
||||
*/
|
||||
|
||||
|
||||
|
@ -30,44 +26,12 @@
|
|||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
/** variables/_cycles/description
|
||||
* The number of scan cycles since the timer was initialized (mod 2^16)
|
||||
*/
|
||||
static uint16_t _cycles;
|
||||
|
||||
/** variables/_cycles__scheduled/description
|
||||
* A list of scheduled events, to be run in a given number of cycles
|
||||
*
|
||||
* After initialization, this should *only* be used as an argument to an
|
||||
* `event_list__...()` function.
|
||||
*/
|
||||
static list__list_t * _cycles__scheduled;
|
||||
|
||||
/** variables/_milliseconds/description
|
||||
* The number of milliseconds since the timer was initialized (mod 2^16)
|
||||
*/
|
||||
static volatile uint16_t _milliseconds;
|
||||
|
||||
/** variables/_milliseconds__scheduled/description
|
||||
* A list of scheduled events, to be run in a given number of milliseconds
|
||||
*
|
||||
* After initialization, this should *only* be used as an argument to an
|
||||
* `event_list__...()` function.
|
||||
*/
|
||||
static list__list_t * _milliseconds__scheduled;
|
||||
static volatile uint16_t _milliseconds__counter;
|
||||
static list__list_t * _milliseconds__scheduled_events = &(list__list_t){};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
uint8_t timer__init(void) {
|
||||
_cycles__scheduled = list__new();
|
||||
_milliseconds__scheduled = list__new();
|
||||
|
||||
if (!_cycles__scheduled || !_milliseconds__scheduled) {
|
||||
list__free(_cycles__scheduled);
|
||||
list__free(_milliseconds__scheduled);
|
||||
return 1; // error
|
||||
}
|
||||
|
||||
OCR0A = 250; // (ticks per millisecond)
|
||||
TCCR0A = 0b00000010; // (configure Timer/Counter 0)
|
||||
TCCR0B = 0b00000011; // (configure Timer/Counter 0)
|
||||
|
@ -77,36 +41,18 @@ uint8_t timer__init(void) {
|
|||
return 0; // success
|
||||
}
|
||||
|
||||
uint16_t timer__get_cycles(void) {
|
||||
return _cycles;
|
||||
}
|
||||
|
||||
uint16_t timer__get_milliseconds(void) {
|
||||
return _milliseconds;
|
||||
}
|
||||
|
||||
uint8_t timer__schedule_cycles(uint16_t cycles, void(*function)(void)) {
|
||||
return event_list__append(_cycles__scheduled, cycles, function);
|
||||
return _milliseconds__counter;
|
||||
}
|
||||
|
||||
uint8_t timer__schedule_milliseconds( uint16_t milliseconds,
|
||||
void(*function)(void) ) {
|
||||
return event_list__append( _milliseconds__scheduled,
|
||||
milliseconds,
|
||||
function );
|
||||
void(*function)(void)) {
|
||||
return event_list__append(
|
||||
_milliseconds__scheduled_events, milliseconds, function );
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void timer___tick_cycles (void) {
|
||||
_cycles++;
|
||||
event_list__tick(_cycles__scheduled);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
ISR(TIMER0_COMPA_vect) {
|
||||
_milliseconds++;
|
||||
event_list__tick(_milliseconds__scheduled);
|
||||
_milliseconds__counter++;
|
||||
event_list__tick(_milliseconds__scheduled_events);
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#
|
||||
|
||||
|
||||
SRC += $(wildcard $(CURDIR)/*.c)
|
||||
SRC += $(wildcard $(CURDIR)/device/$(MCU).c)
|
||||
SRC += $(wildcard $(CURDIR)/event-list/$(MCU).c)
|
||||
|
||||
|
|
|
@ -37,22 +37,21 @@
|
|||
#define main__was_pressed was_pressed
|
||||
#define main__row row
|
||||
#define main__col col
|
||||
#define main__update_leds update_leds
|
||||
#define main__flags flags
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// --- for main() loop ---
|
||||
|
||||
static bool _pressed_1[OPT__KB__ROWS][OPT__KB__COLUMNS];
|
||||
static bool _pressed_2[OPT__KB__ROWS][OPT__KB__COLUMNS];
|
||||
|
||||
bool (* is_pressed) [OPT__KB__ROWS][OPT__KB__COLUMNS] = &_pressed_1;
|
||||
bool (* was_pressed) [OPT__KB__ROWS][OPT__KB__COLUMNS] = &_pressed_2;
|
||||
bool (* is_pressed) [OPT__KB__ROWS][OPT__KB__COLUMNS]
|
||||
= &( bool [OPT__KB__ROWS][OPT__KB__COLUMNS] ){};
|
||||
bool (* was_pressed) [OPT__KB__ROWS][OPT__KB__COLUMNS]
|
||||
= &( bool [OPT__KB__ROWS][OPT__KB__COLUMNS] ){};
|
||||
|
||||
uint8_t row;
|
||||
uint8_t col;
|
||||
|
||||
bool update_leds = true;
|
||||
struct main__flags_t flags = { .update_leds = true };
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -115,7 +114,7 @@ int main(void) {
|
|||
|
||||
// note: only use the `kb__led__logical...` functions here, since the
|
||||
// meaning of the physical LEDs should be controlled by the layout
|
||||
if (update_leds) {
|
||||
if (flags.update_leds) {
|
||||
#define read usb__kb__read_led
|
||||
#define on kb__led__logical_on
|
||||
#define off kb__led__logical_off
|
||||
|
|
|
@ -25,13 +25,19 @@
|
|||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
struct main__flags_t {
|
||||
bool update_leds : 1;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
extern bool (* main__is_pressed) [OPT__KB__ROWS][OPT__KB__COLUMNS];
|
||||
extern bool (* main__was_pressed) [OPT__KB__ROWS][OPT__KB__COLUMNS];
|
||||
|
||||
extern uint8_t main__row;
|
||||
extern uint8_t main__col;
|
||||
|
||||
extern bool main__update_leds;
|
||||
extern struct main__flags_t main__flags;
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -45,6 +51,16 @@ extern bool main__update_leds;
|
|||
// ============================================================================
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// types ----------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// === main__flags_t ===
|
||||
/** types/struct main__flags_t/description
|
||||
* See the documentation for `main__flags`
|
||||
*/
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// variables ------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -71,15 +87,18 @@ extern bool main__update_leds;
|
|||
* Indicates which column is currently being tested for changes of key state
|
||||
*/
|
||||
|
||||
// === main__update_leds ===
|
||||
/** variables/main__update_leds/description
|
||||
* A predicate indicating whether to update the keyboard LED state based on the
|
||||
* USB LED state
|
||||
// === main__flags ===
|
||||
/** variables/main__flags/description
|
||||
* A collection of flags pertaining to the operation of `main()`
|
||||
*
|
||||
* This is for taking over control the LEDs temporarily, as one may want to
|
||||
* do when in a special mode, etc. If you want to change the meaning of the
|
||||
* LEDs under normal use, the correct place to do that is in the layout file,
|
||||
* where the `kb__led__logical_...()` functions are defined (see the
|
||||
* documentation in that and related files for more information).
|
||||
* Struct members:
|
||||
* - update_leds: A predicate indicating whether to update the keyboard LED
|
||||
* state based on the USB LED state.
|
||||
* - This is for taking over control the LEDs temporarily, as one may want
|
||||
* to do when in a special mode, etc. If you want to change the meaning
|
||||
* of the LEDs under normal use, the correct place to do that is in the
|
||||
* layout file, where the `kb__led__logical_...()` functions are defined
|
||||
* (see the documentation in that and related files for more
|
||||
* information).
|
||||
*/
|
||||
|
||||
|
|
Loading…
Reference in New Issue