Skip to content

Commit

Permalink
Merge pull request #340 from UltimateHackingKeyboard/fix_secondaries
Browse files Browse the repository at this point in the history
Fix secondaries
  • Loading branch information
mondalaci authored Nov 2, 2024
2 parents 4fe2147 + a0510b7 commit 43fba79
Show file tree
Hide file tree
Showing 15 changed files with 170 additions and 40 deletions.
5 changes: 0 additions & 5 deletions device/child_image/mcuboot.conf
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,7 @@ CONFIG_BOOT_SERIAL_NO_APPLICATION=y
CONFIG_USB_DEVICE_VID=0x37A8
CONFIG_USB_DEVICE_MANUFACTURER="Ultimate Gadget Laboratories"
CONFIG_DISABLE_FLASH_PATCH=y
# CONFIG_LOG_BACKEND_UART=y
CONFIG_LOG_BACKEND_RTT=n
# CONFIG_MCUBOOT_BOOTLOADER_MODE_SINGLE_APP=y
# CONFIG_MCUBOOT_SHELL=y
# CONFIG_MCUMGR_GRP_OS_ECHO=y
# CONFIG_MCUMGR_SMP_VERBOSE_ERR_RESPONSE=y
CONFIG_SINGLE_APPLICATION_SLOT=y
CONFIG_BOOT_MAX_LINE_INPUT_LEN=8192
CONFIG_BOOT_SERIAL_MAX_RECEIVE_SIZE=4096
Expand Down
67 changes: 53 additions & 14 deletions device/src/messenger.c
Original file line number Diff line number Diff line change
Expand Up @@ -102,25 +102,23 @@ static messenger_channel_t determineChannel(device_id_t dst) {
return MessengerChannel_None;
}

static void receiveLog(device_id_t src, const uint8_t* data, uint16_t len) {
uint8_t ATTR_UNUSED messageId = *(data++);
uint8_t logmask = *(data++);
char deviceAbbrev;
static char getDeviceAbbrev(device_id_t src) {
switch (src) {
case DeviceId_Uhk80_Left:
deviceAbbrev = 'L';
break;
return 'L';
case DeviceId_Uhk80_Right:
deviceAbbrev = 'R';
break;
return 'R';
case DeviceId_Uhk_Dongle:
deviceAbbrev = 'D';
break;
return 'D';
default:
deviceAbbrev = '?';
break;
return '?';
}
LogTo(DEVICE_ID, logmask, "%c>>> %s", deviceAbbrev, data);
}

static void receiveLog(device_id_t src, const uint8_t* data, uint16_t len) {
uint8_t ATTR_UNUSED messageId = *(data++);
uint8_t logmask = *(data++);
LogTo(DEVICE_ID, logmask, "%c>>> %s", getDeviceAbbrev(src), data);
}


Expand Down Expand Up @@ -247,10 +245,51 @@ static void receive(const uint8_t* data, uint16_t len) {
}
}

static bool isSpam(const uint8_t* data) {
if (data[MessageOffset_MsgId1] == MessageId_Ping) {
return true;
}
if (data[MessageOffset_MsgId1] == MessageId_StateSync && data[MessageOffset_MsgId1+1] == StateSyncPropertyId_Battery) {
return DEBUG_EVENTLOOP_SCHEDULE;
}
return false;
}

ATTR_UNUSED static void getMessageDescription(const uint8_t* data, const char** out1, const char** out2) {
switch (data[MessageOffset_MsgId1]) {
case MessageId_StateSync:
*out1 = "StateSync";
*out2 = StateSync_PropertyIdToString(data[MessageOffset_MsgId1+1]);
return;
case MessageId_SyncableProperty:
*out1 = "SyncableProperty";
*out2 = NULL;
return;
case MessageId_Log:
*out1 = "Log";
*out2 = NULL;
return;
case MessageId_Ping:
*out1 = "Ping";
*out2 = NULL;
return;
default:
*out1 = "Unknown";
*out2 = NULL;
return;
}
}

void Messenger_Enqueue(uint8_t src, const uint8_t* data, uint16_t len) {
if (data[2] != MessageId_Ping) {
if (!isSpam(data)) {
MessengerQueue_Put(src, data, len);
EventVector_Set(EventVector_NewMessage);
LOG_SCHEDULE(
const char* desc1;
const char* desc2;
getMessageDescription(data, &desc1, &desc2);
printk(" (%c %s %s)\n", getDeviceAbbrev(data[MessageOffset_Src]), desc1, desc2 == NULL ? "" : desc2);
);
Main_Wake();
}
}
Expand Down
6 changes: 6 additions & 0 deletions device/src/messenger.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@
MessageId_Ping,
} message_id_t;

