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