summaryrefslogtreecommitdiff
path: root/firmware
diff options
context:
space:
mode:
authordefanor <defanor@uberspace.net>2017-01-21 00:26:32 +0300
committerdefanor <defanor@uberspace.net>2017-01-21 00:26:32 +0300
commit74cfe7b1a49aff63c6205a9a13036cf056a75947 (patch)
treee275011666b61c6a93474bceb8ef9a9294e27957 /firmware
Initial commit
Diffstat (limited to 'firmware')
-rw-r--r--firmware/keys.h146
-rw-r--r--firmware/main.cpp142
2 files changed, 288 insertions, 0 deletions
diff --git a/firmware/keys.h b/firmware/keys.h
new file mode 100644
index 0000000..9e2085c
--- /dev/null
+++ b/firmware/keys.h
@@ -0,0 +1,146 @@
+#define MK_CTRL 0x01
+#define MK_SHIFT 0x02
+#define MK_ALT 0x04
+#define MK_GUI 0x08
+#define MK_LCTRL 0x01
+#define MK_LSHIFT 0x02
+#define MK_LALT 0x04
+#define MK_LGUI 0x08
+#define MK_RCTRL 0x10
+#define MK_RSHIFT 0x20
+#define MK_RALT 0x40
+#define MK_RGUI 0x80
+
+#define KS_POWER_DOWN 0x81
+#define KS_SLEEP 0x82
+#define KS_WAKE_UP 0x83
+
+#define KM_PLAY 0xB0
+#define KM_PAUSE 0xB1
+#define KM_RECORD 0xB2
+#define KM_FAST_FORWARD 0xB3
+#define KM_REWIND 0xB4
+#define KM_NEXT 0xB5
+#define KM_PREV 0xB6
+#define KM_STOP 0xB7
+#define KM_EJECT 0xB8
+#define KM_RAND_PLAY 0xB0
+#define KM_PLAY_PAUSE 0xCD
+#define KM_PLAY_SKIP 0xCE
+#define KM_MUTE 0xE2
+#define KM_VOL_INC 0xE9
+#define KM_VOL_DEC 0xEA
+
+#define K_A 4
+#define K_B 5
+#define K_C 6
+#define K_D 7
+#define K_E 8
+#define K_F 9
+#define K_G 10
+#define K_H 11
+#define K_I 12
+#define K_J 13
+#define K_K 14
+#define K_L 15
+#define K_M 16
+#define K_N 17
+#define K_O 18
+#define K_P 19
+#define K_Q 20
+#define K_R 21
+#define K_S 22
+#define K_T 23
+#define K_U 24
+#define K_V 25
+#define K_W 26
+#define K_X 27
+#define K_Y 28
+#define K_Z 29
+#define K_1 30
+#define K_2 31
+#define K_3 32
+#define K_4 33
+#define K_5 34
+#define K_6 35
+#define K_7 36
+#define K_8 37
+#define K_9 38
+#define K_0 39
+#define K_RET 40
+#define K_ESC 41
+#define K_BSPC 42
+#define K_TAB 43
+#define K_SPC 44
+#define K_MINUS 45
+#define K_EQUAL 46
+#define K_LBRACE 47
+#define K_RBRACE 48
+#define K_BSLASH 49
+#define K_NON_US_NUM 50
+#define K_SCOL 51
+#define K_QUOTE 52
+#define K_TILDE 53
+#define K_COMMA 54
+#define K_DOT 55
+#define K_SLASH 56
+#define K_CPSLK 57
+#define K_F1 58
+#define K_F2 59
+#define K_F3 60
+#define K_F4 61
+#define K_F5 62
+#define K_F6 63
+#define K_F7 64
+#define K_F8 65
+#define K_F9 66
+#define K_F10 67
+#define K_F11 68
+#define K_F12 69
+#define K_PRSCR 70
+#define K_SCRLLK 71
+#define K_PAUSE 72
+#define K_INSERT 73
+#define K_HOME 74
+#define K_PGUP 75
+#define K_DEL 76
+#define K_END 77
+#define K_PGDN 78
+#define K_RIGHT 79
+#define K_LEFT 80
+#define K_DOWN 81
+#define K_UP 82
+#define K_NUM_LOCK 83
+#define K_NON_US_BS 100
+#define K_MENU 101
+#define K_F13 104
+#define K_F14 105
+#define K_F15 106
+#define K_F16 107
+#define K_F17 108
+#define K_F18 109
+#define K_F19 110
+#define K_F20 111
+#define K_F21 112
+#define K_F22 113
+#define K_F23 114
+#define K_F24 115
+
+#define KP_SLASH 84
+#define KP_ASTERIX 85
+#define KP_MINUS 86
+#define KP_PLUS 87
+#define KP_ENTER 88
+#define KP_1 89
+#define KP_2 90
+#define KP_3 91
+#define KP_4 92
+#define KP_5 93
+#define KP_6 94
+#define KP_7 95
+#define KP_8 96
+#define KP_9 97
+#define KP_0 98
+#define KP_DOT 99
+
+#define K_SYSRQ 154
diff --git a/firmware/main.cpp b/firmware/main.cpp
new file mode 100644
index 0000000..8975077
--- /dev/null
+++ b/firmware/main.cpp
@@ -0,0 +1,142 @@
+#include "WProgram.h"
+#include "keys.h"
+
+// [esc] [ ~ ] [ 1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] [ 6 ] [ 7 ] [ 8 ] [ 9 ] [ 0 ] [ - ] [ + ]
+// [ \ ] [ / ] [ q ] [ w ] [ f ] [ p ] [ g ] [ j ] [ l ] [ u ] [ y ] [ ; ] [ [ ] [ ] ]
+// [ shift ] [ a ] [ r ] [ s ] [ t ] [ d ] [ tab ] [ h ] [ n ] [ e ] [ i ] [ o ] [ shift ]
+// [control] [ z ] [ x ] [ c ] [ v ] [ b ] [ bkspc ] [ k ] [ m ] [ , ] [ . ] [ ' ] [control]
+// [ meta ] [ ] [ layout] [ alt ] [ ret ] [ space ] [layout ] [ altgr ] [ meta ]
+
+uint8_t keymap[3][7][15] = {
+ { // qwerty
+ {K_ESC, K_TILDE, K_1, K_2, K_3, K_4, K_5, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, K_6, K_7, K_8, K_9, K_0, K_MINUS, K_EQUAL},
+ {K_BSLASH, K_SLASH, K_Q, K_W, K_E, K_R, K_T, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, K_Y, K_U, K_I, K_O, K_P, K_LBRACE, K_RBRACE},
+ {0, 0, K_A, K_S, K_D, K_F, K_G, K_TAB, K_H, K_J, K_K, K_L, K_SCOL, 0, 0},
+ {0, 0, K_Z, K_X, K_C, K_V, K_B, K_BSPC, K_N, K_M, K_COMMA, K_DOT, K_QUOTE, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, K_RET, K_SPC, 0, 0, 0, 0, 0, 0}
+ },
+ { // mostly functional keys
+ // ESC, DEL, and F*
+ {K_ESC, K_DEL, K_F1, K_F2, K_F3, K_F4, K_F5, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, K_F6, K_F7, K_F8, K_F9, K_F10, K_F11, K_F12},
+ // nothing for now
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ // hjkl-style navigation keys
+ {0, 0, 0, K_HOME, K_PGUP, K_PGDN, K_END, K_TAB, K_LEFT, K_DOWN, K_UP, K_RIGHT, 0, 0, 0},
+ // nothing for now
+ {0, 0, 0, 0, 0, 0, 0, K_BSPC,0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, K_RET, K_SPC, 0, 0, 0, 0, 0, 0}
+ },
+ { // colemak
+ {K_ESC, K_TILDE, K_1, K_2, K_3, K_4, K_5, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, K_6, K_7, K_8, K_9, K_0, K_MINUS, K_EQUAL},
+ {K_BSLASH, K_SLASH, K_Q, K_W, K_F, K_P, K_G, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, K_J, K_L, K_U, K_Y, K_SCOL, K_LBRACE, K_RBRACE},
+ {0, 0, K_A, K_R, K_S, K_T, K_D, K_TAB, K_H, K_N, K_E, K_I, K_O, 0, 0},
+ {0, 0, K_Z, K_X, K_C, K_V, K_B, K_BSPC, K_K, K_M, K_COMMA, K_DOT, K_QUOTE, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, K_RET, K_SPC, 0, 0, 0, 0, 0, 0}
+ }
+};
+
+uint8_t p[7][15]; // pressed keys
+uint8_t prev_keys[6] = {0,0,0,0,0,0}, prev_modifiers = 0;
+uint8_t layout = 0;
+uint8_t layout_state = 0;
+
+int type () {
+ uint8_t i, j, ret = 0, k = 0, send = 0, cur_layout = layout;
+
+ // Set modifiers
+ keyboard_modifier_keys =
+ p[5][1] // left ctrl
+ | (p[4][1] << 1) // left shift
+ | (p[6][6] << 2) // left alt
+ | (p[6][1] << 3) // left "gui"
+ | (p[5][14] << 4) // right ctrl
+ | (p[4][14] << 5) // right shift
+ | (p[6][12] << 6) // right alt
+ | (p[6][14] << 7) // right "gui"
+ ;
+
+ // Handle layout keys
+ if (p[6][5] && p[6][10]) {
+ if (layout_state == 0) {
+ // Cycle through layouts. Perhaps should track the order in
+ // which Fn keys are pressed, to determine the direction.
+ layout = (layout + 1) % 3;
+ cur_layout = layout;
+ layout_state = 1;
+ }
+ } else if (p[6][5] || p[6][10]) {
+ // Set the functional layout temporary
+ cur_layout = 1;
+ } else {
+ layout_state = 0;
+ }
+
+ // Fill keyboard_keys
+ for (i = 0; i < 7; i++){
+ for (j = 0; j < 15; j++){
+ if (p[i][j] && k < 6) {
+ if (keymap[layout][i][j]) {
+ keyboard_keys[k] = keymap[cur_layout][i][j];
+ k++;
+ }
+ }
+ }
+ }
+ while (k < 6) {
+ keyboard_keys[k] = 0;
+ k++;
+ }
+
+ // Compare it to the previously sent keys, send if they differ
+ for (k = 0; k < 6; k++)
+ if (prev_keys[k] != keyboard_keys[k])
+ send = 1;
+ if (prev_modifiers != keyboard_modifier_keys)
+ send = 1;
+
+ if (send)
+ ret = usb_keyboard_send();
+
+ prev_modifiers = keyboard_modifier_keys;
+ for (k = 0; k < 6; k++)
+ prev_keys[k] = keyboard_keys[k];
+
+ return ret;
+}
+
+
+extern "C" int main(void) {
+ uint8_t i = 0, j = 0, s = 0;
+ uint8_t row_pins[7] = {2, 23, 9, 17, 13, 12, 11};
+ uint8_t col_pins[15] = {10, 8, 7, 3, 4, 5, 6, 14, 20, 21, 22, 19, 18, 16, 15};
+
+ for (i=0; i < 7; i ++) {
+ pinMode(row_pins[i], OUTPUT);
+ digitalWriteFast(row_pins[i], LOW);
+ }
+ for (i=0; i < 15; i ++) {
+ pinMode(col_pins[i], INPUT_PULLDOWN);
+ }
+
+ while (1) {
+ for (i = 0; i < 7; i++) {
+ digitalWriteFast(row_pins[i], HIGH);
+ for (j = ((i == 1 || i == 3) ? 8 : 0);
+ j < ((i == 0 || i == 2) ? 7 : 15);
+ j++)
+ {
+ s = digitalReadFast(col_pins[j]);
+ p[i][j] = s;
+ }
+ digitalWriteFast(row_pins[i], LOW);
+ }
+ type();
+ delay(5);
+ }
+}