typedef enum {
MessageOffset_Src = 0,
MessageOffset_Dst = 1,
MessageOffset_MsgId1 = 2,
} message_offset_t;

// the point of message_t is to reduce the number of times we need to copy the message.
typedef struct {
const uint8_t* data;
Expand Down
4 changes: 4 additions & 0 deletions device/src/state_sync.c
Original file line number Diff line number Diff line change
Expand Up @@ -691,3 +691,7 @@ void StateSync_ResetConfig() {
// For simplicity, update all for now
StateSync_ResetRightLeftLink(false);
}

const char* StateSync_PropertyIdToString(state_sync_prop_id_t propId) {
return stateSyncProps[propId].name;
}
1 change: 1 addition & 0 deletions device/src/state_sync.h
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@
void StateSync_ReceiveProperty(device_id_t src, state_sync_prop_id_t property, void* data, uint8_t len);
void StateSync_UpdateProperty(state_sync_prop_id_t propId, void* data);
void StateSync_ReceiveStateUpdate(device_id_t src, const uint8_t* data, uint8_t len);
const char* StateSync_PropertyIdToString(state_sync_prop_id_t propId);

void StateSync_ResetRightLeftLink(bool bidirectional);
void StateSync_ResetRightDongleLink(bool bidirectional);
Expand Down
2 changes: 1 addition & 1 deletion right/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ CPU = -mcpu=cortex-m4
FPU = -mfpu=fpv4-sp-d16 -mfloat-abi=hard

# Command for flashing the right half of the keyboard.
FLASH_CMD = ../../lib/agent/node_modules/.bin/tsx ../../lib/agent/packages/usb/update-device-firmware.ts $(PROJECT_OBJ:.axf=.hex)
FLASH_CMD = ../../lib/agent/node_modules/.bin/tsx ../../lib/agent/packages/usb/update-device-firmware.ts --vid=14248 --pid=$(DEVICE_PID) --usb-interface=4 $(PROJECT_OBJ:.axf=.hex)

# Path to the JLink script used for the right half.
JLINK_SCRIPT = ../../scripts/flash-right.jlink
Expand Down
13 changes: 12 additions & 1 deletion right/src/config_parser/parse_config.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ void readRgbColor(config_buffer_t *buffer, rgb_t* keyActionColors, key_action_co
color->blue = ReadUInt8(buffer);
}

parser_error_t ParseConfig(config_buffer_t *buffer)

parser_error_t parseConfig(config_buffer_t *buffer)
{
// Miscellaneous properties

Expand Down Expand Up @@ -338,3 +339,13 @@ parser_error_t ParseConfig(config_buffer_t *buffer)

return ParserError_Success;
}


parser_error_t ParseConfig(config_buffer_t *buffer) {
version_t oldModelVersion = DataModelVersion;
parser_error_t errorCode = parseConfig(buffer);
if (errorCode != ParserError_Success || ParserRunDry) {
DataModelVersion = oldModelVersion;
}
return errorCode;
}
6 changes: 6 additions & 0 deletions right/src/debug.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#define DEBUG_STATESYNC false
#define DEBUG_CONSOLE false
#define DEBUG_EVENTLOOP_SCHEDULE false
#define DEBUG_POSTPONER false
#define WATCH_INTERVAL 500

#ifdef __ZEPHYR__
Expand Down Expand Up @@ -146,6 +147,11 @@
#define LOG_SCHEDULE(CODE)
#endif

#if defined(__ZEPHYR__) && DEBUG_POSTPONER
#define LOG_POSTPONER(CODE) CODE
#else
#define LOG_POSTPONER(CODE)
#endif

#if defined(__ZEPHYR__) && DEBUG_EVENTLOOP_TIMING
#define EVENTLOOP_TIMING(CODE) CODE
Expand Down
19 changes: 14 additions & 5 deletions right/src/event_scheduler.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,16 +41,23 @@ static void scheduleNext()
EventVector_SetValue(EventVector_EventScheduler, gotAny);
}

