|
@@ -8,81 +8,134 @@
|
|
|
CH552G
|
|
|
24Mhz (Internal)
|
|
|
*/
|
|
|
-
|
|
|
#include <Serial.h>
|
|
|
|
|
|
-// Simple mapping: A-Z → HID code 0x04 - 0x1D
|
|
|
-uint8_t asciiToHID(char c) {
|
|
|
- if (c >= 'A' && c <= 'Z') return (c - 'A') + 0x04;
|
|
|
- if (c >= 'a' && c <= 'z') return (c - 'a') + 0x04;
|
|
|
- return 0x00;
|
|
|
-}
|
|
|
+#define MAX_CMD_LEN 32
|
|
|
+
|
|
|
+uint8_t cmdBuf[MAX_CMD_LEN];
|
|
|
+uint8_t cmdIndex = 0;
|
|
|
+//Buffer and state machine for CH9329 UART COMM
|
|
|
+uint8_t kbCmdBuf[MAX_CMD_LEN];
|
|
|
+uint8_t kbCmdIndex = 0;
|
|
|
+uint8_t kbCmdCounter = MAX_CMD_LEN; //How many index left to terminate
|
|
|
+
|
|
|
+/* Function Prototypes */
|
|
|
+void keyboard_get_info();
|
|
|
+void handle_keyboard_get_info_reply();
|
|
|
|
|
|
// Checksum = sum of all bytes except last
|
|
|
uint8_t calcChecksum(uint8_t* data, uint8_t len) {
|
|
|
- uint8_t sum = 0;
|
|
|
- for (uint8_t i = 0; i < len; i++) sum += data[i];
|
|
|
- return sum;
|
|
|
+ uint8_t sum = 0;
|
|
|
+ for (uint8_t i = 0; i < len; i++) sum += data[i];
|
|
|
+ return sum;
|
|
|
}
|
|
|
|
|
|
-//Wrapper for writing an array to serial
|
|
|
-void Serial0_writeBuf(const uint8_t* data, uint8_t len) {
|
|
|
- for (uint8_t i = 0; i < len; i++) {
|
|
|
- Serial0_write(data[i]);
|
|
|
- }
|
|
|
+// flush the serial RX
|
|
|
+void flush_cmd_resp() {
|
|
|
+ delay(100);
|
|
|
+ while (Serial0_available()) {
|
|
|
+ uint8_t b = Serial0_read();
|
|
|
+ USBSerial_print("0x");
|
|
|
+ if (b < 0x10) USBSerial_print("0");
|
|
|
+ USBSerial_print(b, HEX);
|
|
|
+ USBSerial_print(" ");
|
|
|
+ }
|
|
|
+ USBSerial_println("");
|
|
|
}
|
|
|
|
|
|
-void sendKeyPress(char key) {
|
|
|
- uint8_t packet[] = {
|
|
|
- 0x57, 0xAB, 0x00, 0x02, 0x08, // Header, addr, CMD, len
|
|
|
- 0x00, 0x00, asciiToHID(key), 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
|
- 0x00 // checksum placeholder
|
|
|
- };
|
|
|
- packet[13] = calcChecksum(packet, 13);
|
|
|
- Serial0_writeBuf(packet, 14);
|
|
|
+void send_cmd(uint8_t cmd, uint8_t* data, uint8_t length) {
|
|
|
+ uint8_t sum = 0;
|
|
|
+ Serial0_write(0x57);
|
|
|
+ sum += 0x57;
|
|
|
+ Serial0_write(0xAB);
|
|
|
+ sum += 0xAB;
|
|
|
+ Serial0_write(0x00);
|
|
|
+
|
|
|
+ Serial0_write(cmd);
|
|
|
+ sum += cmd;
|
|
|
+ Serial0_write(length);
|
|
|
+ sum += length;
|
|
|
+ for (int i = 0; i < length; i++) {
|
|
|
+ Serial0_write(data[i]);
|
|
|
+ sum += data[i];
|
|
|
+ }
|
|
|
+ Serial0_write(sum);
|
|
|
}
|
|
|
|
|
|
-void sendKeyRelease() {
|
|
|
- uint8_t packet[] = {
|
|
|
- 0x57, 0xAB, 0x00, 0x02, 0x08,
|
|
|
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
|
- 0x00 // checksum placeholder
|
|
|
- };
|
|
|
- packet[13] = calcChecksum(packet, 13);
|
|
|
- Serial0_writeBuf(packet, 14);
|
|
|
+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();
|
|
|
}
|
|
|
|
|
|
-void setup() {
|
|
|
- USBSerial_println("Ready. Type a letter to send to CH9329.");
|
|
|
+//This function will trigger the target handler to handle the buffer data in kbCmdBuf
|
|
|
+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);
|
|
|
+ }
|
|
|
+}
|
|
|
|
|
|
- Serial0_begin(9600); // CH9329 UART default baud
|
|
|
+void setup() {
|
|
|
+ USBSerial_println("Ready");
|
|
|
+ Serial0_begin(9600); // CH9329 UART default baudd
|
|
|
+ delay(100);
|
|
|
+ setup_keyboard_chip_cfg();
|
|
|
}
|
|
|
|
|
|
void loop() {
|
|
|
- if (USBSerial_available()) {
|
|
|
- char c = USBSerial_read();
|
|
|
-
|
|
|
- if (asciiToHID(c)) {
|
|
|
- USBSerial_print("Sending key: ");
|
|
|
- USBSerial_println((char)c);
|
|
|
-
|
|
|
- sendKeyPress(c);
|
|
|
- delay(50);
|
|
|
- sendKeyRelease();
|
|
|
- } else {
|
|
|
- USBSerial_print("Unsupported char: ");
|
|
|
- USBSerial_println((int)c); // show ASCII code for debugging
|
|
|
- }
|
|
|
+ // Read characters into buffer
|
|
|
+ while (USBSerial_available()) {
|
|
|
+ uint8_t c = USBSerial_read();
|
|
|
+ USBSerial_println(c);
|
|
|
+ if (c == 'k') {
|
|
|
+ keyboard_get_info();
|
|
|
}
|
|
|
-
|
|
|
- // Echo UART response from CH9329 to USB
|
|
|
- while (Serial1_available()) {
|
|
|
- uint8_t b = Serial1_read();
|
|
|
-
|
|
|
- USBSerial_print("CH9329 >> 0x");
|
|
|
- if (b < 0x10) USBSerial_print("0");
|
|
|
- USBSerial_println(b, HEX);
|
|
|
+ }
|
|
|
+
|
|
|
+ // Debug: Echo CH9329 response
|
|
|
+ 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;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|