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 години
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  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. // Reset
  45. rcv = ps2_host_send(0xFF);
  46. print("ps2_mouse_init: send 0xFF: ");
  47. phex(ps2_error); print("\n");
  48. ERROR_RETURN();
  49. // ACK
  50. rcv = ps2_host_recv();
  51. print("ps2_mouse_init: read ACK: ");
  52. phex(rcv); phex(ps2_error); print("\n");
  53. ERROR_RETURN();
  54. // BAT takes some time
  55. _delay_ms(100);
  56. rcv = ps2_host_recv();
  57. print("ps2_mouse_init: read BAT: ");
  58. phex(rcv); phex(ps2_error); print("\n");
  59. ERROR_RETURN();
  60. // Device ID
  61. rcv = ps2_host_recv();
  62. print("ps2_mouse_init: read DevID: ");
  63. phex(rcv); phex(ps2_error); print("\n");
  64. ERROR_RETURN();
  65. // Enable data reporting
  66. ps2_host_send(0xF4);
  67. print("ps2_mouse_init: send 0xF4: ");
  68. phex(ps2_error); print("\n");
  69. ERROR_RETURN();
  70. // ACK
  71. rcv = ps2_host_recv();
  72. print("ps2_mouse_init: read ACK: ");
  73. phex(rcv); phex(ps2_error); print("\n");
  74. ERROR_RETURN();
  75. // Set Remote mode
  76. ps2_host_send(0xF0);
  77. print("ps2_mouse_init: send 0xF0: ");
  78. phex(ps2_error); print("\n");
  79. ERROR_RETURN();
  80. // ACK
  81. rcv = ps2_host_recv();
  82. print("ps2_mouse_init: read ACK: ");
  83. phex(rcv); phex(ps2_error); print("\n");
  84. ERROR_RETURN();
  85. return 0;
  86. }
  87. /*
  88. Data format:
  89. bit: 7 6 5 4 3 2 1 0
  90. -----------------------------------------------------------------------
  91. 0 btn: Yovflw Xovflw Ysign Xsign 1 Middle Right Left
  92. 1 x: X movement(0-255)
  93. 2 y: Y movement(0-255)
  94. */
  95. uint8_t ps2_mouse_read(void)
  96. {
  97. uint8_t rcv;
  98. if (!ps2_mouse_enable) return 1;
  99. ps2_host_send(0xEB);
  100. ERROR_RETURN();
  101. rcv=ps2_host_recv();
  102. ERROR_RETURN();
  103. if(rcv==0xFA) {
  104. ps2_mouse_btn = ps2_host_recv();
  105. ERROR_RETURN();
  106. ps2_mouse_x = ps2_host_recv();
  107. ERROR_RETURN();
  108. ps2_mouse_y = ps2_host_recv();
  109. ERROR_RETURN();
  110. }
  111. return 0;
  112. }
  113. bool ps2_mouse_changed(void)
  114. {
  115. return (ps2_mouse_x || ps2_mouse_y || (ps2_mouse_btn & PS2_MOUSE_BTN_MASK) != ps2_mouse_btn_prev);
  116. }
  117. #define PS2_MOUSE_SCROLL_BUTTON 0x04
  118. void ps2_mouse_usb_send(void)
  119. {
  120. static bool scrolled = false;
  121. if (!ps2_mouse_enable) return;
  122. if (ps2_mouse_changed()) {
  123. int8_t x, y, v, h;
  124. x = y = v = h = 0;
  125. // convert scale of X, Y: PS/2(-256/255) -> USB(-127/127)
  126. if (ps2_mouse_btn & (1<<PS2_MOUSE_X_SIGN))
  127. x = ps2_mouse_x > 128 ? (int8_t)ps2_mouse_x : -127;
  128. else
  129. x = ps2_mouse_x < 128 ? (int8_t)ps2_mouse_x : 127;
  130. if (ps2_mouse_btn & (1<<PS2_MOUSE_Y_SIGN))
  131. y = ps2_mouse_y > 128 ? (int8_t)ps2_mouse_y : -127;
  132. else
  133. y = ps2_mouse_y < 128 ? (int8_t)ps2_mouse_y : 127;
  134. // Y is needed to reverse
  135. y = -y;
  136. if (ps2_mouse_btn & PS2_MOUSE_SCROLL_BUTTON) {
  137. // scroll
  138. if (x > 0 || x < 0) h = (x > 64 ? 64 : (x < -64 ? -64 :x));
  139. if (y > 0 || y < 0) v = (y > 64 ? 64 : (y < -64 ? -64 :y));
  140. if (h || v) {
  141. scrolled = true;
  142. usb_mouse_send(0,0, -v/16, h/16, 0);
  143. _delay_ms(100);
  144. }
  145. } else if (!scrolled && (ps2_mouse_btn_prev & PS2_MOUSE_SCROLL_BUTTON)) {
  146. usb_mouse_send(0,0,0,0, PS2_MOUSE_SCROLL_BUTTON);
  147. _delay_ms(100);
  148. usb_mouse_send(0,0,0,0, 0);
  149. } else {
  150. scrolled = false;
  151. usb_mouse_send(x, y, 0, 0, ps2_mouse_btn & PS2_MOUSE_BTN_MASK);
  152. }
  153. ps2_mouse_btn_prev = (ps2_mouse_btn & PS2_MOUSE_BTN_MASK);
  154. ps2_mouse_print();
  155. }
  156. ps2_mouse_x = 0;
  157. ps2_mouse_y = 0;
  158. ps2_mouse_btn = 0;
  159. }
  160. void ps2_mouse_print(void)
  161. {
  162. if (!debug_mouse) return;
  163. print("ps2_mouse[btn|x y]: ");
  164. phex(ps2_mouse_btn); print("|");
  165. phex(ps2_mouse_x); print(" ");
  166. phex(ps2_mouse_y); print("\n");
  167. }