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 години
преди 13 години
преди 13 години
преди 13 години
преди 13 години
преди 13 години
преди 13 години
преди 13 години
преди 13 години
преди 13 години
преди 13 години
преди 13 години
преди 13 години
преди 13 години
преди 13 години
преди 13 години
преди 13 години
преди 13 години
преди 13 години
преди 13 години
преди 13 години
преди 13 години
преди 13 години
преди 13 години
преди 13 години
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  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 <stdbool.h>
  15. #include<avr/io.h>
  16. #include<util/delay.h>
  17. #include "ps2.h"
  18. #include "ps2_mouse.h"
  19. #include "usb_mouse.h"
  20. #define PS2_MOUSE_DEBUG
  21. #ifdef PS2_MOUSE_DEBUG
  22. # include "print.h"
  23. # include "debug.h"
  24. #else
  25. # define print(s)
  26. # define phex(h)
  27. # define phex16(h)
  28. #endif
  29. // disable when errors occur 255 times.
  30. #define ERROR_RETURN() do { \
  31. if (ps2_error) { \
  32. if (ps2_mouse_error_count < 255) { \
  33. ps2_mouse_error_count++; \
  34. } else { \
  35. ps2_mouse_error_count = 0; \
  36. ps2_mouse_enable = false; \
  37. } \
  38. return ps2_error; \
  39. } \
  40. } while (0)
  41. /*
  42. TODO
  43. ----
  44. - Stream mode
  45. - Tracpoint command support: needed
  46. - Middle button + move = Wheel traslation
  47. */
  48. bool ps2_mouse_enable = true;
  49. uint8_t ps2_mouse_x = 0;
  50. uint8_t ps2_mouse_y = 0;
  51. uint8_t ps2_mouse_btn = 0;
  52. uint8_t ps2_mouse_error_count = 0;
  53. static uint8_t ps2_mouse_btn_prev = 0;
  54. uint8_t ps2_mouse_init(void) {
  55. uint8_t rcv;
  56. if (!ps2_mouse_enable) return 1;
  57. ps2_host_init();
  58. // Reset
  59. rcv = ps2_host_send(0xFF);
  60. print("ps2_mouse_init: send 0xFF: ");
  61. phex(ps2_error); print("\n");
  62. ERROR_RETURN();
  63. // ACK
  64. rcv = ps2_host_recv();
  65. print("ps2_mouse_init: read ACK: ");
  66. phex(rcv); phex(ps2_error); print("\n");
  67. ERROR_RETURN();
  68. // BAT takes some time
  69. _delay_ms(100);
  70. rcv = ps2_host_recv();
  71. print("ps2_mouse_init: read BAT: ");
  72. phex(rcv); phex(ps2_error); print("\n");
  73. ERROR_RETURN();
  74. // Device ID
  75. rcv = ps2_host_recv();
  76. print("ps2_mouse_init: read DevID: ");
  77. phex(rcv); phex(ps2_error); print("\n");
  78. ERROR_RETURN();
  79. // Enable data reporting
  80. ps2_host_send(0xF4);
  81. print("ps2_mouse_init: send 0xF4: ");
  82. phex(ps2_error); print("\n");
  83. ERROR_RETURN();
  84. // ACK
  85. rcv = ps2_host_recv();
  86. print("ps2_mouse_init: read ACK: ");
  87. phex(rcv); phex(ps2_error); print("\n");
  88. ERROR_RETURN();
  89. // Set Remote mode
  90. ps2_host_send(0xF0);
  91. print("ps2_mouse_init: send 0xF0: ");
  92. phex(ps2_error); print("\n");
  93. ERROR_RETURN();
  94. // ACK
  95. rcv = ps2_host_recv();
  96. print("ps2_mouse_init: read ACK: ");
  97. phex(rcv); phex(ps2_error); print("\n");
  98. ERROR_RETURN();
  99. return 0;
  100. }
  101. /*
  102. Data format:
  103. bit: 7 6 5 4 3 2 1 0
  104. -----------------------------------------------------------------------
  105. 0 btn: Yovflw Xovflw Ysign Xsign 1 Middle Right Left
  106. 1 x: X movement(0-255)
  107. 2 y: Y movement(0-255)
  108. */
  109. uint8_t ps2_mouse_read(void)
  110. {
  111. uint8_t rcv;
  112. if (!ps2_mouse_enable) return 1;
  113. ps2_host_send(0xEB);
  114. ERROR_RETURN();
  115. rcv=ps2_host_recv();
  116. ERROR_RETURN();
  117. if(rcv==0xFA) {
  118. ps2_mouse_btn = ps2_host_recv();
  119. ERROR_RETURN();
  120. ps2_mouse_x = ps2_host_recv();
  121. ERROR_RETURN();
  122. ps2_mouse_y = ps2_host_recv();
  123. ERROR_RETURN();
  124. }
  125. return 0;
  126. }
  127. bool ps2_mouse_changed(void)
  128. {
  129. return (ps2_mouse_x || ps2_mouse_y || (ps2_mouse_btn & PS2_MOUSE_BTN_MASK) != ps2_mouse_btn_prev);
  130. }
  131. #define PS2_MOUSE_SCROLL_BUTTON 0x04
  132. void ps2_mouse_usb_send(void)
  133. {
  134. static bool scrolled = false;
  135. if (!ps2_mouse_enable) return;
  136. if (ps2_mouse_changed()) {
  137. int8_t x, y, v, h;
  138. x = y = v = h = 0;
  139. // convert scale of X, Y: PS/2(-256/255) -> USB(-127/127)
  140. if (ps2_mouse_btn & (1<<PS2_MOUSE_X_SIGN))
  141. x = ps2_mouse_x > 128 ? (int8_t)ps2_mouse_x : -127;
  142. else
  143. x = ps2_mouse_x < 128 ? (int8_t)ps2_mouse_x : 127;
  144. if (ps2_mouse_btn & (1<<PS2_MOUSE_Y_SIGN))
  145. y = ps2_mouse_y > 128 ? (int8_t)ps2_mouse_y : -127;
  146. else
  147. y = ps2_mouse_y < 128 ? (int8_t)ps2_mouse_y : 127;
  148. // Y is needed to reverse
  149. y = -y;
  150. if (ps2_mouse_btn & PS2_MOUSE_SCROLL_BUTTON) {
  151. // scroll
  152. if (x > 0 || x < 0) h = (x > 64 ? 64 : (x < -64 ? -64 :x));
  153. if (y > 0 || y < 0) v = (y > 64 ? 64 : (y < -64 ? -64 :y));
  154. if (h || v) {
  155. scrolled = true;
  156. usb_mouse_send(0,0, -v/16, h/16, 0);
  157. _delay_ms(100);
  158. }
  159. } else if (!scrolled && (ps2_mouse_btn_prev & PS2_MOUSE_SCROLL_BUTTON)) {
  160. usb_mouse_send(0,0,0,0, PS2_MOUSE_SCROLL_BUTTON);
  161. _delay_ms(100);
  162. usb_mouse_send(0,0,0,0, 0);
  163. } else {
  164. scrolled = false;
  165. usb_mouse_send(x, y, 0, 0, ps2_mouse_btn & PS2_MOUSE_BTN_MASK);
  166. }
  167. ps2_mouse_btn_prev = (ps2_mouse_btn & PS2_MOUSE_BTN_MASK);
  168. ps2_mouse_print();
  169. }
  170. ps2_mouse_x = 0;
  171. ps2_mouse_y = 0;
  172. ps2_mouse_btn = 0;
  173. }
  174. void ps2_mouse_print(void)
  175. {
  176. if (!debug_mouse) return;
  177. print("ps2_mouse[btn|x y]: ");
  178. phex(ps2_mouse_btn); print("|");
  179. phex(ps2_mouse_x); print(" ");
  180. phex(ps2_mouse_y); print("\n");
  181. }