usbkvm_fw2.ino 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. /*
  2. RemdesKVM USB-KVM
  3. Firmware for PCB design v4 or above
  4. Author: tobychui
  5. Upload Settings
  6. CH552G
  7. 24Mhz (Internal)
  8. */
  9. #include <Serial.h>
  10. #define MAX_CMD_LEN 32
  11. //Recv buffer from control software
  12. uint8_t cmdBuf[MAX_CMD_LEN];
  13. uint8_t c;
  14. uint8_t cmdIndex = 0;
  15. uint8_t cmdMaxLen = 0; //Expected length of the LTV command
  16. //Recv buffer from CH9329
  17. uint8_t kbCmdBuf[MAX_CMD_LEN];
  18. uint8_t kbCmdIndex = 0;
  19. uint8_t kbCmdCounter = MAX_CMD_LEN; //How many index left to terminate
  20. /* Function Prototypes */
  21. //ch9329_utils.ino
  22. void send_cmd(uint8_t cmd, uint8_t* data, uint8_t length);
  23. void flush_cmd_resp();
  24. //keyboard_emu.ino
  25. void keyboard_get_info();
  26. void keyboard_reset();
  27. void handle_keyboard_get_info_reply();
  28. int keyboard_press_key(uint8_t keycode);
  29. int keyboard_release_key(uint8_t keycode);
  30. int keyboard_press_modkey(uint8_t opcode);
  31. int keyboard_release_modkey(uint8_t opcode);
  32. //mouse_emu.ino
  33. void mouse_reset();
  34. int mouse_button_press(uint8_t opcode);
  35. int mouse_button_release(uint8_t opcode);
  36. int mouse_scroll_up(uint8_t tilt);
  37. int mouse_scroll_down(uint8_t tilt);
  38. int mouse_move_relative(uint8_t dx, uint8_t dy, uint8_t wheel);
  39. int mouse_move_absolute(uint8_t x_lsb, uint8_t x_msb, uint8_t y_lsb, uint8_t y_msb);
  40. // Set the USB descriptor exposed to the slave device
  41. void setup_keyboard_chip_cfg() {
  42. //Set manufacturer string
  43. uint8_t manufacturer_string[9] = { 0x00, 0x07, 'i', 'm', 'u', 's', 'l', 'a', 'b' };
  44. send_cmd(0x0B, manufacturer_string, 9);
  45. flush_cmd_resp();
  46. //Set product string
  47. uint8_t product_string[11] = { 0x01, 0x09, 'R', 'e', 'm', 'd', 'e', 's', 'K', 'V', 'M' };
  48. send_cmd(0x0B, product_string, 11);
  49. flush_cmd_resp();
  50. }
  51. //This function handles the incoming data from CH9329
  52. void handle_cmd_processing() {
  53. uint8_t cmd = kbCmdBuf[3];
  54. uint8_t value = kbCmdBuf[5]; //The value of 1 byte length reply
  55. switch (cmd) {
  56. case 0x81:
  57. //CMD_GET_INFO
  58. handle_keyboard_get_info_reply();
  59. break;
  60. case 0x82:
  61. //CMD_SEND_KB_GENERAL_DATA
  62. case 0x84:
  63. //CMD_SEND_MS_ABS_DATA
  64. case 0x85:
  65. //CMD_SEND_MS_REL_DATA
  66. break;
  67. }
  68. }
  69. //This function will handle the incoming cmd from RemdesKVM control software
  70. //return 0x00 if success and 0x01 if error
  71. void handle_ctrl_cmd() {
  72. uint8_t cmd = cmdBuf[1]; //Type of operation
  73. uint8_t value = cmdBuf[2]; //values for 2 bytes cmd
  74. switch (cmd) {
  75. case 0x01:
  76. //keyboard press
  77. keyboard_press_key(value);
  78. break;
  79. case 0x02:
  80. //keyboard release
  81. keyboard_release_key(value);
  82. break;
  83. case 0x03:
  84. //keyboard modifier key press
  85. keyboard_press_modkey(value);
  86. break;
  87. case 0x04:
  88. //keyboard modifier key release
  89. keyboard_release_modkey(value);
  90. break;
  91. case 0x05:
  92. //mouse button press
  93. mouse_button_press(value);
  94. break;
  95. case 0x06:
  96. //mouse button release
  97. mouse_button_release(value);
  98. break;
  99. case 0x07:
  100. //Mouse scroll up
  101. mouse_scroll_up(value);
  102. break;
  103. case 0x08:
  104. //Mouse scroll down
  105. mouse_scroll_down(value);
  106. break;
  107. case 0x09:
  108. //Mouse move absolute
  109. mouse_move_absolute(cmdBuf[2], cmdBuf[3], cmdBuf[4], cmdBuf[5]);
  110. break;
  111. case 0x0A:
  112. //Mouse move relative
  113. mouse_move_relative(cmdBuf[2], cmdBuf[3], 0);
  114. break;
  115. case 0x0B:
  116. //Get keyboard LED state
  117. keyboard_get_info();
  118. break;
  119. default:
  120. //unknown operation, do nothing
  121. break;
  122. }
  123. }
  124. void setup() {
  125. Serial0_begin(9600); // CH9329 UART default baudd
  126. delay(100);
  127. setup_keyboard_chip_cfg();
  128. }
  129. void loop() {
  130. // Read characters into buffer
  131. if (USBSerial_available()) {
  132. c = USBSerial_read();
  133. if (c == 0xFF) {
  134. //Reset keyboard state
  135. keyboard_reset();
  136. mouse_reset();
  137. //Reset incoming cmd buff
  138. memset(cmdBuf, 0, sizeof(cmdBuf));
  139. cmdIndex = 0;
  140. cmdMaxLen = MAX_CMD_LEN;
  141. //Reset ch9329 read buf
  142. memset(kbCmdBuf, 0, sizeof(kbCmdBuf));
  143. kbCmdIndex = 0;
  144. kbCmdCounter = MAX_CMD_LEN;
  145. } else {
  146. //Normal cmd
  147. if (cmdIndex == 0) {
  148. //This is the length value
  149. cmdMaxLen = c + 1;
  150. }
  151. cmdBuf[cmdIndex] = c;
  152. cmdIndex++;
  153. cmdMaxLen--;
  154. if (cmdMaxLen == 0) {
  155. //End of ctrl cmd, handle it
  156. handle_ctrl_cmd();
  157. //Clear ctrl cmd buf
  158. memset(cmdBuf, 0, sizeof(cmdBuf));
  159. cmdIndex = 0;
  160. cmdMaxLen = MAX_CMD_LEN;
  161. }
  162. }
  163. }
  164. /*
  165. while (Serial0_available()) {
  166. uint8_t b = Serial0_read();
  167. if (b == 0x57) {
  168. //Start of a new cmd. Clear the buffer
  169. memset(kbCmdBuf, 0, sizeof(kbCmdBuf));
  170. kbCmdIndex = 0;
  171. kbCmdCounter = MAX_CMD_LEN;
  172. } else if (kbCmdIndex == 4) {
  173. //Data length of this cmd
  174. kbCmdCounter = b + 0x02; //Sum byte + this Byte
  175. }
  176. //Append to buffer
  177. kbCmdBuf[kbCmdIndex] = b;
  178. kbCmdIndex++;
  179. kbCmdCounter--;
  180. if (kbCmdCounter == 0) {
  181. //End of command, verify checksum
  182. uint8_t expected_sum = kbCmdBuf[kbCmdIndex - 1];
  183. for (int i = 0; i < kbCmdIndex - 1; i++) {
  184. expected_sum -= kbCmdBuf[i];
  185. }
  186. if (expected_sum == 0) {
  187. //Correct, process the command
  188. handle_cmd_processing();
  189. } else {
  190. //Invalid checksum, skip
  191. }
  192. //Clear the buffer
  193. memset(kbCmdBuf, 0, sizeof(kbCmdBuf));
  194. kbCmdIndex = 0;
  195. kbCmdCounter = MAX_CMD_LEN;
  196. break; //One resp processed. Let write loop take over
  197. }
  198. }
  199. */
  200. }