2012-04-10 10:44:27 +02:00
|
|
|
// vim: ts=4 sw=4 sts=4
|
|
|
|
/* ----------------------------------------------------------------------------
|
|
|
|
* main()
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
* Copyright (c) 2012 Ben Blazak <benblazak.dev@gmail.com>
|
|
|
|
* Released under The MIT License (MIT) (see "license.md")
|
|
|
|
* Project located at <https://github.com/benblazak/ergodox-firmware>
|
|
|
|
* ------------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
|
2012-07-31 23:48:31 +02:00
|
|
|
#include <stdbool.h>
|
|
|
|
#include <stdint.h>
|
2012-04-10 10:44:27 +02:00
|
|
|
#include <util/delay.h>
|
2012-08-07 00:57:23 +02:00
|
|
|
#include "./lib-other/pjrc/usb_keyboard/usb_keyboard.h"
|
|
|
|
#include "./lib/key-functions/public.h"
|
|
|
|
#include "./keyboard/controller.h"
|
|
|
|
#include "./keyboard/layout.h"
|
|
|
|
#include "./keyboard/matrix.h"
|
|
|
|
#include "./main.h"
|
2012-07-31 23:48:31 +02:00
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
2012-08-07 00:57:23 +02:00
|
|
|
static bool _main_kb_is_pressed[KB_ROWS][KB_COLUMNS];
|
|
|
|
bool (*main_kb_is_pressed)[KB_ROWS][KB_COLUMNS] = &_main_kb_is_pressed;
|
2012-07-31 23:48:31 +02:00
|
|
|
|
2012-08-07 00:57:23 +02:00
|
|
|
static bool _main_kb_was_pressed[KB_ROWS][KB_COLUMNS];
|
|
|
|
bool (*main_kb_was_pressed)[KB_ROWS][KB_COLUMNS] = &_main_kb_was_pressed;
|
|
|
|
|
|
|
|
uint8_t main_layers_current;
|
|
|
|
uint8_t main_layers_press[KB_ROWS][KB_COLUMNS];
|
|
|
|
uint8_t main_layers_release[KB_ROWS][KB_COLUMNS];
|
|
|
|
|
|
|
|
uint8_t main_loop_row;
|
|
|
|
uint8_t main_loop_col;
|
|
|
|
|
|
|
|
uint8_t main_arg_layer;
|
|
|
|
uint8_t main_arg_row;
|
|
|
|
uint8_t main_arg_col;
|
|
|
|
bool main_arg_is_pressed;
|
|
|
|
bool main_arg_was_pressed;
|
2012-04-10 10:44:27 +02:00
|
|
|
|
2012-07-31 23:48:31 +02:00
|
|
|
// ----------------------------------------------------------------------------
|
2012-04-10 10:44:27 +02:00
|
|
|
|
2012-07-31 23:48:31 +02:00
|
|
|
/*
|
|
|
|
* main()
|
|
|
|
*/
|
2012-04-10 10:44:27 +02:00
|
|
|
int main(void) {
|
|
|
|
kb_init(); // does controller initialization too
|
|
|
|
|
2012-06-01 09:50:45 +02:00
|
|
|
kb_led_state_power_on();
|
2012-04-12 06:05:45 +02:00
|
|
|
|
2012-04-10 10:44:27 +02:00
|
|
|
usb_init();
|
|
|
|
while (!usb_configured());
|
2012-06-01 09:50:45 +02:00
|
|
|
kb_led_delay_usb_init(); // give the OS time to load drivers, etc.
|
2012-04-10 10:44:27 +02:00
|
|
|
|
2012-06-01 09:50:45 +02:00
|
|
|
kb_led_state_ready();
|
2012-04-12 06:05:45 +02:00
|
|
|
|
2012-04-10 10:44:27 +02:00
|
|
|
for (;;) {
|
2012-08-07 00:57:23 +02:00
|
|
|
// swap `main_kb_is_pressed` and `main_kb_was_pressed`, then update
|
|
|
|
bool (*temp)[KB_ROWS][KB_COLUMNS] = main_kb_was_pressed;
|
|
|
|
main_kb_was_pressed = main_kb_is_pressed;
|
|
|
|
main_kb_is_pressed = temp;
|
|
|
|
|
|
|
|
kb_update_matrix(*main_kb_is_pressed);
|
2012-04-10 10:44:27 +02:00
|
|
|
|
2012-06-21 01:56:24 +02:00
|
|
|
// this loop is responsible to
|
2012-08-07 00:57:23 +02:00
|
|
|
// - "execute" keys when they change state
|
2012-06-21 01:56:24 +02:00
|
|
|
// - 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)
|
2012-08-07 00:57:23 +02:00
|
|
|
// - see "lib/key-functions/public/*.c" for the function definitions
|
|
|
|
#define row main_loop_row
|
|
|
|
#define col main_loop_col
|
|
|
|
#define layer main_arg_layer
|
|
|
|
#define is_pressed main_arg_is_pressed
|
|
|
|
#define was_pressed main_arg_was_pressed
|
|
|
|
for (row=0; row<KB_ROWS; row++) {
|
|
|
|
for (col=0; col<KB_COLUMNS; col++) {
|
|
|
|
is_pressed = (*main_kb_is_pressed)[row][col];
|
|
|
|
was_pressed = (*main_kb_was_pressed)[row][col];
|
bugfix (mostly): changed the way layers are handled
before, if you pressed a key, then shifted layers, then released it, the
first layer's press() would be called, and the 2nd layer's release()
would be called, causing keys to stick, and probably other errors. now,
the layer that the key was on when it was pressed is kept track of, and
the proper release() is called.
also, layers can be shifted per key now, instead of just for the whole
board at once
i also changed how keyboard-private includes are handled. "private"
stuff is now in its own file, instead of being nested in an extra
`#ifdef`.
and i think that's it. i'm pretty tired right now, so there may be
errors, but it seemed to work all right with cursory tests.
2012-06-11 12:27:34 +02:00
|
|
|
|
2012-04-11 03:58:26 +02:00
|
|
|
if (is_pressed != was_pressed) {
|
2012-08-07 00:57:23 +02:00
|
|
|
if (is_pressed) {
|
|
|
|
layer = main_layers_press[row][col];
|
|
|
|
main_layers_release[row][col] = layer;
|
|
|
|
} else {
|
|
|
|
layer = main_layers_release[row][col];
|
|
|
|
}
|
|
|
|
|
|
|
|
// set remaining vars, and "execute" key
|
|
|
|
main_arg_row = row;
|
|
|
|
main_arg_col = col;
|
|
|
|
main_exec_key();
|
2012-04-11 03:58:26 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2012-08-07 00:57:23 +02:00
|
|
|
#undef row
|
|
|
|
#undef col
|
|
|
|
#undef layer
|
|
|
|
#undef is_pressed
|
|
|
|
#undef was_pressed
|
2012-04-10 10:44:27 +02:00
|
|
|
|
2012-06-21 01:56:24 +02:00
|
|
|
// send the USB report (even if nothing's changed)
|
|
|
|
usb_keyboard_send();
|
2012-08-07 00:57:23 +02:00
|
|
|
_delay_ms(MAKEFILE_DEBOUNCE_TIME);
|
2012-06-21 01:56:24 +02:00
|
|
|
|
2012-04-10 10:44:27 +02:00
|
|
|
// update LEDs
|
2012-06-01 09:50:45 +02:00
|
|
|
if (keyboard_leds & (1<<0)) { kb_led_num_on(); }
|
|
|
|
else { kb_led_num_off(); }
|
|
|
|
if (keyboard_leds & (1<<1)) { kb_led_caps_on(); }
|
|
|
|
else { kb_led_caps_off(); }
|
|
|
|
if (keyboard_leds & (1<<2)) { kb_led_scroll_on(); }
|
|
|
|
else { kb_led_scroll_off(); }
|
|
|
|
if (keyboard_leds & (1<<3)) { kb_led_compose_on(); }
|
|
|
|
else { kb_led_compose_off(); }
|
|
|
|
if (keyboard_leds & (1<<4)) { kb_led_kana_on(); }
|
|
|
|
else { kb_led_kana_off(); }
|
2012-04-10 10:44:27 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2012-08-07 00:57:23 +02:00
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
// convenience macros (for the helper functions below)
|
|
|
|
#define layer main_arg_layer
|
|
|
|
#define row main_arg_row
|
|
|
|
#define col main_arg_col
|
|
|
|
#define is_pressed main_arg_is_pressed
|
|
|
|
#define was_pressed main_arg_was_pressed
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Exec key
|
|
|
|
* - Execute the keypress or keyrelease function (if it exists) of the key at
|
|
|
|
* the current possition.
|
|
|
|
*/
|
|
|
|
void main_exec_key(void) {
|
|
|
|
void (*key_function)(void) =
|
|
|
|
( (is_pressed)
|
|
|
|
? kb_layout_press_get(layer, row, col)
|
|
|
|
: kb_layout_release_get(layer, row, col) );
|
|
|
|
|
|
|
|
if (key_function)
|
|
|
|
(*key_function)();
|
|
|
|
}
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|