21 Commits

Author SHA1 Message Date
László Monda
21ae72dd9e Bump version to 8.5.2, update changelog, package.json, versions.h, and Agent. 2018-10-06 21:31:32 +02:00
László Monda
5fe19abe06 Merge branch 'master' into action-cache 2018-10-06 19:44:08 +02:00
Eric Tang
06e34fdcbc Convert the layer cache to an action cache 2018-10-06 10:02:46 -05:00
Eric Tang
cc6666b96d Don't suppress keys upon keymap changes 2018-10-06 10:02:23 -05:00
László Monda
a22dfdd917 Update version to 8.5.1, changelog, package.json and versions.h 2018-10-04 23:10:58 +02:00
László Monda
8b69a25dda Reset UsbReportUpdateSemaphore if it gets stuck for 100ms. This should fix occasional freezes. 2018-10-04 23:04:13 +02:00
László Monda
6f2b45c27c Update changelog, package.json, versions.h and Agent reference. 2018-10-04 22:46:01 +02:00
László Monda
98f7d512de Extract CurrentTime and remove Timer_{Get,Set}CurrentTime() 2018-10-04 20:38:36 +02:00
László Monda
c5cf738fd0 Expose UsbReportUpdateSemaphore via UsbCommand_{Get,Set}Variable() 2018-10-04 19:23:38 +02:00
László Monda
af31ae210a Move the pointer not by 1 but by 5 pixels when testing the USB stack to make the pointer easier to see. 2018-09-26 16:34:01 +02:00
László Monda
44799995b9 Update default issue text to include Karabiner Elements. 2018-09-26 00:03:20 +02:00
László Monda
3f5f83a19b Add issue template. 2018-09-25 23:55:56 +02:00
László Monda
bc4f35e578 Delete issue template. 2018-09-25 23:55:26 +02:00
László Monda
e9309aab16 Add issue template regarding Karabiner Elements 2018-09-25 23:52:09 +02:00
László Monda
f004b84399 Merge pull request #175 from UltimateHackingKeyboard/macro-engine
Use the correct scancode so that commas are outputted
2018-09-19 14:22:01 +02:00
Eric Tang
58f8120611 Use the correct scancode so that commas are outputted 2018-09-18 23:10:08 -05:00
László Monda
5b71fb7aaa Merge pull request #168 from UltimateHackingKeyboard/primary-role-modifiers
Send primary role modifiers consistently
2018-09-03 08:38:08 +02:00
Eric Tang
9d0f41bf5e Send primary role modifiers consistently 2018-09-02 00:02:40 -05:00
László Monda
47a3a8ad80 Merge pull request #163 from UltimateHackingKeyboard/layer-deactivation
Only allow layer switcher keys to deactivate toggled layers
2018-08-26 20:47:10 +02:00
Eric Tang
b4908bf2ac Only allow layer switcher keys to deactivate toggled layers 2018-08-26 11:46:38 -05:00
Eric Tang
846342e851 Deactivate secondary roles when switching keymaps 2018-08-25 07:22:48 -05:00
16 changed files with 83 additions and 57 deletions

View File

@@ -5,6 +5,30 @@ All notable changes to this project will be documented in this file.
The format is loosely based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to the [UHK Versioning](VERSIONING.md) conventions.
## [8.5.2] - 2018-10-06
Device Protocol: 4.5.0 | Module Protocol: 4.0.0 | User Config: 4.1.0 | Hardware Config: 1.0.0
- Don't suppress keys upon keymap change.
## [8.5.1] - 2018-10-04
Device Protocol: 4.5.0 | Module Protocol: 4.0.0 | User Config: 4.1.0 | Hardware Config: 1.0.0
- Reset UsbReportUpdateSemaphore if it gets stuck for 100ms. This should fix occasional freezes.
## [8.5.0] - 2018-10-04
Device Protocol: 4.**5.0** | Module Protocol: 4.0.0 | User Config: 4.1.0 | Hardware Config: 1.0.0
- Send primary role modifiers consistently.
- Only allow layer switcher keys to deactivate toggled layers.
- Deactivate secondary roles when switching keymaps.
- Use the correct scancode so that commas are outputted for macros.
- Move the pointer not by 1 but by 5 pixels when testing the USB stack to make the pointer easier to see.
- Expose UsbReportUpdateSemaphore via UsbCommand_{Get,Set}Variable() `DEVICEPROTOCOL:MINOR`
- Extract CurrentTime and remove Timer_{Get,Set}CurrentTime()
## [8.4.5] - 2018-08-21
Device Protocol: 4.4.0 | Module Protocol: 4.0.0 | User Config: 4.1.0 | Hardware Config: 1.0.0

