1 Commits

Author SHA1 Message Date
Eric Tang
aeaef7b788 Remove the semaphore 2018-08-16 13:54:20 -07:00
28 changed files with 115 additions and 348 deletions

View File

@@ -5,42 +5,6 @@ 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.3] - 2018-10-20
Device Protocol: 4.5.0 | Module Protocol: 4.0.0 | User Config: 4.1.0 | Hardware Config: 1.0.0
- Re-enable the I2C watchdog of the left keyboard half which was accidentally disabled starting from firmware 8.4.3. This should fix the freezes of the left keyboard half.
## [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
- Suppress pressed keys when the layer or keymap changes.
## [8.4.4] - 2018-08-14
Device Protocol: 4.4.0 | Module Protocol: 4.0.0 | User Config: 4.1.0 | Hardware Config: 1.0.0

View File

@@ -1,8 +0,0 @@
Before submitting a new issue, make sure to do the following:
1. If you're using Karabiner Elements on your Mac, close it!
2. Install the latest Agent:
https://github.com/UltimateHackingKeyboard/agent/releases/latest
3. Use Agent to update to the latest firmware:
https://github.com/UltimateHackingKeyboard/firmware/releases/latest
4. Try to reproduce the issue, and only report it if it still persists.

View File

@@ -12,15 +12,19 @@ If you're one of the brave few who wants to hack the firmware then read on.
`git clone --recursive git@github.com:UltimateHackingKeyboard/firmware.git`
2. Download and install MCUXpresso IDE for [Linux](https://storage.googleapis.com/ugl-static/mcuxpresso-ide/mcuxpressoide-10.2.1_795.x86_64.deb.bin), [Mac](https://storage.googleapis.com/ugl-static/mcuxpresso-ide/MCUXpressoIDE_10.2.1_795.pkg), or [Windows](https://storage.googleapis.com/ugl-static/mcuxpresso-ide/MCUXpressoIDE_10.2.1_795.exe).
2. Download and install MCUXpresso IDE for [Linux](https://storage.googleapis.com/ugl-static/mcuxpresso-ide/mcuxpressoide-10.1.1_606.x86_64.deb.bin), [Mac](https://storage.googleapis.com/ugl-static/mcuxpresso-ide/MCUXpressoIDE_10.1.1_606.pkg), or [Windows](https://storage.googleapis.com/ugl-static/mcuxpresso-ide/MCUXpressoIDE_10.1.1_606.exe).
3. In the IDE, import the project by invoking *File -> Import -> General -> Existing Projects into Workspace*, select the *left* or *right* directory depending on the desired firmware, then click on the *Finish* button.
4. In order to be able to flash the firmware via USB from the IDE, you must build [Agent](https://github.com/UltimateHackingKeyboard/agent) which is Git submodule of the this repo and located in the `lib/agent` directory.
## Building and flashing the firmware
5. Finally, in the IDE, click on *Run -> External Tools -> External Tools Configurations*, then select a release firmware to be flashed such as *uhk60-right_release_kboot*, and click on the *Run* button.
For the left keyboard half, make sure to power it via the right keyboard half (which must be powered via USB). Also connect the left keyboard half to your SEGGER J-Link USB debug probe (which must also be connected via USB). Then in KDS, click on *Run -> Run Configurations*, select *GDB SEGGER J-Link Debugging -> uhk60-left_release_jlink*, and click on the *Debug* button.
Going forward, it's easier to flash the firmware of your choice by using the downwards toolbar icon which is located rightwards of the *green play + toolbox icon*.
For the right keyboard half, flash [the bootloader](https://github.com/UltimateHackingKeyboard/bootloader) first.
At this point, you can flash the right firmware via USB from KDS. To achieve this, you must build [Agent](https://github.com/UltimateHackingKeyboard/agent) that is Git submodule of the this repo and located in the `lib/agent` directory. Then in KDS, click on *Run -> Run Configurations*, select *C/C++ Application -> uhk60-right_release_kboot*, and click on the *Run* button.
From this point on, you can upgrade the firmwares of both halves via USB by using the uhk60-left_release_kboot and uhk60-right_release_kboot run configurations. Alternatively, you can use your SEGGER J-Link probe.
## Contributing

View File

@@ -5,7 +5,9 @@
void KEY_SCANNER_HANDLER(void)
{
KeyMatrix_ScanRow(&keyMatrix);
#ifdef I2C_WATCHDOG
RunWatchdog();
#endif
LPTMR_ClearStatusFlags(KEY_SCANNER_LPTMR_BASEADDR, kLPTMR_TimerCompareFlag);
}

View File

@@ -146,6 +146,8 @@ parser_error_t ParseConfig(config_buffer_t *buffer)
AlphanumericSegmentsBrightness = alphanumericSegmentsBrightness;
KeyBacklightBrightness = keyBacklightBrightness;
LedSlaveDriver_UpdateLeds();
// Update mouse key speeds
MouseMoveState.initialSpeed = mouseMoveInitialSpeed;

View File

@@ -15,7 +15,7 @@ void updateLayerStates(void)
for (uint8_t slotId=0; slotId<SLOT_COUNT; slotId++) {
for (uint8_t keyId=0; keyId<MAX_KEY_COUNT_PER_MODULE; keyId++) {
key_state_t *keyState = &KeyStates[slotId][keyId];
if (keyState->current && !keyState->suppressed) {
if (keyState->current) {
key_action_t action = CurrentKeymap[LayerId_Base][slotId][keyId];
if (action.type == KeyActionType_SwitchLayer) {
if (action.switchLayer.mode != SwitchLayerMode_Toggle) {

View File

@@ -84,7 +84,6 @@ void LedDisplay_SetText(uint8_t length, const char* text)
}
allSegmentSets >>= 5;
}
LedSlaveDriver_UpdateLeds(LedDriverId_Left);
}
void LedDisplay_SetLayer(layer_id_t layerId)
@@ -96,7 +95,6 @@ void LedDisplay_SetLayer(layer_id_t layerId)
if (layerId >= LayerId_Mod && layerId <= LayerId_Mouse) {
LedDriverValues[LedDriverId_Left][16 * layerId - 3] = IconsAndLayerTextsBrightness;
}
LedSlaveDriver_UpdateLeds(LedDriverId_Left);
}
bool LedDisplay_GetIcon(led_display_icon_t icon)
@@ -108,7 +106,6 @@ void LedDisplay_SetIcon(led_display_icon_t icon, bool isEnabled)
{
ledIconStates[icon] = isEnabled;
LedDriverValues[LedDriverId_Left][icon + 8] = isEnabled ? IconsAndLayerTextsBrightness : 0;
LedSlaveDriver_UpdateLeds(LedDriverId_Left);
}
void LedDisplay_UpdateIcons(void)

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_COMMA_AND_LESS_THAN_SIGN;
return HID_KEYBOARD_SC_KEYPAD_LESS_THAN_SIGN;
case '/':
case '\?':
return HID_KEYBOARD_SC_SLASH_AND_QUESTION_MARK;
@@ -286,7 +286,7 @@ bool processDelayAction(void)
inDelay = false;
}
} else {
delayStart = CurrentTime;
Timer_SetCurrentTime(&delayStart);
inDelay = true;
}
return inDelay;

View File

@@ -16,13 +16,8 @@
#define LED_DRIVER_SDB_CLOCK kCLOCK_PortA
#define LED_DRIVER_SDB_PIN 2
#define LED_DRIVER_REGISTER_SHUTDOWN 0x0A
#define LED_DRIVER_REGISTER_FRAME 0xFD
#define LED_DRIVER_REGISTER_CONFIGURATION 0x00
#define LED_DRIVER_REGISTER_AUTO_PLAY_CONTROL_1 0x02
#define LED_DRIVER_REGISTER_AUTO_PLAY_CONTROL_2 0x03
#define LED_DRIVER_REGISTER_BREATH_CONTROL_1 0x08
#define LED_DRIVER_REGISTER_BREATH_CONTROL_2 0x09
#define LED_DRIVER_REGISTER_SHUTDOWN 0x0A
#define LED_DRIVER_REGISTER_FRAME 0xFD
#define LED_DRIVER_FRAME_1 0
#define LED_DRIVER_FRAME_2 1
@@ -47,25 +42,6 @@
#define SHUTDOWN_MODE_SHUTDOWN 0
#define SHUTDOWN_MODE_NORMAL 1
#define DISPLAY_MODE_AUTO_FRAME_PLAY 0b01
#define DISPLAY_MODE_SHIFT 3
#define FRAME_START_1 0b000
#define FRAME_START_8 0b111
#define PLAY_LOOP_NUMBER_1 0b001
#define PLAY_LOOP_NUMBER_SHIFT 4
#define PLAY_FRAME_NUMBER_1 0b001
#define FRAME_DELAY_TIME 1
#define FADE_OUT_TIME 5
#define FADE_OUT_TIME_SHIFT 4
#define FADE_IN_TIME 5
#define BREATH_ENABLE 1
#define BREATH_ENABLE_SHIFT 4
#define EXTINGUISH_TIME 0
// Functions:
void InitLedDriver(void);

View File

@@ -60,48 +60,22 @@ static led_driver_state_t ledDriverStates[LED_DRIVER_MAX_COUNT] = {
static uint8_t setFunctionFrameBuffer[] = {LED_DRIVER_REGISTER_FRAME, LED_DRIVER_FRAME_FUNCTION};
static uint8_t setShutdownModeNormalBuffer[] = {LED_DRIVER_REGISTER_SHUTDOWN, SHUTDOWN_MODE_NORMAL};
static uint8_t setFrame1Buffer[] = {LED_DRIVER_REGISTER_FRAME, LED_DRIVER_FRAME_1};
static uint8_t setFrame2Buffer[] = {LED_DRIVER_REGISTER_FRAME, LED_DRIVER_FRAME_2};
static uint8_t setFrame8Buffer[] = {LED_DRIVER_REGISTER_FRAME, LED_DRIVER_FRAME_8};
static uint8_t initLedControlRegistersZeroBuffer[19] = { FRAME_REGISTER_LED_CONTROL_FIRST };
static uint8_t setConfigurationRegisterFadeInBuffer[] = {
LED_DRIVER_REGISTER_CONFIGURATION,
DISPLAY_MODE_AUTO_FRAME_PLAY << DISPLAY_MODE_SHIFT | FRAME_START_8
};
static uint8_t setConfigurationRegisterFadeOutBuffer[] = {
LED_DRIVER_REGISTER_CONFIGURATION,
DISPLAY_MODE_AUTO_FRAME_PLAY << DISPLAY_MODE_SHIFT | FRAME_START_1
};
static uint8_t initAutoPlayControlRegister1Buffer[] = {
LED_DRIVER_REGISTER_AUTO_PLAY_CONTROL_1,
PLAY_LOOP_NUMBER_1 << PLAY_LOOP_NUMBER_SHIFT | PLAY_FRAME_NUMBER_1
};
static uint8_t initAutoPlayControlRegister2Buffer[] = {
LED_DRIVER_REGISTER_AUTO_PLAY_CONTROL_2,
FRAME_DELAY_TIME
};
static uint8_t initBreathControlRegister1Buffer[] = {
LED_DRIVER_REGISTER_BREATH_CONTROL_1,
FADE_OUT_TIME << FADE_OUT_TIME_SHIFT | FADE_IN_TIME
};
static uint8_t initBreathControlRegister2Buffer[] = {
LED_DRIVER_REGISTER_BREATH_CONTROL_2,
BREATH_ENABLE << BREATH_ENABLE_SHIFT | EXTINGUISH_TIME
};
static uint8_t updatePwmRegistersBuffer[PWM_REGISTER_BUFFER_LENGTH];
void LedSlaveDriver_DisableLeds(uint8_t ledDriverId)
void LedSlaveDriver_DisableLeds(void)
{
ledDriverStates[ledDriverId].requests[LedDriverRequest_DisableLeds] = true;
for (uint8_t ledDriverId=0; ledDriverId<=LedDriverId_Last; ledDriverId++) {
memset(LedDriverValues[ledDriverId], 0, LED_DRIVER_LED_COUNT);
}
}
void LedSlaveDriver_EnableLeds(uint8_t ledDriverId)
void LedSlaveDriver_UpdateLeds(void)
{
ledDriverStates[ledDriverId].requests[LedDriverRequest_EnableLeds] = true;
}
for (uint8_t ledDriverId=0; ledDriverId<=LedDriverId_Last; ledDriverId++) {
memset(LedDriverValues[ledDriverId], KeyBacklightBrightness, LED_DRIVER_LED_COUNT);
}
void LedSlaveDriver_UpdateLeds(uint8_t ledDriverId)
{
ledDriverStates[ledDriverId].requests[LedDriverRequest_UpdateLeds] = true;
LedDisplay_UpdateAll();
}
void LedSlaveDriver_Init(uint8_t ledDriverId)
@@ -111,9 +85,13 @@ void LedSlaveDriver_Init(uint8_t ledDriverId)
}
led_driver_state_t *currentLedDriverState = ledDriverStates + ledDriverId;
currentLedDriverState->phase = LedDriverPhase_SetFunctionFrame;
currentLedDriverState->ledIndex = 0;
memset(LedDriverValues[ledDriverId], KeyBacklightBrightness, LED_DRIVER_LED_COUNT);
ledDriverStates[ledDriverId].requests[LedDriverRequest_Init] = true;
if (ledDriverId == LedDriverId_Left) {
LedDisplay_UpdateAll();
}
}
status_t LedSlaveDriver_Update(uint8_t ledDriverId)
@@ -121,62 +99,31 @@ status_t LedSlaveDriver_Update(uint8_t ledDriverId)
status_t status = kStatus_Uhk_IdleSlave;
uint8_t *ledValues = LedDriverValues[ledDriverId];
led_driver_state_t *currentLedDriverState = ledDriverStates + ledDriverId;
uint8_t *ledDriverPhase = &currentLedDriverState->phase;
uint8_t ledDriverAddress = currentLedDriverState->i2cAddress;
uint8_t *ledIndex = &currentLedDriverState->ledIndex;
switch (currentLedDriverState->phase) {
case LedDriverPhase_SetFunctionFrameInit:
switch (*ledDriverPhase) {
case LedDriverPhase_SetFunctionFrame:
if (ledDriverId == LedDriverId_Left && !Slaves[SlaveId_LeftKeyboardHalf].isConnected) {
break;
}
status = I2cAsyncWrite(ledDriverAddress, setFunctionFrameBuffer, sizeof(setFunctionFrameBuffer));
currentLedDriverState->phase = LedDriverPhase_SetShutdownModeNormalInit;
*ledDriverPhase = LedDriverPhase_SetShutdownModeNormal;
break;
case LedDriverPhase_SetShutdownModeNormalInit:
case LedDriverPhase_SetShutdownModeNormal:
status = I2cAsyncWrite(ledDriverAddress, setShutdownModeNormalBuffer, sizeof(setShutdownModeNormalBuffer));
currentLedDriverState->phase = LedDriverPhase_InitAutoPlayControlRegister1Init;
*ledDriverPhase = LedDriverPhase_SetFrame1;
break;
case LedDriverPhase_InitAutoPlayControlRegister1Init:
status = I2cAsyncWrite(ledDriverAddress, initAutoPlayControlRegister1Buffer, sizeof(initAutoPlayControlRegister1Buffer));
currentLedDriverState->phase = LedDriverPhase_InitAutoPlayControlRegister2Init;
break;
case LedDriverPhase_InitAutoPlayControlRegister2Init:
status = I2cAsyncWrite(ledDriverAddress, initAutoPlayControlRegister2Buffer, sizeof(initAutoPlayControlRegister2Buffer));
currentLedDriverState->phase = LedDriverPhase_InitBreathControlRegister1Init;
break;
case LedDriverPhase_InitBreathControlRegister1Init:
status = I2cAsyncWrite(ledDriverAddress, initBreathControlRegister1Buffer, sizeof(initBreathControlRegister1Buffer));
currentLedDriverState->phase = LedDriverPhase_InitBreathControlRegister2Init;
break;
case LedDriverPhase_InitBreathControlRegister2Init:
status = I2cAsyncWrite(ledDriverAddress, initBreathControlRegister2Buffer, sizeof(initBreathControlRegister2Buffer));
currentLedDriverState->phase = LedDriverPhase_SetFrame2Init;
break;
case LedDriverPhase_SetFrame2Init:
status = I2cAsyncWrite(ledDriverAddress, setFrame2Buffer, sizeof(setFrame2Buffer));
currentLedDriverState->phase = LedDriverPhase_InitLedControlRegistersZero1Init;
break;
case LedDriverPhase_InitLedControlRegistersZero1Init:
status = I2cAsyncWrite(ledDriverAddress, initLedControlRegistersZeroBuffer, sizeof(initLedControlRegistersZeroBuffer));
currentLedDriverState->phase = LedDriverPhase_SetFrame8Init;
break;
case LedDriverPhase_SetFrame8Init:
status = I2cAsyncWrite(ledDriverAddress, setFrame8Buffer, sizeof(setFrame8Buffer));
currentLedDriverState->phase = LedDriverPhase_InitLedControlRegistersZero2Init;
break;
case LedDriverPhase_InitLedControlRegistersZero2Init:
status = I2cAsyncWrite(ledDriverAddress, initLedControlRegistersZeroBuffer, sizeof(initLedControlRegistersZeroBuffer));
currentLedDriverState->phase = LedDriverPhase_SetFrame1Init;
break;
case LedDriverPhase_SetFrame1Init:
case LedDriverPhase_SetFrame1:
status = I2cAsyncWrite(ledDriverAddress, setFrame1Buffer, sizeof(setFrame1Buffer));
currentLedDriverState->phase = LedDriverPhase_InitLedControlRegistersInit;
*ledDriverPhase = LedDriverPhase_InitLedControlRegisters;
break;
case LedDriverPhase_InitLedControlRegistersInit:
case LedDriverPhase_InitLedControlRegisters:
status = I2cAsyncWrite(ledDriverAddress, currentLedDriverState->setupLedControlRegistersCommand, LED_CONTROL_REGISTERS_COMMAND_LENGTH);
currentLedDriverState->phase = LedDriverPhase_InitLedValuesInit;
*ledDriverPhase = LedDriverPhase_InitLedValues;
break;
case LedDriverPhase_InitLedValuesInit:
case LedDriverPhase_InitLedValues:
updatePwmRegistersBuffer[0] = FRAME_REGISTER_PWM_FIRST + *ledIndex;
uint8_t chunkSize = MIN(LED_DRIVER_LED_COUNT - *ledIndex, PMW_REGISTER_UPDATE_CHUNK_SIZE);
memcpy(updatePwmRegistersBuffer+1, ledValues + *ledIndex, chunkSize);
@@ -185,35 +132,10 @@ status_t LedSlaveDriver_Update(uint8_t ledDriverId)
if (*ledIndex >= LED_DRIVER_LED_COUNT) {
*ledIndex = 0;
memcpy(currentLedDriverState->targetLedValues, ledValues, LED_DRIVER_LED_COUNT);
currentLedDriverState->phase = LedDriverPhase_Idle;
*ledDriverPhase = LedDriverPhase_UpdateChangedLedValues;
}
break;
case LedDriverPhase_Idle: {
uint8_t i;
for (i = 0; i <= LedDriverRequest_Last; i++) {
if (currentLedDriverState->requests[i]) {
currentLedDriverState->requests[i] = false;
break;
}
}
switch (i) {
case LedDriverRequest_Init:
currentLedDriverState->phase = LedDriverPhase_SetFunctionFrameInit;
break;
case LedDriverRequest_EnableLeds:
currentLedDriverState->phase = LedDriverPhase_SetFunctionFrameEnableLeds;
break;
case LedDriverRequest_DisableLeds:
currentLedDriverState->phase = LedDriverPhase_SetFunctionFrameDisableLeds;
break;
case LedDriverRequest_UpdateLeds:
currentLedDriverState->phase = LedDriverPhase_UpdateChangedLedValuesUpdateLeds;
break;
}
break;
}
case LedDriverPhase_UpdateChangedLedValuesUpdateLeds: {
case LedDriverPhase_UpdateChangedLedValues: {
uint8_t *targetLedValues = currentLedDriverState->targetLedValues;
uint8_t lastLedChunkStartIndex = LED_DRIVER_LED_COUNT - PMW_REGISTER_UPDATE_CHUNK_SIZE;
@@ -233,7 +155,6 @@ status_t LedSlaveDriver_Update(uint8_t ledDriverId)
bool foundStartIndex = count < LED_DRIVER_LED_COUNT;
if (!foundStartIndex) {
*ledIndex = 0;
currentLedDriverState->phase = LedDriverPhase_Idle;
break;
}
@@ -254,34 +175,9 @@ status_t LedSlaveDriver_Update(uint8_t ledDriverId)
*ledIndex += length;
if (*ledIndex >= LED_DRIVER_LED_COUNT) {
*ledIndex = 0;
currentLedDriverState->phase = LedDriverPhase_Idle;
}
break;
}
case LedDriverPhase_SetFunctionFrameDisableLeds:
status = I2cAsyncWrite(ledDriverAddress, setFunctionFrameBuffer, sizeof(setFunctionFrameBuffer));
currentLedDriverState->phase = LedDriverPhase_SetConfigurationRegisterDisableLeds;
break;
case LedDriverPhase_SetConfigurationRegisterDisableLeds:
status = I2cAsyncWrite(ledDriverAddress, setConfigurationRegisterFadeOutBuffer, sizeof(setConfigurationRegisterFadeOutBuffer));
currentLedDriverState->phase = LedDriverPhase_SetFrame1DisableLeds;
break;
case LedDriverPhase_SetFrame1DisableLeds:
status = I2cAsyncWrite(ledDriverAddress, setFrame1Buffer, sizeof(setFrame1Buffer));
currentLedDriverState->phase = LedDriverPhase_Idle;
break;
case LedDriverPhase_SetFunctionFrameEnableLeds:
status = I2cAsyncWrite(ledDriverAddress, setFunctionFrameBuffer, sizeof(setFunctionFrameBuffer));
currentLedDriverState->phase = LedDriverPhase_SetConfigurationRegisterEnableLeds;
break;
case LedDriverPhase_SetConfigurationRegisterEnableLeds:
status = I2cAsyncWrite(ledDriverAddress, setConfigurationRegisterFadeInBuffer, sizeof(setConfigurationRegisterFadeInBuffer));
currentLedDriverState->phase = LedDriverPhase_SetFrame1EnableLeds;
break;
case LedDriverPhase_SetFrame1EnableLeds:
status = I2cAsyncWrite(ledDriverAddress, setFrame1Buffer, sizeof(setFrame1Buffer));
currentLedDriverState->phase = LedDriverPhase_Idle;
break;
}
return status;

View File

@@ -20,14 +20,6 @@
// Typedefs:
enum {
LedDriverRequest_Init,
LedDriverRequest_EnableLeds,
LedDriverRequest_DisableLeds,
LedDriverRequest_UpdateLeds,
LedDriverRequest_Last = LedDriverRequest_UpdateLeds
};
typedef enum {
LedDriverId_Right,
LedDriverId_Left,
@@ -35,31 +27,15 @@
} led_driver_id_t;
typedef enum {
LedDriverPhase_Idle,
LedDriverPhase_SetFunctionFrameInit,
LedDriverPhase_SetFunctionFrameDisableLeds,
LedDriverPhase_SetFunctionFrameEnableLeds,
LedDriverPhase_SetShutdownModeNormalInit,
LedDriverPhase_SetFrame1Init,
LedDriverPhase_SetFrame1EnableLeds,
LedDriverPhase_SetFrame1DisableLeds,
LedDriverPhase_SetFrame2Init,
LedDriverPhase_SetFrame8Init,
LedDriverPhase_InitAutoPlayControlRegister1Init,
LedDriverPhase_InitAutoPlayControlRegister2Init,
LedDriverPhase_InitBreathControlRegister1Init,
LedDriverPhase_InitBreathControlRegister2Init,
LedDriverPhase_InitLedControlRegistersZero1Init,
LedDriverPhase_InitLedControlRegistersZero2Init,
LedDriverPhase_InitLedValuesInit,
LedDriverPhase_UpdateChangedLedValuesUpdateLeds,
LedDriverPhase_SetConfigurationRegisterDisableLeds,
LedDriverPhase_SetConfigurationRegisterEnableLeds,
LedDriverPhase_InitLedControlRegistersInit
LedDriverPhase_SetFunctionFrame,
LedDriverPhase_SetShutdownModeNormal,
LedDriverPhase_SetFrame1,
LedDriverPhase_InitLedControlRegisters,
LedDriverPhase_InitLedValues,
LedDriverPhase_UpdateChangedLedValues,
} led_driver_phase_t;
typedef struct {
bool requests[LedDriverRequest_Last + 1];
led_driver_phase_t phase;
uint8_t targetLedValues[LED_DRIVER_LED_COUNT];
uint8_t ledIndex;
@@ -74,9 +50,8 @@
// Functions:
void LedSlaveDriver_DisableLeds(uint8_t ledDriverId);
void LedSlaveDriver_EnableLeds(uint8_t ledDriverId);
void LedSlaveDriver_UpdateLeds(uint8_t ledDriverId);
void LedSlaveDriver_DisableLeds(void);
void LedSlaveDriver_UpdateLeds(void);
void LedSlaveDriver_Init(uint8_t ledDriverId);
status_t LedSlaveDriver_Update(uint8_t ledDriverId);

View File

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

View File

@@ -9,14 +9,12 @@
#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, CurrentTime);
SetDebugBufferUint32(25, Timer_GetCurrentTime());
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, CurrentTime);
SetUsbTxBufferUint32(1, Timer_GetCurrentTime());
break;
default:
SetUsbTxBufferUint8(0, UsbStatusCode_GetDeviceProperty_InvalidProperty);

View File

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

View File

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

View File

@@ -168,16 +168,12 @@ static volatile bool wakeUpHostAllowed;
static void suspendUhk(void) {
SleepModeActive = true;
for (uint8_t i = 0; i <= LedDriverId_Last; i++) {
LedSlaveDriver_DisableLeds(i);
}
LedSlaveDriver_DisableLeds();
}
static void wakeUpUhk(void) {
SleepModeActive = false;
for (uint8_t i = 0; i <= LedDriverId_Last; i++) {
LedSlaveDriver_EnableLeds(i);
}
LedSlaveDriver_UpdateLeds();
}
void WakeUpHost(void) {

View File

@@ -1,6 +1,5 @@
#include "led_display.h"
#include "usb_composite_device.h"
#include "usb_report_updater.h"
static usb_basic_keyboard_report_t usbBasicKeyboardReports[2];
uint32_t UsbBasicKeyboardActionCounter;
@@ -45,7 +44,6 @@ usb_status_t UsbBasicKeyboardCallback(class_handle_t handle, uint32_t event, voi
switch (event) {
// This event is received when the report has been sent
case kUSB_DeviceHidEventSendResponse:
UsbReportUpdateSemaphore &= ~(1 << USB_BASIC_KEYBOARD_INTERFACE_INDEX);
if (UsbCompositeDevice.attach) {
error = kStatus_USB_Success;
}

View File

@@ -1,5 +1,4 @@
#include "usb_composite_device.h"
#include "usb_report_updater.h"
uint32_t UsbMediaKeyboardActionCounter;
static usb_media_keyboard_report_t usbMediaKeyboardReports[2];
@@ -43,7 +42,6 @@ usb_status_t UsbMediaKeyboardCallback(class_handle_t handle, uint32_t event, voi
switch (event) {
// This event is received when the report has been sent
case kUSB_DeviceHidEventSendResponse:
UsbReportUpdateSemaphore &= ~(1 << USB_MEDIA_KEYBOARD_INTERFACE_INDEX);
if (UsbCompositeDevice.attach) {
error = kStatus_USB_Success;
}

View File

@@ -1,5 +1,4 @@
#include "usb_composite_device.h"
#include "usb_report_updater.h"
uint32_t UsbMouseActionCounter;
static usb_mouse_report_t usbMouseReports[2];
@@ -43,7 +42,6 @@ usb_status_t UsbMouseCallback(class_handle_t handle, uint32_t event, void *param
switch (event) {
// This event is received when the report has been sent
case kUSB_DeviceHidEventSendResponse:
UsbReportUpdateSemaphore &= ~(1 << USB_MOUSE_INTERFACE_INDEX);
if (UsbCompositeDevice.attach) {
error = kStatus_USB_Success;
}

View File

@@ -1,5 +1,4 @@
#include "usb_composite_device.h"
#include "usb_report_updater.h"
uint32_t UsbSystemKeyboardActionCounter;
static usb_system_keyboard_report_t usbSystemKeyboardReports[2];
@@ -43,7 +42,6 @@ usb_status_t UsbSystemKeyboardCallback(class_handle_t handle, uint32_t event, vo
switch (event) {
// This event is received when the report has been sent
case kUSB_DeviceHidEventSendResponse:
UsbReportUpdateSemaphore &= ~(1 << USB_SYSTEM_KEYBOARD_INTERFACE_INDEX);
if (UsbCompositeDevice.attach) {
error = kStatus_USB_Success;
}

View File

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

View File

@@ -25,9 +25,6 @@ static uint16_t DoubleTapSwitchLayerReleaseTimeout = 200;
static bool activeMouseStates[ACTIVE_MOUSE_STATES_COUNT];
bool TestUsbStack = false;
static key_action_t actionCache[SLOT_COUNT][MAX_KEY_COUNT_PER_MODULE];
volatile uint8_t UsbReportUpdateSemaphore = 0;
mouse_kinetic_state_t MouseMoveState = {
.isScroll = false,
@@ -207,15 +204,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)
{
@@ -226,11 +223,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 = CurrentTime;
doubleTapSwitchLayerTriggerTime = Timer_GetCurrentTime();
} else {
doubleTapSwitchLayerKey = keyState;
}
doubleTapSwitchLayerStartTime = CurrentTime;
doubleTapSwitchLayerStartTime = Timer_GetCurrentTime();
}
}
@@ -238,10 +235,6 @@ 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)
{
@@ -293,7 +286,6 @@ 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;
@@ -306,6 +298,11 @@ 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) {
@@ -334,6 +331,7 @@ static void updateActiveUsbReports(void)
if (layerChanged) {
stickyModifiers = 0;
}
bool layerGotReleased = layerChanged && activeLayer == LayerId_Base;
LedDisplay_SetLayer(activeLayer);
if (TestUsbStack) {
@@ -351,43 +349,40 @@ static void updateActiveUsbReports(void)
isEvenMedia = !isEvenMedia;
ActiveUsbMediaKeyboardReport->scancodes[mediaScancodeIndex++] = isEvenMedia ? MEDIA_VOLUME_DOWN : MEDIA_VOLUME_UP;
}
MouseMoveState.xOut = isEven ? -5 : 5;
MouseMoveState.xOut = isEven ? -1 : 1;
}
}
for (uint8_t slotId=0; slotId<SLOT_COUNT; slotId++) {
for (uint8_t keyId=0; keyId<MAX_KEY_COUNT_PER_MODULE; keyId++) {
key_state_t *keyState = &KeyStates[slotId][keyId];
key_action_t *action;
key_action_t *action = &CurrentKeymap[activeLayer][slotId][keyId];
if (keyState->debouncing) {
if ((uint8_t)(CurrentTime - keyState->timestamp) > (keyState->previous ? DebounceTimePress : DebounceTimeRelease)) {
if ((uint8_t)(Timer_GetCurrentTime() - keyState->timestamp) > (keyState->previous ? DebounceTimePress : DebounceTimeRelease)) {
keyState->debouncing = false;
} else {
keyState->current = keyState->previous;
}
} else if (keyState->previous != keyState->current) {
keyState->timestamp = CurrentTime;
keyState->timestamp = Timer_GetCurrentTime();
keyState->debouncing = true;
}
if (keyState->current && !keyState->previous) {
if (SleepModeActive) {
if (keyState->current) {
if (SleepModeActive && !keyState->previous) {
WakeUpHost();
}
if (secondaryRoleState == SecondaryRoleState_Pressed) {
// Trigger secondary role.
key_action_t *baseAction = &CurrentKeymap[LayerId_Base][slotId][keyId];
if (layerGotReleased && !(baseAction->type == KeyActionType_Keystroke && baseAction->keystroke.scancode == 0 && baseAction->keystroke.modifiers)) {
keyState->suppressed = true;
}
// Trigger secondary role.
if (!keyState->previous && secondaryRoleState == SecondaryRoleState_Pressed) {
secondaryRoleState = SecondaryRoleState_Triggered;
keyState->current = false;
} else {
actionCache[slotId][keyId] = CurrentKeymap[activeLayer][slotId][keyId];
}
}
action = &actionCache[slotId][keyId];
if (keyState->current) {
if (action->type == KeyActionType_Keystroke && action->keystroke.secondaryRole) {
} else if (action->type == KeyActionType_Keystroke && action->keystroke.secondaryRole) {
// Press released secondary role key.
if (!keyState->previous && secondaryRoleState == SecondaryRoleState_Released) {
secondaryRoleState = SecondaryRoleState_Pressed;
@@ -400,13 +395,14 @@ static void updateActiveUsbReports(void)
applyKeyAction(keyState, action);
}
} else {
keyState->suppressed = false;
if (keyState->suppressed) {
keyState->suppressed = false;
}
// Release secondary role key.
if (keyState->previous && secondaryRoleSlotId == slotId && secondaryRoleKeyId == keyId) {
// Trigger primary role.
if (secondaryRoleState == SecondaryRoleState_Pressed) {
keyState->previous = false;
applyKeyAction(keyState, action);
}
secondaryRoleState = SecondaryRoleState_Released;
@@ -435,21 +431,10 @@ 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) {
if (Timer_GetElapsedTime(&lastUpdateTime) < USB_SEMAPHORE_TIMEOUT) {
return;
} else {
UsbReportUpdateSemaphore = 0;
}
}
lastUpdateTime = CurrentTime;
UsbReportUpdateCounter++;
ResetActiveUsbBasicKeyboardReport();
@@ -465,32 +450,20 @@ void UpdateUsbReports(void)
bool HasUsbMouseReportChanged = memcmp(ActiveUsbMouseReport, GetInactiveUsbMouseReport(), sizeof(usb_mouse_report_t)) != 0;
if (HasUsbBasicKeyboardReportChanged) {
usb_status_t status = UsbBasicKeyboardAction();
if (status == kStatus_USB_Success) {
UsbReportUpdateSemaphore |= 1 << USB_BASIC_KEYBOARD_INTERFACE_INDEX;
}
UsbBasicKeyboardAction();
}
if (HasUsbMediaKeyboardReportChanged) {
usb_status_t status = UsbMediaKeyboardAction();
if (status == kStatus_USB_Success) {
UsbReportUpdateSemaphore |= 1 << USB_MEDIA_KEYBOARD_INTERFACE_INDEX;
}
UsbMediaKeyboardAction();
}
if (HasUsbSystemKeyboardReportChanged) {
usb_status_t status = UsbSystemKeyboardAction();
if (status == kStatus_USB_Success) {
UsbReportUpdateSemaphore |= 1 << USB_SYSTEM_KEYBOARD_INTERFACE_INDEX;
}
UsbSystemKeyboardAction();
}
// Send out the mouse position and wheel values continuously if the report is not zeros, but only send the mouse button states when they change.
if (HasUsbMouseReportChanged || ActiveUsbMouseReport->x || ActiveUsbMouseReport->y ||
ActiveUsbMouseReport->wheelX || ActiveUsbMouseReport->wheelY) {
usb_status_t status = UsbMouseAction();
if (status == kStatus_USB_Success) {
UsbReportUpdateSemaphore |= 1 << USB_MOUSE_INTERFACE_INDEX;
}
UsbMouseAction();
}
}

View File

@@ -14,8 +14,6 @@
#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 +70,6 @@
extern mouse_kinetic_state_t MouseMoveState;
extern mouse_kinetic_state_t MouseScrollState;
extern uint32_t UsbReportUpdateCounter;
extern volatile uint8_t UsbReportUpdateSemaphore;
extern bool TestUsbStack;
// Functions:

View File

@@ -15,8 +15,8 @@
"commander": "^2.11.0",
"shelljs": "^0.7.8"
},
"firmwareVersion": "8.5.3",
"deviceProtocolVersion": "4.5.0",
"firmwareVersion": "8.4.4",
"deviceProtocolVersion": "4.4.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 5
#define FIRMWARE_PATCH_VERSION 3
#define FIRMWARE_MINOR_VERSION 4
#define FIRMWARE_PATCH_VERSION 4
#define DEVICE_PROTOCOL_MAJOR_VERSION 4
#define DEVICE_PROTOCOL_MINOR_VERSION 5
#define DEVICE_PROTOCOL_MINOR_VERSION 4
#define DEVICE_PROTOCOL_PATCH_VERSION 0
#define MODULE_PROTOCOL_MAJOR_VERSION 4