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.

269 lines
7.3 KiB

  1. /*
  2. Copyright 2011 Jun Wako <wakojun@gmail.com>
  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. Ported to QMK by Peter Roe <pete@13bit.me>
  14. */
  15. #include <stdint.h>
  16. #include <stdbool.h>
  17. #include <avr/io.h>
  18. #include <util/delay.h>
  19. #include "print.h"
  20. #include "util.h"
  21. #include "debug.h"
  22. #include "adb.h"
  23. #include "matrix.h"
  24. #include "report.h"
  25. #include "host.h"
  26. #include "led.h"
  27. #include "timer.h"
  28. #ifndef ADB_MOUSE_MAXACC
  29. # define ADB_MOUSE_MAXACC 8
  30. #endif
  31. static bool is_iso_layout = false;
  32. // matrix state buffer(1:on, 0:off)
  33. static matrix_row_t matrix[MATRIX_ROWS];
  34. static void register_key(uint8_t key);
  35. __attribute__ ((weak))
  36. void matrix_init_kb(void) {
  37. matrix_init_user();
  38. }
  39. __attribute__ ((weak))
  40. void matrix_scan_kb(void) {
  41. matrix_scan_user();
  42. }
  43. __attribute__ ((weak))
  44. void matrix_init_user(void) {
  45. }
  46. __attribute__ ((weak))
  47. void matrix_scan_user(void) {
  48. }
  49. void matrix_init(void)
  50. {
  51. adb_host_init();
  52. // wait for keyboard to boot up and receive command
  53. _delay_ms(2000);
  54. // initialize matrix state: all keys off
  55. for (uint8_t i=0; i < MATRIX_ROWS; i++) matrix[i] = 0x00;
  56. // debug_enable = true;
  57. // debug_matrix = true;
  58. // debug_keyboard = true;
  59. // debug_mouse = true;
  60. // print("debug enabled.\n");
  61. matrix_init_quantum();
  62. }
  63. #ifdef ADB_MOUSE_ENABLE
  64. #ifdef MAX
  65. #undef MAX
  66. #endif
  67. #define MAX(X, Y) ((X) > (Y) ? (X) : (Y))
  68. static report_mouse_t mouse_report = {};
  69. void housekeeping_task_kb(void) {
  70. adb_mouse_task();
  71. }
  72. void adb_mouse_task(void)
  73. {
  74. uint16_t codes;
  75. int16_t x, y;
  76. static int8_t mouseacc;
  77. /* tick of last polling */
  78. static uint16_t tick_ms;
  79. // polling with 12ms interval
  80. if (timer_elapsed(tick_ms) < 12) return;
  81. tick_ms = timer_read();
  82. codes = adb_host_mouse_recv();
  83. // If nothing received reset mouse acceleration, and quit.
  84. if (!codes) {
  85. mouseacc = 1;
  86. return;
  87. };
  88. // Bit sixteen is button.
  89. if (~codes & (1 << 15))
  90. mouse_report.buttons |= MOUSE_BTN1;
  91. if (codes & (1 << 15))
  92. mouse_report.buttons &= ~MOUSE_BTN1;
  93. // lower seven bits are movement, as signed int_7.
  94. // low byte is X-axis, high byte is Y.
  95. y = (codes>>8 & 0x3F);
  96. x = (codes>>0 & 0x3F);
  97. // bit seven and fifteen is negative
  98. // usb does not use int_8, but int_7 (measuring distance) with sign-bit.
  99. if (codes & (1 << 6))
  100. x = (x-0x40);
  101. if (codes & (1 << 14))
  102. y = (y-0x40);
  103. // Accelerate mouse. (They weren't meant to be used on screens larger than 320x200).
  104. x *= mouseacc;
  105. y *= mouseacc;
  106. // Cap our two bytes per axis to one byte.
  107. // Easier with a MIN-function, but since -MAX(-a,-b) = MIN(a,b)...
  108. // I.E. MIN(MAX(x,-127),127) = -MAX(-MAX(x, -127), -127) = MIN(-MIN(-x,127),127)
  109. mouse_report.x = -MAX(-MAX(x, -127), -127);
  110. mouse_report.y = -MAX(-MAX(y, -127), -127);
  111. if (debug_mouse) {
  112. print("adb_host_mouse_recv: "); print_bin16(codes); print("\n");
  113. print("adb_mouse raw: [");
  114. print_hex8(mouseacc); print(" ");
  115. print_hex8(mouse_report.buttons); print("|");
  116. print_decs(mouse_report.x); print(" ");
  117. print_decs(mouse_report.y); print("]\n");
  118. }
  119. // Send result by usb.
  120. host_mouse_send(&mouse_report);
  121. // increase acceleration of mouse
  122. mouseacc += ( mouseacc < ADB_MOUSE_MAXACC ? 1 : 0 );
  123. return;
  124. }
  125. #endif
  126. uint8_t matrix_scan(void)
  127. {
  128. /* extra_key is volatile and more convoluted than necessary because gcc refused
  129. to generate valid code otherwise. Making extra_key uint8_t and constructing codes
  130. here via codes = extra_key<<8 | 0xFF; would consistently fail to even LOAD
  131. extra_key from memory, and leave garbage in the high byte of codes. I tried
  132. dozens of code variations and it kept generating broken assembly output. So
  133. beware if attempting to make extra_key code more logical and efficient. */
  134. static volatile uint16_t extra_key = 0xFFFF;
  135. uint16_t codes;
  136. uint8_t key0, key1;
  137. /* tick of last polling */
  138. static uint16_t tick_ms;
  139. codes = extra_key;
  140. extra_key = 0xFFFF;
  141. if ( codes == 0xFFFF )
  142. {
  143. // polling with 12ms interval
  144. if (timer_elapsed(tick_ms) < 12) return 0;
  145. tick_ms = timer_read();
  146. codes = adb_host_kbd_recv();
  147. }
  148. key0 = codes>>8;
  149. key1 = codes&0xFF;
  150. if (debug_matrix && codes) {
  151. print("adb_host_kbd_recv: "); print_hex16(codes); print("\n");
  152. }
  153. if (codes == 0) { // no keys
  154. return 0;
  155. } else if (codes == 0x7F7F) { // power key press
  156. register_key(0x7F);
  157. } else if (codes == 0xFFFF) { // power key release
  158. register_key(0xFF);
  159. } else if (key0 == 0xFF) { // error
  160. xprintf("adb_host_kbd_recv: ERROR(%d)\n", codes);
  161. // something wrong or plug-in
  162. matrix_init();
  163. return key1;
  164. } else {
  165. /* Swap codes for ISO keyboard
  166. * https://github.com/tmk/tmk_keyboard/issues/35
  167. *
  168. * ANSI
  169. * ,----------- ----------.
  170. * | *a| 1| 2 =|Backspa|
  171. * |----------- ----------|
  172. * |Tab | Q| | ]| *c|
  173. * |----------- ----------|
  174. * |CapsLo| A| '|Return |
  175. * |----------- ----------|
  176. * |Shift | Shift |
  177. * `----------- ----------'
  178. *
  179. * ISO
  180. * ,----------- ----------.
  181. * | *a| 1| 2 =|Backspa|
  182. * |----------- ----------|
  183. * |Tab | Q| | ]|Retur|
  184. * |----------- -----` |
  185. * |CapsLo| A| '| *c| |
  186. * |----------- ----------|
  187. * |Shif| *b| Shift |
  188. * `----------- ----------'
  189. *
  190. * ADB scan code USB usage
  191. * ------------- ---------
  192. * Key ANSI ISO ANSI ISO
  193. * ---------------------------------------------
  194. * *a 0x32 0x0A 0x35 0x35
  195. * *b ---- 0x32 ---- 0x64
  196. * *c 0x2A 0x2A 0x31 0x31(or 0x32)
  197. */
  198. if (is_iso_layout) {
  199. if ((key0 & 0x7F) == 0x32) {
  200. key0 = (key0 & 0x80) | 0x0A;
  201. } else if ((key0 & 0x7F) == 0x0A) {
  202. key0 = (key0 & 0x80) | 0x32;
  203. }
  204. }
  205. register_key(key0);
  206. if (key1 != 0xFF) // key1 is 0xFF when no second key.
  207. extra_key = key1<<8 | 0xFF; // process in a separate call
  208. }
  209. matrix_scan_quantum();
  210. return 1;
  211. }
  212. void matrix_print(void){
  213. }
  214. inline
  215. matrix_row_t matrix_get_row(uint8_t row)
  216. {
  217. return matrix[row];
  218. }
  219. inline
  220. static void register_key(uint8_t key)
  221. {
  222. uint8_t col, row;
  223. col = key&0x07;
  224. row = (key>>3)&0x0F;
  225. if (key&0x80) {
  226. matrix[row] &= ~(1<<col);
  227. } else {
  228. matrix[row] |= (1<<col);
  229. }
  230. }