53 Commits

Author SHA1 Message Date
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
László Monda
3196abe574 Bump firmware version to 8.4.5, update changelog, package.json and versions.h 2018-08-21 21:56:41 +02:00
László Monda
5f0bae1840 Merge branch 'layer-cache' 2018-08-21 16:11:07 +02:00
László Monda
c3a38c8b59 Split the point to point that features Agent installation and running the external tool. 2018-08-21 04:21:06 +02:00
László Monda
1f9d31cad4 Update build instructions. 2018-08-21 04:18:54 +02:00
László Monda
b89de6655e Upgrade to the latest MCUXpresso IDE. 2018-08-21 03:50:30 +02:00
Eric Tang
4a1b747197 Implement a layer cache 2018-08-19 11:28:28 -07:00
László Monda
eca87d2f62 Merge pull request #159 from UltimateHackingKeyboard/suppress-keys
Suppress pressed keys when the layer or keymap changes
2018-08-19 05:00:10 +02:00
Eric Tang
2e2b9d08a9 Suppress pressed keys when the layer or keymap changes 2018-08-18 19:52:07 -07:00
László Monda
b4c2204e50 Bump firmware version to 8.4.4, update changelog, package.json and versions.h 2018-08-14 00:07:21 +02:00
László Monda
4c0546de6c Merge branch 'master' of github.com:UltimateHackingKeyboard/firmware 2018-08-13 23:08:53 +02:00
László Monda
bea4c34a51 Merge pull request #154 from UltimateHackingKeyboard/secondary-role
Ensure that secondary roles are triggered consistently
2018-08-13 23:03:48 +02:00
László Monda
bdc6232780 Merge branch 'master' of github.com:UltimateHackingKeyboard/firmware 2018-08-13 22:38:41 +02:00
László Monda
1d2d1c5049 Merge pull request #153 from UltimateHackingKeyboard/wake
Don't wake the host if a key is held down through the beginning of sleep
2018-08-13 21:42:46 +02:00
Eric Tang
67f07abd0d Ensure that secondary roles are triggered consistently 2018-08-13 12:30:36 -07:00
Eric Tang
4bfcd6e02c Don't wake the host if a key is held down through the beginning of sleep 2018-08-13 12:07:08 -07:00
László Monda
7eb190489b Bump firmware version to 8.4.3, update changelog, package.json, versions.h 2018-08-12 10:41:43 +02:00
László Monda
640c034111 Compensate "double tap to lock layer" timeouts for the timer fix to make them as long as before 8.3.3 2018-08-11 01:53:45 +02:00
László Monda
a6f12848ed Add timer related changelog entry. 2018-08-11 01:48:44 +02:00
László Monda
47f6a27e48 Move left/src/init_clock.[ch] to shared/slave 2018-08-06 00:16:26 +02:00
László Monda
9cc383a91d Delete config.h 2018-08-05 22:49:31 +02:00
László Monda
a441cdf5d2 Delete debug_over_spi.[ch] 2018-08-05 22:47:55 +02:00
László Monda
8297dd5c48 Don't include the debug over SPI code from any file. 2018-08-05 22:44:11 +02:00
László Monda
225a481938 Fix coding style. 2018-08-05 22:31:48 +02:00
László Monda
5572952dc8 Use one liner comment style. 2018-08-05 22:28:30 +02:00
László Monda
7d011237f8 Always use the I2C watchdog for the left half. Remove I2C_WATCHDOG and relevant preprocessor stuff. 2018-08-05 22:24:34 +02:00
László Monda
1a47c6e629 Minor MCUXpresso .cproject file modification. 2018-08-05 22:22:21 +02:00
László Monda
047a232e7e Update .cproject file to make MCUXpresso IDE not pop up the warning regarding SDK version. 2018-08-04 23:48:11 +02:00
László Monda
28f5999cbb Bump firmware version to 8.4.2, update changelog and versions.h 2018-08-02 13:00:31 +02:00
László Monda
fe7505a2df Merge branch 'master' of github.com:UltimateHackingKeyboard/firmware 2018-08-02 12:51:22 +02:00
László Monda
b6ac16074c Merge pull request #149 from UltimateHackingKeyboard/secondary-role
Fix various secondary role bugs
2018-08-02 03:41:25 +02:00
Eric Tang
0bf205c5d2 Keep sticky modifiers active when modifier-only keys are pressed 2018-08-01 18:12:12 -07:00
Eric Tang
e4a99a9400 Make sticky modifiers work consistently 2018-08-01 16:36:29 -07:00
Eric Tang
1e9b5833eb Correctly handle keypresses which triggers a secondary role 2018-08-01 15:53:55 -07:00
Eric Tang
79b052fca7 Remove redundant conditions 2018-07-31 16:12:51 -07:00
László Monda
baee0b5682 Bump firmware version to 8.4.1, update changelog, package.json, versions.h 2018-07-31 23:57:33 +02:00
László Monda
6153d54f59 Merge pull request #144 from UltimateHackingKeyboard/sleep-wake
Make some improvements to the sleep/wake code
2018-07-26 22:47:40 +02:00
Eric Tang
0a6ebe2903 Remove the old code for detecting new keypresses 2018-07-25 15:16:15 -07:00
Eric Tang
2d7cd68459 Make some improvements to the sleep/wake code 2018-07-22 13:13:29 -07:00
31 changed files with 248 additions and 319 deletions

View File

