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-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);
|
|
|
|
|
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
|
|
|
// call the appropriate function for each key(press|release), then send
|
|
|
|
// the usb report if necessary
|
|
|
|
// -------
|
2012-04-12 06:05:45 +02:00
|
|
|
// - everything else is the key function's responsibility; see the
|
2012-05-07 03:36:51 +02:00
|
|
|
// keyboard layout file ("keyboard/ergodox/layout/*.c") for which key
|
2012-04-29 07:39:23 +02:00
|
|
|
// is assigned which function (per layer), and "lib/key-functions.c"
|
|
|
|
// for their definitions
|
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
|
|
|
// - anything passed to the key function by reference may be changed
|
|
|
|
// after the call
|
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) {
|
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) {
|
2012-06-15 23:36:50 +02:00
|
|
|
uint8_t layer = current_layers[row][col];
|
|
|
|
pressed_layers[row][col] = layer;
|
2012-04-11 03:58:26 +02:00
|
|
|
kbfun_funptr_t press_function =
|
2012-06-15 23:36:50 +02:00
|
|
|
kb_layout_press_get(layer, row, col);
|
2012-04-11 03:58:26 +02:00
|
|
|
if (press_function) {
|
|
|
|
(*press_function)(
|
2012-06-15 23:36:50 +02:00
|
|
|
kb_layout_get(layer, row, col),
|
2012-06-15 07:02:57 +02:00
|
|
|
true, ¤t_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
|
|
|
¤t_layers, &pressed_layers,
|
|
|
|
&row, &col );
|
2012-04-11 03:58:26 +02:00
|
|
|
}
|
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
|
|
|
} else {
|
2012-06-15 23:36:50 +02:00
|
|
|
uint8_t layer = pressed_layers[row][col];
|
2012-04-11 03:58:26 +02:00
|
|
|
kbfun_funptr_t release_function =
|
2012-06-15 23:36:50 +02:00
|
|
|
kb_layout_release_get(layer, row, col);
|
2012-04-11 03:58:26 +02:00
|
|
|
if (release_function) {
|
|
|
|
(*release_function)(
|
2012-06-15 23:36:50 +02:00
|
|
|
kb_layout_get(layer, row, col),
|
2012-06-15 07:02:57 +02:00
|
|
|
false, ¤t_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
|
|
|
¤t_layers, &pressed_layers,
|
|
|
|
&row, &col );
|
2012-04-11 03:58:26 +02:00
|
|
|
}
|
|
|
|
}
|
2012-04-10 10:44:27 +02:00
|
|
|
|
2012-04-11 03:58:26 +02:00
|
|
|
usb_keyboard_send();
|
2012-06-01 09:50:45 +02:00
|
|
|
_delay_ms(KB_DEBOUNCE_TIME);
|
2012-04-11 03:58:26 +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;
|
|
|
|
}
|
|
|
|
|