bluefruit.c 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. /*
  2. Bluefruit Protocol for TMK firmware
  3. Author: Benjamin Gould, 2013
  4. Based on code Copyright 2011 Jun Wako <wakojun@gmail.com>
  5. This program is free software: you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation, either version 2 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program. If not, see <http://www.gnu.org/licenses/>.
  15. */
  16. #include <stdint.h>
  17. #include "host.h"
  18. #include "report.h"
  19. #include "print.h"
  20. #include "debug.h"
  21. #include "host_driver.h"
  22. #include "serial.h"
  23. #include "bluefruit.h"
  24. #define BLUEFRUIT_TRACE_SERIAL 1
  25. static uint8_t bluefruit_keyboard_leds = 0;
  26. static void bluefruit_serial_send(uint8_t);
  27. void bluefruit_keyboard_print_report(report_keyboard_t *report) {
  28. if (!debug_keyboard) return;
  29. dprintf("keys: ");
  30. for (int i = 0; i < KEYBOARD_REPORT_KEYS; i++) {
  31. debug_hex8(report->keys[i]);
  32. dprintf(" ");
  33. }
  34. dprintf(" mods: ");
  35. debug_hex8(report->mods);
  36. dprintf(" reserved: ");
  37. debug_hex8(report->reserved);
  38. dprintf("\n");
  39. }
  40. #ifdef BLUEFRUIT_TRACE_SERIAL
  41. static void bluefruit_trace_header() {
  42. dprintf("+------------------------------------+\n");
  43. dprintf("| HID report to Bluefruit via serial |\n");
  44. dprintf("+------------------------------------+\n|");
  45. }
  46. static void bluefruit_trace_footer() { dprintf("|\n+------------------------------------+\n\n"); }
  47. #endif
  48. static void bluefruit_serial_send(uint8_t data) {
  49. #ifdef BLUEFRUIT_TRACE_SERIAL
  50. dprintf(" ");
  51. debug_hex8(data);
  52. dprintf(" ");
  53. #endif
  54. serial_send(data);
  55. }
  56. /*------------------------------------------------------------------*
  57. * Host driver
  58. *------------------------------------------------------------------*/
  59. static uint8_t keyboard_leds(void);
  60. static void send_keyboard(report_keyboard_t *report);
  61. static void send_mouse(report_mouse_t *report);
  62. static void send_system(uint16_t data);
  63. static void send_consumer(uint16_t data);
  64. void sendString(char string[], int length) {
  65. for (int i = 0; i < length; i++) {
  66. serial_send(string[i]);
  67. }
  68. }
  69. static host_driver_t driver = {keyboard_leds, send_keyboard, send_mouse, send_system, send_consumer};
  70. host_driver_t *bluefruit_driver(void) { return &driver; }
  71. static uint8_t keyboard_leds(void) { return bluefruit_keyboard_leds; }
  72. static void send_keyboard(report_keyboard_t *report) {
  73. #ifdef BLUEFRUIT_TRACE_SERIAL
  74. bluefruit_trace_header();
  75. #endif
  76. bluefruit_serial_send(0xFD);
  77. for (uint8_t i = 0; i < KEYBOARD_REPORT_SIZE; i++) {
  78. bluefruit_serial_send(report->raw[i]);
  79. }
  80. #ifdef BLUEFRUIT_TRACE_SERIAL
  81. bluefruit_trace_footer();
  82. #endif
  83. }
  84. static void send_mouse(report_mouse_t *report) {
  85. #ifdef BLUEFRUIT_TRACE_SERIAL
  86. bluefruit_trace_header();
  87. #endif
  88. bluefruit_serial_send(0xFD);
  89. bluefruit_serial_send(0x00);
  90. bluefruit_serial_send(0x03);
  91. bluefruit_serial_send(report->buttons);
  92. bluefruit_serial_send(report->x);
  93. bluefruit_serial_send(report->y);
  94. bluefruit_serial_send(report->v); // should try sending the wheel v here
  95. bluefruit_serial_send(report->h); // should try sending the wheel h here
  96. bluefruit_serial_send(0x00);
  97. #ifdef BLUEFRUIT_TRACE_SERIAL
  98. bluefruit_trace_footer();
  99. #endif
  100. }
  101. static void send_system(uint16_t data) {}
  102. /*
  103. +-----------------+-------------------+-------+
  104. | Consumer Key | Bit Map | Hex |
  105. +-----------------+-------------------+-------+
  106. | Home | 00000001 00000000 | 01 00 |
  107. | KeyboardLayout | 00000010 00000000 | 02 00 |
  108. | Search | 00000100 00000000 | 04 00 |
  109. | Snapshot | 00001000 00000000 | 08 00 |
  110. | VolumeUp | 00010000 00000000 | 10 00 |
  111. | VolumeDown | 00100000 00000000 | 20 00 |
  112. | Play/Pause | 01000000 00000000 | 40 00 |
  113. | Fast Forward | 10000000 00000000 | 80 00 |
  114. | Rewind | 00000000 00000001 | 00 01 |
  115. | Scan Next Track | 00000000 00000010 | 00 02 |
  116. | Scan Prev Track | 00000000 00000100 | 00 04 |
  117. | Random Play | 00000000 00001000 | 00 08 |
  118. | Stop | 00000000 00010000 | 00 10 |
  119. +-------------------------------------+-------+
  120. */
  121. #define CONSUMER2BLUEFRUIT(usage) (usage == AUDIO_MUTE ? 0x0000 : (usage == AUDIO_VOL_UP ? 0x1000 : (usage == AUDIO_VOL_DOWN ? 0x2000 : (usage == TRANSPORT_NEXT_TRACK ? 0x0002 : (usage == TRANSPORT_PREV_TRACK ? 0x0004 : (usage == TRANSPORT_STOP ? 0x0010 : (usage == TRANSPORT_STOP_EJECT ? 0x0000 : (usage == TRANSPORT_PLAY_PAUSE ? 0x4000 : (usage == AL_CC_CONFIG ? 0x0000 : (usage == AL_EMAIL ? 0x0000 : (usage == AL_CALCULATOR ? 0x0000 : (usage == AL_LOCAL_BROWSER ? 0x0000 : (usage == AC_SEARCH ? 0x0400 : (usage == AC_HOME ? 0x0100 : (usage == AC_BACK ? 0x0000 : (usage == AC_FORWARD ? 0x0000 : (usage == AC_STOP ? 0x0000 : (usage == AC_REFRESH ? 0x0000 : (usage == AC_BOOKMARKS ? 0x0000 : 0)))))))))))))))))))
  122. static void send_consumer(uint16_t data) {
  123. static uint16_t last_data = 0;
  124. if (data == last_data) return;
  125. last_data = data;
  126. uint16_t bitmap = CONSUMER2BLUEFRUIT(data);
  127. #ifdef BLUEFRUIT_TRACE_SERIAL
  128. dprintf("\nData: ");
  129. debug_hex16(data);
  130. dprintf("; bitmap: ");
  131. debug_hex16(bitmap);
  132. dprintf("\n");
  133. bluefruit_trace_header();
  134. #endif
  135. bluefruit_serial_send(0xFD);
  136. bluefruit_serial_send(0x00);
  137. bluefruit_serial_send(0x02);
  138. bluefruit_serial_send((bitmap >> 8) & 0xFF);
  139. bluefruit_serial_send(bitmap & 0xFF);
  140. bluefruit_serial_send(0x00);
  141. bluefruit_serial_send(0x00);
  142. bluefruit_serial_send(0x00);
  143. bluefruit_serial_send(0x00);
  144. #ifdef BLUEFRUIT_TRACE_SERIAL
  145. bluefruit_trace_footer();
  146. #endif
  147. }