Keyboard firmwares for Atmel AVR and Cortex-M
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

keyboard.c 18KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594
  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 "keycode.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. } keykind_t;
  39. typedef enum { IDLE, DELAYING, WAITING, PRESSING } kbdstate_t;
  40. uint8_t current_layer = 0;
  41. uint8_t default_layer = 0;
  42. /* keyboard internal states */
  43. static kbdstate_t kbdstate = IDLE;
  44. static uint8_t fn_state_bits = 0;
  45. static keyrecord_t delayed_fn;
  46. static keyrecord_t waiting_key;
  47. static const char *state_str(kbdstate_t state)
  48. {
  49. if (state == IDLE) return PSTR("IDLE");
  50. if (state == DELAYING) return PSTR("DELAYING");
  51. if (state == WAITING) return PSTR("WAITING");
  52. if (state == PRESSING) return PSTR("PRESSING");
  53. return PSTR("UNKNOWN");
  54. }
  55. static inline keykind_t get_keykind(uint8_t code, bool pressed)
  56. {
  57. if IS_KEY(code) return (pressed ? KEY_DOWN : KEY_UP);
  58. if IS_MOD(code) return (pressed ? MOD_DOWN : MOD_UP);
  59. if IS_FN(code) {
  60. if (keymap_fn_keycode(FN_INDEX(code)))
  61. return (pressed ? FNK_DOWN : FNK_UP);
  62. else
  63. return (pressed ? FN_DOWN : FN_UP);
  64. }
  65. if IS_MOUSEKEY(code) return (pressed ? KEY_DOWN : KEY_UP);
  66. if IS_SYSTEM(code) return (pressed ? KEY_DOWN : KEY_UP);
  67. if IS_CONSUMER(code) return (pressed ? KEY_DOWN : KEY_UP);
  68. return NONE;
  69. }
  70. static void clear_keyboard(void)
  71. {
  72. host_clear_keys();
  73. host_clear_mods();
  74. host_send_keyboard_report();
  75. host_system_send(0);
  76. host_consumer_send(0);
  77. mousekey_clear();
  78. mousekey_send();
  79. }
  80. static void clear_keyboard_but_mods(void)
  81. {
  82. host_clear_keys();
  83. host_send_keyboard_report();
  84. host_system_send(0);
  85. host_consumer_send(0);
  86. mousekey_clear();
  87. mousekey_send();
  88. }
  89. static void layer_switch_on(uint8_t code)
  90. {
  91. if (!IS_FN(code)) return;
  92. fn_state_bits |= FN_BIT(code);
  93. if (current_layer != keymap_fn_layer(FN_INDEX(code))) {
  94. clear_keyboard_but_mods();
  95. debug("Layer Switch(on): "); debug_hex(current_layer);
  96. current_layer = keymap_fn_layer(FN_INDEX(code));
  97. debug(" -> "); debug_hex(current_layer); debug("\n");
  98. }
  99. }
  100. static void layer_switch_off(uint8_t code)
  101. {
  102. if (!IS_FN(code)) return;
  103. fn_state_bits &= ~FN_BIT(code);
  104. if (current_layer != keymap_fn_layer(biton(fn_state_bits))) {
  105. clear_keyboard_but_mods();
  106. debug("Layer Switch(off): "); debug_hex(current_layer);
  107. current_layer = keymap_fn_layer(biton(fn_state_bits));
  108. debug(" -> "); debug_hex(current_layer); debug("\n");
  109. }
  110. }
  111. // whether any key except modifier is down or not
  112. static inline bool is_anykey_down(void)
  113. {
  114. for (int r = 0; r < MATRIX_ROWS; r++) {
  115. matrix_row_t matrix_row = matrix_get_row(r);
  116. for (int c = 0; c < MATRIX_COLS; c++) {
  117. if (matrix_row && (1<<c)) {
  118. if (IS_KEY(keymap_get_keycode(current_layer, r, c))) {
  119. return true;
  120. }
  121. }
  122. }
  123. }
  124. return false;
  125. }
  126. static void register_code(uint8_t code)
  127. {
  128. if IS_KEY(code) {
  129. host_add_key(code);
  130. host_send_keyboard_report();
  131. }
  132. else if IS_MOD(code) {
  133. host_add_mod_bit(MOD_BIT(code));
  134. host_send_keyboard_report();
  135. }
  136. else if IS_MOUSEKEY(code) {
  137. mousekey_on(code);
  138. mousekey_send();
  139. }
  140. else if IS_CONSUMER(code) {
  141. uint16_t usage = 0;
  142. switch (code) {
  143. case KC_AUDIO_MUTE:
  144. usage = AUDIO_MUTE;
  145. break;
  146. case KC_AUDIO_VOL_UP:
  147. usage = AUDIO_VOL_UP;
  148. break;
  149. case KC_AUDIO_VOL_DOWN:
  150. usage = AUDIO_VOL_DOWN;
  151. break;
  152. case KC_MEDIA_NEXT_TRACK:
  153. usage = TRANSPORT_NEXT_TRACK;
  154. break;
  155. case KC_MEDIA_PREV_TRACK:
  156. usage = TRANSPORT_PREV_TRACK;
  157. break;
  158. case KC_MEDIA_STOP:
  159. usage = TRANSPORT_STOP;
  160. break;
  161. case KC_MEDIA_PLAY_PAUSE:
  162. usage = TRANSPORT_PLAY_PAUSE;
  163. break;
  164. case KC_MEDIA_SELECT:
  165. usage = AL_CC_CONFIG;
  166. break;
  167. case KC_MAIL:
  168. usage = AL_EMAIL;
  169. break;
  170. case KC_CALCULATOR:
  171. usage = AL_CALCULATOR;
  172. break;
  173. case KC_MY_COMPUTER:
  174. usage = AL_LOCAL_BROWSER;
  175. break;
  176. case KC_WWW_SEARCH:
  177. usage = AC_SEARCH;
  178. break;
  179. case KC_WWW_HOME:
  180. usage = AC_HOME;
  181. break;
  182. case KC_WWW_BACK:
  183. usage = AC_BACK;
  184. break;
  185. case KC_WWW_FORWARD:
  186. usage = AC_FORWARD;
  187. break;
  188. case KC_WWW_STOP:
  189. usage = AC_STOP;
  190. break;
  191. case KC_WWW_REFRESH:
  192. usage = AC_REFRESH;
  193. break;
  194. case KC_WWW_FAVORITES:
  195. usage = AC_BOOKMARKS;
  196. break;
  197. }
  198. host_consumer_send(usage);
  199. }
  200. else if IS_SYSTEM(code) {
  201. uint16_t usage = 0;
  202. switch (code) {
  203. case KC_SYSTEM_POWER:
  204. usage = SYSTEM_POWER_DOWN;
  205. break;
  206. case KC_SYSTEM_SLEEP:
  207. usage = SYSTEM_SLEEP;
  208. break;
  209. case KC_SYSTEM_WAKE:
  210. usage = SYSTEM_WAKE_UP;
  211. break;
  212. }
  213. host_system_send(usage);
  214. }
  215. }
  216. static void unregister_code(uint8_t code)
  217. {
  218. if IS_KEY(code) {
  219. host_del_key(code);
  220. host_send_keyboard_report();
  221. }
  222. else if IS_MOD(code) {
  223. host_del_mod_bit(MOD_BIT(code));
  224. host_send_keyboard_report();
  225. }
  226. else if IS_MOUSEKEY(code) {
  227. mousekey_off(code);
  228. mousekey_send();
  229. }
  230. else if IS_CONSUMER(code) {
  231. host_consumer_send(0x0000);
  232. }
  233. else if IS_SYSTEM(code) {
  234. host_system_send(0x0000);
  235. }
  236. }
  237. /*
  238. *
  239. * Event/State|IDLE DELAYING[f] WAITING[f,k] PRESSING
  240. * -----------+------------------------------------------------------------------
  241. * Fn Down |IDLE(L+) WAITING(Sk) WAITING(Sk) -
  242. * Up |IDLE(L-) IDLE(L-) IDLE(L-) IDLE(L-)
  243. * Fnk Down |DELAYING(Sf) WAITING(Sk) WAINTING(Sk) PRESSING(Rf)
  244. * Up |IDLE(L-) IDLE(Rf,Uf) IDLE(Rf,Ps,Uf)*3 PRESSING(Uf)
  245. * Key Down |PRESSING(Rk) WAITING(Sk) WAITING(Sk) PRESSING(Rk)
  246. * Up |IDLE(Uk) DELAYING(Uk) IDLE(L+,Ps,Uk) IDLE(Uk)*4
  247. * Delay |- IDLE(L+) IDLE(L+,Ps) -
  248. * |
  249. * No key Down|IDLE(Ld) IDLE(Ld) IDLE(Ld) IDLE(Ld)
  250. *
  251. * *2: register Fnk if any key is pressing
  252. * *3: when Fnk == Stored Fnk, if not ignore.
  253. * *4: when no registered key any more
  254. *
  255. * States:
  256. * IDLE:
  257. * DELAYING: delay layer switch after pressing Fn with alt keycode
  258. * WAITING: key is pressed during DELAYING
  259. *
  260. * Events:
  261. * Fn: Fn key without alternative keycode
  262. * Fnk: Fn key with alternative keycode
  263. * -: ignore
  264. *
  265. * Actions:
  266. * Rk: register key
  267. * Uk: unregister key
  268. * Rf: register stored Fn(alt keycode)
  269. * Uf: unregister stored Fn(alt keycode)
  270. * Rs: register stored key
  271. * Us: unregister stored key
  272. * Sk: store key
  273. * Sf: store Fn
  274. * Ps: play stored key(Interpret stored key and transit state)
  275. * L+: Switch to new layer(*unregister* all keys but modifiers)
  276. * L-: Switch back to last layer(*unregister* all keys but modifiers)
  277. * Ld: Switch back to default layer(*unregister* all keys but modifiers)
  278. */
  279. #define NEXT(state) do { \
  280. debug("NEXT: "); print_P(state_str(kbdstate)); \
  281. kbdstate = state; \
  282. debug(" -> "); print_P(state_str(kbdstate)); debug("\n"); \
  283. } while (0)
  284. static inline void process_key(keyevent_t event)
  285. {
  286. uint8_t code = keymap_get_keycode(current_layer, event.key.row, event.key.col);
  287. keykind_t kind = get_keykind(code, event.pressed);
  288. uint8_t tmp_mods;
  289. debug("state: "); print_P(state_str(kbdstate));
  290. debug(" kind: "); debug_hex(kind);
  291. debug(" code: "); debug_hex(code);
  292. if (event.pressed) { debug("d"); } else { debug("u"); }
  293. debug("\n");
  294. switch (kbdstate) {
  295. case IDLE:
  296. switch (kind) {
  297. case FN_DOWN:
  298. layer_switch_on(code);
  299. break;
  300. case FN_UP:
  301. layer_switch_off(code);
  302. break;
  303. case FNK_DOWN:
  304. // repeat Fn alt key when press Fn key down, up then down again quickly
  305. if (KEYEQ(delayed_fn.event.key, event.key) &&
  306. timer_elapsed(delayed_fn.time) < LAYER_DELAY) {
  307. register_code(keymap_fn_keycode(FN_INDEX(code)));
  308. NEXT(PRESSING);
  309. } else {
  310. delayed_fn = (keyrecord_t) {
  311. .event = event,
  312. .code = code,
  313. .mods = keyboard_report->mods,
  314. .time = timer_read()
  315. };
  316. NEXT(DELAYING);
  317. }
  318. break;
  319. case FNK_UP:
  320. layer_switch_off(code);
  321. break;
  322. case KEY_DOWN:
  323. register_code(code);
  324. NEXT(PRESSING);
  325. break;
  326. case MOD_DOWN:
  327. register_code(code);
  328. break;
  329. case KEY_UP:
  330. case MOD_UP:
  331. unregister_code(code);
  332. break;
  333. default:
  334. break;
  335. }
  336. break;
  337. case PRESSING:
  338. switch (kind) {
  339. case FN_DOWN:
  340. // ignored when any key is pressed
  341. break;
  342. case FN_UP:
  343. layer_switch_off(code);
  344. NEXT(IDLE);
  345. break;
  346. case FNK_DOWN:
  347. register_code(keymap_fn_keycode(FN_INDEX(code)));
  348. break;
  349. case FNK_UP:
  350. // can't know whether layer switched or not
  351. layer_switch_off(code);
  352. unregister_code(keymap_fn_keycode(FN_INDEX(code)));
  353. break;
  354. case KEY_DOWN:
  355. case MOD_DOWN:
  356. register_code(code);
  357. break;
  358. case KEY_UP:
  359. case MOD_UP:
  360. unregister_code(code);
  361. // no key registered? mousekey, mediakey, systemkey
  362. if (!host_has_anykey())
  363. NEXT(IDLE);
  364. break;
  365. default:
  366. break;
  367. }
  368. break;
  369. case DELAYING:
  370. switch (kind) {
  371. case FN_DOWN:
  372. case FNK_DOWN:
  373. case KEY_DOWN:
  374. waiting_key = (keyrecord_t) {
  375. .event = event,
  376. .code = code,
  377. .mods = keyboard_report->mods,
  378. .time = timer_read()
  379. };
  380. NEXT(WAITING);
  381. break;
  382. case MOD_DOWN:
  383. register_code(code);
  384. break;
  385. case FN_UP:
  386. layer_switch_off(code);
  387. NEXT(IDLE);
  388. break;
  389. case FNK_UP:
  390. if (code == delayed_fn.code) {
  391. // type Fn with alt keycode
  392. // restore the mod status at the time of pressing Fn key
  393. tmp_mods = keyboard_report->mods;
  394. host_set_mods(delayed_fn.mods);
  395. register_code(keymap_fn_keycode(FN_INDEX(delayed_fn.code)));
  396. unregister_code(keymap_fn_keycode(FN_INDEX(delayed_fn.code)));
  397. host_set_mods(tmp_mods);
  398. NEXT(IDLE);
  399. } else {
  400. layer_switch_off(code);
  401. NEXT(IDLE);
  402. }
  403. break;
  404. case KEY_UP:
  405. unregister_code(code);
  406. NEXT(IDLE);
  407. break;
  408. case MOD_UP:
  409. unregister_code(code);
  410. break;
  411. default:
  412. break;
  413. }
  414. break;
  415. case WAITING:
  416. switch (kind) {
  417. case FN_DOWN:
  418. case FNK_DOWN:
  419. case KEY_DOWN:
  420. tmp_mods = keyboard_report->mods;
  421. host_set_mods(delayed_fn.mods);
  422. register_code(keymap_fn_keycode(FN_INDEX(delayed_fn.code)));
  423. host_set_mods(waiting_key.mods);
  424. register_code(waiting_key.code);
  425. host_set_mods(tmp_mods);
  426. register_code(code);
  427. NEXT(IDLE);
  428. break;
  429. case MOD_DOWN:
  430. register_code(code);
  431. break;
  432. case FN_UP:
  433. layer_switch_off(code);
  434. NEXT(IDLE);
  435. break;
  436. case FNK_UP:
  437. if (code == delayed_fn.code) {
  438. // alt down, key down, alt up
  439. tmp_mods = keyboard_report->mods;
  440. host_set_mods(delayed_fn.mods);
  441. register_code(keymap_fn_keycode(FN_INDEX(delayed_fn.code)));
  442. host_set_mods(waiting_key.mods);
  443. register_code(waiting_key.code);
  444. unregister_code(keymap_fn_keycode(FN_INDEX(delayed_fn.code)));
  445. host_set_mods(tmp_mods);
  446. NEXT(IDLE);
  447. } else {
  448. layer_switch_off(code);
  449. NEXT(IDLE);
  450. }
  451. break;
  452. case KEY_UP:
  453. if (code == waiting_key.code) {
  454. layer_switch_on(delayed_fn.code);
  455. NEXT(IDLE);
  456. // process waiting_key
  457. tmp_mods = keyboard_report->mods;
  458. host_set_mods(waiting_key.mods);
  459. process_key(waiting_key.event);
  460. host_set_mods(tmp_mods);
  461. process_key(event);
  462. } else {
  463. unregister_code(code);
  464. }
  465. break;
  466. case MOD_UP:
  467. unregister_code(code);
  468. break;
  469. default:
  470. break;
  471. }
  472. break;
  473. }
  474. }
  475. void keyboard_init(void)
  476. {
  477. debug_keyboard = true;
  478. timer_init();
  479. matrix_init();
  480. #ifdef PS2_MOUSE_ENABLE
  481. ps2_mouse_init();
  482. #endif
  483. }
  484. void keyboard_task(void)
  485. {
  486. static matrix_row_t matrix_prev[MATRIX_ROWS];
  487. matrix_row_t matrix_row = 0;
  488. matrix_row_t matrix_change = 0;
  489. matrix_scan();
  490. if (command_proc()) {
  491. debug("COMMAND\n");
  492. // TODO: COMMAND state?
  493. clear_keyboard();
  494. return;
  495. }
  496. for (int r = 0; r < MATRIX_ROWS; r++) {
  497. matrix_row = matrix_get_row(r);
  498. matrix_change = matrix_row ^ matrix_prev[r];
  499. if (matrix_change) {
  500. if (debug_matrix) matrix_print();
  501. for (int c = 0; c < MATRIX_COLS; c++) {
  502. if (matrix_change & (1<<c)) {
  503. process_key((keyevent_t){
  504. .key = (key_t){ .row = r, .col = c },
  505. .pressed = (matrix_row & (1<<c))
  506. });
  507. // record a processed key
  508. matrix_prev[r] ^= (1<<c);
  509. // process a key per task call
  510. goto MATRIX_LOOP_END;
  511. }
  512. }
  513. }
  514. }
  515. MATRIX_LOOP_END:
  516. // layer switch when delay term elapses
  517. if (kbdstate == DELAYING || kbdstate == WAITING) {
  518. if (timer_elapsed(delayed_fn.time) > LAYER_DELAY) {
  519. if (kbdstate == DELAYING) {
  520. layer_switch_on(delayed_fn.code);
  521. NEXT(IDLE);
  522. }
  523. if (kbdstate == WAITING) {
  524. layer_switch_on(delayed_fn.code);
  525. NEXT(IDLE);
  526. uint8_t tmp_mods = keyboard_report->mods;
  527. host_set_mods(waiting_key.mods);
  528. process_key(waiting_key.event);
  529. host_set_mods(tmp_mods);
  530. }
  531. }
  532. }
  533. // mousekey repeat & acceleration
  534. mousekey_task();
  535. // FAIL SAFE: clear all key if no key down
  536. if (matrix_change) {
  537. matrix_row_t is_matrix_on = 0;
  538. for (int r = 0; r < MATRIX_ROWS; r++) {
  539. is_matrix_on |= matrix_get_row(r);
  540. }
  541. if (!is_matrix_on) {
  542. debug("FAIL SAFE: clear all keys.\n");
  543. clear_keyboard();
  544. }
  545. }
  546. return;
  547. }
  548. void keyboard_set_leds(uint8_t leds)
  549. {
  550. led_set(leds);
  551. }