diff --git a/right/src/deserialize.c b/right/src/deserialize.c new file mode 100644 index 0000000..cc2f258 --- /dev/null +++ b/right/src/deserialize.c @@ -0,0 +1,241 @@ +#include "deserialize.h" +#include "action.h" +#define longCompactLengthPrefix 0xff + +#define HAS_SCANCODE (1 << 0) +#define HAS_MODS (1 << 1) +#define HAS_LONGPRESS (1 << 2) + +typedef struct { + const uint8_t *buffer; + uint16_t offset; +} serialized_buffer_t; + +enum { + NoneAction = 0, + KeyStrokeAction = 1, + LastKeyStrokeAction = 7, + SwitchLayerAction, + SwitchKeymapAction, + MouseAction, + PlayMacroAction +}; + +// ---------------- + +static uint8_t readUInt8(serialized_buffer_t *buffer) { + return buffer->buffer[buffer->offset++]; +} + +static bool readBool(serialized_buffer_t *buffer) { + return buffer->buffer[buffer->offset++] == 1; +} + +static uint16_t readCompactLength(serialized_buffer_t *buffer) { + uint16_t length = readUInt8(buffer); + if (length == longCompactLengthPrefix) { + length += readUInt8(buffer) << 8; + } + return length; +} + +static const char *readString(serialized_buffer_t *buffer, uint16_t *len) { + const char *str = (const char *)&(buffer->buffer[buffer->offset]); + + *len = readCompactLength(buffer); + buffer->offset += *len; + + return str; +} + +// ---------------- + +static uint8_t findIndex(uint8_t moduleID, uint8_t idx) { + switch (moduleID) { + case 0: + switch (idx) { + case 0 ... 6: + return idx; + case 7: + return 14; + case 8 ... 14: + return idx - 1; + case 15: + return 21; + case 16 ... 21: + return idx - 1; + case 22 ... 27: + return idx; + case 28: + return idx + 1; + case 29 ... 32: + return idx + 2; + case 33: + return 30; + } + break; + + case 1: + switch (idx) { + case 0 ... 11: + return idx; + case 12 ... 17: + return idx + 1; + case 18 ... 19: + return idx + 2; + case 20 ... 28: + return idx + 3; + case 29: + return 33; + case 30: + return 32; + } + break; + } + return idx; +} + +static void processNoneAction(key_action_t *action, serialized_buffer_t *buffer) { + action->type = KEY_ACTION_NONE; +} + +static void processKeyStrokeAction(key_action_t *action, uint8_t actionType, serialized_buffer_t *buffer) { + uint8_t flags = actionType - 1; + + action->type = KEY_ACTION_KEYSTROKE; + + if (flags & HAS_SCANCODE) { + action->keystroke.key = readUInt8(buffer); + } + if (flags & HAS_MODS) { + action->keystroke.mods = readUInt8(buffer); + } + if (flags & HAS_LONGPRESS) { + action->keystroke.longPress = readUInt8(buffer); + } +} + +static void processSwitchLayerAction(key_action_t *action, serialized_buffer_t *buffer) { + uint8_t layer = readUInt8(buffer) + 1; + bool isToggle = readBool(buffer); + + action->type = KEY_ACTION_SWITCH_LAYER; + action->switchLayer.layer = layer; + action->switchLayer.isToggle = isToggle; +} + +static void processSwitchKeymapAction(key_action_t *action, serialized_buffer_t *buffer) { + uint16_t len; + const char *keymap = readString(buffer, &len); + + action->type = KEY_ACTION_SWITCH_KEYMAP; + + // TODO: Implement this +} + +static void processMouseAction(key_action_t *action, serialized_buffer_t *buffer) { + uint8_t mouseAction = readUInt8(buffer); + + action->type = KEY_ACTION_MOUSE; + switch (mouseAction) { + case 0: // leftClick + action->mouse.buttonActions |= MOUSE_BUTTON_LEFT; + break; + case 1: // middleClick + action->mouse.buttonActions |= MOUSE_BUTTON_MIDDLE; + break; + case 2: // rightClick + action->mouse.buttonActions |= MOUSE_BUTTON_RIGHT; + break; + case 3: // moveUp + action->mouse.moveActions |= MOUSE_MOVE_UP; + break; + case 4: // moveDown + action->mouse.moveActions |= MOUSE_MOVE_DOWN; + break; + case 5: // moveLeft + action->mouse.moveActions |= MOUSE_MOVE_LEFT; + break; + case 6: // moveRight + action->mouse.moveActions |= MOUSE_MOVE_RIGHT; + break; + case 7: // scrollUp + action->mouse.scrollActions |= MOUSE_SCROLL_UP; + break; + case 8: // scrollDown + action->mouse.scrollActions |= MOUSE_SCROLL_DOWN; + break; + case 9: // scrollLeft + action->mouse.scrollActions |= MOUSE_SCROLL_LEFT; + break; + case 10: // scrollRight + action->mouse.scrollActions |= MOUSE_SCROLL_RIGHT; + break; + case 11: // accelerate + action->mouse.moveActions |= MOUSE_ACCELERATE; + break; + case 12: // decelerate + action->mouse.moveActions |= MOUSE_DECELERATE; + break; + } +} + +static void processKeyAction(key_action_t *action, serialized_buffer_t *buffer) { + uint8_t actionType = readUInt8(buffer); + + switch (actionType) { + case NoneAction: + return processNoneAction(action, buffer); + case KeyStrokeAction ... LastKeyStrokeAction: + return processKeyStrokeAction(action, actionType, buffer); + case SwitchLayerAction: + return processSwitchLayerAction(action, buffer); + case SwitchKeymapAction: + return processSwitchKeymapAction(action, buffer); + case MouseAction: + return processMouseAction(action, buffer); + default: + // TODO: Handle the case where the actionType is unknown + break; + } +} + +static void processKeyActions(uint8_t targetLayer, serialized_buffer_t *buffer, uint8_t moduleID, uint8_t pointerRole) { + uint8_t actionCount = readCompactLength(buffer); + + for (uint8_t actionIdx = 0; actionIdx < actionCount; actionIdx++) { + uint8_t pos = findIndex(moduleID, actionIdx); + key_action_t *action = &(CurrentKeymap[targetLayer][moduleID][pos]); + + processKeyAction(action, buffer); + } +} + +static void processModule(serialized_buffer_t *buffer, uint8_t targetLayer) { + uint8_t moduleID, pointerRole; + + moduleID = readUInt8(buffer); + pointerRole = readUInt8(buffer); + + processKeyActions(targetLayer, buffer, moduleID, pointerRole); +} + +static void clearModule(uint8_t targetLayer, uint8_t moduleID) { + memset(&CurrentKeymap[targetLayer][moduleID], 0, MAX_KEY_COUNT_PER_MODULE * sizeof(key_action_t)); +} + +// ---------- + +void deserialize_Layer (const uint8_t *data, uint8_t targetLayer) { + serialized_buffer_t buffer; + + buffer.buffer = data; + buffer.offset = 0; + + uint8_t moduleCount = readCompactLength(&buffer); + + for (uint8_t modIdx = 0; modIdx < moduleCount; modIdx++) { + clearModule(targetLayer, modIdx); + processModule(&buffer, targetLayer); + } +} diff --git a/right/src/deserialize.h b/right/src/deserialize.h new file mode 100644 index 0000000..4989836 --- /dev/null +++ b/right/src/deserialize.h @@ -0,0 +1,8 @@ +#ifndef __DESERIALIZE_H__ +#define __DESERIALIZE_H__ 1 + +#include + +void deserialize_Layer(const uint8_t *data, uint8_t targetLayer); + +#endif diff --git a/right/src/main.c b/right/src/main.c index e45e9af..7c3f11d 100644 --- a/right/src/main.c +++ b/right/src/main.c @@ -3,6 +3,7 @@ #include "init_peripherials.h" #include "usb_composite_device.h" #include "led_driver.h" +#include "deserialize.h" key_matrix_t KeyMatrix = { .colNum = KEYBOARD_MATRIX_COLS_NUM, @@ -47,6 +48,16 @@ key_matrix_t KeyMatrix = { uint8_t PreviousKeyStates[SLOT_COUNT][MAX_KEY_COUNT_PER_MODULE]; uint8_t CurrentKeyStates[SLOT_COUNT][MAX_KEY_COUNT_PER_MODULE]; +static const uint8_t testData[] = + {0x03, 0x00, 0x01, 0x22, 0x02, 0x24, 0x02, 0x25, 0x02, 0x26, 0x02, 0x27, 0x02, 0x2d, 0x02, 0x2e, 0x02, 0x2a, 0x02, + 0x1c, 0x02, 0x18, 0x02, 0x0c, 0x02, 0x12, 0x04, 0x13, 0x22, 0x02, 0x2f, 0x02, 0x30, 0x02, 0x31, 0x02, 0x0b, 0x02, + 0x0d, 0x02, 0x0e, 0x02, 0x0f, 0x02, 0x33, 0x02, 0x34, 0x02, 0x28, 0x02, 0x11, 0x02, 0x10, 0x02, 0x36, 0x02, 0x37, + 0x02, 0x38, 0x0a, 0x03, 0x02, 0x2c, 0x02, 0x1c, 0x02, 0x1b, 0x02, 0x1a, 0x02, 0x14, 0x02, 0x1d, 0x01, 0x01, 0x1f, + 0x02, 0x35, 0x02, 0x1e, 0x02, 0x1f, 0x02, 0x20, 0x02, 0x21, 0x02, 0x22, 0x02, 0x23, 0x06, 0x29, 0x09, 0x02, 0x14, + 0x02, 0x1a, 0x02, 0x08, 0x02, 0x15, 0x02, 0x17, 0x02, 0x2b, 0x02, 0x04, 0x02, 0x16, 0x02, 0x07, 0x02, 0x09, 0x02, + 0x0a, 0x02, 0x2d, 0x02, 0x1d, 0x02, 0x1b, 0x02, 0x06, 0x02, 0x19, 0x02, 0x05, 0x02, 0x04, 0x02, 0x05, 0x02, 0x06, + 0x02, 0x07, 0x02, 0x08, 0x02, 0x09, 0x02, 0x02, 0x00 }; + void main() { InitPeripherials(); InitClock(); @@ -55,6 +66,8 @@ void main() { UsbKeyboadTask(); InitUsb(); + // deserialize_Layer(testData, 0); + while (1) { UsbKeyboadTask(); asm("wfi");