@@ -5,6 +5,49 @@ 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.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
- Don't wake the host if a key is held down through the beginning of sleep.
- Ensure that secondary roles are triggered consistently.
## [8.4.3] - 2018-08-12
Device Protocol: 4.4.0 | Module Protocol: 4.0.0 | User Config: 4.1.0 | Hardware Config: 1.0.0
- Compensate "double tap to lock layer" timeouts for the timer fix to make them as long as before 8.3.3
## [8.4.2] - 2018-08-02
Device Protocol: 4.4.0 | Module Protocol: 4.0.0 | User Config: 4.1.0 | Hardware Config: 1.0.0
- Fix various bugs related to secondary role handling and sticky modifier states.
## [8.4.1] - 2018-07-31
Device Protocol: 4.4.0 | Module Protocol: 4.0.0 | User Config: 4.1.0 | Hardware Config: 1.0.0
- Make some improvements to the sleep/wake code.
## [8.4.0] - 2018-07-24
Device Protocol: 4.**4.0** | Module Protocol: 4.0.0 | User Config: 4.1.0 | Hardware Config: 1.0.0
@@ -20,6 +63,7 @@ Device Protocol: 4.**4.0** | Module Protocol: 4.0.0 | User Config: 4.1.0 | Hardw
Device Protocol: 4.3.1 | Module Protocol: 4.0.0 | User Config: 4.1.0 | Hardware Config: 1.0.0
- Implement the macro engine.
- Fix the timer which makes it tick twice as fast as before.
- Fix the nondeterministic bug that made USB hang.
- Restore the Windows related commits of firmware 8.3.1 because the USB hang bug has been fixed.
- Restore debouncing to 100ms until it gets really fixed.

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

@@ -12,19 +12,15 @@ 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.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).
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).
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.
## Building and flashing the firmware
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.
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.
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 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.
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*.
## Contributing

View File

