Kamiel

Necoboard.ino

Jun 14th, 2014
297
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 15.20 KB | None | 0 0
  1. /*
  2.  * Nekoboard.ino --- keyboard firmware code
  3.  *
  4.  * By:  Yuriy Pitomets < [email protected] >
  5.  * License: GNU GPL v.3
  6.  *
  7.  */
  8.  
  9.  
  10. const char Key_LEFT_CTRL               = 0x80;
  11. const char Key_LEFT_SHIFT              = 0x81;
  12. const char Key_LEFT_ALT                = 0x82;
  13. const char Key_LEFT_GUI                = 0x83;
  14. const char Key_RIGHT_CTRL              = 0x84;
  15. const char Key_RIGHT_SHIFT             = 0x85;
  16. const char Key_RIGHT_ALT               = 0x86;
  17. const char Key_RIGHT_GUI               = 0x87;
  18.  
  19. const char Key_UP_ARROW                = 0xDA;
  20. const char Key_DOWN_ARROW              = 0xD9;
  21. const char Key_LEFT_ARROW              = 0xD8;
  22. const char Key_RIGHT_ARROW             = 0xD7;
  23. const char Key_RETURN                  = 0xB0;
  24. const char Key_ESC                     = 0xB1;
  25. const char Key_BACKSPACE               = 0xB2;
  26. const char Key_TAB                     = 0xB3;
  27. const char Key_INSERT                  = 0xD1;
  28. const char Key_DELETE                  = 0xD4;
  29. const char Key_PAGE_UP                 = 0xD3;
  30. const char Key_PAGE_DOWN               = 0xD6;
  31. const char Key_HOME                    = 0xD2;
  32. const char Key_END                     = 0xD5;
  33.  
  34. const char Key_CAPS_LOCK               = 0xC1;
  35. const char Key_F1                      = 0xC2;
  36. const char Key_F2                      = 0xC3;
  37. const char Key_F3                      = 0xC4;
  38. const char Key_F4                      = 0xC5;
  39. const char Key_F5                      = 0xC6;
  40. const char Key_F6                      = 0xC7;
  41. const char Key_F7                      = 0xC8;
  42. const char Key_F8                      = 0xC9;
  43. const char Key_F9                      = 0xCA;
  44. const char Key_F10                     = 0xCB;
  45. const char Key_F11                     = 0xCC;
  46. const char Key_F12                     = 0xCD;
  47.  
  48. const char Key_0                       = '0';
  49. const char Key_1                       = '1';
  50. const char Key_2                       = '2';
  51. const char Key_3                       = '3';
  52. const char Key_4                       = '4';
  53. const char Key_5                       = '5';
  54. const char Key_6                       = '6';
  55. const char Key_7                       = '7';
  56. const char Key_8                       = '8';
  57. const char Key_9                       = '9';
  58. const char Key_A                       = 'a';
  59. const char Key_B                       = 'b';
  60. const char Key_C                       = 'c';
  61. const char Key_D                       = 'd';
  62. const char Key_E                       = 'e';
  63. const char Key_F                       = 'f';
  64. const char Key_G                       = 'g';
  65. const char Key_H                       = 'h';
  66. const char Key_I                       = 'i';
  67. const char Key_J                       = 'j';
  68. const char Key_K                       = 'k';
  69. const char Key_L                       = 'l';
  70. const char Key_M                       = 'm';
  71. const char Key_N                       = 'n';
  72. const char Key_O                       = 'o';
  73. const char Key_P                       = 'p';
  74. const char Key_Q                       = 'q';
  75. const char Key_R                       = 'r';
  76. const char Key_S                       = 's';
  77. const char Key_T                       = 't';
  78. const char Key_U                       = 'u';
  79. const char Key_V                       = 'v';
  80. const char Key_W                       = 'w';
  81. const char Key_X                       = 'x';
  82. const char Key_Y                       = 'y';
  83. const char Key_Z                       = 'z';
  84.  
  85. const char Key_SPACE                   = ' ';
  86. const char Key_DOT                     = '.';
  87. const char Key_COMMA                   = ',';
  88. const char Key_SEMICOLON               = ';';
  89. const char Key_COLON                   = ':';
  90. const char Key_BACKTICK                = '`';
  91. const char Key_TILDA                   = '~';
  92. const char Key_EXCLAMATION             = '!';
  93. const char Key_AT                      = '@';
  94. const char Key_HASH                    = '#';
  95. const char Key_DOLLAR                  = '$';
  96. const char Key_CENT                    = '%';
  97. const char Key_CARET                   = '^';
  98. const char Key_AMPERSAND               = '&';
  99. const char Key_ASTERISK                = '*';
  100. const char Key_MINUS                   = '-';
  101. const char Key_PLUS                    = '+';
  102. const char Key_EQUAL                   = '=';
  103. const char Key_LEFT_PAREN              = '(';
  104. const char Key_RIGHT_PAREN             = ')';
  105. const char Key_LEFT_BRACKET            = '[';
  106. const char Key_RIGHT_BRACKET           = ']';
  107. const char Key_LEFT_BRACE              = '{';
  108. const char Key_RIGHT_BRACE             = '}';
  109. const char Key_LESS                    = '<';
  110. const char Key_GREATER                 = '>';
  111. const char Key_QUOTE                   = '\'';
  112. const char Key_BACKSLASH               = '\\';
  113. const char Key_PIPE                    = '|';
  114. const char Key_SLASH                   = '/';
  115.  
  116. const char Key_KEYPAD_CLEAR            = 0xDB;
  117. const char Key_KEYPAD_SLASH            = 0xDC;
  118. const char Key_KEYPAD_MULTIPLY         = 0xDD;
  119. const char Key_KEYPAD_MINUS            = 0xDE;
  120. const char Key_KEYPAD_PLUS             = 0xDF;
  121. const char Key_ENTER                   = 0xe0;
  122. const char Key_KEYPAD_1                = 0xe1;
  123. const char Key_KEYPAD_2                = 0xe2;
  124. const char Key_KEYPAD_3                = 0xe3;
  125. const char Key_KEYPAD_4                = 0xe4;
  126. const char Key_KEYPAD_5                = 0xe5;
  127. const char Key_KEYPAD_6                = 0xe6;
  128. const char Key_KEYPAD_7                = 0xe7;
  129. const char Key_KEYPAD_8                = 0xe8;
  130. const char Key_KEYPAD_9                = 0xe9;
  131. const char Key_KEYPAD_0                = 0xea;
  132. const char Key_KEYPAD_DOT              = 0xeb;
  133. const char Key_DANISH_DOLLAR           = 0xec;
  134. const char Key_PC_APPLCIATION          = 0xed;
  135. const char Key_F13                     = 0xF0;
  136. const char Key_F16                     = 0xF3;
  137. const char Key_F17                     = 0xF4;
  138. const char Key_F18                     = 0xF5;
  139. const char Key_F19                     = 0xF6;
  140.  
  141. const char Key_HELP                    = 0xfb;
  142. const char Key_BACKLIGHT_DOWN          = 0xF1;
  143. const char Key_BACKLIGHT_UP            = 0xF2;
  144. const char NO_KEY                      = false;
  145. const char Key_RIGHT_FN                = 0xfe;
  146. const char Key_LEFT_FN                 = 0xff;
  147.  
  148. const byte Rows    = 9;
  149. const byte Columns = 5;
  150.  
  151. const byte Layouts = 3;
  152.  
  153. const char MatrixLayouts[Layouts][Columns][Rows] = {
  154.   {{Key_Q             ,Key_O             ,Key_COMMA
  155.    ,Key_QUOTE         ,Key_A             ,Key_SEMICOLON
  156.    ,Key_BACKSLASH     ,Key_AMPERSAND     ,Key_HASH            }
  157.   ,{Key_X             ,Key_I             ,Key_Y
  158.    ,Key_K             ,Key_U             ,Key_P
  159.    ,Key_J             ,Key_E             ,Key_DOT             }
  160.   ,{Key_LEFT_FN       ,Key_F9            ,Key_LEFT_CTRL
  161.    ,Key_LEFT_GUI      ,Key_SPACE         ,Key_LEFT_ALT
  162.    ,Key_F10           ,Key_LEFT_SHIFT    ,NO_KEY              }
  163.   ,{Key_T             ,Key_W             ,Key_G
  164.    ,Key_H             ,Key_M             ,Key_F
  165.    ,Key_D             ,Key_B             ,Key_C               }
  166.   ,{Key_MINUS         ,Key_SLASH         ,Key_L
  167.    ,Key_S             ,Key_Z             ,Key_R
  168.    ,Key_N             ,Key_V             ,Key_DOLLAR          }
  169.   },// raw
  170.   {{Key_Q             ,Key_O             ,Key_COMMA
  171.    ,Key_QUOTE         ,Key_A             ,Key_SEMICOLON
  172.    ,Key_BACKSLASH     ,Key_CENT          ,Key_CARET           }
  173.   ,{Key_X             ,Key_I             ,Key_Y
  174.    ,Key_K             ,Key_U             ,Key_P
  175.    ,Key_J             ,Key_E             ,Key_DOT             }
  176.   ,{Key_LEFT_FN       ,Key_F9            ,Key_LEFT_CTRL
  177.    ,Key_LEFT_GUI      ,Key_SPACE         ,Key_LEFT_ALT
  178.    ,Key_F10           ,Key_LEFT_SHIFT    ,NO_KEY              }
  179.   ,{Key_T             ,Key_W             ,Key_G
  180.    ,Key_H             ,Key_M             ,Key_F
  181.    ,Key_D             ,Key_B             ,Key_C               }
  182.   ,{Key_MINUS         ,Key_SLASH         ,Key_L
  183.    ,Key_S             ,Key_Z             ,Key_R
  184.    ,Key_N             ,Key_V             ,Key_AT              }
  185.   },// with shift
  186.   {{Key_LEFT_BRACKET  ,Key_HOME          ,Key_7
  187.    ,Key_EXCLAMATION   ,Key_F1            ,Key_9
  188.    ,Key_TAB           ,Key_ESC           ,Key_TILDA           }
  189.   ,{Key_ASTERISK      ,Key_END           ,Key_1
  190.    ,Key_LEFT_PAREN    ,Key_PAGE_DOWN     ,Key_3
  191.    ,Key_LEFT_BRACE    ,Key_PAGE_UP       ,Key_5               }
  192.   ,{Key_LEFT_FN       ,Key_F11           ,Key_LEFT_CTRL
  193.    ,Key_LEFT_GUI      ,Key_BACKSPACE     ,Key_LEFT_ALT
  194.    ,Key_F12           ,Key_LEFT_SHIFT    ,NO_KEY              }
  195.   ,{Key_UP_ARROW      ,Key_RIGHT_BRACE   ,Key_2
  196.    ,Key_DOWN_ARROW    ,Key_RIGHT_PAREN   ,Key_0
  197.    ,Key_LEFT_ARROW    ,Key_EQUAL         ,Key_4               }
  198.   ,{Key_DELETE        ,Key_RETURN        ,Key_8
  199.    ,Key_F8            ,Key_PLUS          ,Key_6
  200.    ,Key_RIGHT_ARROW   ,Key_RIGHT_BRACKET ,Key_BACKTICK        }
  201.   } // with function
  202. };
  203.  
  204. const byte UnshiftCount = 22;
  205. const char UnshiftKeys[UnshiftCount] = {
  206.   Key_LEFT_BRACKET  ,Key_7             ,Key_EXCLAMATION,
  207.   Key_9             ,Key_TILDA         ,Key_ASTERISK,
  208.   Key_1             ,Key_LEFT_PAREN    ,Key_3, Key_LEFT_BRACE,
  209.   Key_5             ,Key_RIGHT_BRACE   ,Key_2,
  210.   Key_RIGHT_PAREN   ,Key_0             ,Key_EQUAL,
  211.   Key_4             ,Key_8             ,Key_PLUS,
  212.   Key_6             ,Key_RIGHT_BRACKET ,Key_BACKTICK };
  213.  
  214. const byte RowPins[Rows]       = {  9,  8,  7,  6,  5,  4,  3, A1, A2 };
  215. const byte ColumnPins[Columns] = { 10, 16, 14, 15, A0 };
  216.  
  217. const unsigned int RoundDelay = 10000;
  218.  
  219. const byte BounceProtect = 3;
  220. const byte BounceClear = 0;
  221.  
  222. const byte FirstLayer  = 0;
  223. const byte SecondLayer = 1;
  224. const byte ThirdLayer  = 2;
  225.  
  226. const byte States = 2;
  227. const byte StateBounce = 0;
  228. const byte StateLayer  = 1;
  229.  
  230. typedef byte (*const key_position)[States];
  231.  
  232. byte currentLayers;
  233. byte matrixState[Columns][Rows][States];
  234.  
  235. const byte  ShiftCount = 1;
  236. key_position ShiftPositions[ShiftCount] = { &matrixState[2][7] };
  237.  
  238. const byte  FnCount    = 1;
  239. key_position FnPositions[FnCount]       = { &matrixState[2][0] };
  240.  
  241. void clean_matrix_state();
  242. void setup_pins();
  243. byte current_layer() __attribute__((const));
  244. void scan_matrix();
  245. void scan_key(const byte column, const byte row, const byte keyState);
  246. void key_press(key_position keyPosition, const char keyCode);
  247. void key_release(key_position keyPosition, const char keyCode);
  248. void unshift(key_position keyPosition, const char keyCode);
  249. void shift_release(key_position keyPosition);
  250. void function_release(key_position keyPosition);
  251.  
  252. void setup()
  253. {
  254.   clean_matrix_state();
  255.   setup_pins();
  256.   Keyboard.begin();
  257.   Serial.begin(9600);
  258. }
  259.  
  260. void loop()
  261. {
  262.   scan_matrix();
  263.   delayMicroseconds(RoundDelay);
  264. }
  265.  
  266. void clean_matrix_state()
  267. {
  268.   currentLayers = FirstLayer;
  269.  
  270.   for (byte column = 0; column < Columns; column++) {
  271.     for (byte row = 0; row < Rows; row++) {
  272.       matrixState[column][row][StateBounce] = BounceClear;
  273.       matrixState[column][row][StateLayer]  = FirstLayer;
  274.     }
  275.   }
  276. }
  277.  
  278. void setup_pins()
  279. {
  280.   for (byte row = 0; row < Rows; row++) {
  281.     pinMode(RowPins[row], OUTPUT);
  282.     digitalWrite(RowPins[row], HIGH);
  283.   }
  284.   for (byte column = 0; column < Columns; column++) {
  285.     pinMode(ColumnPins[column], INPUT);
  286.     digitalWrite(ColumnPins[column], HIGH);
  287.   }
  288. }
  289.  
  290. byte current_layer()
  291. {
  292.   // TODO: refactor me
  293.   if ((currentLayers & ThirdLayer) == ThirdLayer) {
  294.     return ThirdLayer;
  295.   } else if ((currentLayers & SecondLayer) == SecondLayer) {
  296.     return SecondLayer;
  297.   } else {
  298.     return FirstLayer;
  299.   }
  300. }
  301.  
  302. void scan_matrix()
  303. {
  304.   for (byte row = 0; row < Rows; row++) {
  305.     digitalWrite(RowPins[row], LOW);
  306.  
  307.     for (byte column = 0; column < Columns; column++) {
  308.       scan_key(column, row, !digitalRead(ColumnPins[column]));
  309.     }
  310.     digitalWrite(RowPins[row], HIGH);
  311.   }
  312. }
  313.  
  314. void scan_key(const byte column, const byte row, const byte keyState)
  315. {
  316.   key_position keyPosition = &matrixState[column][row];
  317.  
  318.   if (keyState) {
  319.     if (*keyPosition[StateBounce] < BounceProtect) {
  320.       ++*keyPosition[StateBounce];
  321.       if (*keyPosition[StateBounce] == BounceProtect) {
  322.         *keyPosition[StateLayer] = current_layer();
  323.         Serial.print("Press Key -> ");
  324.         Serial.println(MatrixLayouts[*keyPosition[StateLayer]][column][row]);
  325.         Serial.print("Press layer: ");
  326.         Serial.println(*keyPosition[StateLayer]);
  327.         //key_press(keyPosition, MatrixLayouts[*keyPosition[StateLayer]][column][row]);
  328.       }
  329.     }
  330.   } else {
  331.     if (*keyPosition[StateBounce] > BounceClear) {
  332.       --*keyPosition[StateBounce];
  333.       if (*keyPosition[StateBounce] == BounceClear) {
  334.         Serial.print("Release Key -> ");
  335.         Serial.println(MatrixLayouts[*keyPosition[StateLayer]][column][row]);
  336.         Serial.print("Release layer: ");
  337.         Serial.println(*keyPosition[StateLayer]);
  338.         key_release(keyPosition, MatrixLayouts[*keyPosition[StateLayer]][column][row]);
  339. //        key_release(key, MatrixLayouts[0][column][row]);
  340. //        key_release(key, MatrixLayouts[1][column][row]);
  341. //        key_release(key, MatrixLayouts[2][column][row]);
  342.         *keyPosition[StateLayer] = FirstLayer;
  343.       }
  344.     }
  345.   }
  346. }
  347.  
  348. void key_press(key_position keyPosition, const char keyCode)
  349. {
  350.   switch (keyCode) {
  351.     case Key_LEFT_SHIFT:
  352.     case Key_RIGHT_SHIFT:
  353.     {
  354.       currentLayers |= SecondLayer;
  355.     }
  356.     break;
  357.     case Key_LEFT_FN:
  358.     case Key_RIGHT_FN:
  359.     {
  360.       currentLayers |= ThirdLayer;
  361.     }
  362.     break;
  363.     case NO_KEY:
  364.     {
  365.       return;
  366.     }
  367.   }
  368.   // unshift(keyPosition, keyCode);
  369.   Keyboard.press(keyCode);
  370. }
  371.  
  372. void key_release(key_position keyPosition, const char keyCode)
  373. {
  374.   switch (keyCode) {
  375.     case Key_LEFT_SHIFT:
  376.     case Key_RIGHT_SHIFT:
  377.     {
  378.       // shift_release(keyPosition);
  379.     }
  380.     break;
  381.     case Key_LEFT_FN:
  382.     case Key_RIGHT_FN:
  383.     {
  384.       // function_release(keyPosition);
  385.     }
  386.     break;
  387.     case NO_KEY:
  388.     {
  389.       return;
  390.     }
  391.   }
  392.   Keyboard.release(keyCode);
  393. }
  394.  
  395. void unshift(key_position keyPosition, const char keyCode)
  396. {
  397.   if ((currentLayers & SecondLayer) == SecondLayer) {
  398.     return;
  399.   }
  400.   for (byte key = 0; key < UnshiftCount; key++){
  401.     if (UnshiftKeys[key] == keyCode) {
  402.       for (byte shift = 0; shift < ShiftCount; shift++) {
  403.         if (*ShiftPositions[shift][StateBounce] > BounceClear) {
  404.           key_release(ShiftPositions[shift], keyCode);
  405.           *ShiftPositions[shift][StateBounce] = BounceClear;
  406.           *ShiftPositions[shift][StateLayer] = FirstLayer;
  407.         }
  408.       }
  409.       break;
  410.     }
  411.   }
  412. }
  413.  
  414. void shift_release(key_position keyPosition)
  415. {
  416.   byte single = true;
  417.  
  418.   for (byte shift = 0; shift < ShiftCount; shift++) {
  419.     if ( keyPosition != ShiftPositions[shift]
  420.       && *ShiftPositions[shift][StateBounce] > BounceClear
  421.        ) {
  422.       single = false;
  423.       break;
  424.     }
  425.   }
  426.   if (single) {
  427.     currentLayers &= ~SecondLayer;
  428.   }
  429. }
  430.  
  431. void function_release(key_position keyPosition)
  432. {
  433.   byte single = true;
  434.  
  435.   for (byte function = 0; function < FnCount; function++) {
  436.     if ( keyPosition != FnPositions[function]
  437.       && *FnPositions[function][0] > 0
  438.        ) {
  439.       single = false;
  440.       break;
  441.     }
  442.   }
  443.   if (single) {
  444.     currentLayers &= ~ThirdLayer;
  445.   }
  446. }
Advertisement
Add Comment
Please, Sign In to add comment