|
@@ -3,8 +3,8 @@
|
|
|
|
|
|
This file handle keyboard emulation and key writes
|
|
|
*/
|
|
|
-#define MAX_KEYBOARD_HID_KEYCODE_NO 6
|
|
|
-#define ENABLE_KEYBOARD_DEBUG_PRINTOUT
|
|
|
+#define KEYBOARD_HID_KEYCODE_LENGTH 6
|
|
|
+//#define ENABLE_KEYBOARD_DEBUG_PRINTOUT
|
|
|
|
|
|
/* Modifier keycode for CH9329 */
|
|
|
#define MOD_LCTRL 0x01
|
|
@@ -17,7 +17,9 @@
|
|
|
#define MOD_RGUI 0x80
|
|
|
|
|
|
/* Runtime variables */
|
|
|
-uint8_t keyboard_state[6] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
|
|
+uint8_t keyboard_state[KEYBOARD_HID_KEYCODE_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
|
|
+uint8_t keyboard_pressing_key_count = 0; //No. of key currently pressing, max is 6
|
|
|
+uint8_t keyboard_modifiers = 0x00; //Current modifier key state
|
|
|
|
|
|
//byte 0: Computer connected
|
|
|
//byte 1:
|
|
@@ -58,25 +60,20 @@ void handle_keyboard_get_info_reply() {
|
|
|
#endif
|
|
|
}
|
|
|
|
|
|
-/* helper to write an array of uint8_t to CH9329 */
|
|
|
-void Serial0_writeBuf(const uint8_t* data, uint8_t len) {
|
|
|
- for (uint8_t i = 0; i < len; i++) {
|
|
|
- Serial0_write(data[i]);
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-/* Send key combinations, keycode must be an array with length 6 */
|
|
|
-int keyboard_send_key_combinations(uint8_t modifiers, uint8_t* keycode, uint8_t length) {
|
|
|
- if (length != MAX_KEYBOARD_HID_KEYCODE_NO) {
|
|
|
- //This function must take in an array of 6 keycodes
|
|
|
- return -1;
|
|
|
- }
|
|
|
+/* Send key combinations to CH9329*/
|
|
|
+int keyboard_send_key_combinations() {
|
|
|
uint8_t packet[14] = {
|
|
|
0x57, 0xAB, 0x00, 0x02, 0x08,
|
|
|
- modifiers, 0x00,
|
|
|
- keycode[0], keycode[1], keycode[2], keycode[3], keycode[4], keycode[5],
|
|
|
+ keyboard_modifiers, 0x00,
|
|
|
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
|
0x00
|
|
|
};
|
|
|
+
|
|
|
+ //Populate the HID keycodes
|
|
|
+ for (uint8_t i = 0; i < KEYBOARD_HID_KEYCODE_LENGTH; i++) {
|
|
|
+ packet[7 + i] = keyboard_state[i];
|
|
|
+ }
|
|
|
+
|
|
|
packet[13] = calcChecksum(packet, 13);
|
|
|
Serial0_writeBuf(packet, 14);
|
|
|
return 0;
|
|
@@ -224,4 +221,131 @@ uint8_t javascript_keycode_to_hid_opcode(uint8_t keycode) {
|
|
|
default:
|
|
|
return 0x00; // Unknown / unsupported
|
|
|
}
|
|
|
+}
|
|
|
+
|
|
|
+//Send a keyboard press by JavaScript keycode
|
|
|
+int keyboard_press_key(uint8_t keycode) {
|
|
|
+ //Convert javascript keycode to HID
|
|
|
+ keycode = javascript_keycode_to_hid_opcode(keycode);
|
|
|
+ if (keycode == 0x00) {
|
|
|
+ //Not supported
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Already pressed? Skip
|
|
|
+ for (int i = 0; i < 6; i++) {
|
|
|
+ if (keyboard_state[i] == keycode) {
|
|
|
+ return 0; // Already held
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //Get the empty slot in the current HID list
|
|
|
+ for (int i = 0; i < 6; i++) {
|
|
|
+ if (keyboard_state[i] == 0x00) {
|
|
|
+ keyboard_state[i] = keycode;
|
|
|
+ keyboard_pressing_key_count++;
|
|
|
+ keyboard_send_key_combinations();
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //No space left
|
|
|
+ return -1;
|
|
|
+}
|
|
|
+
|
|
|
+//Send a keyboard release by JavaScript keycode
|
|
|
+int keyboard_release_key(uint8_t keycode) {
|
|
|
+ //Convert javascript keycode to HID
|
|
|
+ keycode = javascript_keycode_to_hid_opcode(keycode);
|
|
|
+ if (keycode == 0x00) {
|
|
|
+ //Not supported
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+
|
|
|
+ //Get the position where the key is pressed
|
|
|
+ for (int i = 0; i < 6; i++) {
|
|
|
+ if (keyboard_state[i] == keycode) {
|
|
|
+ keyboard_state[i] = 0x00;
|
|
|
+ if (keyboard_pressing_key_count > 0) {
|
|
|
+ keyboard_pressing_key_count--;
|
|
|
+ }
|
|
|
+ keyboard_send_key_combinations();
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //That key is not pressed
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+uint8_t keyboard_get_modifier_bit_from_opcode(uint8_t opcode) {
|
|
|
+ switch (opcode) {
|
|
|
+ case 0x01:
|
|
|
+ return MOD_LCTRL;
|
|
|
+ case 0x02:
|
|
|
+ return MOD_LSHIFT;
|
|
|
+ case 0x03:
|
|
|
+ return MOD_LALT;
|
|
|
+ case 0x04:
|
|
|
+ return MOD_LGUI;
|
|
|
+ case 0x05:
|
|
|
+ return MOD_RCTRL;
|
|
|
+ case 0x06:
|
|
|
+ return MOD_RSHIFT;
|
|
|
+ case 0x07:
|
|
|
+ return MOD_RALT;
|
|
|
+ case 0x08:
|
|
|
+ return MOD_RGUI;
|
|
|
+ case 0x09:
|
|
|
+ //Ctrl + Alt + Del
|
|
|
+ return MOD_LCTRL | MOD_LALT;
|
|
|
+ case 0x0A:
|
|
|
+ //Win + Shift + S
|
|
|
+ return MOD_LSHIFT | MOD_LGUI;
|
|
|
+ break;
|
|
|
+ //To be added
|
|
|
+ default:
|
|
|
+ return 0x00;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+//Set the modifier key bit
|
|
|
+int keyboard_press_modkey(uint8_t opcode) {
|
|
|
+ if (opcode == 0x00){
|
|
|
+ //Reset the modkeys
|
|
|
+ keyboard_modifiers = 0;
|
|
|
+ keyboard_send_key_combinations();
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ uint8_t mask = keyboard_get_modifier_bit_from_opcode(opcode);
|
|
|
+ if (mask == 0x00){
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ keyboard_modifiers |= mask;
|
|
|
+ keyboard_send_key_combinations();
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+//Unset modifier key bit
|
|
|
+int keyboard_release_modkey(uint8_t opcode) {
|
|
|
+ if (opcode == 0x00){
|
|
|
+ //Reset the modkeys
|
|
|
+ keyboard_modifiers = 0;
|
|
|
+ keyboard_send_key_combinations();
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ uint8_t mask = keyboard_get_modifier_bit_from_opcode(opcode);
|
|
|
+ if (mask == 0x00){
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ keyboard_modifiers &= ~mask;
|
|
|
+ keyboard_send_key_combinations();
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+//Reset all keypress on keyboard
|
|
|
+void keyboard_reset(){
|
|
|
+ memset(keyboard_state, 0x00, sizeof(keyboard_state));
|
|
|
+ keyboard_modifiers = 0x00;
|
|
|
+ keyboard_send_key_combinations();
|
|
|
}
|