1
ISSUE_TEMPLATE Normal file
View File

@@ -0,0 +1 @@
If you're using Karabiner Elements on your Mac, then stop here! Make sure to close Karabiner Elements, then try to reproduce the issue again, even if you think that Karabiner Elements shouldn't be the cause. Karabiner Elements is the source of numerous problems, and we don't want to receive any more reports it causes.

View File

@@ -5,7 +5,6 @@
#include "config_parser/parse_keymap.h"
#include "config_parser/config_globals.h"
#include "macros.h"
#include "usb_report_updater.h"
keymap_reference_t AllKeymaps[MAX_KEYMAP_NUM] = {
{
@@ -25,7 +24,6 @@ void SwitchKeymapById(uint8_t index)
ValidatedUserConfigBuffer.offset = AllKeymaps[index].offset;
ParseKeymap(&ValidatedUserConfigBuffer, index, AllKeymapsCount, AllMacrosCount);
LedDisplay_UpdateText();
KeymapChanged = true;
}
bool SwitchKeymapByAbbreviation(uint8_t length, char *abbrev)

View File

@@ -70,7 +70,7 @@ uint8_t characterToScancode(char character)
return HID_KEYBOARD_SC_DOT_AND_GREATER_THAN_SIGN;
case ',':
case '<':
return HID_KEYBOARD_SC_KEYPAD_LESS_THAN_SIGN;
return HID_KEYBOARD_SC_COMMA_AND_LESS_THAN_SIGN;
case '/':
case '\?':
return HID_KEYBOARD_SC_SLASH_AND_QUESTION_MARK;
@@ -286,7 +286,7 @@ bool processDelayAction(void)
inDelay = false;
}
} else {
Timer_SetCurrentTime(&delayStart);
delayStart = CurrentTime;
inDelay = true;
}
return inDelay;

View File

