Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * Nekoboard.ino --- keyboard firmware code
- *
- * By: Yuriy Pitomets < [email protected] >
- * License: GNU GPL v.3
- *
- */
- const char Key_LEFT_CTRL = 0x80;
- const char Key_LEFT_SHIFT = 0x81;
- const char Key_LEFT_ALT = 0x82;
- const char Key_LEFT_GUI = 0x83;
- const char Key_RIGHT_CTRL = 0x84;
- const char Key_RIGHT_SHIFT = 0x85;
- const char Key_RIGHT_ALT = 0x86;
- const char Key_RIGHT_GUI = 0x87;
- const char Key_UP_ARROW = 0xDA;
- const char Key_DOWN_ARROW = 0xD9;
- const char Key_LEFT_ARROW = 0xD8;
- const char Key_RIGHT_ARROW = 0xD7;
- const char Key_RETURN = 0xB0;
- const char Key_ESC = 0xB1;
- const char Key_BACKSPACE = 0xB2;
- const char Key_TAB = 0xB3;
- const char Key_INSERT = 0xD1;
- const char Key_DELETE = 0xD4;
- const char Key_PAGE_UP = 0xD3;
- const char Key_PAGE_DOWN = 0xD6;
- const char Key_HOME = 0xD2;
- const char Key_END = 0xD5;
- const char Key_CAPS_LOCK = 0xC1;
- const char Key_F1 = 0xC2;
- const char Key_F2 = 0xC3;
- const char Key_F3 = 0xC4;
- const char Key_F4 = 0xC5;
- const char Key_F5 = 0xC6;
- const char Key_F6 = 0xC7;
- const char Key_F7 = 0xC8;
- const char Key_F8 = 0xC9;
- const char Key_F9 = 0xCA;
- const char Key_F10 = 0xCB;
- const char Key_F11 = 0xCC;
- const char Key_F12 = 0xCD;
- const char Key_0 = '0';
- const char Key_1 = '1';
- const char Key_2 = '2';
- const char Key_3 = '3';
- const char Key_4 = '4';
- const char Key_5 = '5';
- const char Key_6 = '6';
- const char Key_7 = '7';
- const char Key_8 = '8';
- const char Key_9 = '9';
- const char Key_A = 'a';
- const char Key_B = 'b';
- const char Key_C = 'c';
- const char Key_D = 'd';
- const char Key_E = 'e';
- const char Key_F = 'f';
- const char Key_G = 'g';
- const char Key_H = 'h';
- const char Key_I = 'i';
- const char Key_J = 'j';
- const char Key_K = 'k';
- const char Key_L = 'l';
- const char Key_M = 'm';
- const char Key_N = 'n';
- const char Key_O = 'o';
- const char Key_P = 'p';
- const char Key_Q = 'q';
- const char Key_R = 'r';
- const char Key_S = 's';
- const char Key_T = 't';
- const char Key_U = 'u';
- const char Key_V = 'v';
- const char Key_W = 'w';
- const char Key_X = 'x';
- const char Key_Y = 'y';
- const char Key_Z = 'z';
- const char Key_SPACE = ' ';
- const char Key_DOT = '.';
- const char Key_COMMA = ',';
- const char Key_SEMICOLON = ';';
- const char Key_COLON = ':';
- const char Key_BACKTICK = '`';
- const char Key_TILDA = '~';
- const char Key_EXCLAMATION = '!';
- const char Key_AT = '@';
- const char Key_HASH = '#';
- const char Key_DOLLAR = '$';
- const char Key_CENT = '%';
- const char Key_CARET = '^';
- const char Key_AMPERSAND = '&';
- const char Key_ASTERISK = '*';
- const char Key_MINUS = '-';
- const char Key_PLUS = '+';
- const char Key_EQUAL = '=';
- const char Key_LEFT_PAREN = '(';
- const char Key_RIGHT_PAREN = ')';
- const char Key_LEFT_BRACKET = '[';
- const char Key_RIGHT_BRACKET = ']';
- const char Key_LEFT_BRACE = '{';
- const char Key_RIGHT_BRACE = '}';
- const char Key_LESS = '<';
- const char Key_GREATER = '>';
- const char Key_QUOTE = '\'';
- const char Key_BACKSLASH = '\\';
- const char Key_PIPE = '|';
- const char Key_SLASH = '/';
- const char Key_KEYPAD_CLEAR = 0xDB;
- const char Key_KEYPAD_SLASH = 0xDC;
- const char Key_KEYPAD_MULTIPLY = 0xDD;
- const char Key_KEYPAD_MINUS = 0xDE;
- const char Key_KEYPAD_PLUS = 0xDF;
- const char Key_ENTER = 0xe0;
- const char Key_KEYPAD_1 = 0xe1;
- const char Key_KEYPAD_2 = 0xe2;
- const char Key_KEYPAD_3 = 0xe3;
- const char Key_KEYPAD_4 = 0xe4;
- const char Key_KEYPAD_5 = 0xe5;
- const char Key_KEYPAD_6 = 0xe6;
- const char Key_KEYPAD_7 = 0xe7;
- const char Key_KEYPAD_8 = 0xe8;
- const char Key_KEYPAD_9 = 0xe9;
- const char Key_KEYPAD_0 = 0xea;
- const char Key_KEYPAD_DOT = 0xeb;
- const char Key_DANISH_DOLLAR = 0xec;
- const char Key_PC_APPLCIATION = 0xed;
- const char Key_F13 = 0xF0;
- const char Key_F16 = 0xF3;
- const char Key_F17 = 0xF4;
- const char Key_F18 = 0xF5;
- const char Key_F19 = 0xF6;
- const char Key_HELP = 0xfb;
- const char Key_BACKLIGHT_DOWN = 0xF1;
- const char Key_BACKLIGHT_UP = 0xF2;
- const char NO_KEY = false;
- const char Key_RIGHT_FN = 0xfe;
- const char Key_LEFT_FN = 0xff;
- const byte Rows = 9;
- const byte Columns = 5;
- const byte Layouts = 3;
- const char MatrixLayouts[Layouts][Columns][Rows] = {
- {{Key_Q ,Key_O ,Key_COMMA
- ,Key_QUOTE ,Key_A ,Key_SEMICOLON
- ,Key_BACKSLASH ,Key_AMPERSAND ,Key_HASH }
- ,{Key_X ,Key_I ,Key_Y
- ,Key_K ,Key_U ,Key_P
- ,Key_J ,Key_E ,Key_DOT }
- ,{Key_LEFT_FN ,Key_F9 ,Key_LEFT_CTRL
- ,Key_LEFT_GUI ,Key_SPACE ,Key_LEFT_ALT
- ,Key_F10 ,Key_LEFT_SHIFT ,NO_KEY }
- ,{Key_T ,Key_W ,Key_G
- ,Key_H ,Key_M ,Key_F
- ,Key_D ,Key_B ,Key_C }
- ,{Key_MINUS ,Key_SLASH ,Key_L
- ,Key_S ,Key_Z ,Key_R
- ,Key_N ,Key_V ,Key_DOLLAR }
- },// raw
- {{Key_Q ,Key_O ,Key_COMMA
- ,Key_QUOTE ,Key_A ,Key_SEMICOLON
- ,Key_BACKSLASH ,Key_CENT ,Key_CARET }
- ,{Key_X ,Key_I ,Key_Y
- ,Key_K ,Key_U ,Key_P
- ,Key_J ,Key_E ,Key_DOT }
- ,{Key_LEFT_FN ,Key_F9 ,Key_LEFT_CTRL
- ,Key_LEFT_GUI ,Key_SPACE ,Key_LEFT_ALT
- ,Key_F10 ,Key_LEFT_SHIFT ,NO_KEY }
- ,{Key_T ,Key_W ,Key_G
- ,Key_H ,Key_M ,Key_F
- ,Key_D ,Key_B ,Key_C }
- ,{Key_MINUS ,Key_SLASH ,Key_L
- ,Key_S ,Key_Z ,Key_R
- ,Key_N ,Key_V ,Key_AT }
- },// with shift
- {{Key_LEFT_BRACKET ,Key_HOME ,Key_7
- ,Key_EXCLAMATION ,Key_F1 ,Key_9
- ,Key_TAB ,Key_ESC ,Key_TILDA }
- ,{Key_ASTERISK ,Key_END ,Key_1
- ,Key_LEFT_PAREN ,Key_PAGE_DOWN ,Key_3
- ,Key_LEFT_BRACE ,Key_PAGE_UP ,Key_5 }
- ,{Key_LEFT_FN ,Key_F11 ,Key_LEFT_CTRL
- ,Key_LEFT_GUI ,Key_BACKSPACE ,Key_LEFT_ALT
- ,Key_F12 ,Key_LEFT_SHIFT ,NO_KEY }
- ,{Key_UP_ARROW ,Key_RIGHT_BRACE ,Key_2
- ,Key_DOWN_ARROW ,Key_RIGHT_PAREN ,Key_0
- ,Key_LEFT_ARROW ,Key_EQUAL ,Key_4 }
- ,{Key_DELETE ,Key_RETURN ,Key_8
- ,Key_F8 ,Key_PLUS ,Key_6
- ,Key_RIGHT_ARROW ,Key_RIGHT_BRACKET ,Key_BACKTICK }
- } // with function
- };
- const byte UnshiftCount = 22;
- const char UnshiftKeys[UnshiftCount] = {
- Key_LEFT_BRACKET ,Key_7 ,Key_EXCLAMATION,
- Key_9 ,Key_TILDA ,Key_ASTERISK,
- Key_1 ,Key_LEFT_PAREN ,Key_3, Key_LEFT_BRACE,
- Key_5 ,Key_RIGHT_BRACE ,Key_2,
- Key_RIGHT_PAREN ,Key_0 ,Key_EQUAL,
- Key_4 ,Key_8 ,Key_PLUS,
- Key_6 ,Key_RIGHT_BRACKET ,Key_BACKTICK };
- const byte RowPins[Rows] = { 9, 8, 7, 6, 5, 4, 3, A1, A2 };
- const byte ColumnPins[Columns] = { 10, 16, 14, 15, A0 };
- const unsigned int RoundDelay = 10000;
- const byte BounceProtect = 3;
- const byte BounceClear = 0;
- const byte FirstLayer = 0;
- const byte SecondLayer = 1;
- const byte ThirdLayer = 2;
- const byte States = 2;
- const byte StateBounce = 0;
- const byte StateLayer = 1;
- typedef byte (*const key_position)[States];
- byte currentLayers;
- byte matrixState[Columns][Rows][States];
- const byte ShiftCount = 1;
- key_position ShiftPositions[ShiftCount] = { &matrixState[2][7] };
- const byte FnCount = 1;
- key_position FnPositions[FnCount] = { &matrixState[2][0] };
- void clean_matrix_state();
- void setup_pins();
- byte current_layer() __attribute__((const));
- void scan_matrix();
- void scan_key(const byte column, const byte row, const byte keyState);
- void key_press(key_position keyPosition, const char keyCode);
- void key_release(key_position keyPosition, const char keyCode);
- void unshift(key_position keyPosition, const char keyCode);
- void shift_release(key_position keyPosition);
- void function_release(key_position keyPosition);
- void setup()
- {
- clean_matrix_state();
- setup_pins();
- Keyboard.begin();
- Serial.begin(9600);
- }
- void loop()
- {
- scan_matrix();
- delayMicroseconds(RoundDelay);
- }
- void clean_matrix_state()
- {
- currentLayers = FirstLayer;
- for (byte column = 0; column < Columns; column++) {
- for (byte row = 0; row < Rows; row++) {
- matrixState[column][row][StateBounce] = BounceClear;
- matrixState[column][row][StateLayer] = FirstLayer;
- }
- }
- }
- void setup_pins()
- {
- for (byte row = 0; row < Rows; row++) {
- pinMode(RowPins[row], OUTPUT);
- digitalWrite(RowPins[row], HIGH);
- }
- for (byte column = 0; column < Columns; column++) {
- pinMode(ColumnPins[column], INPUT);
- digitalWrite(ColumnPins[column], HIGH);
- }
- }
- byte current_layer()
- {
- // TODO: refactor me
- if ((currentLayers & ThirdLayer) == ThirdLayer) {
- return ThirdLayer;
- } else if ((currentLayers & SecondLayer) == SecondLayer) {
- return SecondLayer;
- } else {
- return FirstLayer;
- }
- }
- void scan_matrix()
- {
- for (byte row = 0; row < Rows; row++) {
- digitalWrite(RowPins[row], LOW);
- for (byte column = 0; column < Columns; column++) {
- scan_key(column, row, !digitalRead(ColumnPins[column]));
- }
- digitalWrite(RowPins[row], HIGH);
- }
- }
- void scan_key(const byte column, const byte row, const byte keyState)
- {
- key_position keyPosition = &matrixState[column][row];
- if (keyState) {
- if (*keyPosition[StateBounce] < BounceProtect) {
- ++*keyPosition[StateBounce];
- if (*keyPosition[StateBounce] == BounceProtect) {
- *keyPosition[StateLayer] = current_layer();
- Serial.print("Press Key -> ");
- Serial.println(MatrixLayouts[*keyPosition[StateLayer]][column][row]);
- Serial.print("Press layer: ");
- Serial.println(*keyPosition[StateLayer]);
- //key_press(keyPosition, MatrixLayouts[*keyPosition[StateLayer]][column][row]);
- }
- }
- } else {
- if (*keyPosition[StateBounce] > BounceClear) {
- --*keyPosition[StateBounce];
- if (*keyPosition[StateBounce] == BounceClear) {
- Serial.print("Release Key -> ");
- Serial.println(MatrixLayouts[*keyPosition[StateLayer]][column][row]);
- Serial.print("Release layer: ");
- Serial.println(*keyPosition[StateLayer]);
- key_release(keyPosition, MatrixLayouts[*keyPosition[StateLayer]][column][row]);
- // key_release(key, MatrixLayouts[0][column][row]);
- // key_release(key, MatrixLayouts[1][column][row]);
- // key_release(key, MatrixLayouts[2][column][row]);
- *keyPosition[StateLayer] = FirstLayer;
- }
- }
- }
- }
- void key_press(key_position keyPosition, const char keyCode)
- {
- switch (keyCode) {
- case Key_LEFT_SHIFT:
- case Key_RIGHT_SHIFT:
- {
- currentLayers |= SecondLayer;
- }
- break;
- case Key_LEFT_FN:
- case Key_RIGHT_FN:
- {
- currentLayers |= ThirdLayer;
- }
- break;
- case NO_KEY:
- {
- return;
- }
- }
- // unshift(keyPosition, keyCode);
- Keyboard.press(keyCode);
- }
- void key_release(key_position keyPosition, const char keyCode)
- {
- switch (keyCode) {
- case Key_LEFT_SHIFT:
- case Key_RIGHT_SHIFT:
- {
- // shift_release(keyPosition);
- }
- break;
- case Key_LEFT_FN:
- case Key_RIGHT_FN:
- {
- // function_release(keyPosition);
- }
- break;
- case NO_KEY:
- {
- return;
- }
- }
- Keyboard.release(keyCode);
- }
- void unshift(key_position keyPosition, const char keyCode)
- {
- if ((currentLayers & SecondLayer) == SecondLayer) {
- return;
- }
- for (byte key = 0; key < UnshiftCount; key++){
- if (UnshiftKeys[key] == keyCode) {
- for (byte shift = 0; shift < ShiftCount; shift++) {
- if (*ShiftPositions[shift][StateBounce] > BounceClear) {
- key_release(ShiftPositions[shift], keyCode);
- *ShiftPositions[shift][StateBounce] = BounceClear;
- *ShiftPositions[shift][StateLayer] = FirstLayer;
- }
- }
- break;
- }
- }
- }
- void shift_release(key_position keyPosition)
- {
- byte single = true;
- for (byte shift = 0; shift < ShiftCount; shift++) {
- if ( keyPosition != ShiftPositions[shift]
- && *ShiftPositions[shift][StateBounce] > BounceClear
- ) {
- single = false;
- break;
- }
- }
- if (single) {
- currentLayers &= ~SecondLayer;
- }
- }
- void function_release(key_position keyPosition)
- {
- byte single = true;
- for (byte function = 0; function < FnCount; function++) {
- if ( keyPosition != FnPositions[function]
- && *FnPositions[function][0] > 0
- ) {
- single = false;
- break;
- }
- }
- if (single) {
- currentLayers &= ~ThirdLayer;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment