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.

преди 13 години
преди 10 години
преди 13 години
преди 13 години
преди 13 години
преди 13 години
преди 13 години
преди 13 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 13 години
преди 13 години
преди 13 години
преди 10 години
преди 10 години
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. /*
  2. Copyright 2011,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 <stdbool.h>
  15. #include<avr/io.h>
  16. #include<util/delay.h>
  17. #include "ps2.h"
  18. #include "ps2_mouse.h"
  19. #include "report.h"
  20. #include "host.h"
  21. #define PS2_MOUSE_DEBUG
  22. #ifdef PS2_MOUSE_DEBUG
  23. # include "print.h"
  24. # include "debug.h"
  25. #else
  26. # define print(s)
  27. # define phex(h)
  28. # define phex16(h)
  29. #endif
  30. static report_mouse_t mouse_report = {};
  31. static void ps2_mouse_print_raw_data(void);
  32. static void ps2_mouse_print_usb_data(void);
  33. /* supports only 3 button mouse at this time */
  34. uint8_t ps2_mouse_init(void) {
  35. uint8_t rcv;
  36. ps2_host_init();
  37. _delay_ms(1000); // wait for powering up
  38. // send Reset
  39. rcv = ps2_host_send(0xFF);
  40. print("ps2_mouse_init: send Reset: ");
  41. phex(rcv); phex(ps2_error); print("\n");
  42. // read completion code of BAT
  43. rcv = ps2_host_recv();
  44. print("ps2_mouse_init: read BAT: ");
  45. phex(rcv); phex(ps2_error); print("\n");
  46. // read Device ID
  47. rcv = ps2_host_recv();
  48. print("ps2_mouse_init: read DevID: ");
  49. phex(rcv); phex(ps2_error); print("\n");
  50. // send Enable Data Reporting
  51. rcv = ps2_host_send(0xF4);
  52. print("ps2_mouse_init: send 0xF4: ");
  53. phex(rcv); phex(ps2_error); print("\n");
  54. // send Set Remote mode
  55. rcv = ps2_host_send(0xF0);
  56. print("ps2_mouse_init: send 0xF0: ");
  57. phex(rcv); phex(ps2_error); print("\n");
  58. return 0;
  59. }
  60. /* scroll support
  61. * TODO: should be build option
  62. */
  63. #define PS2_MOUSE_SCROLL_BUTTON 0x04
  64. #define X_IS_NEG (mouse_report.buttons & (1<<PS2_MOUSE_X_SIGN))
  65. #define Y_IS_NEG (mouse_report.buttons & (1<<PS2_MOUSE_Y_SIGN))
  66. #define X_IS_OVF (mouse_report.buttons & (1<<PS2_MOUSE_X_OVFLW))
  67. #define Y_IS_OVF (mouse_report.buttons & (1<<PS2_MOUSE_Y_OVFLW))
  68. void ps2_mouse_task(void)
  69. {
  70. enum { SCROLL_NONE, SCROLL_BTN, SCROLL_SENT };
  71. static uint8_t scroll_state = SCROLL_NONE;
  72. static uint8_t buttons_prev = 0;
  73. /* receives packet from mouse */
  74. uint8_t rcv;
  75. rcv = ps2_host_send(PS2_MOUSE_READ_DATA);
  76. if (rcv == PS2_ACK) {
  77. mouse_report.buttons = ps2_host_recv_response();
  78. mouse_report.x = ps2_host_recv_response();
  79. mouse_report.y = ps2_host_recv_response();
  80. } else {
  81. if (!debug_mouse) print("ps2_mouse: fail to get mouse packet\n");
  82. return;
  83. }
  84. /* if mouse moves or buttons state changes */
  85. if (mouse_report.x || mouse_report.y ||
  86. ((mouse_report.buttons ^ buttons_prev) & PS2_MOUSE_BTN_MASK)) {
  87. ps2_mouse_print_raw_data();
  88. buttons_prev = mouse_report.buttons;
  89. // PS/2 mouse data is '9-bit integer'(-256 to 255) which is comprised of sign-bit and 8-bit value.
  90. // bit: 8 7 ... 0
  91. // sign \8-bit/
  92. //
  93. // Meanwhile USB HID mouse indicates 8bit data(-127 to 127), note that -128 is not used.
  94. //
  95. // This converts PS/2 data into HID value. Use only -127-127 out of PS/2 9-bit.
  96. mouse_report.x = X_IS_NEG ?
  97. ((!X_IS_OVF && -127 <= mouse_report.x && mouse_report.x <= -1) ? mouse_report.x : -127) :
  98. ((!X_IS_OVF && 0 <= mouse_report.x && mouse_report.x <= 127) ? mouse_report.x : 127);
  99. mouse_report.y = Y_IS_NEG ?
  100. ((!Y_IS_OVF && -127 <= mouse_report.y && mouse_report.y <= -1) ? mouse_report.y : -127) :
  101. ((!Y_IS_OVF && 0 <= mouse_report.y && mouse_report.y <= 127) ? mouse_report.y : 127);
  102. // remove sign and overflow flags
  103. mouse_report.buttons &= PS2_MOUSE_BTN_MASK;
  104. // invert coordinate of y to conform to USB HID mouse
  105. mouse_report.y = -mouse_report.y;
  106. if ((mouse_report.buttons & PS2_MOUSE_SCROLL_BUTTON) == PS2_MOUSE_SCROLL_BUTTON) {
  107. if (scroll_state == SCROLL_NONE) scroll_state = SCROLL_BTN;
  108. // doesn't send Scroll Button
  109. mouse_report.buttons &= ~PS2_MOUSE_SCROLL_BUTTON;
  110. if (mouse_report.x || mouse_report.y) {
  111. scroll_state = SCROLL_SENT;
  112. mouse_report.v = -mouse_report.y/2;
  113. mouse_report.h = mouse_report.x/2;
  114. mouse_report.x = 0;
  115. mouse_report.y = 0;
  116. host_mouse_send(&mouse_report);
  117. }
  118. } else if (scroll_state == SCROLL_BTN &&
  119. (mouse_report.buttons & PS2_MOUSE_SCROLL_BUTTON) == 0) {
  120. scroll_state = SCROLL_NONE;
  121. // send Scroll Button(down and up at once) when not scrolled
  122. mouse_report.buttons |= PS2_MOUSE_SCROLL_BUTTON;
  123. host_mouse_send(&mouse_report);
  124. _delay_ms(100);
  125. mouse_report.buttons &= ~PS2_MOUSE_SCROLL_BUTTON;
  126. host_mouse_send(&mouse_report);
  127. } else {
  128. scroll_state = SCROLL_NONE;
  129. host_mouse_send(&mouse_report);
  130. }
  131. ps2_mouse_print_usb_data();
  132. }
  133. // clear report
  134. mouse_report.x = 0;
  135. mouse_report.y = 0;
  136. mouse_report.v = 0;
  137. mouse_report.h = 0;
  138. mouse_report.buttons = 0;
  139. }
  140. static void ps2_mouse_print_raw_data(void)
  141. {
  142. if (!debug_mouse) return;
  143. print("ps2_mouse raw [btn|x y]: [");
  144. phex(mouse_report.buttons); print("|");
  145. print_hex8((uint8_t)mouse_report.x); print(" ");
  146. print_hex8((uint8_t)mouse_report.y); print("]\n");
  147. }
  148. static void ps2_mouse_print_usb_data(void)
  149. {
  150. if (!debug_mouse) return;
  151. print("ps2_mouse usb [btn|x y v h]: [");
  152. phex(mouse_report.buttons); print("|");
  153. print_hex8((uint8_t)mouse_report.x); print(" ");
  154. print_hex8((uint8_t)mouse_report.y); print(" ");
  155. print_hex8((uint8_t)mouse_report.v); print(" ");
  156. print_hex8((uint8_t)mouse_report.h); print("]\n");
  157. }
  158. /* PS/2 Mouse Synopsis
  159. * http://www.computer-engineering.org/ps2mouse/
  160. *
  161. * Command:
  162. * 0xFF: Reset
  163. * 0xF6: Set Defaults Sampling; rate=100, resolution=4cnt/mm, scaling=1:1, reporting=disabled
  164. * 0xF5: Disable Data Reporting
  165. * 0xF4: Enable Data Reporting
  166. * 0xF3: Set Sample Rate
  167. * 0xF2: Get Device ID
  168. * 0xF0: Set Remote Mode
  169. * 0xEB: Read Data
  170. * 0xEA: Set Stream Mode
  171. * 0xE9: Status Request
  172. * 0xE8: Set Resolution
  173. * 0xE7: Set Scaling 2:1
  174. * 0xE6: Set Scaling 1:1
  175. *
  176. * Mode:
  177. * Stream Mode: devices sends the data when it changs its state
  178. * Remote Mode: host polls the data periodically
  179. *
  180. * This code uses Remote Mode and polls the data with Read Data(0xEB).
  181. *
  182. * Data format:
  183. * byte|7 6 5 4 3 2 1 0
  184. * ----+--------------------------------------------------------------
  185. * 0|Yovflw Xovflw Ysign Xsign 1 Middle Right Left
  186. * 1| X movement
  187. * 2| Y movement
  188. */