@@ -2,12 +2,13 @@
#include "timer.h"
#include "peripherals/test_led.h"
volatile uint32_t CurrentTime;
static uint32_t timerClockFrequency;
static volatile uint32_t currentTime, delayLength;
static volatile uint32_t delayLength;
void PIT_TIMER_HANDLER(void)
{
currentTime++;
CurrentTime++;
if (delayLength) {
--delayLength;
}
@@ -28,15 +29,11 @@ void Timer_Init(void)
PIT_StartTimer(PIT, PIT_TIMER_CHANNEL);
}
uint32_t Timer_GetCurrentTime() {
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
@@ -44,11 +41,6 @@ uint32_t Timer_GetCurrentTimeMicros() {
return ms * 1000U * TIMER_INTERVAL_MSEC + us;
}
void Timer_SetCurrentTime(uint32_t *time)
{
*time = Timer_GetCurrentTime();
}
void Timer_SetCurrentTimeMicros(uint32_t *time)
{
*time = Timer_GetCurrentTimeMicros();
@@ -56,20 +48,18 @@ void Timer_SetCurrentTimeMicros(uint32_t *time)
uint32_t Timer_GetElapsedTime(uint32_t *time)
{
uint32_t elapsedTime = Timer_GetCurrentTime() - *time;
return elapsedTime;
return CurrentTime - *time;
}
uint32_t Timer_GetElapsedTimeMicros(uint32_t *time)
{
uint32_t elapsedTime = Timer_GetCurrentTimeMicros() - *time;
return elapsedTime;
return Timer_GetCurrentTimeMicros() - *time;
}
uint32_t Timer_GetElapsedTimeAndSetCurrent(uint32_t *time)
{
uint32_t elapsedTime = Timer_GetElapsedTime(time);
*time = Timer_GetCurrentTime();
*time = CurrentTime;
return elapsedTime;
}

View File

@@ -9,12 +9,14 @@
#define TIMER_INTERVAL_MSEC 1
// Variables:
extern volatile uint32_t CurrentTime;
// Functions:
void Timer_Init(void);
uint32_t Timer_GetCurrentTime();
uint32_t Timer_GetCurrentTimeMicros();
void Timer_SetCurrentTime(uint32_t *time);
void Timer_SetCurrentTimeMicros(uint32_t *time);
uint32_t Timer_GetElapsedTime(uint32_t *time);
uint32_t Timer_GetElapsedTimeMicros(uint32_t *time);

View File

@@ -22,7 +22,7 @@ void UsbCommand_GetDebugBuffer(void)
SetDebugBufferUint32(13, I2cWatchdog_RecoveryCounter);
SetDebugBufferUint32(17, MatrixScanCounter);
SetDebugBufferUint32(21, UsbReportUpdateCounter);
SetDebugBufferUint32(25, Timer_GetCurrentTime());
SetDebugBufferUint32(25, CurrentTime);
SetDebugBufferUint32(29, UsbGenericHidActionCounter);
SetDebugBufferUint32(33, UsbBasicKeyboardActionCounter);
SetDebugBufferUint32(37, UsbMediaKeyboardActionCounter);

View File

@@ -69,7 +69,7 @@ void UsbCommand_GetDeviceProperty(void)
SetUsbTxBufferUint32(6, I2cMainBusActualBaudRateBps);
break;
case DevicePropertyId_Uptime:
SetUsbTxBufferUint32(1, Timer_GetCurrentTime());
SetUsbTxBufferUint32(1, CurrentTime);
break;
default:
SetUsbTxBufferUint8(0, UsbStatusCode_GetDeviceProperty_InvalidProperty);

View File

@@ -21,5 +21,8 @@ void UsbCommand_GetVariable(void)
case UsbVariable_DebounceTimeRelease:
SetUsbTxBufferUint8(1, DebounceTimeRelease);
break;
case UsbVariable_UsbReportSemaphore:
SetUsbTxBufferUint8(1, UsbReportUpdateSemaphore);
break;
}
}

View File

@@ -24,5 +24,8 @@ void UsbCommand_SetVariable(void)
case UsbVariable_DebounceTimeRelease:
DebounceTimeRelease = GetUsbRxBufferUint8(2);
break;
case UsbVariable_UsbReportSemaphore:
UsbReportUpdateSemaphore = GetUsbRxBufferUint8(2);
break;
}
}

View File

