Skip to content

Commit

Permalink
make postponing mechanism more robust
Browse files Browse the repository at this point in the history
  • Loading branch information
kareltucek committed Mar 28, 2019
1 parent 87b6ffd commit 91a90d0
Show file tree
Hide file tree
Showing 8 changed files with 79 additions and 20 deletions.
2 changes: 1 addition & 1 deletion right/src/key_states.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#define ACTIVATED_NOW(A) (((A)->current & KeyState_Sw) && !((A)->previous & KeyState_Sw) )
#define ACTIVATED_EARLIER(A) (((A)->current & KeyState_Sw) && ((A)->previous & KeyState_Sw) )
#define DEACTIVATED_NOW(A) (!((A)->current & KeyState_Sw) && ((A)->previous & KeyState_Sw) )
#define DEACTIVATED_EARLIER(A) (!((A)->current & KeyState_Sw) && !((A)->previous & KeyState_Sw) )
#define KEYSTATE(A, B, C) (((A) ? KeyState_Hw : 0 ) | ((B) ? KeyState_HwDebounced : 0) | ((C) ? KeyState_Sw : 0))

// Typedefs:
Expand All @@ -28,7 +29,6 @@
uint8_t timestamp;
uint8_t previous;
uint8_t current;
uint8_t postponed;
bool debouncing : 1;
} key_state_t;

Expand Down
3 changes: 2 additions & 1 deletion right/src/macros.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "key_matrix.h"
#include "usb_report_updater.h"
#include "led_display.h"
#include "postponer.h"
#include "macro_recorder.h"

macro_reference_t AllMacros[MAX_MACRO_NUM];
Expand Down Expand Up @@ -1024,7 +1025,7 @@ bool processResolveSecondary(uint16_t timeout1, uint16_t timeout2, uint8_t prima
}
//phase 2 - "safety margin" - wait another `timeout2` ms, and if the switcher is released during this time, still interpret it as a primary action
bool timer2Exceeded = Timer_GetElapsedTime(&s->resolveSecondaryPhase2StartTime) >= timeout2;
if(!timer1Exceeded && !timer2Exceeded && ACTIVE(s->currentMacroKey) && PendingPostponedAndReleased) {
if(!timer1Exceeded && !timer2Exceeded && ACTIVE(s->currentMacroKey) && PendingPostponedAndReleased && Postponer_PendingCount() < 3) {
return true;
}
//phase 3 - resolve the situation - if the switcher is released first or within the "safety margin", interpret it as primary action, otherwise secondary
Expand Down
40 changes: 40 additions & 0 deletions right/src/postponer.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#include "postponer.h"
#include "usb_report_updater.h"

postponer_buffer_record_type_t buffer[POSTPONER_BUFFER_SIZE];
uint8_t buffer_size = 0;
uint8_t buffer_position = 0;

void Postponer_RunPostponed(void) {
if(buffer_size == 0) {
return;
}

if(DEACTIVATED_EARLIER(buffer[buffer_position].key)) {
ActivateKey(buffer[buffer_position].key, true);
buffer_position = (buffer_position + 1) % POSTPONER_BUFFER_SIZE;
buffer_size--;
} else if(ACTIVATED_EARLIER(buffer[buffer_position].key) && !buffer[buffer_position].key->debouncing) {
/*if the user taps a key twice and holds, we need to "end" the first tap even if the
* key is physically being held
*/
buffer[buffer_position].key->current &= ~KeyState_Sw;
}

//try prevent loss of keys if some mechanism postpones more keys than we can properly let through
while(buffer_size > POSTPONER_MAX_FILL) {
ActivateKey(buffer[buffer_position].key, true);
buffer_position = (buffer_position + 1) % POSTPONER_BUFFER_SIZE;
buffer_size--;
}
}

void Postponer_TrackKey(key_state_t *keyState) {
uint8_t pos = (buffer_position + buffer_size) % POSTPONER_BUFFER_SIZE;
buffer[pos].key = keyState;
buffer_size = buffer_size < POSTPONER_BUFFER_SIZE ? buffer_size + 1 : buffer_size;
}

uint8_t Postponer_PendingCount() {
return buffer_size;
}
23 changes: 23 additions & 0 deletions right/src/postponer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#ifndef SRC_POSTPONER_H_
#define SRC_POSTPONER_H_

// Includes:

#include "key_states.h"

// Macros:

#define POSTPONER_BUFFER_SIZE 20
#define POSTPONER_MAX_FILL 15

// Typedefs:
typedef struct {
key_state_t * key;
} postponer_buffer_record_type_t;

// Functions:
void Postponer_RunPostponed(void);
void Postponer_TrackKey(key_state_t *keyState);
uint8_t Postponer_PendingCount();

#endif /* SRC_POSTPONER_H_ */
Empty file removed right/src/secondary_resolver.c
Empty file.
7 changes: 0 additions & 7 deletions right/src/secondary_resolver.h

This file was deleted.

22 changes: 11 additions & 11 deletions right/src/usb_report_updater.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
#include "slave_drivers/is31fl3731_driver.h"
#include "slave_drivers/uhk_module_driver.h"
#include "macros.h"
#include "key_states.h"
#include "right_key_matrix.h"
#include "layer.h"
#include "usb_report_updater.h"
Expand All @@ -17,6 +16,7 @@
#include "usb_commands/usb_command_get_debug_buffer.h"
#include "arduino_hid/ConsumerAPI.h"
#include "macro_recorder.h"
#include "postponer.h"

static uint32_t mouseUsbReportUpdateTime = 0;
static uint32_t mouseElapsedTime;
Expand Down Expand Up @@ -389,7 +389,7 @@ void mergeReports(void)
}
}

