Keyboard.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408
  1. /*
  2. MNT Reform v2 Keyboard Firmware
  3. Copyright 2019 Lukas F. Hartmann / MNT Research GmbH, Berlin
  4. lukas@mntmn.com
  5. */
  6. /*
  7. LUFA Library
  8. Copyright (C) Dean Camera, 2018.
  9. dean [at] fourwalledcubicle [dot] com
  10. www.lufa-lib.org
  11. */
  12. /*
  13. Copyright 2018 Dean Camera (dean [at] fourwalledcubicle [dot] com)
  14. Permission to use, copy, modify, distribute, and sell this
  15. software and its documentation for any purpose is hereby granted
  16. without fee, provided that the above copyright notice appear in
  17. all copies and that both that the copyright notice and this
  18. permission notice and warranty disclaimer appear in supporting
  19. documentation, and that the name of the author not be used in
  20. advertising or publicity pertaining to distribution of the
  21. software without specific, written prior permission.
  22. The author disclaims all warranties with regard to this
  23. software, including all implied warranties of merchantability
  24. and fitness. In no event shall the author be liable for any
  25. special, indirect or consequential damages or any damages
  26. whatsoever resulting from loss of use, data or profits, whether
  27. in an action of contract, negligence or other tortious action,
  28. arising out of or in connection with the use or performance of
  29. this software.
  30. */
  31. #include "Config/LUFAConfig.h"
  32. #include "Keyboard.h"
  33. #include <avr/io.h>
  34. /** Buffer to hold the previously generated Keyboard HID report, for comparison purposes inside the HID class driver. */
  35. static uint8_t PrevKeyboardHIDReportBuffer[sizeof(USB_KeyboardReport_Data_t)];
  36. /** LUFA HID Class driver interface configuration and state information. This structure is
  37. * passed to all HID Class driver functions, so that multiple instances of the same class
  38. * within a device can be differentiated from one another.
  39. */
  40. USB_ClassInfo_HID_Device_t Keyboard_HID_Interface =
  41. {
  42. .Config =
  43. {
  44. .InterfaceNumber = INTERFACE_ID_Keyboard,
  45. .ReportINEndpoint =
  46. {
  47. .Address = KEYBOARD_EPADDR,
  48. .Size = KEYBOARD_EPSIZE,
  49. .Banks = 1,
  50. },
  51. .PrevReportINBuffer = PrevKeyboardHIDReportBuffer,
  52. .PrevReportINBufferSize = sizeof(PrevKeyboardHIDReportBuffer),
  53. },
  54. };
  55. #define output_low(port,pin) port &= ~(1<<pin)
  56. #define output_high(port,pin) port |= (1<<pin)
  57. #define set_input(portdir,pin) portdir &= ~(1<<pin)
  58. #define set_output(portdir,pin) portdir |= (1<<pin)
  59. int main(void)
  60. {
  61. SetupHardware();
  62. GlobalInterruptEnable();
  63. for (;;)
  64. {
  65. HID_Device_USBTask(&Keyboard_HID_Interface);
  66. USB_USBTask();
  67. }
  68. }
  69. /** Configures the board hardware and chip peripherals for the demo's functionality. */
  70. void SetupHardware()
  71. {
  72. // Disable watchdog if enabled by bootloader/fuses
  73. MCUSR &= ~(1 << WDRF);
  74. wdt_disable();
  75. // Disable clock division
  76. clock_prescale_set(clock_div_1);
  77. // Hardware Initialization
  78. USB_Init();
  79. // declare port pins as inputs (0) and outputs (1)
  80. DDRB = 0b01110000;
  81. DDRD = 0b11010001;
  82. DDRF = 0b10000000;
  83. DDRE = 0b00000000;
  84. DDRC = 0b00000000;
  85. // initial pin states
  86. PORTB = 0b10001111;
  87. PORTD = 0b00101110;
  88. PORTF = 0b01111111;
  89. PORTC = 0b01000000;
  90. // disable JTAG
  91. MCUCR |=(1<<JTD);
  92. MCUCR |=(1<<JTD);
  93. }
  94. /** Event handler for the library USB Connection event. */
  95. void EVENT_USB_Device_Connect(void)
  96. {
  97. }
  98. /** Event handler for the library USB Disconnection event. */
  99. void EVENT_USB_Device_Disconnect(void)
  100. {
  101. }
  102. /** Event handler for the library USB Configuration Changed event. */
  103. void EVENT_USB_Device_ConfigurationChanged(void)
  104. {
  105. bool ConfigSuccess = true;
  106. ConfigSuccess &= HID_Device_ConfigureEndpoints(&Keyboard_HID_Interface);
  107. USB_Device_EnableSOFEvents();
  108. }
  109. /** Event handler for the library USB Control Request reception event. */
  110. void EVENT_USB_Device_ControlRequest(void)
  111. {
  112. HID_Device_ProcessControlRequest(&Keyboard_HID_Interface);
  113. }
  114. /** Event handler for the USB device Start Of Frame event. */
  115. void EVENT_USB_Device_StartOfFrame(void)
  116. {
  117. HID_Device_MillisecondElapsed(&Keyboard_HID_Interface);
  118. }
  119. #define KEY_A 0x04
  120. #define KEY_B 0x05
  121. #define KEY_C 0x06
  122. #define KEY_D 0x07
  123. #define KEY_E 0x08
  124. #define KEY_F 0x09
  125. #define KEY_G 0x0A
  126. #define KEY_H 0x0B
  127. #define KEY_I 0x0C
  128. #define KEY_J 0x0D
  129. #define KEY_K 0x0E
  130. #define KEY_L 0x0F
  131. #define KEY_M 0x10
  132. #define KEY_N 0x11
  133. #define KEY_O 0x12
  134. #define KEY_P 0x13
  135. #define KEY_Q 0x14
  136. #define KEY_R 0x15
  137. #define KEY_S 0x16
  138. #define KEY_T 0x17
  139. #define KEY_U 0x18
  140. #define KEY_V 0x19
  141. #define KEY_W 0x1A
  142. #define KEY_X 0x1B
  143. #define KEY_Y 0x1C
  144. #define KEY_Z 0x1D
  145. #define KEY_1 0x1E
  146. #define KEY_2 0x1F
  147. #define KEY_3 0x20
  148. #define KEY_4 0x21
  149. #define KEY_5 0x22
  150. #define KEY_6 0x23
  151. #define KEY_7 0x24
  152. #define KEY_8 0x25
  153. #define KEY_9 0x26
  154. #define KEY_0 0x27
  155. #define KEY_ENTER 0x28
  156. #define KEY_ESCAPE 0x29
  157. #define KEY_BACKSPACE 0x2A
  158. #define KEY_TAB 0x2B
  159. #define KEY_SPACE 0x2C
  160. #define KEY_MINUS_AND_UNDERSCORE 0x2D
  161. #define KEY_EQUAL_AND_PLUS 0x2E
  162. #define KEY_OPENING_BRACKET_AND_OPENING_BRACE 0x2F
  163. #define KEY_CLOSING_BRACKET_AND_CLOSING_BRACE 0x30
  164. #define KEY_BACKSLASH_AND_PIPE 0x31
  165. #define KEY_NON_US_HASHMARK_AND_TILDE 0x32
  166. #define KEY_SEMICOLON_AND_COLON 0x33
  167. #define KEY_APOSTROPHE_AND_QUOTE 0x34
  168. #define KEY_GRAVE_ACCENT_AND_TILDE 0x35
  169. #define KEY_COMMA_AND_LESS_THAN_SIGN 0x36
  170. #define KEY_DOT_AND_GREATER_THAN_SIGN 0x37
  171. #define KEY_SLASH_AND_QUESTION_MARK 0x38
  172. #define KEY_CAPS_LOCK 0x39
  173. #define KEY_F1 0x3A
  174. #define KEY_F2 0x3B
  175. #define KEY_F3 0x3C
  176. #define KEY_F4 0x3D
  177. #define KEY_F5 0x3E
  178. #define KEY_F6 0x3F
  179. #define KEY_F7 0x40
  180. #define KEY_F8 0x41
  181. #define KEY_F9 0x42
  182. #define KEY_F10 0x43
  183. #define KEY_F11 0x44
  184. #define KEY_F12 0x45
  185. #define KEY_PRINT_SCREEN 0x46
  186. #define KEY_SCROLL_LOCK 0x47
  187. #define KEY_PAUSE 0x48
  188. #define KEY_INSERT 0x49
  189. #define KEY_HOME 0x4A
  190. #define KEY_PAGE_UP 0x4B
  191. #define KEY_DELETE 0x4C
  192. #define KEY_END 0x4D
  193. #define KEY_PAGE_DOWN 0x4E
  194. #define KEY_RIGHT_ARROW 0x4F
  195. #define KEY_LEFT_ARROW 0x50
  196. #define KEY_DOWN_ARROW 0x51
  197. #define KEY_UP_ARROW 0x52
  198. #define KEY_NUM_LOCK 0x53
  199. #define KEY_KEYPAD_SLASH 0x54
  200. #define KEY_KEYPAD_ASTERISK 0x55
  201. #define KEY_KEYPAD_MINUS 0x56
  202. #define KEY_KEYPAD_PLUS 0x57
  203. #define KEY_KEYPAD_ENTER 0x58
  204. #define KEY_KEYPAD_1_AND_END 0x59
  205. #define KEY_KEYPAD_2_AND_DOWN_ARROW 0x5A
  206. #define KEY_KEYPAD_3_AND_PAGE_DOWN 0x5B
  207. #define KEY_KEYPAD_4_AND_LEFT_ARROW 0x5C
  208. #define KEY_KEYPAD_5 0x5D
  209. #define KEY_KEYPAD_6_AND_RIGHT_ARROW 0x5E
  210. #define KEY_KEYPAD_7_AND_HOME 0x5F
  211. #define KEY_KEYPAD_8_AND_UP_ARROW 0x60
  212. #define KEY_KEYPAD_9_AND_PAGE_UP 0x61
  213. #define KEY_KEYPAD_0_AND_INSERT 0x62
  214. #define KEY_KEYPAD_DOT_AND_DELETE 0x63
  215. #define KEY_NON_US_BACKSLASH_AND_PIPE 0x64
  216. #define KEY_APPLICATION 0x65
  217. #define KEY_POWER 0x66
  218. #define KEY_KEYPAD_EQUAL_SIGN 0x67
  219. #define KEY_F13 0x68
  220. #define KEY_F14 0x69
  221. #define KEY_F15 0x6A
  222. #define KEY_F16 0x6B
  223. #define KEY_F17 0x6C
  224. #define KEY_F18 0x6D
  225. #define KEY_F19 0x6E
  226. #define KEY_F20 0x6F
  227. #define KEY_F21 0x70
  228. #define KEY_F22 0x71
  229. #define KEY_F23 0x72
  230. #define KEY_F24 0x73
  231. #define KEY_MUTE 0x7F
  232. #define KEY_VOLUME_UP 0x80
  233. #define KEY_VOLUME_DOWN 0x81
  234. #ifdef NEO2
  235. const uint8_t matrix[15*6] = {
  236. KEY_ESCAPE, KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5, KEY_F6, KEY_F7, KEY_F8, KEY_F9, KEY_F10, KEY_F11, KEY_F12, HID_KEYBOARD_SC_PAGE_UP, HID_KEYBOARD_SC_PAGE_DOWN,
  237. KEY_GRAVE_ACCENT_AND_TILDE, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7, KEY_8, KEY_9, KEY_0, KEY_MINUS_AND_UNDERSCORE, KEY_EQUAL_AND_PLUS, KEY_BACKSPACE, 0,
  238. KEY_TAB, KEY_Q, KEY_W, KEY_E, KEY_R, KEY_T, KEY_Y, KEY_U, KEY_I, KEY_O, KEY_P, KEY_OPENING_BRACKET_AND_OPENING_BRACE, KEY_CLOSING_BRACKET_AND_CLOSING_BRACE, KEY_ENTER, 0,
  239. HID_KEYBOARD_SC_CAPS_LOCK, KEY_A, KEY_S, KEY_D, KEY_F, KEY_G, KEY_H, KEY_J, KEY_K, KEY_L, KEY_SEMICOLON_AND_COLON, KEY_APOSTROPHE_AND_QUOTE, HID_KEYBOARD_SC_CAPS_LOCK,0,0,
  240. HID_KEYBOARD_SC_LEFT_SHIFT, KEY_Z, KEY_X, KEY_C, KEY_V, KEY_B, KEY_N, KEY_M, HID_KEYBOARD_SC_COMMA_AND_LESS_THAN_SIGN, HID_KEYBOARD_SC_DOT_AND_GREATER_THAN_SIGN, KEY_SLASH_AND_QUESTION_MARK, HID_KEYBOARD_SC_UP_ARROW, HID_KEYBOARD_SC_RIGHT_SHIFT, 0,0,
  241. HID_KEYBOARD_SC_LEFT_CONTROL, HID_KEYBOARD_SC_RIGHT_ALT, HID_KEYBOARD_SC_LEFT_ALT, KEY_SPACE, HID_KEYBOARD_SC_RIGHT_ALT, HID_KEYBOARD_SC_LEFT_ARROW, HID_KEYBOARD_SC_DOWN_ARROW, HID_KEYBOARD_SC_RIGHT_ARROW, KEY_SPACE,KEY_SPACE,0,0,0,0,0
  242. };
  243. #else
  244. const uint8_t matrix[15*6] = {
  245. KEY_ESCAPE, KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5, KEY_F6, KEY_F7, KEY_F8, KEY_F9, KEY_F10, KEY_F11, KEY_F12, KEY_DELETE, 0,
  246. KEY_GRAVE_ACCENT_AND_TILDE, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7, KEY_8, KEY_9, KEY_0, KEY_MINUS_AND_UNDERSCORE, KEY_EQUAL_AND_PLUS, KEY_BACKSPACE, 0,
  247. KEY_TAB, KEY_Q, KEY_W, KEY_E, KEY_R, KEY_T, KEY_Y, KEY_U, KEY_I, KEY_O, KEY_P, KEY_OPENING_BRACKET_AND_OPENING_BRACE, KEY_CLOSING_BRACKET_AND_CLOSING_BRACE, KEY_BACKSLASH_AND_PIPE, 0,
  248. HID_KEYBOARD_SC_LEFT_CONTROL, HID_KEYBOARD_SC_EXSEL, KEY_A, KEY_S, KEY_D, KEY_F, KEY_G, KEY_H, KEY_J, KEY_K, KEY_L, KEY_SEMICOLON_AND_COLON, KEY_APOSTROPHE_AND_QUOTE, KEY_ENTER, 0,
  249. HID_KEYBOARD_SC_LEFT_SHIFT, HID_KEYBOARD_SC_LEFT_SHIFT, KEY_Z, KEY_X, KEY_C, KEY_V, KEY_B, KEY_N, KEY_M, HID_KEYBOARD_SC_COMMA_AND_LESS_THAN_SIGN, HID_KEYBOARD_SC_DOT_AND_GREATER_THAN_SIGN, KEY_SLASH_AND_QUESTION_MARK, HID_KEYBOARD_SC_UP_ARROW, HID_KEYBOARD_SC_RIGHT_SHIFT, 0,
  250. HID_KEYBOARD_SC_LEFT_GUI, HID_KEYBOARD_SC_LEFT_ALT, HID_KEYBOARD_SC_LEFT_CONTROL, KEY_SPACE, KEY_SPACE, KEY_SPACE, HID_KEYBOARD_SC_RIGHT_ALT, HID_KEYBOARD_SC_PAGE_UP, HID_KEYBOARD_SC_PAGE_DOWN, HID_KEYBOARD_SC_LEFT_ARROW, HID_KEYBOARD_SC_DOWN_ARROW, HID_KEYBOARD_SC_RIGHT_ARROW, 0,0,0
  251. };
  252. // f8 = sleep
  253. // 49 = mute
  254. // 84 = scroll lock
  255. /*const uint8_t matrix2[15*6] = {
  256. 0x84, KEY_F14, KEY_F15, KEY_F3, KEY_F4, KEY_F5, KEY_F6, KEY_F7, KEY_F8, KEY_F9, 0x49, HID_KEYBOARD_SC_VOLUME_DOWN, HID_KEYBOARD_SC_VOLUME_UP, 0x62, 0xf8,
  257. KEY_GRAVE_ACCENT_AND_TILDE, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7, KEY_8, KEY_9, KEY_0, KEY_MINUS_AND_UNDERSCORE, KEY_EQUAL_AND_PLUS, KEY_BACKSPACE, 0,
  258. KEY_TAB, KEY_Q, KEY_W, KEY_E, KEY_R, KEY_T, KEY_Y, KEY_U, KEY_I, KEY_O, KEY_P, KEY_OPENING_BRACKET_AND_OPENING_BRACE, KEY_CLOSING_BRACKET_AND_CLOSING_BRACE, KEY_ENTER, 0,
  259. HID_KEYBOARD_SC_RIGHT_CONTROL, KEY_A, KEY_S, KEY_D, KEY_F, KEY_G, KEY_H, KEY_J, KEY_K, KEY_L, KEY_SEMICOLON_AND_COLON, KEY_APOSTROPHE_AND_QUOTE, KEY_BACKSLASH_AND_PIPE,0,0,
  260. HID_KEYBOARD_SC_LEFT_SHIFT, KEY_Z, KEY_X, KEY_C, KEY_V, KEY_B, KEY_N, KEY_M, HID_KEYBOARD_SC_COMMA_AND_LESS_THAN_SIGN, HID_KEYBOARD_SC_DOT_AND_GREATER_THAN_SIGN, HID_KEYBOARD_SC_PAGE_UP, KEY_SLASH_AND_QUESTION_MARK, HID_KEYBOARD_SC_RIGHT_SHIFT, 0,0,
  261. HID_KEYBOARD_SC_EXSEL, HID_KEYBOARD_SC_LEFT_GUI, HID_KEYBOARD_SC_LEFT_ALT, KEY_SPACE, HID_KEYBOARD_SC_HOME, HID_KEYBOARD_SC_PAGE_DOWN, HID_KEYBOARD_SC_END, HID_KEYBOARD_SC_RIGHT_ALT, KEY_SPACE,KEY_SPACE,0,0,0,0,0
  262. };*/
  263. #endif
  264. /** HID class driver callback function for the creation of HID reports to the host.
  265. *
  266. * \param[in] HIDInterfaceInfo Pointer to the HID class interface configuration structure being referenced
  267. * \param[in,out] ReportID Report ID requested by the host if non-zero, otherwise callback should set to the generated report ID
  268. * \param[in] ReportType Type of the report to create, either HID_REPORT_ITEM_In or HID_REPORT_ITEM_Feature
  269. * \param[out] ReportData Pointer to a buffer where the created report should be stored
  270. * \param[out] ReportSize Number of bytes written in the report (or zero if no report is to be sent)
  271. *
  272. * \return Boolean \c true to force the sending of the report, \c false to let the library determine if it needs to be sent
  273. */
  274. char metaPressed = 0;
  275. bool CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo,
  276. uint8_t* const ReportID,
  277. const uint8_t ReportType,
  278. void* ReportData,
  279. uint16_t* const ReportSize)
  280. {
  281. USB_KeyboardReport_Data_t* KeyboardReport = (USB_KeyboardReport_Data_t*)ReportData;
  282. uint8_t metaPressedNow = 0;
  283. // how many keys are pressed this round
  284. uint8_t usedKeyCodes = 0;
  285. // pull ROWs low one after the other
  286. for (int y=0; y<6; y++) {
  287. switch (y) {
  288. case 0: output_low(PORTB, 6); break;
  289. case 1: output_low(PORTB, 5); break;
  290. case 2: output_low(PORTB, 4); break;
  291. case 3: output_low(PORTD, 7); break;
  292. case 4: output_low(PORTD, 6); break;
  293. case 5: output_low(PORTD, 4); break;
  294. }
  295. // check input COLs
  296. for (int x=0; x<14; x++) {
  297. uint16_t keycode = matrix[y*15+x];
  298. uint8_t pressed = 0;
  299. // alternative matrix when fn key is pressed
  300. #ifndef NEO2
  301. if (metaPressed) {
  302. //keycode = matrix2[y*15+x];
  303. }
  304. #endif
  305. // column pins are all over the place
  306. switch (x) {
  307. case 0: pressed = !(PIND&(1<<5)); break;
  308. case 1: pressed = !(PIND&(1<<3)); break;
  309. case 2: pressed = !(PIND&(1<<2)); break;
  310. case 3: pressed = !(PIND&(1<<1)); break;
  311. case 4: pressed = !(PINB&(1<<3)); break;
  312. case 5: pressed = !(PINB&(1<<2)); break;
  313. case 6: pressed = !(PINB&(1<<1)); break;
  314. case 7: pressed = !(PINB&(1<<0)); break;
  315. case 8: pressed = !(PINF&(1<<0)); break;
  316. case 9: pressed = !(PINF&(1<<1)); break;
  317. case 10: pressed = !(PINF&(1<<4)); break;
  318. case 11: pressed = !(PINF&(1<<5)); break;
  319. case 12: pressed = !(PINF&(1<<6)); break;
  320. case 13: pressed = !(PINC&(1<<6)); break;
  321. }
  322. if (pressed) {
  323. if (keycode == HID_KEYBOARD_SC_EXSEL) {
  324. metaPressedNow = 1;
  325. } else {
  326. KeyboardReport->KeyCode[usedKeyCodes++] = keycode;
  327. }
  328. }
  329. }
  330. switch (y) {
  331. case 0: output_high(PORTB, 6); break;
  332. case 1: output_high(PORTB, 5); break;
  333. case 2: output_high(PORTB, 4); break;
  334. case 3: output_high(PORTD, 7); break;
  335. case 4: output_high(PORTD, 6); break;
  336. case 5: output_high(PORTD, 4); break;
  337. }
  338. }
  339. metaPressed = metaPressedNow;
  340. *ReportSize = sizeof(USB_KeyboardReport_Data_t);
  341. return false;
  342. }
  343. /** HID class driver callback function for the processing of HID reports from the host.
  344. *
  345. * \param[in] HIDInterfaceInfo Pointer to the HID class interface configuration structure being referenced
  346. * \param[in] ReportID Report ID of the received report from the host
  347. * \param[in] ReportType The type of report that the host has sent, either HID_REPORT_ITEM_Out or HID_REPORT_ITEM_Feature
  348. * \param[in] ReportData Pointer to a buffer where the received report has been stored
  349. * \param[in] ReportSize Size in bytes of the received HID report
  350. */
  351. void CALLBACK_HID_Device_ProcessHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo,
  352. const uint8_t ReportID,
  353. const uint8_t ReportType,
  354. const void* ReportData,
  355. const uint16_t ReportSize)
  356. {
  357. }