serial_mouse_mousesystems.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. /*
  2. Copyright 2011,2013 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. */
  14. #include <stdint.h>
  15. #include <avr/io.h>
  16. #include <util/delay.h>
  17. #include "serial.h"
  18. #include "serial_mouse.h"
  19. #include "report.h"
  20. #include "host.h"
  21. #include "timer.h"
  22. #include "print.h"
  23. #include "debug.h"
  24. //#define SERIAL_MOUSE_CENTER_SCROLL
  25. static void print_usb_data(const report_mouse_t *report);
  26. void serial_mouse_task(void)
  27. {
  28. /* 5 byte ring buffer */
  29. static uint8_t buffer[5];
  30. static int buffer_cur = 0;
  31. int16_t rcv;
  32. report_mouse_t report = {0, 0, 0, 0, 0};
  33. rcv = serial_recv2();
  34. if (rcv < 0)
  35. /* no new data */
  36. return;
  37. if (debug_mouse)
  38. xprintf("serial_mouse: byte: %04X\n", rcv);
  39. /*
  40. * Synchronization: mouse(4) says that all
  41. * bytes but the first one in the packet have
  42. * bit 7 == 0, but this is untrue.
  43. * Therefore we discard all bytes up to the
  44. * first one with the characteristic bit pattern.
  45. */
  46. if (buffer_cur == 0 && (rcv >> 3) != 0x10)
  47. return;
  48. buffer[buffer_cur++] = (uint8_t)rcv;
  49. if (buffer_cur < 5)
  50. return;
  51. buffer_cur = 0;
  52. #ifdef SERIAL_MOUSE_CENTER_SCROLL
  53. if ((buffer[0] & 0x7) == 0x5 && (buffer[1] || buffer[2])) {
  54. report.h = (int8_t)buffer[1];
  55. /* USB HID uses only values from -127 to 127 */
  56. report.h = report.h < -127 ? -127 : report.h;
  57. report.v = (int8_t)buffer[2];
  58. report.v = report.v < -127 ? -127 : report.v;
  59. print_usb_data(&report);
  60. host_mouse_send(&report);
  61. if (buffer[3] || buffer[4]) {
  62. report.h = (int8_t)buffer[3];
  63. report.h = report.h < -127 ? -127 : report.h;
  64. report.v = (int8_t)buffer[4];
  65. report.v = report.v < -127 ? -127 : report.v;
  66. print_usb_data(&report);
  67. host_mouse_send(&report);
  68. }
  69. return;
  70. }
  71. #endif
  72. /*
  73. * parse 5 byte packet.
  74. * NOTE: We only get a complete packet
  75. * if the mouse moved or the button states
  76. * change.
  77. */
  78. if (!(buffer[0] & (1 << 2)))
  79. report.buttons |= MOUSE_BTN1;
  80. if (!(buffer[0] & (1 << 1)))
  81. report.buttons |= MOUSE_BTN3;
  82. if (!(buffer[0] & (1 << 0)))
  83. report.buttons |= MOUSE_BTN2;
  84. report.x = (int8_t)buffer[1];
  85. /* USB HID uses only values from -127 to 127 */
  86. report.x = report.x < -127 ? -127 : report.x;
  87. report.y = -(int8_t)buffer[2];
  88. report.y = report.y < -127 ? -127 : report.y;
  89. print_usb_data(&report);
  90. host_mouse_send(&report);
  91. if (buffer[3] || buffer[4]) {
  92. report.x = (int8_t)buffer[3];
  93. report.x = report.x < -127 ? -127 : report.x;
  94. report.y = -(int8_t)buffer[4];
  95. report.y = report.y < -127 ? -127 : report.y;
  96. print_usb_data(&report);
  97. host_mouse_send(&report);
  98. }
  99. }
  100. static void print_usb_data(const report_mouse_t *report)
  101. {
  102. if (!debug_mouse)
  103. return;
  104. xprintf("serial_mouse usb: [%02X|%d %d %d %d]\n",
  105. report->buttons, report->x, report->y,
  106. report->v, report->h);
  107. }