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.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.

hace 10 años
hace 10 años
hace 10 años
hace 10 años
hace 10 años
hace 10 años
hace 10 años
hace 10 años
hace 10 años
hace 10 años
hace 10 años
hace 10 años
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339
  1. /*
  2. Copyright 2013 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 "host.h"
  15. #include "report.h"
  16. #include "debug.h"
  17. #include "action_util.h"
  18. #include "timer.h"
  19. static inline void add_key_byte(uint8_t code);
  20. static inline void del_key_byte(uint8_t code);
  21. #ifdef NKRO_ENABLE
  22. static inline void add_key_bit(uint8_t code);
  23. static inline void del_key_bit(uint8_t code);
  24. #endif
  25. static uint8_t real_mods = 0;
  26. static uint8_t weak_mods = 0;
  27. #ifdef USB_6KRO_ENABLE
  28. #undef KEYBOARD_REPORT_KEYS
  29. #define KEYBOARD_REPORT_KEYS 6
  30. #define RO_ADD(a, b) ((a + b) % KEYBOARD_REPORT_KEYS)
  31. #define RO_SUB(a, b) ((a - b + KEYBOARD_REPORT_KEYS) % KEYBOARD_REPORT_KEYS)
  32. #define RO_INC(a) RO_ADD(a, 1)
  33. #define RO_DEC(a) RO_SUB(a, 1)
  34. static int8_t cb_head = 0;
  35. static int8_t cb_tail = 0;
  36. static int8_t cb_count = 0;
  37. #endif
  38. // TODO: pointer variable is not needed
  39. //report_keyboard_t keyboard_report = {};
  40. report_keyboard_t *keyboard_report = &(report_keyboard_t){};
  41. #ifndef NO_ACTION_ONESHOT
  42. static int8_t oneshot_mods = 0;
  43. #if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
  44. static int16_t oneshot_time = 0;
  45. #endif
  46. #endif
  47. void send_keyboard_report(void) {
  48. keyboard_report->mods = real_mods;
  49. keyboard_report->mods |= weak_mods;
  50. #ifndef NO_ACTION_ONESHOT
  51. if (oneshot_mods) {
  52. #if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
  53. if (TIMER_DIFF_16(timer_read(), oneshot_time) >= ONESHOT_TIMEOUT) {
  54. dprintf("Oneshot: timeout\n");
  55. clear_oneshot_mods();
  56. }
  57. #endif
  58. keyboard_report->mods |= oneshot_mods;
  59. if (has_anykey()) {
  60. clear_oneshot_mods();
  61. }
  62. }
  63. #endif
  64. host_keyboard_send(keyboard_report);
  65. }
  66. /* key */
  67. void add_key(uint8_t key)
  68. {
  69. #ifdef NKRO_ENABLE
  70. if (keyboard_protocol && keyboard_nkro) {
  71. add_key_bit(key);
  72. return;
  73. }
  74. #endif
  75. add_key_byte(key);
  76. }
  77. void del_key(uint8_t key)
  78. {
  79. #ifdef NKRO_ENABLE
  80. if (keyboard_protocol && keyboard_nkro) {
  81. del_key_bit(key);
  82. return;
  83. }
  84. #endif
  85. del_key_byte(key);
  86. }
  87. void clear_keys(void)
  88. {
  89. // not clear mods
  90. for (int8_t i = 1; i < KEYBOARD_REPORT_SIZE; i++) {
  91. keyboard_report->raw[i] = 0;
  92. }
  93. }
  94. /* modifier */
  95. uint8_t get_mods(void) { return real_mods; }
  96. void add_mods(uint8_t mods) { real_mods |= mods; }
  97. void del_mods(uint8_t mods) { real_mods &= ~mods; }
  98. void set_mods(uint8_t mods) { real_mods = mods; }
  99. void clear_mods(void) { real_mods = 0; }
  100. /* weak modifier */
  101. uint8_t get_weak_mods(void) { return weak_mods; }
  102. void add_weak_mods(uint8_t mods) { weak_mods |= mods; }
  103. void del_weak_mods(uint8_t mods) { weak_mods &= ~mods; }
  104. void set_weak_mods(uint8_t mods) { weak_mods = mods; }
  105. void clear_weak_mods(void) { weak_mods = 0; }
  106. /* Oneshot modifier */
  107. #ifndef NO_ACTION_ONESHOT
  108. void set_oneshot_mods(uint8_t mods)
  109. {
  110. oneshot_mods = mods;
  111. #if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
  112. oneshot_time = timer_read();
  113. #endif
  114. }
  115. void clear_oneshot_mods(void)
  116. {
  117. oneshot_mods = 0;
  118. #if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
  119. oneshot_time = 0;
  120. #endif
  121. }
  122. #endif
  123. /*
  124. * inspect keyboard state
  125. */
  126. uint8_t has_anykey(void)
  127. {
  128. #ifdef USB_6KRO_ENABLE
  129. #ifdef NKRO_ENABLE
  130. if (!keyboard_nkro) {
  131. #endif
  132. return cb_count;
  133. #ifdef NKRO_ENABLE
  134. }
  135. #endif
  136. #else
  137. uint8_t cnt = 0;
  138. for (uint8_t i = 1; i < KEYBOARD_REPORT_SIZE; i++) {
  139. if (keyboard_report->raw[i])
  140. cnt++;
  141. }
  142. return cnt;
  143. #endif
  144. }
  145. uint8_t has_anymod(void)
  146. {
  147. return bitpop(real_mods);
  148. }
  149. uint8_t get_first_key(void)
  150. {
  151. #ifdef NKRO_ENABLE
  152. if (keyboard_protocol && keyboard_nkro) {
  153. uint8_t i = 0;
  154. for (; i < KEYBOARD_REPORT_BITS && !keyboard_report->nkro.bits[i]; i++)
  155. ;
  156. return i<<3 | biton(keyboard_report->nkro.bits[i]);
  157. }
  158. #endif
  159. #ifdef USB_6KRO_ENABLE
  160. uint8_t i = cb_head;
  161. do {
  162. if (keyboard_report->keys[i] != 0) {
  163. break;
  164. }
  165. i = RO_INC(i);
  166. } while (i != cb_tail);
  167. return keyboard_report->keys[i];
  168. #else
  169. return keyboard_report->keys[0];
  170. #endif
  171. }
  172. #ifdef USB_6KRO_ENABLE
  173. #ifdef DEBUG
  174. static void dump_report_keys(void) {
  175. dprintf("\n");
  176. for (uint8_t i = 0; i < REPORT_KEYS; i++) {
  177. dprintf("%02X ", keyboard_report->keys[i]);
  178. }
  179. dprintf("\n");
  180. for (uint8_t i = 0; i < REPORT_KEYS; i++) {
  181. dprintf("%c%c ", i==cb_head?'H':' ', i==cb_tail?'T':' ');
  182. }
  183. dprintf("\n");
  184. }
  185. #endif
  186. #endif
  187. /* local functions */
  188. static inline void add_key_byte(uint8_t code)
  189. {
  190. #ifdef USB_6KRO_ENABLE
  191. int8_t i = cb_head;
  192. int8_t empty = -1;
  193. if (cb_count) {
  194. do {
  195. if (keyboard_report->keys[i] == code) {
  196. return;
  197. }
  198. if (empty == -1 && keyboard_report->keys[i] == 0) {
  199. empty = i;
  200. }
  201. i = RO_INC(i);
  202. } while (i != cb_tail);
  203. if (i == cb_tail) {
  204. if (cb_tail == cb_head) {
  205. // buffer is full
  206. if (empty == -1) {
  207. // pop head when has no empty space
  208. cb_head = RO_INC(cb_head);
  209. cb_count--;
  210. }
  211. else {
  212. // left shift when has empty space
  213. uint8_t offset = 1;
  214. i = RO_INC(empty);
  215. do {
  216. if (keyboard_report->keys[i] != 0) {
  217. keyboard_report->keys[empty] = keyboard_report->keys[i];
  218. keyboard_report->keys[i] = 0;
  219. empty = RO_INC(empty);
  220. }
  221. else {
  222. offset++;
  223. }
  224. i = RO_INC(i);
  225. } while (i != cb_tail);
  226. cb_tail = RO_SUB(cb_tail, offset);
  227. }
  228. }
  229. }
  230. }
  231. // add to tail
  232. keyboard_report->keys[cb_tail] = code;
  233. cb_tail = RO_INC(cb_tail);
  234. cb_count++;
  235. #ifdef DEBUG
  236. dump_report_keys();
  237. #endif
  238. #else
  239. int8_t i = 0;
  240. int8_t empty = -1;
  241. for (; i < KEYBOARD_REPORT_KEYS; i++) {
  242. if (keyboard_report->keys[i] == code) {
  243. break;
  244. }
  245. if (empty == -1 && keyboard_report->keys[i] == 0) {
  246. empty = i;
  247. }
  248. }
  249. if (i == KEYBOARD_REPORT_KEYS) {
  250. if (empty != -1) {
  251. keyboard_report->keys[empty] = code;
  252. }
  253. }
  254. #endif
  255. }
  256. static inline void del_key_byte(uint8_t code)
  257. {
  258. #ifdef USB_6KRO_ENABLE
  259. uint8_t i = cb_head;
  260. if (cb_count) {
  261. do {
  262. if (keyboard_report->keys[i] == code) {
  263. keyboard_report->keys[i] = 0;
  264. cb_count--;
  265. if (cb_count == 0) {
  266. // reset head and tail
  267. cb_tail = cb_head = 0;
  268. }
  269. if (i == RO_DEC(cb_tail)) {
  270. // left shift when next to tail
  271. do {
  272. cb_tail = RO_DEC(cb_tail);
  273. if (keyboard_report->keys[RO_DEC(cb_tail)] != 0) {
  274. break;
  275. }
  276. } while (cb_tail != cb_head);
  277. }
  278. break;
  279. }
  280. i = RO_INC(i);
  281. } while (i != cb_tail);
  282. }
  283. #ifdef DEBUG
  284. dump_report_keys();
  285. #endif
  286. #else
  287. for (uint8_t i = 0; i < KEYBOARD_REPORT_KEYS; i++) {
  288. if (keyboard_report->keys[i] == code) {
  289. keyboard_report->keys[i] = 0;
  290. }
  291. }
  292. #endif
  293. }
  294. #ifdef NKRO_ENABLE
  295. static inline void add_key_bit(uint8_t code)
  296. {
  297. if ((code>>3) < KEYBOARD_REPORT_BITS) {
  298. keyboard_report->nkro.bits[code>>3] |= 1<<(code&7);
  299. } else {
  300. dprintf("add_key_bit: can't add: %02X\n", code);
  301. }
  302. }
  303. static inline void del_key_bit(uint8_t code)
  304. {
  305. if ((code>>3) < KEYBOARD_REPORT_BITS) {
  306. keyboard_report->nkro.bits[code>>3] &= ~(1<<(code&7));
  307. } else {
  308. dprintf("del_key_bit: can't del: %02X\n", code);
  309. }
  310. }
  311. #endif