Keyboard firmwares for Atmel AVR and Cortex-M
Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

keyboard.c 16KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494
  1. /*
  2. Copyright 2011 Jun Wako <[email protected]>
  3. This program is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation, either version 2 of the License, or
  6. (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program. If not, see <http://www.gnu.org/licenses/>.
  13. */
  14. #include "keyboard.h"
  15. #include "matrix.h"
  16. #include "keymap.h"
  17. #include "host.h"
  18. #include "led.h"
  19. #include "usb_keycodes.h"
  20. #include "timer.h"
  21. #include "print.h"
  22. #include "debug.h"
  23. #include "command.h"
  24. #include "util.h"
  25. #ifdef MOUSEKEY_ENABLE
  26. #include "mousekey.h"
  27. #endif
  28. #ifdef EXTRAKEY_ENABLE
  29. #include <util/delay.h>
  30. #endif
  31. #define LAYER_DELAY 250
  32. typedef enum keykind {
  33. NONE,
  34. FN_DOWN, FN_UP,
  35. FNK_DOWN, FNK_UP,
  36. KEY_DOWN, KEY_UP,
  37. MOD_DOWN, MOD_UP,
  38. MOUSEKEY_DOWN, MOUSEKEY_UP,
  39. DELAY
  40. } keykind_t;
  41. typedef enum { IDLE, DELAYING, WAITING, PRESSING } kbdstate_t;
  42. uint8_t current_layer = 0;
  43. uint8_t default_layer = 0;
  44. /* keyboard internal states */
  45. static kbdstate_t kbdstate = IDLE;
  46. static uint8_t fn_state_bits = 0;
  47. static keyrecord_t delayed_fn;
  48. static keyrecord_t waiting_key;
  49. static const char *state_str(kbdstate_t state)
  50. {
  51. if (state == IDLE) return PSTR("IDLE");
  52. if (state == DELAYING) return PSTR("DELAYING");
  53. if (state == WAITING) return PSTR("WAITING");
  54. if (state == PRESSING) return PSTR("PRESSING");
  55. return PSTR("UNKNOWN");
  56. }
  57. static inline keykind_t get_keykind(uint8_t code, bool pressed)
  58. {
  59. if IS_KEY(code) return (pressed ? KEY_DOWN : KEY_UP);
  60. if IS_MOD(code) return (pressed ? MOD_DOWN : MOD_UP);
  61. if IS_FN(code) {
  62. if (keymap_fn_keycode(FN_INDEX(code)))
  63. return (pressed ? FNK_DOWN : FNK_UP);
  64. else
  65. return (pressed ? FN_DOWN : FN_UP);
  66. }
  67. if IS_MOUSEKEY(code) return (pressed ? MOUSEKEY_DOWN : MOUSEKEY_UP);
  68. return NONE;
  69. }
  70. static void layer_switch_on(uint8_t code)
  71. {
  72. if (!IS_FN(code)) return;
  73. fn_state_bits |= FN_BIT(code);
  74. if (current_layer != keymap_fn_layer(FN_INDEX(code))) {
  75. //TODO: clear all key execpt Mod key
  76. debug("Layer Switch(on): "); debug_hex(current_layer);
  77. current_layer = keymap_fn_layer(FN_INDEX(code));
  78. debug(" -> "); debug_hex(current_layer); debug("\n");
  79. }
  80. }
  81. static void layer_switch_off(uint8_t code)
  82. {
  83. if (!IS_FN(code)) return;
  84. fn_state_bits &= ~FN_BIT(code);
  85. if (current_layer != keymap_fn_layer(biton(fn_state_bits))) {
  86. //TODO: clear all key execpt Mod key
  87. debug("Layer Switch(off): "); debug_hex(current_layer);
  88. current_layer = keymap_fn_layer(biton(fn_state_bits));
  89. debug(" -> "); debug_hex(current_layer); debug("\n");
  90. }
  91. }
  92. static inline uint8_t get_keycode(key_t key)
  93. {
  94. return keymap_get_keycode(current_layer, key.row, key.col);
  95. }
  96. // whether any key except modifier is down or not
  97. static inline bool is_anykey_down(void)
  98. {
  99. for (int r = 0; r < MATRIX_ROWS; r++) {
  100. matrix_row_t matrix_row = matrix_get_row(r);
  101. for (int c = 0; c < MATRIX_COLS; c++) {
  102. if (matrix_row && (1<<c)) {
  103. if (IS_KEY(get_keycode((key_t){ .row = r, .col = c }))) {
  104. return true;
  105. }
  106. }
  107. }
  108. }
  109. return false;
  110. }
  111. static void register_code(uint8_t code)
  112. {
  113. if IS_KEY(code) {
  114. host_add_key(code);
  115. host_send_keyboard_report();
  116. }
  117. else if IS_MOD(code) {
  118. host_add_mod_bit(MOD_BIT(code));
  119. host_send_keyboard_report();
  120. }
  121. else if IS_MOUSEKEY(code) {
  122. mousekey_on(code);
  123. mousekey_send();
  124. }
  125. }
  126. static void unregister_code(uint8_t code)
  127. {
  128. if IS_KEY(code) {
  129. host_del_key(code);
  130. host_send_keyboard_report();
  131. }
  132. else if IS_MOD(code) {
  133. host_del_mod_bit(MOD_BIT(code));
  134. host_send_keyboard_report();
  135. }
  136. else if IS_MOUSEKEY(code) {
  137. mousekey_off(code);
  138. mousekey_send();
  139. }
  140. }
  141. /*
  142. *
  143. * Event/State|IDLE DELAYING[f] WAITING[f,k] PRESSING
  144. * -----------+------------------------------------------------------------------
  145. * Fn Down |IDLE(L+) WAITING(Sk) WAITING(Sk) -
  146. * Up |IDLE(L-) IDLE(L-) IDLE(L-) IDLE(L-)
  147. * Fnk Down |DELAYING(Sf) WAITING(Sk) WAINTING(Sk) PRESSING(Rf)
  148. * Up |IDLE(L-) IDLE(Rf,Uf) IDLE(Rf,Ps,Uf)*3 PRESSING(Uf)
  149. * Key Down |PRESSING(Rk) WAITING(Sk) WAITING(Sk) PRESSING(Rk)
  150. * Up |IDLE(Uk) DELAYING(Uk) IDLE(L+,Ps,Uk) IDLE(Uk)*4
  151. * Delay |- IDLE(L+) IDLE(L+,Ps) -
  152. * |
  153. * No key Down|IDLE(Ld) IDLE(Ld) IDLE(Ld) IDLE(Ld)
  154. *
  155. * *2: register Fnk if any key is pressing
  156. * *3: when Fnk == Stored Fnk, if not ignore.
  157. * *4: when no registered key any more
  158. *
  159. * States:
  160. * IDLE:
  161. * DELAYING: delay layer switch after pressing Fn with alt keycode
  162. * WAITING: key is pressed during DELAYING
  163. *
  164. * Events:
  165. * Fn: Fn key without alternative keycode
  166. * Fnk: Fn key with alternative keycode
  167. * -: ignore
  168. *
  169. * Actions:
  170. * Rk: register key
  171. * Uk: unregister key
  172. * Rf: register stored Fn(alt keycode)
  173. * Uf: unregister stored Fn(alt keycode)
  174. * Rs: register stored key
  175. * Us: unregister stored key
  176. * Sk: store key
  177. * Sf: store Fn
  178. * Ps: play stored key(Interpret stored key and transit state)
  179. * L+: Switch to new layer(*retain* Modifiers only)
  180. * L-: Switch back to last layer(*clear* stored key/Fn, *unregister* all Modifier/key)
  181. * Ld: Switch back to default layer(*clear* stored key/Fn, *unregister* all Modifier/key)
  182. */
  183. #define NEXT(state) do { \
  184. debug("NEXT: "); print_P(state_str(kbdstate)); \
  185. kbdstate = state; \
  186. debug(" -> "); print_P(state_str(kbdstate)); debug("\n"); \
  187. } while (0)
  188. static inline void process_key(keyevent_t event)
  189. {
  190. /* TODO: ring buffer
  191. static keyrecord_t waiting_keys[5];
  192. static uint8_t waiting_keys_head = 0;
  193. static uint8_t waiting_keys_tail = 0;
  194. */
  195. uint8_t code = get_keycode(event.key);
  196. keykind_t kind = get_keykind(code, event.pressed);
  197. uint8_t tmp_mods;
  198. debug("state: "); print_P(state_str(kbdstate));
  199. debug(" kind: "); debug_hex(kind);
  200. debug(" code: "); debug_hex(code);
  201. if (event.pressed) { debug("d"); } else { debug("u"); }
  202. debug("\n");
  203. switch (kbdstate) {
  204. case IDLE:
  205. switch (kind) {
  206. case FN_DOWN:
  207. layer_switch_on(code);
  208. break;
  209. case FN_UP:
  210. layer_switch_off(code);
  211. break;
  212. case FNK_DOWN:
  213. // repeat Fn alt key when press Fn key down, up then down again quickly
  214. if (KEYEQ(delayed_fn.event.key, event.key) &&
  215. timer_elapsed(delayed_fn.time) < LAYER_DELAY) {
  216. register_code(keymap_fn_keycode(FN_INDEX(code)));
  217. NEXT(PRESSING);
  218. } else {
  219. delayed_fn = (keyrecord_t) {
  220. .event = event,
  221. .code = code,
  222. .mods = keyboard_report->mods,
  223. .time = timer_read()
  224. };
  225. NEXT(DELAYING);
  226. }
  227. break;
  228. case FNK_UP:
  229. layer_switch_off(code);
  230. break;
  231. case KEY_DOWN:
  232. case MOUSEKEY_DOWN:
  233. register_code(code);
  234. NEXT(PRESSING);
  235. break;
  236. case MOD_DOWN:
  237. register_code(code);
  238. break;
  239. case KEY_UP:
  240. case MOUSEKEY_UP:
  241. case MOD_UP:
  242. unregister_code(code);
  243. break;
  244. default:
  245. break;
  246. }
  247. break;
  248. case PRESSING:
  249. switch (kind) {
  250. case FN_DOWN:
  251. // ignored when any key is pressed
  252. break;
  253. case FN_UP:
  254. layer_switch_off(code);
  255. NEXT(IDLE);
  256. break;
  257. case FNK_DOWN:
  258. register_code(keymap_fn_keycode(FN_INDEX(code)));
  259. break;
  260. case FNK_UP:
  261. unregister_code(keymap_fn_keycode(FN_INDEX(code)));
  262. break;
  263. case KEY_DOWN:
  264. case MOD_DOWN:
  265. case MOUSEKEY_DOWN:
  266. register_code(code);
  267. break;
  268. case KEY_UP:
  269. case MOD_UP:
  270. case MOUSEKEY_UP:
  271. unregister_code(code);
  272. // no key registered? mousekey, mediakey, systemkey
  273. if (!host_has_anykey())
  274. NEXT(IDLE);
  275. break;
  276. default:
  277. break;
  278. }
  279. break;
  280. case DELAYING:
  281. switch (kind) {
  282. case FN_DOWN:
  283. case FNK_DOWN:
  284. case KEY_DOWN:
  285. case MOUSEKEY_DOWN:
  286. waiting_key = (keyrecord_t) {
  287. .event = event,
  288. .code = code,
  289. .mods = keyboard_report->mods,
  290. .time = timer_read()
  291. };
  292. NEXT(WAITING);
  293. break;
  294. case MOD_DOWN:
  295. register_code(code);
  296. break;
  297. case FN_UP:
  298. layer_switch_off(code);
  299. NEXT(IDLE);
  300. break;
  301. case FNK_UP:
  302. if (code == delayed_fn.code) {
  303. // type Fn with alt keycode
  304. // restore the mod status at the time of pressing Fn key
  305. tmp_mods = keyboard_report->mods;
  306. host_set_mods(delayed_fn.mods);
  307. register_code(keymap_fn_keycode(FN_INDEX(delayed_fn.code)));
  308. unregister_code(keymap_fn_keycode(FN_INDEX(delayed_fn.code)));
  309. host_set_mods(tmp_mods);
  310. NEXT(IDLE);
  311. } else {
  312. layer_switch_off(code);
  313. NEXT(IDLE);
  314. }
  315. break;
  316. case KEY_UP:
  317. case MOUSEKEY_UP:
  318. unregister_code(code);
  319. NEXT(IDLE);
  320. break;
  321. case MOD_UP:
  322. unregister_code(code);
  323. break;
  324. default:
  325. break;
  326. }
  327. break;
  328. case WAITING:
  329. switch (kind) {
  330. case FN_DOWN:
  331. case FNK_DOWN:
  332. case KEY_DOWN:
  333. case MOUSEKEY_DOWN:
  334. tmp_mods = keyboard_report->mods;
  335. host_set_mods(delayed_fn.mods);
  336. register_code(keymap_fn_keycode(FN_INDEX(delayed_fn.code)));
  337. host_set_mods(waiting_key.mods);
  338. register_code(waiting_key.code);
  339. host_set_mods(tmp_mods);
  340. register_code(code);
  341. NEXT(IDLE);
  342. break;
  343. case MOD_DOWN:
  344. register_code(code);
  345. break;
  346. case FN_UP:
  347. layer_switch_off(code);
  348. NEXT(IDLE);
  349. break;
  350. case FNK_UP:
  351. if (code == delayed_fn.code) {
  352. // alt down, key down, alt up
  353. tmp_mods = keyboard_report->mods;
  354. host_set_mods(delayed_fn.mods);
  355. register_code(keymap_fn_keycode(FN_INDEX(delayed_fn.code)));
  356. host_set_mods(waiting_key.mods);
  357. register_code(waiting_key.code);
  358. unregister_code(keymap_fn_keycode(FN_INDEX(delayed_fn.code)));
  359. host_set_mods(tmp_mods);
  360. NEXT(IDLE);
  361. } else {
  362. layer_switch_off(code);
  363. NEXT(IDLE);
  364. }
  365. break;
  366. case KEY_UP:
  367. case MOUSEKEY_UP:
  368. if (code == waiting_key.code) {
  369. layer_switch_on(delayed_fn.code);
  370. NEXT(IDLE);
  371. // process waiting_key
  372. tmp_mods = keyboard_report->mods;
  373. host_set_mods(waiting_key.mods);
  374. process_key(waiting_key.event);
  375. host_set_mods(tmp_mods);
  376. process_key(event);
  377. } else {
  378. unregister_code(code);
  379. }
  380. break;
  381. case MOD_UP:
  382. unregister_code(code);
  383. break;
  384. default:
  385. break;
  386. }
  387. break;
  388. }
  389. // TODO: FAIL SAFE: unregister all keys when no key down
  390. }
  391. void keyboard_init(void)
  392. {
  393. debug_keyboard = true;
  394. timer_init();
  395. matrix_init();
  396. #ifdef PS2_MOUSE_ENABLE
  397. ps2_mouse_init();
  398. #endif
  399. }
  400. void keyboard_task(void)
  401. {
  402. static matrix_row_t matrix_prev[MATRIX_ROWS];
  403. matrix_row_t matrix_row = 0;
  404. matrix_row_t matrix_change = 0;
  405. matrix_scan();
  406. if (command_proc()) {
  407. debug("COMMAND\n");
  408. // TODO: clear all keys
  409. host_clear_keyboard_report();
  410. host_send_keyboard_report();
  411. return;
  412. }
  413. for (int r = 0; r < MATRIX_ROWS; r++) {
  414. matrix_row = matrix_get_row(r);
  415. matrix_change = matrix_row ^ matrix_prev[r];
  416. if (matrix_change) {
  417. // TODO: print once per scan
  418. if (debug_matrix) matrix_print();
  419. for (int c = 0; c < MATRIX_COLS; c++) {
  420. if (matrix_change & (1<<c)) {
  421. process_key((keyevent_t){
  422. .key = (key_t){ .row = r, .col = c },
  423. .pressed = (matrix_row & (1<<c))
  424. });
  425. // record a processed key
  426. matrix_prev[r] ^= (1<<c);
  427. // process a key per task call
  428. goto MATRIX_LOOP_END;
  429. }
  430. }
  431. }
  432. }
  433. MATRIX_LOOP_END:
  434. // TODO: FAIL SAFE: clear all key if no key down
  435. // layer switch when delay term elapses
  436. if (kbdstate == DELAYING || kbdstate == WAITING) {
  437. if (timer_elapsed(delayed_fn.time) > LAYER_DELAY) {
  438. if (kbdstate == DELAYING) {
  439. layer_switch_on(delayed_fn.code);
  440. NEXT(IDLE);
  441. }
  442. if (kbdstate == WAITING) {
  443. layer_switch_on(delayed_fn.code);
  444. NEXT(IDLE);
  445. uint8_t tmp_mods = keyboard_report->mods;
  446. host_set_mods(waiting_key.mods);
  447. process_key(waiting_key.event);
  448. host_set_mods(tmp_mods);
  449. }
  450. }
  451. }
  452. // mousekey repeat & acceleration
  453. mousekey_task();
  454. return;
  455. }
  456. void keyboard_set_leds(uint8_t leds)
  457. {
  458. led_set(leds);
  459. }