static void activateKey(key_state_t *keyState, bool debounce) {
void ActivateKey(key_state_t *keyState, bool debounce) {
keyState->previous = 0;
keyState->current = KeyState_Hw | KeyState_HwDebounced | KeyState_Sw;
if(debounce) {
Expand Down Expand Up @@ -417,17 +417,14 @@ static inline void preprocessKeyState(key_state_t *keyState) {

bool currSW = currDB;

if (SuppressingKeys) {
if (SuppressingKeys || Postponer_PendingCount() > 0) {
currSW = currDB && prevSW;
keyState->postponed += (currDB && !prevDB) ? 1 : 0;
} else if(keyState->postponed && !SuppressingKeys && !prevSW) {
keyState->postponed--;
currDB = true;
currSW = true;
activateKey(keyState, true);
if(currDB && !prevDB) {
Postponer_TrackKey(keyState);
}
}

PendingPostponedAndReleased |= keyState->postponed && !currDB;
PendingPostponedAndReleased |= prevDB && !prevSW && !currDB;

keyState->current = KEYSTATE(currHW, currDB, currSW);
}
Expand All @@ -439,6 +436,9 @@ static void preprocessKeyStates() {
preprocessKeyState(keyState);
}
}
if(!SuppressingKeys || Postponer_PendingCount() > POSTPONER_MAX_FILL) {
Postponer_RunPostponed();
}
}

static void updateActiveUsbReports(void)
Expand Down Expand Up @@ -534,7 +534,7 @@ static void updateActiveUsbReports(void)
if (DEACTIVATED_NOW(keyState) && secondaryRoleSlotId == slotId && secondaryRoleKeyId == keyId && secondaryRoleState != SecondaryRoleState_Released) {
// Trigger primary role.
if (secondaryRoleState == SecondaryRoleState_Pressed) {
activateKey(keyState, true);
ActivateKey(keyState, true);
applyKeyAction(keyState, action, slotId, keyId);
}
secondaryRoleState = SecondaryRoleState_Released;
Expand Down
2 changes: 2 additions & 0 deletions right/src/usb_report_updater.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
// Includes:

#include "config_parser/parse_keymap.h"
#include "key_states.h"

// Macros:

Expand Down Expand Up @@ -89,5 +90,6 @@

void UpdateUsbReports(void);
void ToggleMouseState(serialized_mouse_action_t action, bool activate);
void ActivateKey(key_state_t *keyState, bool debounce);

#endif

0 comments on commit 91a90d0

Please sign in to comment.