@@ -44,7 +44,8 @@ SOURCE = $(wildcard src/*.c) \
../lib/KSDK_2.0_MKL03Z8xxx4/devices/MKL03Z4/drivers/fsl_lptmr.c \
../lib/KSDK_2.0_MKL03Z8xxx4/devices/MKL03Z4/drivers/fsl_spi.c \
../lib/KSDK_2.0_MKL03Z8xxx4/devices/MKL03Z4/drivers/fsl_tpm.c \
$(wildcard ../shared/*.c)
$(wildcard ../shared/*.c) \
$(wildcard ../shared/slave/*.c)
# Header files.
IPATH = src \

View File

@@ -1,13 +0,0 @@
#ifndef __CONFIG_H__
#define __CONFIG_H__
// Macros:
#define I2C_WATCHDOG_VALUE_REINIT 1
#define I2C_WATCHDOG_VALUE_REBOOT 2
// #define DEBUG_OVER_SPI
#define I2C_WATCHDOG I2C_WATCHDOG_VALUE_REINIT
// #define I2C_WATCHDOG I2C_WATCHDOG_VALUE_REBOOT
#endif

View File

@@ -1,56 +0,0 @@
#ifdef DEBUG_OVER_SPI
#include "debug_over_spi.h"
#include "config.h"
#include "fsl_gpio.h"
#define EXAMPLE_SPI_MASTER (SPI0)
#define EXAMPLE_SPI_MASTER_SOURCE_CLOCK (kCLOCK_BusClk)
#define BUFFER_SIZE (64)
static uint8_t srcBuff[BUFFER_SIZE];
static spi_transfer_t xfer = {0};
static spi_master_config_t userConfig;
spi_master_handle_t handle;
static volatile bool masterFinished = true;
static void masterCallback(SPI_Type *base, spi_master_handle_t *masterHandle, status_t status, void *userData)
{
masterFinished = true;
}
void DebugOverSpi_Init(void)
{
CLOCK_EnableClock(DEBUG_OVER_SPI_MOSI_CLOCK);
CLOCK_EnableClock(DEBUG_OVER_SPI_SCK_CLOCK);
PORT_SetPinMux(DEBUG_OVER_SPI_MOSI_PORT, DEBUG_OVER_SPI_MOSI_PIN, kPORT_MuxAlt3);
PORT_SetPinMux(DEBUG_OVER_SPI_SCK_PORT, DEBUG_OVER_SPI_SCK_PIN, kPORT_MuxAlt3);
GPIO_PinInit(DEBUG_OVER_SPI_MOSI_GPIO, DEBUG_OVER_SPI_MOSI_PIN, &(gpio_pin_config_t){kGPIO_DigitalOutput, 0});
GPIO_PinInit(DEBUG_OVER_SPI_SCK_GPIO, DEBUG_OVER_SPI_SCK_PIN, &(gpio_pin_config_t){kGPIO_DigitalOutput, 0});
GPIO_SetPinsOutput(DEBUG_OVER_SPI_MOSI_GPIO, 1U << DEBUG_OVER_SPI_MOSI_PIN);
GPIO_SetPinsOutput(DEBUG_OVER_SPI_SCK_GPIO, 1U << DEBUG_OVER_SPI_SCK_PIN);
SPI_MasterGetDefaultConfig(&userConfig);
uint32_t srcFreq = CLOCK_GetFreq(EXAMPLE_SPI_MASTER_SOURCE_CLOCK);
SPI_MasterInit(EXAMPLE_SPI_MASTER, &userConfig, srcFreq);
SPI_MasterTransferCreateHandle(EXAMPLE_SPI_MASTER, &handle, masterCallback, NULL);
}
void DebugOverSpi_Send(uint8_t *tx, uint8_t len)
{
if (masterFinished) {
masterFinished = false;
memcpy(srcBuff, tx, MIN(BUFFER_SIZE, len));
xfer.txData = srcBuff;
xfer.dataSize = len;
SPI_MasterTransferNonBlocking(EXAMPLE_SPI_MASTER, &handle, &xfer);
}
}
#endif

View File

@@ -1,34 +0,0 @@
#ifdef DEBUG_OVER_SPI
#ifndef __DEBUG_OVER_SPI_H__
#define __DEBUG_OVER_SPI_H__
// Includes:
#include "fsl_common.h"
#include "fsl_port.h"
#include "fsl_spi.h"
// Macros:
#define DEBUG_OVER_SPI_MOSI_PORT PORTA
#define DEBUG_OVER_SPI_MOSI_GPIO GPIOA
#define DEBUG_OVER_SPI_MOSI_CLOCK kCLOCK_PortA
#define DEBUG_OVER_SPI_MOSI_PIN 7
#define DEBUG_OVER_SPI_SCK_PORT PORTB
#define DEBUG_OVER_SPI_SCK_GPIO GPIOB
#define DEBUG_OVER_SPI_SCK_CLOCK kCLOCK_PortB
#define DEBUG_OVER_SPI_SCK_PIN 0
// Functions:
void DebugOverSpi_Init(void);
void DebugOverSpi_Send(uint8_t *tx, uint8_t len);
#endif
#else
#define DebugOverSpi_Init()
#define DebugOverSpi_Send(tx, len)
#endif

View File

@@ -3,40 +3,31 @@
#include "i2c_watchdog.h"
#include "test_led.h"
#include "init_peripherals.h"
#include "config.h"
/* NOTE: Because of a bug in the ROM bootloader of the KL03Z, the watchdog timer is disabled and cannot be re-enabled.
* See https://community.nxp.com/thread/457893
* Therefore the hardware watchdog timer cannot be used without an extra way to enter bootloader or application mode.
*/
#ifdef I2C_WATCHDOG
static uint32_t prevWatchdogCounter = 0;
static uint32_t I2cWatchdog_RecoveryCounter; /* counter for how many times we had to recover and restart */
// NOTE: Because of a bug in the ROM bootloader of the KL03Z, the watchdog timer is disabled and cannot be re-enabled.
// See https://community.nxp.com/thread/457893
// Therefore the hardware watchdog timer cannot be used without an extra way to enter bootloader or application mode.
static uint32_t prevWatchdogCounter = 0;
static uint32_t I2cWatchdog_RecoveryCounter; // Counter for how many times we had to recover and restart
void RunWatchdog(void)
{
static volatile uint32_t I2cWatchdog_WatchCounter = 0; /* counter for timer */
static int cntr = 0;
static volatile uint32_t I2cWatchdog_WatchCounter = 0; // Counter for timer
static int counter = 0;
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;
counter++;
if (counter == 100) { // We get called from KEY_SCANNER_HANDLER() which runs at 1ms, thus scaling down by 100 here to get 100 ms period
counter=0;
TestLed_Toggle();
I2cWatchdog_WatchCounter++;
if (I2cWatchdog_WatchCounter>10) { /* do not check within the first 1000 ms, as I2C might not be running yet */
if (I2cWatchdog_WatchCounter > 10) { // Do not check within the first 1000 ms, as I2C might not be running yet
if (I2C_Watchdog == prevWatchdogCounter) { // Restart I2C if there hasn't been any interrupt during 100 ms. I2C_Watchdog gets incremented for every I2C transaction
I2cWatchdog_RecoveryCounter++;
#if I2C_WATCHDOG == I2C_WATCHDOG_VALUE_REBOOT
NVIC_SystemReset();
#endif
#if I2C_WATCHDOG == I2C_WATCHDOG_VALUE_REINIT
I2C_SlaveDeinit(I2C_BUS_BASEADDR);
initI2c();
#endif
}
}
prevWatchdogCounter = I2C_Watchdog; /* remember previous counter */
prevWatchdogCounter = I2C_Watchdog;
}
}
#endif

View File

@@ -9,7 +9,6 @@
#include "led_pwm.h"
#include "slave_protocol_handler.h"
#include "i2c_watchdog.h"
#include "debug_over_spi.h"
#include "main.h"
i2c_slave_config_t slaveConfig;
@@ -23,7 +22,6 @@ static void i2cSlaveCallback(I2C_Type *base, i2c_slave_transfer_t *xfer, void *u
{
dosBuffer[0] = xfer->event;
dosBuffer[1] = userData;
DebugOverSpi_Send(dosBuffer, 2);
switch (xfer->event) {
case kI2C_SlaveTransmitEvent:
@@ -86,6 +84,5 @@ void InitPeripherals(void)
InitLedDriver();
TestLed_Init();
LedPwm_Init();
DebugOverSpi_Init();
initI2c();
}

View File

@@ -1,6 +1,5 @@
#include "fsl_lptmr.h"
#include "key_scanner.h"
#include "config.h"
#include "i2c_watchdog.h"
void KEY_SCANNER_HANDLER(void)

View File

@@ -1,9 +1,8 @@
#include "main.h"
#include "init_clock.h"
#include "slave/init_clock.h"
#include "init_peripherals.h"
#include "bootloader.h"
#include <stdio.h>
#include "config.h"
#include "key_scanner.h"
DEFINE_BOOTLOADER_CONFIG_AREA(I2C_ADDRESS_LEFT_KEYBOARD_HALF_BOOTLOADER)
@@ -15,11 +14,7 @@ key_matrix_t keyMatrix = {
{PORTB, GPIOB, kCLOCK_PortB, 11},
{PORTA, GPIOA, kCLOCK_PortA, 6},
{PORTA, GPIOA, kCLOCK_PortA, 8},
#ifdef DEBUG_OVER_SPI
{PORTA, GPIOA, kCLOCK_PortA, 8},
#else
{PORTB, GPIOB, kCLOCK_PortB, 0},
#endif
{PORTB, GPIOB, kCLOCK_PortB, 6},
{PORTA, GPIOA, kCLOCK_PortA, 3},
{PORTA, GPIOA, kCLOCK_PortA, 12}
@@ -28,11 +23,7 @@ key_matrix_t keyMatrix = {
{PORTB, GPIOB, kCLOCK_PortB, 7},
{PORTB, GPIOB, kCLOCK_PortB, 10},
{PORTA, GPIOA, kCLOCK_PortA, 5},
#ifdef DEBUG_OVER_SPI
{PORTA, GPIOA, kCLOCK_PortA, 5},
#else
{PORTA, GPIOA, kCLOCK_PortA, 7},
#endif
{PORTA, GPIOA, kCLOCK_PortA, 4}
}
};

View File

@@ -460,73 +460,73 @@
<storageModule moduleId="com.crt.config">
<projectStorage>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;TargetConfig&gt;
&lt;Properties property_3="NXP" property_4="MK22FN512xxx12" property_count="5" version="70200"/&gt;
&lt;Properties property_3="NXP" property_4="MK22FN512xxx12" property_count="5" version="100200"/&gt;
&lt;infoList vendor="NXP"&gt;&lt;info chip="MK22FN512xxx12" name="MK22FN512xxx12"&gt;&lt;chip&gt;&lt;name&gt;MK22FN512xxx12&lt;/name&gt;
&lt;family&gt;K2x&lt;/family&gt;
&lt;vendor&gt;NXP&lt;/vendor&gt;
&lt;memory can_program="true" id="Flash" is_ro="true" size="512" type="Flash"/&gt;
&lt;memory id="RAM" size="128" type="RAM"/&gt;
&lt;memoryInstance derived_from="Flash" driver="FTFA_2K.cfx" id="PROGRAM_FLASH" location="0x0" size="0x80000"/&gt;
&lt;memoryInstance derived_from="RAM" id="SRAM_UPPER" location="0x20000000" size="0x10000"/&gt;
&lt;memoryInstance derived_from="RAM" id="SRAM_LOWER" location="0x1fff0000" size="0x10000"/&gt;
&lt;peripheralInstance derived_from="FTFA_FlashConfig" id="FTFA_FlashConfig" location="0x400"/&gt;
&lt;peripheralInstance derived_from="DMA" id="DMA" location="0x40008000"/&gt;
&lt;peripheralInstance derived_from="FB" id="FB" location="0x4000C000"/&gt;
&lt;peripheralInstance derived_from="FMC" id="FMC" location="0x4001F000"/&gt;
&lt;peripheralInstance derived_from="FTFA" id="FTFA" location="0x40020000"/&gt;
&lt;peripheralInstance derived_from="DMAMUX" id="DMAMUX" location="0x40021000"/&gt;
&lt;peripheralInstance derived_from="FTM0" id="FTM0" location="0x40038000"/&gt;
&lt;peripheralInstance derived_from="FTM1" id="FTM1" location="0x40039000"/&gt;
&lt;peripheralInstance derived_from="FTM2" id="FTM2" location="0x4003A000"/&gt;
&lt;peripheralInstance derived_from="FTM3" id="FTM3" location="0x40026000"/&gt;
&lt;peripheralInstance derived_from="ADC0" id="ADC0" location="0x4003B000"/&gt;
&lt;peripheralInstance derived_from="ADC1" id="ADC1" location="0x40027000"/&gt;
&lt;peripheralInstance derived_from="DAC0" id="DAC0" location="0x4003F000"/&gt;
&lt;peripheralInstance derived_from="DAC1" id="DAC1" location="0x40028000"/&gt;
&lt;peripheralInstance derived_from="RNG" id="RNG" location="0x40029000"/&gt;
&lt;peripheralInstance derived_from="LPUART0" id="LPUART0" location="0x4002A000"/&gt;
&lt;peripheralInstance derived_from="SPI0" id="SPI0" location="0x4002C000"/&gt;
&lt;peripheralInstance derived_from="SPI1" id="SPI1" location="0x4002D000"/&gt;
&lt;peripheralInstance derived_from="I2S0" id="I2S0" location="0x4002F000"/&gt;
&lt;peripheralInstance derived_from="CRC" id="CRC" location="0x40032000"/&gt;
&lt;peripheralInstance derived_from="PDB0" id="PDB0" location="0x40036000"/&gt;
&lt;peripheralInstance derived_from="PIT" id="PIT" location="0x40037000"/&gt;
&lt;peripheralInstance derived_from="RTC" id="RTC" location="0x4003D000"/&gt;
&lt;peripheralInstance derived_from="RFVBAT" id="RFVBAT" location="0x4003E000"/&gt;
&lt;peripheralInstance derived_from="LPTMR0" id="LPTMR0" location="0x40040000"/&gt;
&lt;peripheralInstance derived_from="RFSYS" id="RFSYS" location="0x40041000"/&gt;
&lt;peripheralInstance derived_from="SIM" id="SIM" location="0x40047000"/&gt;
&lt;peripheralInstance derived_from="PORTA" id="PORTA" location="0x40049000"/&gt;
&lt;peripheralInstance derived_from="PORTB" id="PORTB" location="0x4004A000"/&gt;
&lt;peripheralInstance derived_from="PORTC" id="PORTC" location="0x4004B000"/&gt;
&lt;peripheralInstance derived_from="PORTD" id="PORTD" location="0x4004C000"/&gt;
&lt;peripheralInstance derived_from="PORTE" id="PORTE" location="0x4004D000"/&gt;
&lt;peripheralInstance derived_from="WDOG" id="WDOG" location="0x40052000"/&gt;
&lt;peripheralInstance derived_from="EWM" id="EWM" location="0x40061000"/&gt;
&lt;peripheralInstance derived_from="MCG" id="MCG" location="0x40064000"/&gt;
&lt;peripheralInstance derived_from="OSC" id="OSC" location="0x40065000"/&gt;
&lt;peripheralInstance derived_from="I2C0" id="I2C0" location="0x40066000"/&gt;
&lt;peripheralInstance derived_from="I2C1" id="I2C1" location="0x40067000"/&gt;
&lt;peripheralInstance derived_from="UART0" id="UART0" location="0x4006A000"/&gt;
&lt;peripheralInstance derived_from="UART1" id="UART1" location="0x4006B000"/&gt;
&lt;peripheralInstance derived_from="UART2" id="UART2" location="0x4006C000"/&gt;
&lt;peripheralInstance derived_from="USB0" id="USB0" location="0x40072000"/&gt;
&lt;peripheralInstance derived_from="CMP0" id="CMP0" location="0x40073000"/&gt;
&lt;peripheralInstance derived_from="CMP1" id="CMP1" location="0x40073008"/&gt;
&lt;peripheralInstance derived_from="VREF" id="VREF" location="0x40074000"/&gt;
&lt;peripheralInstance derived_from="LLWU" id="LLWU" location="0x4007C000"/&gt;
&lt;peripheralInstance derived_from="PMC" id="PMC" location="0x4007D000"/&gt;
&lt;peripheralInstance derived_from="SMC" id="SMC" location="0x4007E000"/&gt;
&lt;peripheralInstance derived_from="RCM" id="RCM" location="0x4007F000"/&gt;
&lt;peripheralInstance derived_from="GPIOA" id="GPIOA" location="0x400FF000"/&gt;
&lt;peripheralInstance derived_from="GPIOB" id="GPIOB" location="0x400FF040"/&gt;
&lt;peripheralInstance derived_from="GPIOC" id="GPIOC" location="0x400FF080"/&gt;
&lt;peripheralInstance derived_from="GPIOD" id="GPIOD" location="0x400FF0C0"/&gt;
&lt;peripheralInstance derived_from="GPIOE" id="GPIOE" location="0x400FF100"/&gt;
&lt;peripheralInstance derived_from="SystemControl" id="SystemControl" location="0xE000E000"/&gt;
&lt;peripheralInstance derived_from="SysTick" id="SysTick" location="0xE000E010"/&gt;
&lt;peripheralInstance derived_from="NVIC" id="NVIC" location="0xE000E100"/&gt;
&lt;peripheralInstance derived_from="MCM" id="MCM" location="0xE0080000"/&gt;
&lt;memory can_program="true" id="Flash" is_ro="true" size="0" type="Flash"/&gt;
&lt;memory id="RAM" size="0" type="RAM"/&gt;
&lt;memoryInstance derived_from="Flash" driver="FTFA_2K.cfx" id="PROGRAM_FLASH" location="0x00000000" size="0x00080000"/&gt;
&lt;memoryInstance derived_from="RAM" id="SRAM_UPPER" location="0x20000000" size="0x00010000"/&gt;
&lt;memoryInstance derived_from="RAM" id="SRAM_LOWER" location="0x1fff0000" size="0x00010000"/&gt;
&lt;peripheralInstance derived_from="FTFA-FlashConfig" determined="infoFile" id="FTFA-FlashConfig" location="0x400"/&gt;
&lt;peripheralInstance derived_from="DMA" determined="infoFile" id="DMA" location="0x40008000"/&gt;
&lt;peripheralInstance derived_from="FB" determined="infoFile" id="FB" location="0x4000C000"/&gt;
&lt;peripheralInstance derived_from="FMC" determined="infoFile" id="FMC" location="0x4001F000"/&gt;
&lt;peripheralInstance derived_from="FTFA" determined="infoFile" id="FTFA" location="0x40020000"/&gt;
&lt;peripheralInstance derived_from="DMAMUX" determined="infoFile" id="DMAMUX" location="0x40021000"/&gt;
&lt;peripheralInstance derived_from="FTM0" determined="infoFile" id="FTM0" location="0x40038000"/&gt;
&lt;peripheralInstance derived_from="FTM1" determined="infoFile" id="FTM1" location="0x40039000"/&gt;
&lt;peripheralInstance derived_from="FTM2" determined="infoFile" id="FTM2" location="0x4003A000"/&gt;
&lt;peripheralInstance derived_from="FTM3" determined="infoFile" id="FTM3" location="0x40026000"/&gt;
&lt;peripheralInstance derived_from="ADC0" determined="infoFile" id="ADC0" location="0x4003B000"/&gt;
&lt;peripheralInstance derived_from="ADC1" determined="infoFile" id="ADC1" location="0x40027000"/&gt;
&lt;peripheralInstance derived_from="DAC0" determined="infoFile" id="DAC0" location="0x4003F000"/&gt;
&lt;peripheralInstance derived_from="DAC1" determined="infoFile" id="DAC1" location="0x40028000"/&gt;
&lt;peripheralInstance derived_from="RNG" determined="infoFile" id="RNG" location="0x40029000"/&gt;
&lt;peripheralInstance derived_from="LPUART0" determined="infoFile" id="LPUART0" location="0x4002A000"/&gt;
&lt;peripheralInstance derived_from="SPI0" determined="infoFile" id="SPI0" location="0x4002C000"/&gt;
&lt;peripheralInstance derived_from="SPI1" determined="infoFile" id="SPI1" location="0x4002D000"/&gt;
&lt;peripheralInstance derived_from="I2S0" determined="infoFile" id="I2S0" location="0x4002F000"/&gt;
&lt;peripheralInstance derived_from="CRC" determined="infoFile" id="CRC" location="0x40032000"/&gt;
&lt;peripheralInstance derived_from="PDB0" determined="infoFile" id="PDB0" location="0x40036000"/&gt;
&lt;peripheralInstance derived_from="PIT" determined="infoFile" id="PIT" location="0x40037000"/&gt;
&lt;peripheralInstance derived_from="RTC" determined="infoFile" id="RTC" location="0x4003D000"/&gt;
&lt;peripheralInstance derived_from="RFVBAT" determined="infoFile" id="RFVBAT" location="0x4003E000"/&gt;
&lt;peripheralInstance derived_from="LPTMR0" determined="infoFile" id="LPTMR0" location="0x40040000"/&gt;
&lt;peripheralInstance derived_from="RFSYS" determined="infoFile" id="RFSYS" location="0x40041000"/&gt;
&lt;peripheralInstance derived_from="SIM" determined="infoFile" id="SIM" location="0x40047000"/&gt;
&lt;peripheralInstance derived_from="PORTA" determined="infoFile" id="PORTA" location="0x40049000"/&gt;
&lt;peripheralInstance derived_from="PORTB" determined="infoFile" id="PORTB" location="0x4004A000"/&gt;
&lt;peripheralInstance derived_from="PORTC" determined="infoFile" id="PORTC" location="0x4004B000"/&gt;
&lt;peripheralInstance derived_from="PORTD" determined="infoFile" id="PORTD" location="0x4004C000"/&gt;
&lt;peripheralInstance derived_from="PORTE" determined="infoFile" id="PORTE" location="0x4004D000"/&gt;
&lt;peripheralInstance derived_from="WDOG" determined="infoFile" id="WDOG" location="0x40052000"/&gt;
&lt;peripheralInstance derived_from="EWM" determined="infoFile" id="EWM" location="0x40061000"/&gt;
&lt;peripheralInstance derived_from="MCG" determined="infoFile" id="MCG" location="0x40064000"/&gt;
&lt;peripheralInstance derived_from="OSC" determined="infoFile" id="OSC" location="0x40065000"/&gt;
&lt;peripheralInstance derived_from="I2C0" determined="infoFile" id="I2C0" location="0x40066000"/&gt;
&lt;peripheralInstance derived_from="I2C1" determined="infoFile" id="I2C1" location="0x40067000"/&gt;
&lt;peripheralInstance derived_from="UART0" determined="infoFile" id="UART0" location="0x4006A000"/&gt;
&lt;peripheralInstance derived_from="UART1" determined="infoFile" id="UART1" location="0x4006B000"/&gt;
&lt;peripheralInstance derived_from="UART2" determined="infoFile" id="UART2" location="0x4006C000"/&gt;
&lt;peripheralInstance derived_from="USB0" determined="infoFile" id="USB0" location="0x40072000"/&gt;
&lt;peripheralInstance derived_from="CMP0" determined="infoFile" id="CMP0" location="0x40073000"/&gt;
&lt;peripheralInstance derived_from="CMP1" determined="infoFile" id="CMP1" location="0x40073008"/&gt;
&lt;peripheralInstance derived_from="VREF" determined="infoFile" id="VREF" location="0x40074000"/&gt;
&lt;peripheralInstance derived_from="LLWU" determined="infoFile" id="LLWU" location="0x4007C000"/&gt;
&lt;peripheralInstance derived_from="PMC" determined="infoFile" id="PMC" location="0x4007D000"/&gt;
&lt;peripheralInstance derived_from="SMC" determined="infoFile" id="SMC" location="0x4007E000"/&gt;
&lt;peripheralInstance derived_from="RCM" determined="infoFile" id="RCM" location="0x4007F000"/&gt;
&lt;peripheralInstance derived_from="GPIOA" determined="infoFile" id="GPIOA" location="0x400FF000"/&gt;
&lt;peripheralInstance derived_from="GPIOB" determined="infoFile" id="GPIOB" location="0x400FF040"/&gt;
&lt;peripheralInstance derived_from="GPIOC" determined="infoFile" id="GPIOC" location="0x400FF080"/&gt;
&lt;peripheralInstance derived_from="GPIOD" determined="infoFile" id="GPIOD" location="0x400FF0C0"/&gt;
&lt;peripheralInstance derived_from="GPIOE" determined="infoFile" id="GPIOE" location="0x400FF100"/&gt;
&lt;peripheralInstance derived_from="SystemControl" determined="infoFile" id="SystemControl" location="0xE000E000"/&gt;
&lt;peripheralInstance derived_from="SysTick" determined="infoFile" id="SysTick" location="0xE000E010"/&gt;
&lt;peripheralInstance derived_from="NVIC" determined="infoFile" id="NVIC" location="0xE000E100"/&gt;
&lt;peripheralInstance derived_from="MCM" determined="infoFile" id="MCM" location="0xE0080000"/&gt;
&lt;/chip&gt;
&lt;processor&gt;&lt;name gcc_name="cortex-m4"&gt;Cortex-M4&lt;/name&gt;
&lt;family&gt;Cortex-M&lt;/family&gt;
@@ -538,6 +538,6 @@
</storageModule>
<storageModule moduleId="com.nxp.mcuxpresso.core.datamodels">
<sdkName>SDK_2.x_MK22FN512xxx12</sdkName>
<sdkVersion>2.3.1</sdkVersion>
<sdkVersion>2.2.0</sdkVersion>
</storageModule>
</cproject>

View File

@@ -5,6 +5,7 @@
#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] = {
{
@@ -24,6 +25,7 @@ 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

@@ -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) {
if (keyState->current && !keyState->suppressed) {
key_action_t action = CurrentKeymap[LayerId_Base][slotId][keyId];
if (action.type == KeyActionType_SwitchLayer) {
if (action.switchLayer.mode != SwitchLayerMode_Toggle) {

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

@@ -163,21 +163,28 @@ static usb_device_class_config_list_struct_t UsbDeviceCompositeConfigList = {
}
}};
bool IsHostSleeping = false;
volatile bool SleepModeActive = true;
static volatile bool wakeUpHostAllowed;
static void suspendHost(void) {
IsHostSleeping = true;
static void suspendUhk(void) {
SleepModeActive = true;
LedSlaveDriver_DisableLeds();
}
void WakeUpHost(bool sendResume) {
if (sendResume) { // The device should wake up the host.
static void wakeUpUhk(void) {
SleepModeActive = false;
LedSlaveDriver_UpdateLeds();
}
void WakeUpHost(void) {
if (!wakeUpHostAllowed) {
return;
}
// Send resume signal - this will call USB_DeviceKhciControl(khciHandle, kUSB_DeviceControlResume, NULL);
USB_DeviceSetStatus(UsbCompositeDevice.deviceHandle, kUSB_DeviceStatusBus, NULL);
while (SleepModeActive) {
;
}
IsHostSleeping = false;
LedSlaveDriver_UpdateLeds();
}
static usb_status_t usbDeviceCallback(usb_device_handle handle, uint32_t event, void *param)
@@ -190,10 +197,6 @@ static usb_status_t usbDeviceCallback(usb_device_handle handle, uint32_t event,
return status;
}
if (IsHostSleeping) {
WakeUpHost(false); // Wake up the keyboard if there is any activity on the bus.
}
switch (event) {
case kUSB_DeviceEventBusReset:
UsbCompositeDevice.attach = 0;
@@ -201,17 +204,17 @@ static usb_status_t usbDeviceCallback(usb_device_handle handle, uint32_t event,
break;
case kUSB_DeviceEventSuspend:
if (UsbCompositeDevice.attach) {
suspendHost(); // The host sends this event when it goes to sleep, so turn off all the LEDs.
suspendUhk(); // The host sends this event when it goes to sleep, so turn off all the LEDs.
status = kStatus_USB_Success;
}
break;
case kUSB_DeviceEventResume:
// We will just wake up the host if there is any activity on the bus.
// The problem is that the host won't send a resume event when it boots, so the lights will never come back on.
wakeUpUhk();
status = kStatus_USB_Success;
break;
case kUSB_DeviceEventSetConfiguration:
UsbCompositeDevice.attach = 1;
wakeUpUhk();
UsbCompositeDevice.currentConfiguration = *temp8;
UsbGenericHidSetConfiguration(UsbCompositeDevice.genericHidHandle, *temp8);
UsbBasicKeyboardSetConfiguration(UsbCompositeDevice.basicKeyboardHandle, *temp8);
@@ -266,6 +269,10 @@ static usb_status_t usbDeviceCallback(usb_device_handle handle, uint32_t event,
case kUSB_DeviceEventGetHidPhysicalDescriptor:
status = USB_DeviceGetHidPhysicalDescriptor(handle, (usb_device_get_hid_physical_descriptor_struct_t *)param);
break;
case kUSB_DeviceEventSetRemoteWakeup:
wakeUpHostAllowed = *temp8;
status = kStatus_USB_Success;
break;
}
return status;

View File

@@ -28,12 +28,12 @@
// Variables:
extern bool IsHostSleeping;
extern volatile bool SleepModeActive;
extern usb_composite_device_t UsbCompositeDevice;
//Functions:
void InitUsb(void);
void WakeUpHost(bool sendResume);
void WakeUpHost(void);
#endif

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

@@ -20,11 +20,13 @@
static uint32_t mouseUsbReportUpdateTime = 0;
static uint32_t mouseElapsedTime;
uint16_t DoubleTapSwitchLayerTimeout = 150;
static uint16_t DoubleTapSwitchLayerReleaseTimeout = 100;
uint16_t DoubleTapSwitchLayerTimeout = 300;
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];
volatile uint8_t UsbReportUpdateSemaphore = 0;
@@ -206,15 +208,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)
{
@@ -225,17 +227,22 @@ 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;
}
}
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)
{
@@ -247,8 +254,13 @@ static void applyKeyAction(key_state_t *keyState, key_action_t *action)
switch (action->type) {
case KeyActionType_Keystroke:
if (action->keystroke.scancode) {
if (!keyState->previous) {
stickyModifiers = action->keystroke.modifiers;
}
} else {
ActiveUsbBasicKeyboardReport->modifiers |= action->keystroke.modifiers;
}
switch (action->keystroke.keystrokeType) {
case KeystrokeType_Basic:
if (basicScancodeIndex >= USB_BASIC_KEYBOARD_MAX_KEYS || action->keystroke.scancode == 0) {
@@ -271,6 +283,9 @@ static void applyKeyAction(key_state_t *keyState, key_action_t *action)
}
break;
case KeyActionType_Mouse:
if (!keyState->previous) {
stickyModifiers = 0;
}
activeMouseStates[action->mouseAction] = true;
break;
case KeyActionType_SwitchLayer:
@@ -278,26 +293,22 @@ static void applyKeyAction(key_state_t *keyState, key_action_t *action)
break;
case KeyActionType_SwitchKeymap:
if (!keyState->previous) {
stickyModifiers = 0;
secondaryRoleState = SecondaryRoleState_Released;
SwitchKeymapById(action->switchKeymap.keymapId);
}
break;
case KeyActionType_PlayMacro:
if (!keyState->previous) {
stickyModifiers = 0;
Macros_StartMacro(action->playMacro.macroId);
}
break;
}
}
static uint8_t secondaryRoleState = SecondaryRoleState_Released;
static uint8_t secondaryRoleSlotId;
static uint8_t secondaryRoleKeyId;
static secondary_role_t secondaryRole;
static void updateActiveUsbReports(void)
{
static uint8_t previousModifiers = 0;
if (MacroPlaying) {
Macros_ContinueMacro();
memcpy(ActiveUsbMouseReport, &MacroMouseReport, sizeof MacroMouseReport);
@@ -320,7 +331,12 @@ static void updateActiveUsbReports(void)
if (activeLayer == LayerId_Base) {
activeLayer = GetActiveLayer();
}
bool layerGotReleased = previousLayer != LayerId_Base && activeLayer == LayerId_Base;
bool layerChanged = previousLayer != activeLayer;
if (layerChanged) {
stickyModifiers = 0;
}
bool keymapChangedLastCycle = KeymapChanged;
KeymapChanged = false;
LedDisplay_SetLayer(activeLayer);
if (TestUsbStack) {
@@ -338,58 +354,64 @@ 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;
}
}
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 = &CurrentKeymap[activeLayer][slotId][keyId];
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;
}
if (keyState->current) {
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;
if (keyState->current && !keyState->previous) {
if (SleepModeActive) {
WakeUpHost();
}
if (secondaryRoleState == SecondaryRoleState_Pressed) {
// Trigger secondary role.
secondaryRoleState = SecondaryRoleState_Triggered;
keyState->current = false;
} else {
layerCache[slotId][keyId] = activeLayer;
}
}
if (action->type == KeyActionType_Keystroke && action->keystroke.secondaryRole) {
action = &CurrentKeymap[layerCache[slotId][keyId]][slotId][keyId];
if (keyState->current) {
if ((KeymapChanged || keymapChangedLastCycle) && keyState->previous) {
keyState->suppressed = true;
} else if (action->type == KeyActionType_Keystroke && action->keystroke.secondaryRole) {
// Press released secondary role key.
if (!keyState->previous && action->type == KeyActionType_Keystroke && action->keystroke.secondaryRole && secondaryRoleState == SecondaryRoleState_Released) {
if (!keyState->previous && secondaryRoleState == SecondaryRoleState_Released) {
secondaryRoleState = SecondaryRoleState_Pressed;
secondaryRoleSlotId = slotId;
secondaryRoleKeyId = keyId;
secondaryRole = action->keystroke.secondaryRole;
keyState->suppressed = true;
}
} else {
// Trigger secondary role.
if (!keyState->previous && secondaryRoleState == SecondaryRoleState_Pressed) {
secondaryRoleState = SecondaryRoleState_Triggered;
} else {
applyKeyAction(keyState, action);
}
}
} else {
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;
@@ -405,15 +427,12 @@ static void updateActiveUsbReports(void)
// When a layer switcher key gets pressed along with another key that produces some modifiers
// and the accomanying key gets released then keep the related modifiers active a long as the
// layer switcher key stays pressed. Useful for Alt+Tab keymappings and the like.
if (activeLayer != LayerId_Base && activeLayer == PreviousHeldLayer && basicScancodeIndex == 0) {
ActiveUsbBasicKeyboardReport->modifiers |= previousModifiers;
}
ActiveUsbBasicKeyboardReport->modifiers |= stickyModifiers;
if (secondaryRoleState == SecondaryRoleState_Triggered && IS_SECONDARY_ROLE_MODIFIER(secondaryRole)) {
ActiveUsbBasicKeyboardReport->modifiers |= SECONDARY_ROLE_MODIFIER_TO_HID_MODIFIER(secondaryRole);
}
previousModifiers = ActiveUsbBasicKeyboardReport->modifiers;
previousLayer = activeLayer;
}
@@ -425,19 +444,7 @@ void UpdateUsbReports(void)
KeyStates[SlotId_RightKeyboardHalf][keyId].current = RightKeyMatrix.keyStates[keyId];
}
if (IsHostSleeping) {
for (uint8_t slotId = 0; slotId < SLOT_COUNT; slotId++) {
for (uint8_t keyId = 0; keyId < MAX_KEY_COUNT_PER_MODULE; keyId++) {
if (KeyStates[slotId][keyId].current) {
WakeUpHost(true);
return;
}
}
}
return;
}
if (UsbReportUpdateSemaphore) {
if (UsbReportUpdateSemaphore && !SleepModeActive) {
return;
}
@@ -455,10 +462,6 @@ void UpdateUsbReports(void)
bool HasUsbSystemKeyboardReportChanged = memcmp(ActiveUsbSystemKeyboardReport, GetInactiveUsbSystemKeyboardReport(), sizeof(usb_system_keyboard_report_t)) != 0;
bool HasUsbMouseReportChanged = memcmp(ActiveUsbMouseReport, GetInactiveUsbMouseReport(), sizeof(usb_mouse_report_t)) != 0;
if (IsHostSleeping && (previousLayer != LayerId_Base || HasUsbBasicKeyboardReportChanged || HasUsbMediaKeyboardReportChanged || HasUsbSystemKeyboardReportChanged || HasUsbMouseReportChanged)) {
WakeUpHost(true); // Wake up the host if any key is pressed and the computer is sleeping.
}
if (HasUsbBasicKeyboardReportChanged) {
usb_status_t status = UsbBasicKeyboardAction();
if (status == kStatus_USB_Success) {

View File

@@ -72,6 +72,7 @@
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.0",
"deviceProtocolVersion": "4.4.0",
"firmwareVersion": "8.5.0",
"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_MINOR_VERSION 5
#define FIRMWARE_PATCH_VERSION 0
#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