@@ -42,7 +42,8 @@
UsbVariable_TestSwitches,
UsbVariable_TestUsbStack,
UsbVariable_DebounceTimePress,
UsbVariable_DebounceTimeRelease
UsbVariable_DebounceTimeRelease,
UsbVariable_UsbReportSemaphore,
} usb_variable_id_t;
typedef enum {

View File

@@ -25,8 +25,7 @@ static uint16_t DoubleTapSwitchLayerReleaseTimeout = 200;
static bool activeMouseStates[ACTIVE_MOUSE_STATES_COUNT];
bool TestUsbStack = false;
bool KeymapChanged = false;
static uint8_t layerCache[SLOT_COUNT][MAX_KEY_COUNT_PER_MODULE];
static key_action_t actionCache[SLOT_COUNT][MAX_KEY_COUNT_PER_MODULE];
volatile uint8_t UsbReportUpdateSemaphore = 0;
@@ -208,15 +207,15 @@ static void handleSwitchLayerAction(key_state_t *keyState, key_action_t *action)
doubleTapSwitchLayerKey = NULL;
}
if (action->type != KeyActionType_SwitchLayer) {
return;
}
if (!keyState->previous && isLayerDoubleTapToggled && ToggledLayer == action->switchLayer.layer) {
ToggledLayer = LayerId_Base;
isLayerDoubleTapToggled = false;
}
if (action->type != KeyActionType_SwitchLayer) {
return;
}
if (keyState->previous && doubleTapSwitchLayerKey == keyState &&
Timer_GetElapsedTime(&doubleTapSwitchLayerTriggerTime) > DoubleTapSwitchLayerReleaseTimeout)
{
@@ -227,11 +226,11 @@ static void handleSwitchLayerAction(key_state_t *keyState, key_action_t *action)
if (doubleTapSwitchLayerKey && Timer_GetElapsedTimeAndSetCurrent(&doubleTapSwitchLayerStartTime) < DoubleTapSwitchLayerTimeout) {
ToggledLayer = action->switchLayer.layer;
isLayerDoubleTapToggled = true;
doubleTapSwitchLayerTriggerTime = Timer_GetCurrentTime();
doubleTapSwitchLayerTriggerTime = CurrentTime;
} else {
doubleTapSwitchLayerKey = keyState;
}
doubleTapSwitchLayerStartTime = Timer_GetCurrentTime();
doubleTapSwitchLayerStartTime = CurrentTime;
}
}
@@ -239,6 +238,10 @@ static uint8_t basicScancodeIndex = 0;
static uint8_t mediaScancodeIndex = 0;
static uint8_t systemScancodeIndex = 0;
static uint8_t stickyModifiers;
static uint8_t secondaryRoleState = SecondaryRoleState_Released;
static uint8_t secondaryRoleSlotId;
static uint8_t secondaryRoleKeyId;
static secondary_role_t secondaryRole;
static void applyKeyAction(key_state_t *keyState, key_action_t *action)
{
@@ -290,6 +293,7 @@ static void applyKeyAction(key_state_t *keyState, key_action_t *action)
case KeyActionType_SwitchKeymap:
if (!keyState->previous) {
stickyModifiers = 0;
secondaryRoleState = SecondaryRoleState_Released;
SwitchKeymapById(action->switchKeymap.keymapId);
}
break;
@@ -302,11 +306,6 @@ static void applyKeyAction(key_state_t *keyState, key_action_t *action)
}
}
static uint8_t secondaryRoleState = SecondaryRoleState_Released;
static uint8_t secondaryRoleSlotId;
static uint8_t secondaryRoleKeyId;
static secondary_role_t secondaryRole;
static void updateActiveUsbReports(void)
{
if (MacroPlaying) {
@@ -335,8 +334,6 @@ static void updateActiveUsbReports(void)
if (layerChanged) {
stickyModifiers = 0;
}
bool keymapChangedLastCycle = KeymapChanged;
KeymapChanged = false;
LedDisplay_SetLayer(activeLayer);
if (TestUsbStack) {
@@ -354,7 +351,7 @@ static void updateActiveUsbReports(void)
isEvenMedia = !isEvenMedia;
ActiveUsbMediaKeyboardReport->scancodes[mediaScancodeIndex++] = isEvenMedia ? MEDIA_VOLUME_DOWN : MEDIA_VOLUME_UP;
}
MouseMoveState.xOut = isEven ? -1 : 1;
MouseMoveState.xOut = isEven ? -5 : 5;
}
}
@@ -364,13 +361,13 @@ static void updateActiveUsbReports(void)
key_action_t *action;
if (keyState->debouncing) {
if ((uint8_t)(Timer_GetCurrentTime() - keyState->timestamp) > (keyState->previous ? DebounceTimePress : DebounceTimeRelease)) {
if ((uint8_t)(CurrentTime - keyState->timestamp) > (keyState->previous ? DebounceTimePress : DebounceTimeRelease)) {
keyState->debouncing = false;
} else {
keyState->current = keyState->previous;
}
} else if (keyState->previous != keyState->current) {
keyState->timestamp = Timer_GetCurrentTime();
keyState->timestamp = CurrentTime;
keyState->debouncing = true;
}
@@ -383,16 +380,14 @@ static void updateActiveUsbReports(void)
secondaryRoleState = SecondaryRoleState_Triggered;
keyState->current = false;
} else {
layerCache[slotId][keyId] = activeLayer;
actionCache[slotId][keyId] = CurrentKeymap[activeLayer][slotId][keyId];
}
}
action = &CurrentKeymap[layerCache[slotId][keyId]][slotId][keyId];
action = &actionCache[slotId][keyId];
if (keyState->current) {
if ((KeymapChanged || keymapChangedLastCycle) && keyState->previous) {
keyState->suppressed = true;
} else if (action->type == KeyActionType_Keystroke && action->keystroke.secondaryRole) {
if (action->type == KeyActionType_Keystroke && action->keystroke.secondaryRole) {
// Press released secondary role key.
if (!keyState->previous && secondaryRoleState == SecondaryRoleState_Released) {
secondaryRoleState = SecondaryRoleState_Pressed;
@@ -411,6 +406,7 @@ static void updateActiveUsbReports(void)
if (keyState->previous && secondaryRoleSlotId == slotId && secondaryRoleKeyId == keyId) {
// Trigger primary role.
if (secondaryRoleState == SecondaryRoleState_Pressed) {
keyState->previous = false;
applyKeyAction(keyState, action);
}
secondaryRoleState = SecondaryRoleState_Released;
@@ -439,14 +435,21 @@ uint32_t UsbReportUpdateCounter;
void UpdateUsbReports(void)
{
static uint32_t lastUpdateTime;
for (uint8_t keyId = 0; keyId < RIGHT_KEY_MATRIX_KEY_COUNT; keyId++) {
KeyStates[SlotId_RightKeyboardHalf][keyId].current = RightKeyMatrix.keyStates[keyId];
}
if (UsbReportUpdateSemaphore && !SleepModeActive) {
return;
if (Timer_GetElapsedTime(&lastUpdateTime) < USB_SEMAPHORE_TIMEOUT) {
return;
} else {
UsbReportUpdateSemaphore = 0;
}
}
lastUpdateTime = CurrentTime;
UsbReportUpdateCounter++;
ResetActiveUsbBasicKeyboardReport();

View File

@@ -14,6 +14,8 @@
#define SECONDARY_ROLE_MODIFIER_TO_HID_MODIFIER(secondaryRoleModifier) (1 << ((secondaryRoleModifier) - 1))
#define SECONDARY_ROLE_LAYER_TO_LAYER_ID(secondaryRoleLayer) ((secondaryRoleLayer) - SecondaryRole_RightSuper)
#define USB_SEMAPHORE_TIMEOUT 100 // ms
// Typedefs:
typedef enum {
@@ -72,7 +74,6 @@
extern uint32_t UsbReportUpdateCounter;
extern volatile uint8_t UsbReportUpdateSemaphore;
extern bool TestUsbStack;
extern bool KeymapChanged;
// Functions:

View File

@@ -15,8 +15,8 @@
"commander": "^2.11.0",
"shelljs": "^0.7.8"
},
"firmwareVersion": "8.4.5",
"deviceProtocolVersion": "4.4.0",
"firmwareVersion": "8.5.2",
"deviceProtocolVersion": "4.5.0",
"moduleProtocolVersion": "4.0.0",
"userConfigVersion": "4.1.0",
"hardwareConfigVersion": "1.0.0",

View File

@@ -19,11 +19,11 @@
// Variables:
#define FIRMWARE_MAJOR_VERSION 8
#define FIRMWARE_MINOR_VERSION 4
#define FIRMWARE_PATCH_VERSION 5
#define FIRMWARE_MINOR_VERSION 5
#define FIRMWARE_PATCH_VERSION 2
#define DEVICE_PROTOCOL_MAJOR_VERSION 4
#define DEVICE_PROTOCOL_MINOR_VERSION 4
#define DEVICE_PROTOCOL_MINOR_VERSION 5
#define DEVICE_PROTOCOL_PATCH_VERSION 0
#define MODULE_PROTOCOL_MAJOR_VERSION 4