diff --git a/left/src/i2c_watchdog.c b/left/src/i2c_watchdog.c index ae7f20e..40718a6 100644 --- a/left/src/i2c_watchdog.c +++ b/left/src/i2c_watchdog.c @@ -21,7 +21,7 @@ void RunWatchdog(void) cntr++; if (cntr==100) { /* we get called from KEY_SCANNER_HANDLER() which runs at 1ms, thus scaling down by 100 here to get 100 ms period */ cntr=0; - TEST_LED_TOGGLE(); + TestLed_Toggle(); I2cWatchdog_WatchCounter++; if (I2cWatchdog_WatchCounter>10) { /* do not check within the first 1000 ms, as I2C might not be running yet */ diff --git a/left/src/init_peripherals.c b/left/src/init_peripherals.c index ed352b2..e39916e 100644 --- a/left/src/init_peripherals.c +++ b/left/src/init_peripherals.c @@ -84,7 +84,7 @@ void InitPeripherals(void) { initInterruptPriorities(); InitLedDriver(); - InitTestLed(); + TestLed_Init(); LedPwm_Init(); DebugOverSpi_Init(); initI2c(); diff --git a/left/src/slave_protocol_handler.c b/left/src/slave_protocol_handler.c index c52edc0..4ceb40f 100644 --- a/left/src/slave_protocol_handler.c +++ b/left/src/slave_protocol_handler.c @@ -42,7 +42,7 @@ void SlaveRxHandler(void) case SlaveCommand_SetTestLed: TxMessage.length = 0; bool isLedOn = RxMessage.data[1]; - TEST_LED_SET(isLedOn); + TestLed_Set(isLedOn); break; case SlaveCommand_SetLedPwmBrightness: TxMessage.length = 0; diff --git a/left/src/test_led.c b/left/src/test_led.c index acb24cd..0f084d3 100644 --- a/left/src/test_led.c +++ b/left/src/test_led.c @@ -1,10 +1,10 @@ #include "test_led.h" #include "fsl_port.h" -extern void InitTestLed(void) +extern void TestLed_Init(void) { CLOCK_EnableClock(TEST_LED_CLOCK); PORT_SetPinMux(TEST_LED_PORT, TEST_LED_PIN, kPORT_MuxAsGpio); GPIO_PinInit(TEST_LED_GPIO, TEST_LED_PIN, &(gpio_pin_config_t){kGPIO_DigitalOutput, 0}); - TEST_LED_ON(); + TestLed_On(); } diff --git a/left/src/test_led.h b/left/src/test_led.h index 2c3416f..7f4df88 100644 --- a/left/src/test_led.h +++ b/left/src/test_led.h @@ -15,13 +15,28 @@ #define TEST_LED_CLOCK kCLOCK_PortB #define TEST_LED_PIN 13 - #define TEST_LED_ON() GPIO_SetPinsOutput(TEST_LED_GPIO, 1U << TEST_LED_PIN) - #define TEST_LED_OFF() GPIO_ClearPinsOutput(TEST_LED_GPIO, 1U << TEST_LED_PIN) - #define TEST_LED_SET(state) GPIO_WritePinOutput(TEST_LED_GPIO, TEST_LED_PIN, (state)) - #define TEST_LED_TOGGLE() GPIO_TogglePinsOutput(TEST_LED_GPIO, 1U << TEST_LED_PIN) + static inline void TestLed_On(void) + { + GPIO_SetPinsOutput(TEST_LED_GPIO, 1U << TEST_LED_PIN); + } + + static inline void TestLed_Off(void) + { + GPIO_ClearPinsOutput(TEST_LED_GPIO, 1U << TEST_LED_PIN); + } + + static inline void TestLed_Set(bool state) + { + GPIO_WritePinOutput(TEST_LED_GPIO, TEST_LED_PIN, state); + } + + static inline void TestLed_Toggle(void) + { + GPIO_TogglePinsOutput(TEST_LED_GPIO, 1U << TEST_LED_PIN); + } // Functions: - void InitTestLed(void); + void TestLed_Init(void); #endif diff --git a/right/src/config_parser/parse_macro.c b/right/src/config_parser/parse_macro.c index 416d76a..23edb45 100644 --- a/right/src/config_parser/parse_macro.c +++ b/right/src/config_parser/parse_macro.c @@ -60,7 +60,7 @@ parser_error_t parseScrollMouseMacroAction(config_buffer_t *buffer, macro_action parser_error_t parseDelayMacroAction(config_buffer_t *buffer, macro_action_t *macroAction) { - int16_t delay = ReadInt16(buffer); + uint16_t delay = ReadUInt16(buffer); macroAction->type = MacroActionType_Delay; macroAction->delay.delay = delay; diff --git a/right/src/init_peripherals.c b/right/src/init_peripherals.c index 2103a3b..f820fdc 100644 --- a/right/src/init_peripherals.c +++ b/right/src/init_peripherals.c @@ -157,7 +157,7 @@ void InitPeripherals(void) InitMergeSensor(); ADC_Init(); initI2c(); - InitTestLed(); + TestLed_Init(); LedPwm_Init(); InitI2cWatchdog(); InitKeyDebouncer(); diff --git a/right/src/key_debouncer.c b/right/src/key_debouncer.c index fceebcb..0ec19e7 100644 --- a/right/src/key_debouncer.c +++ b/right/src/key_debouncer.c @@ -7,7 +7,7 @@ void PIT_KEY_DEBOUNCER_HANDLER(void) { - TEST_LED_TOGGLE(); + TestLed_Toggle(); for (uint8_t slotId=0; slotId': - return 0; + return HID_KEYBOARD_SC_DOT_AND_GREATER_THAN_SIGN; case ',': case '<': - return 0; + return HID_KEYBOARD_SC_KEYPAD_LESS_THAN_SIGN; case '/': case '\?': - return 0; + return HID_KEYBOARD_SC_SLASH_AND_QUESTION_MARK; case '-': case '_': - return 0; + return HID_KEYBOARD_SC_MINUS_AND_UNDERSCORE; + case '\n': + return HID_KEYBOARD_SC_ENTER; + case ' ': + return HID_KEYBOARD_SC_SPACE; } return 0; } +bool characterToShift(char character) +{ + switch (character) { + case 'A' ... 'Z': + case ')': + case '!': + case '@': + case '#': + case '$': + case '%': + case '^': + case '&': + case '*': + case '(': + case '~': + case '{': + case '}': + case ':': + case '\"': + case '+': + case '|': + case '>': + case '<': + case '\?': + case '_': + return true; + } + return false; +} + void addBasicScancode(uint8_t scancode) { if (!scancode) { @@ -184,89 +218,183 @@ void deleteSystemScancode(uint8_t scancode) } } -bool processKeyMacroAction(void) +void addScancode(uint16_t scancode, macro_sub_action_t type) +{ + switch (type) { + case KeystrokeType_Basic: + addBasicScancode(scancode); + break; + case KeystrokeType_Media: + addMediaScancode(scancode); + break; + case KeystrokeType_System: + addSystemScancode(scancode); + break; + } +} + +void deleteScancode(uint16_t scancode, macro_sub_action_t type) +{ + switch (type) { + case KeystrokeType_Basic: + deleteBasicScancode(scancode); + break; + case KeystrokeType_Media: + deleteMediaScancode(scancode); + break; + case KeystrokeType_System: + deleteSystemScancode(scancode); + break; + } +} + +bool processKeyAction(void) { static bool pressStarted; switch (currentMacroAction.key.action) { - case MacroSubAction_Press: + case MacroSubAction_Tap: if (!pressStarted) { pressStarted = true; addModifiers(currentMacroAction.key.modifierMask); - switch (currentMacroAction.key.type) { - case KeystrokeType_Basic: - addBasicScancode(currentMacroAction.key.scancode); - break; - case KeystrokeType_Media: - // addMediaScancode(currentMacroAction.key.scancode); - break; - case KeystrokeType_System: - addSystemScancode(currentMacroAction.key.scancode); - break; - } + addScancode(currentMacroAction.key.scancode, currentMacroAction.key.type); return true; } pressStarted = false; deleteModifiers(currentMacroAction.key.modifierMask); - switch (currentMacroAction.key.type) { - case KeystrokeType_Basic: - deleteBasicScancode(currentMacroAction.key.scancode); - break; - case KeystrokeType_Media: - // deleteMediaScancode(currentMacroAction.key.scancode); - break; - case KeystrokeType_System: - deleteSystemScancode(currentMacroAction.key.scancode); - break; - } + deleteScancode(currentMacroAction.key.scancode, currentMacroAction.key.type); break; case MacroSubAction_Release: deleteModifiers(currentMacroAction.key.modifierMask); - switch (currentMacroAction.key.type) { - case KeystrokeType_Basic: - deleteBasicScancode(currentMacroAction.key.scancode); - break; - case KeystrokeType_Media: - // deleteMediaScancode(currentMacroAction.key.scancode); - break; - case KeystrokeType_System: - deleteSystemScancode(currentMacroAction.key.scancode); - break; - } + deleteScancode(currentMacroAction.key.scancode, currentMacroAction.key.type); break; - case MacroSubAction_Hold: + case MacroSubAction_Press: addModifiers(currentMacroAction.key.modifierMask); - switch (currentMacroAction.key.type) { - case KeystrokeType_Basic: - addBasicScancode(currentMacroAction.key.scancode); - break; - case KeystrokeType_Media: - // addMediaScancode(currentMacroAction.key.scancode); - break; - case KeystrokeType_System: - addSystemScancode(currentMacroAction.key.scancode); - break; - } + addScancode(currentMacroAction.key.scancode, currentMacroAction.key.type); break; } return false; } +bool processDelayAction(void) +{ + static bool inDelay; + static uint32_t delayStart; + + if (inDelay) { + if (Timer_GetElapsedTime(&delayStart) >= currentMacroAction.delay.delay) { + inDelay = false; + } + } else { + Timer_SetCurrentTime(&delayStart); + inDelay = true; + } + return inDelay; +} + +bool processMouseButtonAction(void) +{ + static bool pressStarted; + + switch (currentMacroAction.key.action) { + case MacroSubAction_Tap: + if (!pressStarted) { + pressStarted = true; + MacroMouseReport.buttons |= currentMacroAction.mouseButton.mouseButtonsMask; + return true; + } + pressStarted = false; + MacroMouseReport.buttons &= ~currentMacroAction.mouseButton.mouseButtonsMask; + break; + case MacroSubAction_Release: + MacroMouseReport.buttons &= ~currentMacroAction.mouseButton.mouseButtonsMask; + break; + case MacroSubAction_Press: + MacroMouseReport.buttons |= currentMacroAction.mouseButton.mouseButtonsMask; + break; + } + return false; +} + +bool processMoveMouseAction(void) +{ + static bool inMotion; + + if (inMotion) { + MacroMouseReport.x = 0; + MacroMouseReport.y = 0; + inMotion = false; + } else { + MacroMouseReport.x = currentMacroAction.moveMouse.x; + MacroMouseReport.y = currentMacroAction.moveMouse.y; + inMotion = true; + } + return inMotion; +} + +bool processScrollMouseAction(void) +{ + static bool inMotion; + + if (inMotion) { + MacroMouseReport.wheelX = 0; + MacroMouseReport.wheelY = 0; + inMotion = false; + } else { + MacroMouseReport.wheelX = currentMacroAction.scrollMouse.x; + MacroMouseReport.wheelY = currentMacroAction.scrollMouse.y; + inMotion = true; + } + return inMotion; +} + +bool processTextAction(void) +{ + static uint16_t textIndex; + static uint8_t reportIndex = USB_BASIC_KEYBOARD_MAX_KEYS; + char character; + uint8_t scancode; + + if (textIndex == currentMacroAction.text.textLen) { + textIndex = 0; + reportIndex = USB_BASIC_KEYBOARD_MAX_KEYS; + memset(&MacroBasicKeyboardReport, 0, sizeof MacroBasicKeyboardReport); + return false; + } + if (reportIndex == USB_BASIC_KEYBOARD_MAX_KEYS) { + reportIndex = 0; + memset(&MacroBasicKeyboardReport, 0, sizeof MacroBasicKeyboardReport); + return true; + } + character = currentMacroAction.text.text[textIndex]; + scancode = characterToScancode(character); + for (uint8_t i = 0; i < reportIndex; i++) { + if (MacroBasicKeyboardReport.scancodes[i] == scancode) { + reportIndex = USB_BASIC_KEYBOARD_MAX_KEYS; + return true; + } + } + MacroBasicKeyboardReport.scancodes[reportIndex++] = scancode; + MacroBasicKeyboardReport.modifiers = characterToShift(character) ? HID_KEYBOARD_MODIFIER_LEFTSHIFT : 0; + ++textIndex; + return true; +} + bool processCurrentMacroAction(void) { switch (currentMacroAction.type) { case MacroActionType_Delay: - return false; + return processDelayAction(); case MacroActionType_Key: - return processKeyMacroAction(); + return processKeyAction(); case MacroActionType_MouseButton: - return false; + return processMouseButtonAction(); case MacroActionType_MoveMouse: - return false; + return processMoveMouseAction(); case MacroActionType_ScrollMouse: - return false; + return processScrollMouseAction(); case MacroActionType_Text: - return false; + return processTextAction(); } return false; } diff --git a/right/src/macros.h b/right/src/macros.h index 6eecc1a..a4f1c52 100644 --- a/right/src/macros.h +++ b/right/src/macros.h @@ -20,8 +20,8 @@ } macro_reference_t; typedef enum { + MacroSubAction_Tap, MacroSubAction_Press, - MacroSubAction_Hold, MacroSubAction_Release, } macro_sub_action_t; @@ -55,7 +55,7 @@ int16_t y; } ATTR_PACKED scrollMouse; struct { - int16_t delay; + uint16_t delay; } ATTR_PACKED delay; struct { const char *text; diff --git a/right/src/peripherals/test_led.c b/right/src/peripherals/test_led.c index 50197e1..1d46a3e 100644 --- a/right/src/peripherals/test_led.c +++ b/right/src/peripherals/test_led.c @@ -1,10 +1,31 @@ #include "test_led.h" #include "fsl_port.h" +#include "timer.h" -void InitTestLed(void) +void TestLed_Init(void) { CLOCK_EnableClock(TEST_LED_CLOCK); PORT_SetPinMux(TEST_LED_GPIO_PORT, TEST_LED_GPIO_PIN, kPORT_MuxAsGpio); GPIO_PinInit(TEST_LED_GPIO, TEST_LED_GPIO_PIN, &(gpio_pin_config_t){kGPIO_DigitalOutput, 1}); - TEST_LED_ON(); + TestLed_On(); +} + +void TestLed_Blink(uint8_t times) +{ + TestLed_Off(); + Timer_Delay(500); + if (!times) { + TestLed_On(); + Timer_Delay(500); + TestLed_Off(); + Timer_Delay(500); + return; + } + while (times--) { + TestLed_On(); + Timer_Delay(100); + TestLed_Off(); + Timer_Delay(100); + } + Timer_Delay(400); } diff --git a/right/src/peripherals/test_led.h b/right/src/peripherals/test_led.h index cd90365..6e4efc1 100644 --- a/right/src/peripherals/test_led.h +++ b/right/src/peripherals/test_led.h @@ -15,13 +15,29 @@ #define TEST_LED_CLOCK kCLOCK_PortD #define TEST_LED_GPIO_PIN 7U - #define TEST_LED_ON() GPIO_SetPinsOutput(TEST_LED_GPIO, 1U << TEST_LED_GPIO_PIN) - #define TEST_LED_OFF() GPIO_ClearPinsOutput(TEST_LED_GPIO, 1U << TEST_LED_GPIO_PIN) - #define TEST_LED_SET(state) GPIO_WritePinOutput(TEST_LED_GPIO, TEST_LED_GPIO_PIN, (state)) - #define TEST_LED_TOGGLE() GPIO_TogglePinsOutput(TEST_LED_GPIO, 1U << TEST_LED_GPIO_PIN) + static inline void TestLed_On(void) + { + GPIO_SetPinsOutput(TEST_LED_GPIO, 1U << TEST_LED_GPIO_PIN); + } + + static inline void TestLed_Off(void) + { + GPIO_ClearPinsOutput(TEST_LED_GPIO, 1U << TEST_LED_GPIO_PIN); + } + + static inline void TestLed_Set(bool state) + { + GPIO_WritePinOutput(TEST_LED_GPIO, TEST_LED_GPIO_PIN, state); + } + + static inline void TestLed_Toggle(void) + { + GPIO_TogglePinsOutput(TEST_LED_GPIO, 1U << TEST_LED_GPIO_PIN); + } // Functions: - void InitTestLed(void); + void TestLed_Init(void); + void TestLed_Blink(uint8_t times); #endif diff --git a/right/src/timer.c b/right/src/timer.c index 2a61051..1d1be35 100644 --- a/right/src/timer.c +++ b/right/src/timer.c @@ -4,11 +4,14 @@ static volatile uint32_t CurrentTime; static uint32_t timerClockFrequency; +static volatile uint32_t currentTime, delayLength; void PIT_TIMER_HANDLER(void) { - CurrentTime++; - //TEST_LED_TOGGLE(); + currentTime++; + if (delayLength) { + --delayLength; + } PIT_ClearStatusFlags(PIT, PIT_TIMER_CHANNEL, kPIT_TimerFlag); } @@ -27,14 +30,14 @@ void Timer_Init(void) } uint32_t Timer_GetCurrentTime() { - return CurrentTime; + return currentTime; } uint32_t Timer_GetCurrentTimeMicros() { uint32_t primask, count, ms; primask = DisableGlobalIRQ(); // Make sure the read is atomic count = PIT_GetCurrentTimerCount(PIT, PIT_TIMER_CHANNEL); // Read the current timer count - ms = CurrentTime; // Read the overflow counter + ms = currentTime; // Read the overflow counter EnableGlobalIRQ(primask); // Enable interrupts again if they where enabled before - this should make it interrupt safe // Calculate the counter value in microseconds - note that the PIT timer is counting downward, so we need to subtract the count from the period value @@ -77,3 +80,11 @@ uint32_t Timer_GetElapsedTimeAndSetCurrentMicros(uint32_t *time) *time = Timer_GetCurrentTimeMicros(); return elapsedTime; } + +void Timer_Delay(uint32_t length) +{ + delayLength = length; + while (delayLength) { + ; + } +} diff --git a/right/src/usb_commands/usb_command_set_test_led.c b/right/src/usb_commands/usb_command_set_test_led.c index 51ed9ee..0104270 100644 --- a/right/src/usb_commands/usb_command_set_test_led.c +++ b/right/src/usb_commands/usb_command_set_test_led.c @@ -6,6 +6,6 @@ void UsbCommand_SetTestLed(void) { bool isTestLedOn = GetUsbRxBufferUint8(1); - TEST_LED_SET(isTestLedOn); + TestLed_Set(isTestLedOn); UhkModuleStates[UhkModuleDriverId_LeftKeyboardHalf].sourceVars.isTestLedOn = isTestLedOn; } diff --git a/right/src/usb_report_updater.c b/right/src/usb_report_updater.c index 7ec1a90..3def481 100644 --- a/right/src/usb_report_updater.c +++ b/right/src/usb_report_updater.c @@ -280,6 +280,11 @@ static void applyKeyAction(key_state_t *keyState, key_action_t *action) SwitchKeymapById(action->switchKeymap.keymapId); } break; + case KeyActionType_PlayMacro: + if (!keyState->previous) { + Macros_StartMacro(action->playMacro.macroId); + } + break; } } @@ -292,10 +297,19 @@ static bool sendChar = false; static void updateActiveUsbReports(void) { - memset(activeMouseStates, 0, ACTIVE_MOUSE_STATES_COUNT); - static uint8_t previousModifiers = 0; + if (MacroPlaying) { + Macros_ContinueMacro(); + memcpy(ActiveUsbMouseReport, &MacroMouseReport, sizeof MacroMouseReport); + memcpy(ActiveUsbBasicKeyboardReport, &MacroBasicKeyboardReport, sizeof MacroBasicKeyboardReport); + memcpy(ActiveUsbMediaKeyboardReport, &MacroMediaKeyboardReport, sizeof MacroMediaKeyboardReport); + memcpy(ActiveUsbSystemKeyboardReport, &MacroSystemKeyboardReport, sizeof MacroSystemKeyboardReport); + return; + } + + memset(activeMouseStates, 0, ACTIVE_MOUSE_STATES_COUNT); + basicScancodeIndex = 0; mediaScancodeIndex = 0; systemScancodeIndex = 0; @@ -314,15 +328,6 @@ static void updateActiveUsbReports(void) bool layerGotReleased = previousLayer != LayerId_Base && activeLayer == LayerId_Base; LedDisplay_SetLayer(activeLayer); - if (MacroPlaying) { - Macros_ContinueMacro(); - memcpy(&ActiveUsbMouseReport, &MacroMouseReport, sizeof MacroMouseReport); - memcpy(&ActiveUsbBasicKeyboardReport, &MacroBasicKeyboardReport, sizeof MacroBasicKeyboardReport); - memcpy(&ActiveUsbMediaKeyboardReport, &MacroMediaKeyboardReport, sizeof MacroMediaKeyboardReport); - memcpy(&ActiveUsbSystemKeyboardReport, &MacroSystemKeyboardReport, sizeof MacroSystemKeyboardReport); - return; - } - key_state_t *testKeyState = &KeyStates[SlotId_LeftKeyboardHalf][0]; if (!testKeyState->previous && testKeyState->current && activeLayer == LayerId_Fn) { simulateKeypresses = !simulateKeypresses;