123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194 |
- /*
- RemdesKVM USB-KVM
- Firmware for PCB design v4 or above
- Author: tobychui
- Upload Settings
- CH552G
- 24Mhz (Internal)
- */
- #include <Serial.h>
- #define MAX_CMD_LEN 32
- //Recv buffer from control software
- uint8_t cmdBuf[MAX_CMD_LEN];
- uint8_t cmdIndex = 0;
- uint8_t cmdMaxLen = 0; //Expected length of the LTV command
- //Recv buffer from CH9329
- uint8_t kbCmdBuf[MAX_CMD_LEN];
- uint8_t kbCmdIndex = 0;
- uint8_t kbCmdCounter = MAX_CMD_LEN; //How many index left to terminate
- /* Function Prototypes */
- //ch9329_utils.ino
- void send_cmd(uint8_t cmd, uint8_t* data, uint8_t length);
- void flush_cmd_resp();
- //keyboard_emu.ino
- void keyboard_get_info();
- void keyboard_reset();
- void handle_keyboard_get_info_reply();
- int keyboard_press_key(uint8_t keycode);
- int keyboard_release_key(uint8_t keycode);
- int keyboard_press_modkey(uint8_t opcode);
- int keyboard_release_modkey(uint8_t opcode);
- //mouse_emu.ino
- int mouse_button_press(uint8_t opcode);
- int mouse_button_release(uint8_t opcode);
- int mouse_scroll_up(uint8_t tilt);
- int mouse_scroll_down(uint8_t tilt);
- // Set the USB descriptor exposed to the slave device
- void setup_keyboard_chip_cfg() {
- //Set manufacturer string
- uint8_t manufacturer_string[9] = { 0x00, 0x07, 'i', 'm', 'u', 's', 'l', 'a', 'b' };
- send_cmd(0x0B, manufacturer_string, 9);
- flush_cmd_resp();
- //Set product string
- uint8_t product_string[11] = { 0x01, 0x09, 'R', 'e', 'm', 'd', 'e', 's', 'K', 'V', 'M' };
- send_cmd(0x0B, product_string, 11);
- flush_cmd_resp();
- }
- //This function will trigger the target handler to handle the buffer data recv from CH9329
- void handle_cmd_processing(uint8_t cmd) {
- switch (cmd) {
- case 0x81:
- handle_keyboard_get_info_reply();
- break;
- default:
- //Unknown reply
- USBSerial_print("Unknown cmd recv: 0x");
- USBSerial_println(cmd, HEX);
- }
- }
- //This function will handle the incoming cmd from RemdesKVM control software
- //return 0x00 if success and 0x01 if error
- void handle_ctrl_cmd() {
- uint8_t cmd = cmdBuf[1]; //Type of operation
- uint8_t value = cmdBuf[2]; //values for 2 bytes cmd
- int ret = 0;
- switch (cmd) {
- case 0x01:
- //keyboard press
- ret = keyboard_press_key(value);
- break;
- case 0x02:
- //keyboard release
- ret = keyboard_release_key(value);
- break;
- case 0x03:
- //keyboard modifier key press
- ret = keyboard_press_modkey(value);
- break;
- case 0x04:
- //keyboard modifier key release
- ret = keyboard_release_modkey(value);
- break;
- case 0x05:
- //mouse button press
- ret = mouse_button_press(value);
- break;
- case 0x06:
- //mouse button release
- ret = mouse_button_release(value);
- break;
- case 0x07:
- //Mouse scroll up
- ret = mouse_scroll_up(value);
- break;
- case 0x08:
- //Mouse scroll down
- ret = mouse_scroll_down(value);
- break;
- default:
- //unknown operation, do nothing
- ret = -1;
- break;
- }
- if (ret < 0){
- //Error
- USBSerial_print(0x01);
- }else{
- USBSerial_print(0x00);
- }
- }
- void setup() {
- USBSerial_println("Ready");
- Serial0_begin(9600); // CH9329 UART default baudd
- delay(100);
- setup_keyboard_chip_cfg();
- }
- void loop() {
- // Read characters into buffer
- while (USBSerial_available()) {
- uint8_t c = USBSerial_read();
- if (c == 0xFF) {
- //Reset
- keyboard_reset();
- memset(cmdBuf, 0, sizeof(cmdBuf));
- cmdIndex = 0;
- cmdMaxLen = 0;
- continue;
- }
- if (cmdIndex == 0) {
- //This is the length value
- cmdMaxLen = c + 1;
- }
- cmdBuf[cmdIndex] = c;
- cmdIndex++;
- cmdMaxLen--;
- if (cmdMaxLen == 0) {
- //End of ctrl cmd, handle it
- handle_ctrl_cmd();
- //Clear ctrl cmd buf
- memset(cmdBuf, 0, sizeof(cmdBuf));
- cmdIndex = 0;
- cmdMaxLen = 0;
- }
- }
- while (Serial0_available()) {
- uint8_t b = Serial0_read();
- if (b == 0x57) {
- //Start of a new cmd. Clear the buffer
- memset(kbCmdBuf, 0, sizeof(kbCmdBuf));
- kbCmdIndex = 0;
- kbCmdCounter = MAX_CMD_LEN;
- } else if (kbCmdIndex == 4) {
- //Data length of this cmd
- kbCmdCounter = b + 0x02; //Sum byte + this Byte
- }
- //Append to buffer
- kbCmdBuf[kbCmdIndex] = b;
- kbCmdIndex++;
- kbCmdCounter--;
- if (kbCmdCounter == 0) {
- //End of command, verify checksum
- uint8_t expected_sum = kbCmdBuf[kbCmdIndex - 1];
- for (int i = 0; i < kbCmdIndex - 1; i++) {
- expected_sum -= kbCmdBuf[i];
- }
- if (expected_sum == 0) {
- //Correct, process the command
- handle_cmd_processing(kbCmdBuf[3]);
- } else {
- USBSerial_println("Invalid checksum or cmd too long, skipping");
- }
- //Clear the buffer
- memset(kbCmdBuf, 0, sizeof(kbCmdBuf));
- kbCmdIndex = 0;
- kbCmdCounter = MAX_CMD_LEN;
- }
- }
- }
|