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>
|
|
|
|
* ------------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
|
|
|
|
#include <util/delay.h>
|
2012-04-29 08:40:00 +02:00
|
|
|
#include "lib-other/pjrc/usb_keyboard/usb_keyboard.h"
|
|
|
|
#include "lib/data-types.h"
|
2012-06-21 01:56:24 +02:00
|
|
|
#include "lib/key-functions.h"
|
2012-04-10 10:44:27 +02:00
|
|
|
|
|
|
|
#include "keyboard.h"
|
|
|
|
|
|
|
|
|
|
|
|
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-06-15 07:02:57 +02:00
|
|
|
// the overall current layer
|
2012-06-15 23:36:50 +02:00
|
|
|
static uint8_t current_layer;
|
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
|
|
|
// the current layer for each key
|
|
|
|
static uint8_t current_layers[KB_ROWS][KB_COLUMNS];
|
|
|
|
// the layer each key was on when it was last pressed
|
|
|
|
static uint8_t pressed_layers[KB_ROWS][KB_COLUMNS];
|
2012-04-10 10:44:27 +02:00
|
|
|
|
|
|
|
// swap `kb_is_pressed` and `kb_was_pressed`, then update
|
|
|
|
bool (*temp)[KB_ROWS][KB_COLUMNS] = kb_was_pressed;
|
|
|
|
kb_was_pressed = kb_is_pressed;
|
|
|
|
kb_is_pressed = temp;
|
|
|
|
|
|
|
|
kb_update_matrix(*kb_is_pressed);
|
|
|
|
|
2012-06-21 01:56:24 +02:00
|
|
|
// 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
|
2012-04-11 03:58:26 +02:00
|
|
|
for (uint8_t row=0; row<KB_ROWS; row++) {
|
|
|
|
for (uint8_t col=0; col<KB_COLUMNS; 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
|
|
|
bool is_pressed = (*kb_is_pressed)[row][col];
|
|
|
|
bool was_pressed = (*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-06-21 01:56:24 +02:00
|
|
|
uint8_t layer = ( (is_pressed)
|
|
|
|
? current_layers[row][col]
|
|
|
|
: pressed_layers[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-06-21 01:56:24 +02:00
|
|
|
if (is_pressed)
|
2012-06-15 23:36:50 +02:00
|
|
|
pressed_layers[row][col] = layer;
|
2012-06-21 01:56:24 +02:00
|
|
|
|
|
|
|
_kbfun_exec_key(
|
|
|
|
is_pressed, 0, layer,
|
|
|
|
&row, &col, ¤t_layer,
|
|
|
|
¤t_layers, &pressed_layers );
|
2012-04-11 03:58:26 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
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();
|
|
|
|
_delay_ms(KB_DEBOUNCE_TIME);
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|