#define DISABLE_IN_EVENTLOOP_SCHEDULE_DEBUG() \
if (DEBUG_EVENTLOOP_SCHEDULE) { \
return; \
#define RETURN_IF_SPAM(EVT) if (isSpam(EVT)) { return; }

static bool isSpam(event_scheduler_event_t evt)
{
switch (evt) {
case EventSchedulerEvent_UpdateBattery:
case EventSchedulerEvent_UpdateMergeSensor:
return DEBUG_EVENTLOOP_SCHEDULE;
default:
return false;
}
}

static void processEvt(event_scheduler_event_t evt)
{
switch (evt) {
case EventSchedulerEvent_UpdateBattery:
DISABLE_IN_EVENTLOOP_SCHEDULE_DEBUG();
Charger_UpdateBatteryState();
break;
case EventSchedulerEvent_ShiftScreen:
Expand Down Expand Up @@ -91,7 +98,6 @@ static void processEvt(event_scheduler_event_t evt)
UhkModuleSlaveDriver_UpdateConnectionStatus();
break;
case EventSchedulerEvent_UpdateMergeSensor:
DISABLE_IN_EVENTLOOP_SCHEDULE_DEBUG();
MergeSensor_Update();
break;
case EventSchedulerEvent_PowerMode:
Expand All @@ -111,6 +117,7 @@ static void processEvt(event_scheduler_event_t evt)

void EventScheduler_Reschedule(uint32_t at, event_scheduler_event_t evt, const char* label)
{
RETURN_IF_SPAM(evt);
LOG_SCHEDULE(
printk("%c", PostponerCore_EventsShouldBeQueued() ? 'P' : ' ');
printk(" !!! Replan: %s\n", label);
Expand All @@ -132,6 +139,7 @@ void EventScheduler_Reschedule(uint32_t at, event_scheduler_event_t evt, const c

void EventScheduler_Schedule(uint32_t at, event_scheduler_event_t evt, const char* label)
{
RETURN_IF_SPAM(evt);
LOG_SCHEDULE(
printk("%c", PostponerCore_EventsShouldBeQueued() ? 'P' : ' ');
printk(" !!! Plan: %s\n", label);
Expand All @@ -152,6 +160,7 @@ void EventScheduler_Schedule(uint32_t at, event_scheduler_event_t evt, const cha

void EventScheduler_Unschedule(event_scheduler_event_t evt)
{
RETURN_IF_SPAM(evt);
times[evt] = 0;
labels[evt] = NULL;

Expand Down
74 changes: 63 additions & 11 deletions right/src/postponer.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "debug.h"
#include "config_manager.h"
#include "event_scheduler.h"
#include "macros/keyid_parser.h"

#ifdef __ZEPHYR__
#include <zephyr/sys/printk.h>
Expand Down Expand Up @@ -40,6 +41,11 @@ bool Postponer_MouseBlocked = false;
static void autoShift();
static void chording();

struct postponer_run_state_t {
bool runEventsThisCycle;
bool runEventsNextCycle;
bool eventsShouldBeQueued;
} runState;

//##############################
//### Implementation Helpers ###
Expand Down Expand Up @@ -86,13 +92,16 @@ static void applyEventAndConsume(postponer_buffer_record_type_t* rec) {
Postponer_LastKeyMods = rec->event.key.modifiers;
// This gives the key two ticks (this and next) to get properly processed before execution of next queued event.
// PostponerCore_PostponeNCycles(1);
EventVector_Set(EventVector_NativeActions);
Macros_WakeBecauseOfKeystateChange();
consumeEvent(1);

break;
case PostponerEventType_UnblockMouse:
Postponer_MouseBlocked = false;
Postponer_LastKeyLayer = 255;
Postponer_LastKeyMods = 0;
EventVector_Set(EventVector_MouseController);
// PostponerCore_PostponeNCycles(1);
consumeEvent(1);
break;
Expand All @@ -106,11 +115,14 @@ static void applyEventAndConsume(postponer_buffer_record_type_t* rec) {
if (Timer_GetElapsedTime(&delayStartedAt) >= rec->event.delay.length) {
delayActive = false;
consumeEvent(1);
} else {
runState.runEventsThisCycle = false;
runState.runEventsNextCycle = false;
EventScheduler_Schedule(delayStartedAt + rec->event.delay.length, EventSchedulerEvent_Postponer, "Postponer - apply delay");
}
}
break;
}

}
}

Expand Down Expand Up @@ -179,12 +191,6 @@ static void appendEvent(postponer_event_t event)
// cyclesUntilActivation = MAX(n + 1, cyclesUntilActivation);
// }

struct postponer_run_state_t {
bool runEventsThisCycle;
bool runEventsNextCycle;
bool eventsShouldBeQueued;
} runState;


bool PostponerCore_EventsShouldBeQueued(void)
{
Expand Down Expand Up @@ -243,9 +249,50 @@ void PostponerCore_TrackDelay(uint32_t length)
);
}

#ifdef __ZEPHYR__
ATTR_UNUSED static const char* actionToString(postponer_event_type_t action) {
switch(action) {
case PostponerEventType_PressKey:
return "PressKey";
case PostponerEventType_ReleaseKey:
return "ReleaseKey";
case PostponerEventType_UnblockMouse:
return "UnblockMouse";
case PostponerEventType_Delay:
return "Delay";
}
return "Unknown";
}

ATTR_UNUSED static void printRecord(const char* prefix, postponer_buffer_record_type_t* record) {
postponer_event_type_t actionType = record->event.type;
bool isKeyAction = actionType == PostponerEventType_PressKey || actionType == PostponerEventType_ReleaseKey;
const char* action = actionToString(actionType);
const char* keyAbbrev;
if (isKeyAction) {
keyAbbrev = MacroKeyIdParser_KeyIdToAbbreviation(Utils_KeyStateToKeyId(record->event.key.keyState));
} else {
keyAbbrev = "";
}
printk("%s %s %s\n", prefix, action, keyAbbrev);
}

ATTR_UNUSED static void printContentPretty() {
if (bufferSize == 0) {
printk("? Postponer queue is empty!\n");
return;
}
printk("? Postponer content:\n");
for (uint8_t i = 0; i < bufferSize; i++) {
postponer_buffer_record_type_t* record = &buffer[POS(i)];
printRecord(" -", record);
}
}
#endif

void PostponerCore_RunPostponedEvents(void)
{
LOG_POSTPONER(printk("? RunPostponedEvents called! ---\n"));
runState.runEventsThisCycle = bufferSize > 0;
runState.runEventsNextCycle = bufferSize > 0;
runState.eventsShouldBeQueued = bufferSize > 0 || Cfg.ChordingDelay || Cfg.AutoShiftDelay || EventVector_IsSet(EventVector_NativeActionsPostponing) || EventVector_IsSet(EventVector_MacroEnginePostponing);
Expand All @@ -260,19 +307,24 @@ void PostponerCore_RunPostponedEvents(void)
}
// Process one event every two cycles. (Unless someone keeps Postponer active by touching cycles_until_activation.)
if ( bufferSize != 0 && (runState.runEventsThisCycle || bufferSize > POSTPONER_BUFFER_MAX_FILL)) {
LOG_POSTPONER(printRecord("? applying event", &buffer[bufferPosition]););
LOG_SCHEDULE(printk("P applying event\n"));
CurrentPostponedTime = buffer[bufferPosition].time;
applyEventAndConsume(&buffer[bufferPosition]);
} else {
if (bufferSize) {
LOG_POSTPONER(printRecord("? NOT applying event", &buffer[bufferPosition]););
}
}

bool executeNextCycle = bufferSize > 0 && (runState.runEventsThisCycle || runState.runEventsNextCycle);

LOG_POSTPONER(printContentPretty());
EventVector_SetValue(EventVector_Postponer, executeNextCycle);
}

void PostponerCore_FinishCycle(void)
{
// cyclesUntilActivation -= cyclesUntilActivation > 0 ? 1 : 0;
if(bufferSize == 0 /*&& cyclesUntilActivation == 0*/) {
void PostponerCore_UpdatePostponedTime() {
if (bufferSize == 0) {
CurrentPostponedTime = CurrentTime;
}
}
Expand Down
1 change: 1 addition & 0 deletions right/src/postponer.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@
void PostponerCore_TrackDelay(uint32_t length) ;
void PostponerCore_RunPostponedEvents(void);
void PostponerCore_FinishCycle(void);
void PostponerCore_UpdatePostponedTime();

// Functions (Basic Query APIs):

Expand Down
Loading

0 comments on commit 43fba79

Please sign in to comment.