Compare commits
179 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6f2b45c27c | ||
|
|
98f7d512de | ||
|
|
c5cf738fd0 | ||
|
|
af31ae210a | ||
|
|
44799995b9 | ||
|
|
3f5f83a19b | ||
|
|
bc4f35e578 | ||
|
|
e9309aab16 | ||
|
|
f004b84399 | ||
|
|
58f8120611 | ||
|
|
5b71fb7aaa | ||
|
|
9d0f41bf5e | ||
|
|
47a3a8ad80 | ||
|
|
b4908bf2ac | ||
|
|
846342e851 | ||
|
|
3196abe574 | ||
|
|
5f0bae1840 | ||
|
|
c3a38c8b59 | ||
|
|
1f9d31cad4 | ||
|
|
b89de6655e | ||
|
|
4a1b747197 | ||
|
|
eca87d2f62 | ||
|
|
2e2b9d08a9 | ||
|
|
b4c2204e50 | ||
|
|
4c0546de6c | ||
|
|
bea4c34a51 | ||
|
|
bdc6232780 | ||
|
|
1d2d1c5049 | ||
|
|
67f07abd0d | ||
|
|
4bfcd6e02c | ||
|
|
7eb190489b | ||
|
|
640c034111 | ||
|
|
a6f12848ed | ||
|
|
47f6a27e48 | ||
|
|
9cc383a91d | ||
|
|
a441cdf5d2 | ||
|
|
8297dd5c48 | ||
|
|
225a481938 | ||
|
|
5572952dc8 | ||
|
|
7d011237f8 | ||
|
|
1a47c6e629 | ||
|
|
047a232e7e | ||
|
|
28f5999cbb | ||
|
|
fe7505a2df | ||
|
|
b6ac16074c | ||
|
|
0bf205c5d2 | ||
|
|
e4a99a9400 | ||
|
|
1e9b5833eb | ||
|
|
79b052fca7 | ||
|
|
baee0b5682 | ||
|
|
6153d54f59 | ||
|
|
0a6ebe2903 | ||
|
|
1fbbeb0f33 | ||
|
|
456f0e9e58 | ||
|
|
0248a0e79f | ||
|
|
0e5ec29433 | ||
|
|
2d7cd68459 | ||
|
|
5ac10fabcb | ||
|
|
b11017609d | ||
|
|
c3a5d258e5 | ||
|
|
a2866feb77 | ||
|
|
8c50192d6c | ||
|
|
63d82d92db | ||
|
|
1bced1be13 | ||
|
|
86196d438c | ||
|
|
d722b3d173 | ||
|
|
2ef5c49090 | ||
|
|
5a137392ee | ||
|
|
27d12ea31f | ||
|
|
9ba09ec8eb | ||
|
|
014addd777 | ||
|
|
4562a17155 | ||
|
|
950843ca2c | ||
|
|
9600f46f83 | ||
|
|
ef7589d83a | ||
|
|
84f48ed055 | ||
|
|
ebef301e27 | ||
|
|
5b8b8d93e4 | ||
|
|
d48049535e | ||
|
|
5bd479ab8e | ||
|
|
372151848a | ||
|
|
5b32c0da43 | ||
|
|
edf34de4b5 | ||
|
|
8c7eb079ec | ||
|
|
6612f7cced | ||
|
|
7606f311c8 | ||
|
|
9fe73233af | ||
|
|
cba1ef97b6 | ||
|
|
c69f664e85 | ||
|
|
6c895988de | ||
|
|
f16a004583 | ||
|
|
c870f335a7 | ||
|
|
b6f59563c7 | ||
|
|
409bd01af6 | ||
|
|
b9b5eb2c76 | ||
|
|
11a8ffbaf5 | ||
|
|
9938f14d20 | ||
|
|
217259ba63 | ||
|
|
e5afa33b79 | ||
|
|
d3dfc9bd2c | ||
|
|
8f6251bc4d | ||
|
|
b93f211502 | ||
|
|
69411e53e9 | ||
|
|
39819e6058 | ||
|
|
bd97bba4b5 | ||
|
|
4214f3e0b6 | ||
|
|
6eceb6ad30 | ||
|
|
994e2f6b79 | ||
|
|
baa5e8f037 | ||
|
|
cbd5f1b500 | ||
|
|
c1dc4be8c8 | ||
|
|
1bd8c7dca8 | ||
|
|
d72ea4dde5 | ||
|
|
5d621880ec | ||
|
|
5c3e2966c4 | ||
|
|
d21fe30139 | ||
|
|
224d9eae42 | ||
|
|
8c02f3db53 | ||
|
|
02bbeb7177 | ||
|
|
cdfabaec42 | ||
|
|
0e9525ce9a | ||
|
|
633a6cec77 | ||
|
|
d35a7cc644 | ||
|
|
76a91c010b | ||
|
|
54b0a595bc | ||
|
|
4b9aa0860c | ||
|
|
df8792a60d | ||
|
|
5988fce59b | ||
|
|
314eb0d771 | ||
|
|
c1f5a96e1b | ||
|
|
64592d7032 | ||
|
|
c6b180b8f5 | ||
|
|
0155447c6a | ||
|
|
04f4053bde | ||
|
|
09a58b607c | ||
|
|
be82530412 | ||
|
|
6e11c0b8af | ||
|
|
9fade6368c | ||
|
|
ff99c2e734 | ||
|
|
6d356114a8 | ||
|
|
3041132959 | ||
|
|
2877773cac | ||
|
|
a061febd01 | ||
|
|
e3773fd5c0 | ||
|
|
a92835454d | ||
|
|
64e5fa7ecb | ||
|
|
d1894fb62a | ||
|
|
fe7065be4a | ||
|
|
e7b3127af1 | ||
|
|
724378cf6c | ||
|
|
14eb9c6ec0 | ||
|
|
9a8b1ef8b9 | ||
|
|
2cc94bd1fc | ||
|
|
ad8de4dd56 | ||
|
|
5e97ad1b3c | ||
|
|
fe06ed0a4b | ||
|
|
d449123fab | ||
|
|
4d483e7896 | ||
|
|
b1cbeefa28 | ||
|
|
9be3cf4865 | ||
|
|
65006cc376 | ||
|
|
fc01b29823 | ||
|
|
462595ef03 | ||
|
|
b0d85795f4 | ||
|
|
2c91ef51db | ||
|
|
a54e7ac0a8 | ||
|
|
64f54c268b | ||
|
|
d889d51a7d | ||
|
|
b284e9fa58 | ||
|
|
1a0da7971a | ||
|
|
53a82a5f57 | ||
|
|
10985abcdb | ||
|
|
e60a282742 | ||
|
|
a691b16ebe | ||
|
|
c38114648a | ||
|
|
3fc4419f4f | ||
|
|
033bdf6491 | ||
|
|
18e3ba9558 | ||
|
|
3fb552cc55 |
36
.travis.yml
36
.travis.yml
@@ -1,36 +1,22 @@
|
||||
language: c
|
||||
|
||||
os:
|
||||
- linux
|
||||
- osx
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- $HOME/Library/Caches/Homebrew/Cask
|
||||
# Cache for the gcc archives
|
||||
- $HOME/gcc-cache/
|
||||
|
||||
install: eclipse -noSplash
|
||||
-application org.eclipse.equinox.p2.director
|
||||
-repository http://gnuarmeclipse.sourceforge.net/updates
|
||||
-installIUs ilg.gnuarmeclipse.managedbuild.cross.feature.group
|
||||
-profileProperties org.eclipse.update.install.features=true
|
||||
|
||||
before_script:
|
||||
- tar -xf gcc-arm-none-eabi-7-2017-q4-major-*.tar.bz2
|
||||
- export PATH=$PATH:$PWD/gcc-arm-none-eabi-7-2017-q4-major/bin
|
||||
install:
|
||||
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then GCC_NAME="gcc-arm-none-eabi-7-2017-q4-major-mac.tar.bz2"; else GCC_NAME="gcc-arm-none-eabi-7-2017-q4-major-linux.tar.bz2"; fi
|
||||
- if test ! -e $HOME/gcc-cache/$GCC_NAME ; then wget "https://developer.arm.com/-/media/Files/downloads/gnu-rm/7-2017q4/$GCC_NAME" -O $HOME/gcc-cache/$GCC_NAME ; fi
|
||||
- tar -xf $HOME/gcc-cache/$GCC_NAME -C $HOME
|
||||
- export PATH=$PATH:$HOME/gcc-arm-none-eabi-7-2017-q4-major/bin
|
||||
|
||||
script:
|
||||
- eclipse -noSplash -application org.eclipse.cdt.managedbuilder.core.headlessbuild -import $TRAVIS_BUILD_DIR/left/build -import $TRAVIS_BUILD_DIR/right/build -build all
|
||||
- make -C left clean && make -j2 -C left DEBUG=1
|
||||
- make -C left clean && make -j2 -C left DEBUG=0
|
||||
- make -C right clean && make -j2 -C right DEBUG=1
|
||||
- make -C right clean && make -j2 -C right DEBUG=0
|
||||
|
||||
matrix:
|
||||
include:
|
||||
- os: linux
|
||||
sudo: required
|
||||
before_install:
|
||||
- curl https://nixos.org/nix/install | sh && . ~/.nix-profile/etc/profile.d/nix.sh
|
||||
- nix-env -i eclipse-cpp
|
||||
- wget "https://developer.arm.com/-/media/Files/downloads/gnu-rm/7-2017q4/gcc-arm-none-eabi-7-2017-q4-major-linux.tar.bz2"
|
||||
- os: osx
|
||||
env: PATH="$PATH:/Applications/Eclipse CPP.app/Contents/MacOS"
|
||||
before_install:
|
||||
- brew cask install eclipse-cpp
|
||||
- wget "https://developer.arm.com/-/media/Files/downloads/gnu-rm/7-2017q4/gcc-arm-none-eabi-7-2017-q4-major-mac.tar.bz2"
|
||||
|
||||
93
CHANGELOG.md
93
CHANGELOG.md
@@ -5,6 +5,99 @@ 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
|
||||
|
||||
- Rewrite the key debouncer and set the press and release timeouts to 50ms.
|
||||
- Add hardcoded test keymap.
|
||||
- Make debounce timeouts configurable via USB. `DEVICEPROTOCOL:MINOR`
|
||||
- Make the hardcoded test keymap able to trigger via USB. `DEVICEPROTOCOL:MINOR`
|
||||
- Allow the USB stack test mode to be activated via USB. `DEVICEPROTOCOL:MINOR`
|
||||
|
||||
## [8.3.3] - 2018-07-03
|
||||
|
||||
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.
|
||||
|
||||
## [8.3.2] - 2018-06-27
|
||||
|
||||
Device Protocol: 4.3.1 | Module Protocol: 4.0.0 | User Config: 4.1.0 | Hardware Config: 1.0.0
|
||||
|
||||
- Make the debouncer debounce not only on key presses but also on key releases, and change the debounce interval from 100ms to the suggested 5ms of MX switches.
|
||||
- Revert the Windows related commits of firmware 8.3.1 because they introduced a nondeterministic bug that made USB hang.
|
||||
- Add base layer key mappings for the left and right add-ons for testing purposes.
|
||||
|
||||
## [8.3.1] - 2018-06-07
|
||||
|
||||
Device Protocol: 4.3.1 | Module Protocol: 4.0.0 | User Config: 4.1.0 | Hardware Config: 1.0.0
|
||||
|
||||
- Fix media key repetition bug on Windows.
|
||||
- Fix bug that made Windows unable to sleep when the UHK was plugged in.
|
||||
- Fix bug that made Chrome Remote Desktop blocked from interacting on Windows.
|
||||
- Fix bug that made locked layers not release. This bug was introduced in the previous release.
|
||||
|
||||
## [8.3.0] - 2018-06-03
|
||||
|
||||
Device Protocol: 4.3.1 | Module Protocol: 4.0.0 | User Config: 4.**1.0** | Hardware Config: 1.0.0
|
||||
|
||||
- Make the config parser handle switch layer actions with hold on double tap disabled. `USERCONFIG:MINOR`
|
||||
- Set key debounce timeout from 80ms to 100ms. This should further reduce key chattering.
|
||||
|
||||
## [8.2.5] - 2018-05-27
|
||||
|
||||
Device Protocol: 4.3.1 | Module Protocol: 4.0.0 | User Config: 4.0.1 | Hardware Config: 1.0.0
|
||||
|
||||
- Now really fix the bug that made the hardware and user configuration not load from the EEPROM on some hosts right after firmware update.
|
||||
|
||||
## [8.2.4] - 2018-05-21
|
||||
|
||||
Device Protocol: 4.3.**1** | Module Protocol: 4.0.0 | User Config: 4.0.1 | Hardware Config: 1.0.0
|
||||
|
||||
1
ISSUE_TEMPLATE
Normal file
1
ISSUE_TEMPLATE
Normal 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.
|
||||
12
README.md
12
README.md
@@ -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
|
||||
|
||||
|
||||
@@ -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 \
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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;
|
||||
TEST_LED_TOGGLE();
|
||||
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
|
||||
|
||||
@@ -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:
|
||||
@@ -84,8 +82,7 @@ void InitPeripherals(void)
|
||||
{
|
||||
initInterruptPriorities();
|
||||
InitLedDriver();
|
||||
InitTestLed();
|
||||
TestLed_Init();
|
||||
LedPwm_Init();
|
||||
DebugOverSpi_Init();
|
||||
initI2c();
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#include "fsl_lptmr.h"
|
||||
#include "key_scanner.h"
|
||||
#include "config.h"
|
||||
#include "i2c_watchdog.h"
|
||||
|
||||
void KEY_SCANNER_HANDLER(void)
|
||||
|
||||
@@ -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}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -42,7 +42,7 @@ void SlaveRxHandler(void)
|
||||
case SlaveCommand_SetTestLed:
|
||||
TxMessage.length = 0;
|
||||
bool isLedOn = RxMessage.data[1];
|
||||
TEST_LED_SET(isLedOn);
|
||||
TestLed_Set(isLedOn);
|
||||
break;
|
||||
case SlaveCommand_SetLedPwmBrightness:
|
||||
TxMessage.length = 0;
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
#include "test_led.h"
|
||||
#include "fsl_port.h"
|
||||
|
||||
extern void InitTestLed(void)
|
||||
extern void TestLed_Init(void)
|
||||
{
|
||||
CLOCK_EnableClock(TEST_LED_CLOCK);
|
||||
PORT_SetPinMux(TEST_LED_PORT, TEST_LED_PIN, kPORT_MuxAsGpio);
|
||||
GPIO_PinInit(TEST_LED_GPIO, TEST_LED_PIN, &(gpio_pin_config_t){kGPIO_DigitalOutput, 0});
|
||||
TEST_LED_ON();
|
||||
TestLed_On();
|
||||
}
|
||||
|
||||
@@ -15,13 +15,28 @@
|
||||
#define TEST_LED_CLOCK kCLOCK_PortB
|
||||
#define TEST_LED_PIN 13
|
||||
|
||||
#define TEST_LED_ON() GPIO_SetPinsOutput(TEST_LED_GPIO, 1U << TEST_LED_PIN)
|
||||
#define TEST_LED_OFF() GPIO_ClearPinsOutput(TEST_LED_GPIO, 1U << TEST_LED_PIN)
|
||||
#define TEST_LED_SET(state) GPIO_WritePinOutput(TEST_LED_GPIO, TEST_LED_PIN, (state))
|
||||
#define TEST_LED_TOGGLE() GPIO_TogglePinsOutput(TEST_LED_GPIO, 1U << TEST_LED_PIN)
|
||||
static inline void TestLed_On(void)
|
||||
{
|
||||
GPIO_SetPinsOutput(TEST_LED_GPIO, 1U << TEST_LED_PIN);
|
||||
}
|
||||
|
||||
static inline void TestLed_Off(void)
|
||||
{
|
||||
GPIO_ClearPinsOutput(TEST_LED_GPIO, 1U << TEST_LED_PIN);
|
||||
}
|
||||
|
||||
static inline void TestLed_Set(bool state)
|
||||
{
|
||||
GPIO_WritePinOutput(TEST_LED_GPIO, TEST_LED_PIN, state);
|
||||
}
|
||||
|
||||
static inline void TestLed_Toggle(void)
|
||||
{
|
||||
GPIO_TogglePinsOutput(TEST_LED_GPIO, 1U << TEST_LED_PIN);
|
||||
}
|
||||
|
||||
// Functions:
|
||||
|
||||
void InitTestLed(void);
|
||||
void TestLed_Init(void);
|
||||
|
||||
#endif
|
||||
|
||||
Submodule lib/agent updated: ab8ae31324...6e2b1fb18d
@@ -38,7 +38,7 @@ JLINK_SCRIPT = ../scripts/flash-right.jlink
|
||||
BUILD_FLAGS = -DCPU_$(PART)_cm4 -DUSB_STACK_BM -DBL_HAS_BOOTLOADER_CONFIG=1
|
||||
|
||||
# Address of the app vector table. The bootloader will take up the flash before this address.
|
||||
BL_APP_VECTOR_TABLE_ADDRESS = 0xc000
|
||||
BL_APP_VECTOR_TABLE_ADDRESS ?= 0xc000
|
||||
|
||||
# Source files.
|
||||
SOURCE = $(wildcard src/*.c) \
|
||||
|
||||
@@ -457,4 +457,87 @@
|
||||
<resource resourceType="PROJECT" workspacePath="/uhk-right"/>
|
||||
</configuration>
|
||||
</storageModule>
|
||||
<storageModule moduleId="com.crt.config">
|
||||
<projectStorage><?xml version="1.0" encoding="UTF-8"?>
|
||||
<TargetConfig>
|
||||
<Properties property_3="NXP" property_4="MK22FN512xxx12" property_count="5" version="100200"/>
|
||||
<infoList vendor="NXP"><info chip="MK22FN512xxx12" name="MK22FN512xxx12"><chip><name>MK22FN512xxx12</name>
|
||||
<family>K2x</family>
|
||||
<vendor>NXP</vendor>
|
||||
<memory can_program="true" id="Flash" is_ro="true" size="0" type="Flash"/>
|
||||
<memory id="RAM" size="0" type="RAM"/>
|
||||
<memoryInstance derived_from="Flash" driver="FTFA_2K.cfx" id="PROGRAM_FLASH" location="0x00000000" size="0x00080000"/>
|
||||
<memoryInstance derived_from="RAM" id="SRAM_UPPER" location="0x20000000" size="0x00010000"/>
|
||||
<memoryInstance derived_from="RAM" id="SRAM_LOWER" location="0x1fff0000" size="0x00010000"/>
|
||||
<peripheralInstance derived_from="FTFA-FlashConfig" determined="infoFile" id="FTFA-FlashConfig" location="0x400"/>
|
||||
<peripheralInstance derived_from="DMA" determined="infoFile" id="DMA" location="0x40008000"/>
|
||||
<peripheralInstance derived_from="FB" determined="infoFile" id="FB" location="0x4000C000"/>
|
||||
<peripheralInstance derived_from="FMC" determined="infoFile" id="FMC" location="0x4001F000"/>
|
||||
<peripheralInstance derived_from="FTFA" determined="infoFile" id="FTFA" location="0x40020000"/>
|
||||
<peripheralInstance derived_from="DMAMUX" determined="infoFile" id="DMAMUX" location="0x40021000"/>
|
||||
<peripheralInstance derived_from="FTM0" determined="infoFile" id="FTM0" location="0x40038000"/>
|
||||
<peripheralInstance derived_from="FTM1" determined="infoFile" id="FTM1" location="0x40039000"/>
|
||||
<peripheralInstance derived_from="FTM2" determined="infoFile" id="FTM2" location="0x4003A000"/>
|
||||
<peripheralInstance derived_from="FTM3" determined="infoFile" id="FTM3" location="0x40026000"/>
|
||||
<peripheralInstance derived_from="ADC0" determined="infoFile" id="ADC0" location="0x4003B000"/>
|
||||
<peripheralInstance derived_from="ADC1" determined="infoFile" id="ADC1" location="0x40027000"/>
|
||||
<peripheralInstance derived_from="DAC0" determined="infoFile" id="DAC0" location="0x4003F000"/>
|
||||
<peripheralInstance derived_from="DAC1" determined="infoFile" id="DAC1" location="0x40028000"/>
|
||||
<peripheralInstance derived_from="RNG" determined="infoFile" id="RNG" location="0x40029000"/>
|
||||
<peripheralInstance derived_from="LPUART0" determined="infoFile" id="LPUART0" location="0x4002A000"/>
|
||||
<peripheralInstance derived_from="SPI0" determined="infoFile" id="SPI0" location="0x4002C000"/>
|
||||
<peripheralInstance derived_from="SPI1" determined="infoFile" id="SPI1" location="0x4002D000"/>
|
||||
<peripheralInstance derived_from="I2S0" determined="infoFile" id="I2S0" location="0x4002F000"/>
|
||||
<peripheralInstance derived_from="CRC" determined="infoFile" id="CRC" location="0x40032000"/>
|
||||
<peripheralInstance derived_from="PDB0" determined="infoFile" id="PDB0" location="0x40036000"/>
|
||||
<peripheralInstance derived_from="PIT" determined="infoFile" id="PIT" location="0x40037000"/>
|
||||
<peripheralInstance derived_from="RTC" determined="infoFile" id="RTC" location="0x4003D000"/>
|
||||
<peripheralInstance derived_from="RFVBAT" determined="infoFile" id="RFVBAT" location="0x4003E000"/>
|
||||
<peripheralInstance derived_from="LPTMR0" determined="infoFile" id="LPTMR0" location="0x40040000"/>
|
||||
<peripheralInstance derived_from="RFSYS" determined="infoFile" id="RFSYS" location="0x40041000"/>
|
||||
<peripheralInstance derived_from="SIM" determined="infoFile" id="SIM" location="0x40047000"/>
|
||||
<peripheralInstance derived_from="PORTA" determined="infoFile" id="PORTA" location="0x40049000"/>
|
||||
<peripheralInstance derived_from="PORTB" determined="infoFile" id="PORTB" location="0x4004A000"/>
|
||||
<peripheralInstance derived_from="PORTC" determined="infoFile" id="PORTC" location="0x4004B000"/>
|
||||
<peripheralInstance derived_from="PORTD" determined="infoFile" id="PORTD" location="0x4004C000"/>
|
||||
<peripheralInstance derived_from="PORTE" determined="infoFile" id="PORTE" location="0x4004D000"/>
|
||||
<peripheralInstance derived_from="WDOG" determined="infoFile" id="WDOG" location="0x40052000"/>
|
||||
<peripheralInstance derived_from="EWM" determined="infoFile" id="EWM" location="0x40061000"/>
|
||||
<peripheralInstance derived_from="MCG" determined="infoFile" id="MCG" location="0x40064000"/>
|
||||
<peripheralInstance derived_from="OSC" determined="infoFile" id="OSC" location="0x40065000"/>
|
||||
<peripheralInstance derived_from="I2C0" determined="infoFile" id="I2C0" location="0x40066000"/>
|
||||
<peripheralInstance derived_from="I2C1" determined="infoFile" id="I2C1" location="0x40067000"/>
|
||||
<peripheralInstance derived_from="UART0" determined="infoFile" id="UART0" location="0x4006A000"/>
|
||||
<peripheralInstance derived_from="UART1" determined="infoFile" id="UART1" location="0x4006B000"/>
|
||||
<peripheralInstance derived_from="UART2" determined="infoFile" id="UART2" location="0x4006C000"/>
|
||||
<peripheralInstance derived_from="USB0" determined="infoFile" id="USB0" location="0x40072000"/>
|
||||
<peripheralInstance derived_from="CMP0" determined="infoFile" id="CMP0" location="0x40073000"/>
|
||||
<peripheralInstance derived_from="CMP1" determined="infoFile" id="CMP1" location="0x40073008"/>
|
||||
<peripheralInstance derived_from="VREF" determined="infoFile" id="VREF" location="0x40074000"/>
|
||||
<peripheralInstance derived_from="LLWU" determined="infoFile" id="LLWU" location="0x4007C000"/>
|
||||
<peripheralInstance derived_from="PMC" determined="infoFile" id="PMC" location="0x4007D000"/>
|
||||
<peripheralInstance derived_from="SMC" determined="infoFile" id="SMC" location="0x4007E000"/>
|
||||
<peripheralInstance derived_from="RCM" determined="infoFile" id="RCM" location="0x4007F000"/>
|
||||
<peripheralInstance derived_from="GPIOA" determined="infoFile" id="GPIOA" location="0x400FF000"/>
|
||||
<peripheralInstance derived_from="GPIOB" determined="infoFile" id="GPIOB" location="0x400FF040"/>
|
||||
<peripheralInstance derived_from="GPIOC" determined="infoFile" id="GPIOC" location="0x400FF080"/>
|
||||
<peripheralInstance derived_from="GPIOD" determined="infoFile" id="GPIOD" location="0x400FF0C0"/>
|
||||
<peripheralInstance derived_from="GPIOE" determined="infoFile" id="GPIOE" location="0x400FF100"/>
|
||||
<peripheralInstance derived_from="SystemControl" determined="infoFile" id="SystemControl" location="0xE000E000"/>
|
||||
<peripheralInstance derived_from="SysTick" determined="infoFile" id="SysTick" location="0xE000E010"/>
|
||||
<peripheralInstance derived_from="NVIC" determined="infoFile" id="NVIC" location="0xE000E100"/>
|
||||
<peripheralInstance derived_from="MCM" determined="infoFile" id="MCM" location="0xE0080000"/>
|
||||
</chip>
|
||||
<processor><name gcc_name="cortex-m4">Cortex-M4</name>
|
||||
<family>Cortex-M</family>
|
||||
</processor>
|
||||
<link href="MK22F51212_internal_peripheral.xml" show="embed" type="simple"/>
|
||||
</info>
|
||||
</infoList>
|
||||
</TargetConfig></projectStorage>
|
||||
</storageModule>
|
||||
<storageModule moduleId="com.nxp.mcuxpresso.core.datamodels">
|
||||
<sdkName>SDK_2.x_MK22FN512xxx12</sdkName>
|
||||
<sdkVersion>2.2.0</sdkVersion>
|
||||
</storageModule>
|
||||
</cproject>
|
||||
|
||||
@@ -48,7 +48,7 @@ static parser_error_t parseKeyStrokeAction(key_action_t *keyAction, uint8_t keyS
|
||||
static parser_error_t parseSwitchLayerAction(key_action_t *KeyAction, config_buffer_t *buffer)
|
||||
{
|
||||
uint8_t layer = ReadUInt8(buffer) + 1;
|
||||
uint8_t mode = ReadBool(buffer) ? SwitchLayerMode_Toggle : SwitchLayerMode_HoldAndDoubleTapToggle;
|
||||
switch_layer_mode_t mode = ReadUInt8(buffer);
|
||||
|
||||
KeyAction->type = KeyActionType_SwitchLayer;
|
||||
KeyAction->switchLayer.layer = layer;
|
||||
|
||||
@@ -60,7 +60,7 @@ parser_error_t parseScrollMouseMacroAction(config_buffer_t *buffer, macro_action
|
||||
|
||||
parser_error_t parseDelayMacroAction(config_buffer_t *buffer, macro_action_t *macroAction)
|
||||
{
|
||||
int16_t delay = ReadInt16(buffer);
|
||||
uint16_t delay = ReadUInt16(buffer);
|
||||
|
||||
macroAction->type = MacroActionType_Delay;
|
||||
macroAction->delay.delay = delay;
|
||||
|
||||
@@ -35,10 +35,12 @@
|
||||
#define I2C_EEPROM_BUS_BAUD_RATE 1000000 // 1 Mhz is the maximum speed of the EEPROM.
|
||||
#define I2C_EEPROM_BUS_MUX kPORT_MuxAlt2
|
||||
|
||||
#define I2C_EEPROM_BUS_SDA_GPIO GPIOC
|
||||
#define I2C_EEPROM_BUS_SDA_PORT PORTC
|
||||
#define I2C_EEPROM_BUS_SDA_CLOCK kCLOCK_PortC
|
||||
#define I2C_EEPROM_BUS_SDA_PIN 11
|
||||
|
||||
#define I2C_EEPROM_BUS_SCL_GPIO GPIOC
|
||||
#define I2C_EEPROM_BUS_SCL_PORT PORTC
|
||||
#define I2C_EEPROM_BUS_SCL_CLOCK kCLOCK_PortC
|
||||
#define I2C_EEPROM_BUS_SCL_PIN 10
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
#include "init_peripherals.h"
|
||||
#include "eeprom.h"
|
||||
#include "timer.h"
|
||||
#include "key_debouncer.h"
|
||||
#include "usb_api.h"
|
||||
#include "slave_scheduler.h"
|
||||
#include "bootloader/wormhole.h"
|
||||
@@ -21,6 +20,38 @@ bool IsBusPalOn;
|
||||
volatile uint32_t I2cMainBusRequestedBaudRateBps = I2C_MAIN_BUS_NORMAL_BAUD_RATE;
|
||||
volatile uint32_t I2cMainBusActualBaudRateBps;
|
||||
|
||||
static i2c_bus_t i2cMainBus = {
|
||||
.baseAddr = I2C_MAIN_BUS_BASEADDR,
|
||||
.clockSrc = I2C_MAIN_BUS_CLK_SRC,
|
||||
.mux = I2C_MAIN_BUS_MUX,
|
||||
|
||||
.sdaClock = I2C_MAIN_BUS_SDA_CLOCK,
|
||||
.sdaGpio = I2C_MAIN_BUS_SDA_GPIO,
|
||||
.sdaPort = I2C_MAIN_BUS_SDA_PORT,
|
||||
.sdaPin = I2C_MAIN_BUS_SDA_PIN,
|
||||
|
||||
.sclClock = I2C_MAIN_BUS_SCL_CLOCK,
|
||||
.sclGpio = I2C_MAIN_BUS_SCL_GPIO,
|
||||
.sclPort = I2C_MAIN_BUS_SCL_PORT,
|
||||
.sclPin = I2C_MAIN_BUS_SCL_PIN,
|
||||
};
|
||||
|
||||
static i2c_bus_t i2cEepromBus = {
|
||||
.baseAddr = I2C_EEPROM_BUS_BASEADDR,
|
||||
.clockSrc = I2C_EEPROM_BUS_CLK_SRC,
|
||||
.mux = I2C_EEPROM_BUS_MUX,
|
||||
|
||||
.sdaClock = I2C_EEPROM_BUS_SDA_CLOCK,
|
||||
.sdaGpio = I2C_EEPROM_BUS_SDA_GPIO,
|
||||
.sdaPort = I2C_EEPROM_BUS_SDA_PORT,
|
||||
.sdaPin = I2C_EEPROM_BUS_SDA_PIN,
|
||||
|
||||
.sclClock = I2C_EEPROM_BUS_SCL_CLOCK,
|
||||
.sclGpio = I2C_EEPROM_BUS_SCL_GPIO,
|
||||
.sclPort = I2C_EEPROM_BUS_SCL_PORT,
|
||||
.sclPin = I2C_EEPROM_BUS_SCL_PIN,
|
||||
};
|
||||
|
||||
static void initBusPalState(void) {
|
||||
IsBusPalOn = Wormhole.magicNumber == WORMHOLE_MAGIC_NUMBER && Wormhole.enumerationMode == EnumerationMode_BusPal;
|
||||
if (IsBusPalOn) {
|
||||
@@ -32,12 +63,10 @@ static void initBusPalState(void) {
|
||||
static void initInterruptPriorities(void)
|
||||
{
|
||||
NVIC_SetPriority(PIT_I2C_WATCHDOG_IRQ_ID, 1);
|
||||
NVIC_SetPriority(PIT_TIMER_IRQ_ID, 2);
|
||||
NVIC_SetPriority(I2C_EEPROM_BUS_IRQ_ID, 2);
|
||||
NVIC_SetPriority(PIT_KEY_SCANNER_IRQ_ID, 3);
|
||||
NVIC_SetPriority(PIT_KEY_DEBOUNCER_IRQ_ID, 3);
|
||||
NVIC_SetPriority(I2C_MAIN_BUS_IRQ_ID, 3);
|
||||
NVIC_SetPriority(USB_IRQ_ID, 3);
|
||||
NVIC_SetPriority(I2C_EEPROM_BUS_IRQ_ID, 0);
|
||||
NVIC_SetPriority(PIT_TIMER_IRQ_ID, 3);
|
||||
NVIC_SetPriority(I2C_MAIN_BUS_IRQ_ID, 4);
|
||||
NVIC_SetPriority(USB_IRQ_ID, 4);
|
||||
}
|
||||
|
||||
static void delay(void)
|
||||
@@ -45,91 +74,73 @@ static void delay(void)
|
||||
for (volatile uint32_t i=0; i<62; i++);
|
||||
}
|
||||
|
||||
static void recoverI2c(void)
|
||||
static void recoverI2cBus(i2c_bus_t *i2cBus)
|
||||
{
|
||||
PORT_SetPinMux(I2C_MAIN_BUS_SDA_PORT, I2C_MAIN_BUS_SDA_PIN, kPORT_MuxAsGpio);
|
||||
PORT_SetPinMux(I2C_MAIN_BUS_SCL_PORT, I2C_MAIN_BUS_SCL_PIN, kPORT_MuxAsGpio);
|
||||
GPIO_PinInit(I2C_MAIN_BUS_SCL_GPIO, I2C_MAIN_BUS_SCL_PIN, &(gpio_pin_config_t){kGPIO_DigitalOutput, 1});
|
||||
PORT_SetPinMux(i2cBus->sdaPort, i2cBus->sdaPin, kPORT_MuxAsGpio);
|
||||
PORT_SetPinMux(i2cBus->sclPort, i2cBus->sclPin, kPORT_MuxAsGpio);
|
||||
GPIO_PinInit(i2cBus->sclGpio, i2cBus->sclPin, &(gpio_pin_config_t){kGPIO_DigitalOutput, 1});
|
||||
|
||||
bool isOn = true;
|
||||
for (int i=0; i<20; i++) {
|
||||
GPIO_PinInit(I2C_MAIN_BUS_SDA_GPIO, I2C_MAIN_BUS_SDA_PIN, &(gpio_pin_config_t){kGPIO_DigitalInput});
|
||||
bool isSdaHigh = GPIO_ReadPinInput(I2C_MAIN_BUS_SDA_GPIO, I2C_MAIN_BUS_SDA_PIN);
|
||||
GPIO_PinInit(I2C_MAIN_BUS_SDA_GPIO, I2C_MAIN_BUS_SDA_PIN, &(gpio_pin_config_t){kGPIO_DigitalOutput, 1});
|
||||
GPIO_PinInit(i2cBus->sdaGpio, i2cBus->sdaPin, &(gpio_pin_config_t){kGPIO_DigitalInput});
|
||||
bool isSdaHigh = GPIO_ReadPinInput(i2cBus->sdaGpio, i2cBus->sdaPin);
|
||||
GPIO_PinInit(i2cBus->sdaGpio, i2cBus->sdaPin, &(gpio_pin_config_t){kGPIO_DigitalOutput, 1});
|
||||
|
||||
if (isSdaHigh) {
|
||||
return;
|
||||
}
|
||||
|
||||
GPIO_WritePinOutput(I2C_MAIN_BUS_SCL_GPIO, I2C_MAIN_BUS_SCL_PIN, isOn);
|
||||
GPIO_WritePinOutput(i2cBus->sclGpio, i2cBus->sclPin, isOn);
|
||||
delay();
|
||||
isOn = !isOn;
|
||||
}
|
||||
|
||||
GPIO_WritePinOutput(I2C_MAIN_BUS_SDA_GPIO, I2C_MAIN_BUS_SDA_PIN, 0);
|
||||
GPIO_WritePinOutput(i2cBus->sdaGpio, i2cBus->sdaPin, 0);
|
||||
delay();
|
||||
GPIO_WritePinOutput(I2C_MAIN_BUS_SCL_GPIO, I2C_MAIN_BUS_SCL_PIN, 1);
|
||||
GPIO_WritePinOutput(i2cBus->sclGpio, i2cBus->sclPin, 1);
|
||||
delay();
|
||||
GPIO_WritePinOutput(I2C_MAIN_BUS_SDA_GPIO, I2C_MAIN_BUS_SDA_PIN, 1);
|
||||
GPIO_WritePinOutput(i2cBus->sdaGpio, i2cBus->sdaPin, 1);
|
||||
delay();
|
||||
}
|
||||
|
||||
static void initI2cMainBus(void)
|
||||
static void initI2cBus(i2c_bus_t *i2cBus)
|
||||
{
|
||||
CLOCK_EnableClock(I2C_MAIN_BUS_SDA_CLOCK);
|
||||
CLOCK_EnableClock(I2C_MAIN_BUS_SCL_CLOCK);
|
||||
CLOCK_EnableClock(i2cBus->sdaClock);
|
||||
CLOCK_EnableClock(i2cBus->sclClock);
|
||||
|
||||
recoverI2c();
|
||||
recoverI2cBus(i2cBus);
|
||||
|
||||
port_pin_config_t pinConfig = {
|
||||
.pullSelect = kPORT_PullUp,
|
||||
.openDrainEnable = kPORT_OpenDrainEnable,
|
||||
.mux = I2C_MAIN_BUS_MUX,
|
||||
.mux = i2cBus->mux,
|
||||
};
|
||||
|
||||
PORT_SetPinConfig(I2C_MAIN_BUS_SDA_PORT, I2C_MAIN_BUS_SDA_PIN, &pinConfig);
|
||||
PORT_SetPinConfig(I2C_MAIN_BUS_SCL_PORT, I2C_MAIN_BUS_SCL_PIN, &pinConfig);
|
||||
PORT_SetPinConfig(i2cBus->sdaPort, i2cBus->sdaPin, &pinConfig);
|
||||
PORT_SetPinConfig(i2cBus->sclPort, i2cBus->sclPin, &pinConfig);
|
||||
|
||||
i2c_master_config_t masterConfig;
|
||||
I2C_MasterGetDefaultConfig(&masterConfig);
|
||||
masterConfig.baudRate_Bps = I2cMainBusRequestedBaudRateBps;
|
||||
uint32_t sourceClock = CLOCK_GetFreq(I2C_MAIN_BUS_CLK_SRC);
|
||||
I2C_MasterInit(I2C_MAIN_BUS_BASEADDR, &masterConfig, sourceClock);
|
||||
I2cMainBusActualBaudRateBps = I2C_ActualBaudRate;
|
||||
masterConfig.baudRate_Bps = i2cBus == &i2cMainBus ? I2cMainBusRequestedBaudRateBps : I2C_EEPROM_BUS_BAUD_RATE;
|
||||
uint32_t sourceClock = CLOCK_GetFreq(i2cBus->clockSrc);
|
||||
I2C_MasterInit(i2cBus->baseAddr, &masterConfig, sourceClock);
|
||||
|
||||
if (i2cBus == &i2cMainBus) {
|
||||
I2cMainBusActualBaudRateBps = I2C_ActualBaudRate;
|
||||
}
|
||||
}
|
||||
|
||||
void ReinitI2cMainBus(void)
|
||||
{
|
||||
I2C_MasterDeinit(I2C_MAIN_BUS_BASEADDR);
|
||||
initI2cMainBus();
|
||||
initI2cBus(&i2cMainBus);
|
||||
InitSlaveScheduler();
|
||||
}
|
||||
|
||||
static void initI2cEepromBus(void)
|
||||
{
|
||||
port_pin_config_t pinConfig = {
|
||||
.pullSelect = kPORT_PullUp,
|
||||
.openDrainEnable = kPORT_OpenDrainEnable,
|
||||
.mux = I2C_EEPROM_BUS_MUX,
|
||||
};
|
||||
|
||||
CLOCK_EnableClock(I2C_EEPROM_BUS_SDA_CLOCK);
|
||||
CLOCK_EnableClock(I2C_EEPROM_BUS_SCL_CLOCK);
|
||||
|
||||
PORT_SetPinConfig(I2C_EEPROM_BUS_SDA_PORT, I2C_EEPROM_BUS_SDA_PIN, &pinConfig);
|
||||
PORT_SetPinConfig(I2C_EEPROM_BUS_SCL_PORT, I2C_EEPROM_BUS_SCL_PIN, &pinConfig);
|
||||
|
||||
i2c_master_config_t masterConfig;
|
||||
I2C_MasterGetDefaultConfig(&masterConfig);
|
||||
masterConfig.baudRate_Bps = I2C_EEPROM_BUS_BAUD_RATE;
|
||||
uint32_t sourceClock = CLOCK_GetFreq(I2C_EEPROM_BUS_CLK_SRC);
|
||||
I2C_MasterInit(I2C_EEPROM_BUS_BASEADDR, &masterConfig, sourceClock);
|
||||
}
|
||||
|
||||
static void initI2c(void)
|
||||
{
|
||||
initI2cMainBus();
|
||||
initI2cEepromBus();
|
||||
initI2cBus(&i2cMainBus);
|
||||
initI2cBus(&i2cEepromBus);
|
||||
}
|
||||
|
||||
void InitPeripherals(void)
|
||||
@@ -142,9 +153,8 @@ void InitPeripherals(void)
|
||||
InitMergeSensor();
|
||||
ADC_Init();
|
||||
initI2c();
|
||||
InitTestLed();
|
||||
TestLed_Init();
|
||||
LedPwm_Init();
|
||||
InitI2cWatchdog();
|
||||
InitKeyDebouncer();
|
||||
EEPROM_Init();
|
||||
}
|
||||
|
||||
@@ -1,10 +1,28 @@
|
||||
#ifndef __INIT_PERIPHERALS_H__
|
||||
#define __INIT_PERIPHERALS_H__
|
||||
|
||||
// Includes
|
||||
// Includes:
|
||||
|
||||
#include "fsl_common.h"
|
||||
|
||||
// Typedefs:
|
||||
|
||||
typedef struct {
|
||||
clock_name_t clockSrc;
|
||||
I2C_Type *baseAddr;
|
||||
uint16_t mux;
|
||||
|
||||
clock_ip_name_t sdaClock;
|
||||
GPIO_Type *sdaGpio;
|
||||
PORT_Type *sdaPort;
|
||||
uint32_t sdaPin;
|
||||
|
||||
clock_ip_name_t sclClock;
|
||||
GPIO_Type *sclGpio;
|
||||
PORT_Type *sclPort;
|
||||
uint32_t sclPin;
|
||||
} i2c_bus_t;
|
||||
|
||||
// Variables:
|
||||
|
||||
extern bool IsBusPalOn;
|
||||
|
||||
@@ -28,9 +28,9 @@
|
||||
} keystroke_type_t;
|
||||
|
||||
typedef enum {
|
||||
SwitchLayerMode_Hold,
|
||||
SwitchLayerMode_HoldAndDoubleTapToggle,
|
||||
SwitchLayerMode_Toggle,
|
||||
SwitchLayerMode_Hold,
|
||||
} switch_layer_mode_t;
|
||||
|
||||
typedef enum {
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
#include "key_debouncer.h"
|
||||
#include "fsl_pit.h"
|
||||
#include "slot.h"
|
||||
#include "module.h"
|
||||
#include "key_states.h"
|
||||
#include "peripherals/test_led.h"
|
||||
|
||||
void PIT_KEY_DEBOUNCER_HANDLER(void)
|
||||
{
|
||||
TEST_LED_TOGGLE();
|
||||
for (uint8_t slotId=0; slotId<SLOT_COUNT; slotId++) {
|
||||
for (uint8_t keyId=0; keyId<MAX_KEY_COUNT_PER_MODULE; keyId++) {
|
||||
uint8_t *debounceCounter = &KeyStates[slotId][keyId].debounceCounter;
|
||||
if (*debounceCounter < 0xff) {
|
||||
(*debounceCounter)++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PIT_ClearStatusFlags(PIT, PIT_KEY_DEBOUNCER_CHANNEL, PIT_TFLG_TIF_MASK);
|
||||
}
|
||||
|
||||
void InitKeyDebouncer(void)
|
||||
{
|
||||
pit_config_t pitConfig;
|
||||
PIT_GetDefaultConfig(&pitConfig);
|
||||
PIT_Init(PIT, &pitConfig);
|
||||
PIT_SetTimerPeriod(PIT, PIT_KEY_DEBOUNCER_CHANNEL, MSEC_TO_COUNT(KEY_DEBOUNCER_INTERVAL_MSEC, PIT_SOURCE_CLOCK));
|
||||
PIT_EnableInterrupts(PIT, PIT_KEY_DEBOUNCER_CHANNEL, kPIT_TimerInterruptEnable);
|
||||
EnableIRQ(PIT_KEY_DEBOUNCER_IRQ_ID);
|
||||
PIT_StartTimer(PIT, PIT_KEY_DEBOUNCER_CHANNEL);
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
#ifndef __KEY_DEBOUNCER_H__
|
||||
#define __KEY_DEBOUNCER_H__
|
||||
|
||||
// Includes:
|
||||
|
||||
#include "peripherals/pit.h"
|
||||
#include "fsl_common.h"
|
||||
|
||||
// Macros:
|
||||
|
||||
#define KEY_DEBOUNCER_INTERVAL_MSEC 1
|
||||
#define KEY_DEBOUNCER_TIMEOUT_MSEC 80
|
||||
|
||||
// Functions:
|
||||
|
||||
void InitKeyDebouncer(void);
|
||||
|
||||
#endif
|
||||
@@ -1,22 +0,0 @@
|
||||
#include "fsl_pit.h"
|
||||
#include "key_scanner.h"
|
||||
|
||||
uint32_t KeyScannerCounter;
|
||||
|
||||
void PIT_KEY_SCANNER_HANDLER(void)
|
||||
{
|
||||
KeyMatrix_ScanRow(&RightKeyMatrix);
|
||||
KeyScannerCounter++;
|
||||
PIT_ClearStatusFlags(PIT, PIT_KEY_SCANNER_CHANNEL, PIT_TFLG_TIF_MASK);
|
||||
}
|
||||
|
||||
void InitKeyScanner(void)
|
||||
{
|
||||
pit_config_t pitConfig;
|
||||
PIT_GetDefaultConfig(&pitConfig);
|
||||
PIT_Init(PIT, &pitConfig);
|
||||
PIT_SetTimerPeriod(PIT, PIT_KEY_SCANNER_CHANNEL, USEC_TO_COUNT(KEY_SCANNER_INTERVAL_USEC, PIT_SOURCE_CLOCK));
|
||||
PIT_EnableInterrupts(PIT, PIT_KEY_SCANNER_CHANNEL, kPIT_TimerInterruptEnable);
|
||||
EnableIRQ(PIT_KEY_SCANNER_IRQ_ID);
|
||||
PIT_StartTimer(PIT, PIT_KEY_SCANNER_CHANNEL);
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
#ifndef __KEY_SCANNER_H__
|
||||
#define __KEY_SCANNER_H__
|
||||
|
||||
// Includes:
|
||||
|
||||
#include "peripherals/pit.h"
|
||||
#include "right_key_matrix.h"
|
||||
|
||||
// Macros:
|
||||
|
||||
#define KEY_SCANNER_INTERVAL_USEC (1000 / RIGHT_KEY_MATRIX_ROWS_NUM)
|
||||
|
||||
// Variables:
|
||||
|
||||
extern uint32_t KeyScannerCounter;
|
||||
|
||||
// Functions:
|
||||
|
||||
void InitKeyScanner(void);
|
||||
|
||||
#endif
|
||||
@@ -10,10 +10,11 @@
|
||||
// Typedefs:
|
||||
|
||||
typedef struct {
|
||||
bool previous;
|
||||
bool current;
|
||||
bool suppressed;
|
||||
uint8_t debounceCounter;
|
||||
uint8_t timestamp;
|
||||
bool previous : 1;
|
||||
bool current : 1;
|
||||
bool suppressed : 1;
|
||||
bool debouncing : 1;
|
||||
} key_state_t;
|
||||
|
||||
// Variables:
|
||||
|
||||
@@ -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)
|
||||
@@ -128,6 +130,102 @@ key_action_t CurrentKeymap[LAYER_COUNT][SLOT_COUNT][MAX_KEY_COUNT_PER_MODULE] =
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_V }},
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_B }},
|
||||
|
||||
// Row 5
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_LEFT_CONTROL }},
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_LEFT_GUI }},
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_LEFT_ALT }},
|
||||
{ .type = KeyActionType_SwitchLayer, .switchLayer = { .layer = LayerId_Fn }},
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_SPACE }},
|
||||
{ .type = KeyActionType_SwitchLayer, .switchLayer = { .layer = LayerId_Mod }},
|
||||
{ .type = KeyActionType_None },
|
||||
},
|
||||
|
||||
// Left module
|
||||
{
|
||||
// Row 1
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_GRAVE_ACCENT_AND_TILDE }},
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_1_AND_EXCLAMATION }},
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_2_AND_AT }},
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_3_AND_HASHMARK }},
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_4_AND_DOLLAR }},
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_5_AND_PERCENTAGE }},
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_6_AND_CARET }},
|
||||
|
||||
// Row 2
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_TAB }},
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_Q }},
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_W }},
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_E }},
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_R }},
|
||||
{ .type = KeyActionType_None },
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_T }},
|
||||
|
||||
// Row 3
|
||||
{ .type = KeyActionType_SwitchLayer, .switchLayer = { .layer = LayerId_Mouse }},
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_A }},
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_S }},
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_D }},
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_F }},
|
||||
{ .type = KeyActionType_None },
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_G }},
|
||||
|
||||
// Row 4
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_LEFT_SHIFT }},
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_NON_US_BACKSLASH_AND_PIPE }},
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_Z }},
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_X }},
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_C }},
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_V }},
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_B }},
|
||||
|
||||
// Row 5
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_LEFT_CONTROL }},
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_LEFT_GUI }},
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_LEFT_ALT }},
|
||||
{ .type = KeyActionType_SwitchLayer, .switchLayer = { .layer = LayerId_Fn }},
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_SPACE }},
|
||||
{ .type = KeyActionType_SwitchLayer, .switchLayer = { .layer = LayerId_Mod }},
|
||||
{ .type = KeyActionType_None },
|
||||
},
|
||||
|
||||
// Right module
|
||||
{
|
||||
// Row 1
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_GRAVE_ACCENT_AND_TILDE }},
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_1_AND_EXCLAMATION }},
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_2_AND_AT }},
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_3_AND_HASHMARK }},
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_4_AND_DOLLAR }},
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_5_AND_PERCENTAGE }},
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_6_AND_CARET }},
|
||||
|
||||
// Row 2
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_TAB }},
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_Q }},
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_W }},
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_E }},
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_R }},
|
||||
{ .type = KeyActionType_None },
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_T }},
|
||||
|
||||
// Row 3
|
||||
{ .type = KeyActionType_SwitchLayer, .switchLayer = { .layer = LayerId_Mouse }},
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_A }},
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_S }},
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_D }},
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_F }},
|
||||
{ .type = KeyActionType_None },
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_G }},
|
||||
|
||||
// Row 4
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_LEFT_SHIFT }},
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_NON_US_BACKSLASH_AND_PIPE }},
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_Z }},
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_X }},
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_C }},
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_V }},
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_B }},
|
||||
|
||||
// Row 5
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_LEFT_CONTROL }},
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_LEFT_GUI }},
|
||||
|
||||
@@ -5,24 +5,23 @@
|
||||
#include "keymap.h"
|
||||
|
||||
static bool heldLayers[LAYER_COUNT];
|
||||
static switch_layer_mode_t pressedLayers[LAYER_COUNT];
|
||||
static bool toggledLayers[LAYER_COUNT];
|
||||
|
||||
void updateLayerStates(void)
|
||||
{
|
||||
memset(heldLayers, false, LAYER_COUNT);
|
||||
memset(pressedLayers, false, LAYER_COUNT);
|
||||
memset(toggledLayers, false, LAYER_COUNT);
|
||||
|
||||
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) {
|
||||
heldLayers[action.switchLayer.layer] = true;
|
||||
}
|
||||
if (action.switchLayer.mode != SwitchLayerMode_Hold && !keyState->previous && keyState->current) {
|
||||
pressedLayers[action.switchLayer.layer] = action.switchLayer.mode;
|
||||
} else if (!keyState->previous) {
|
||||
toggledLayers[action.switchLayer.layer] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -40,11 +39,11 @@ layer_id_t GetActiveLayer()
|
||||
// Handle toggled layers
|
||||
|
||||
for (layer_id_t layerId=LayerId_Mod; layerId<=LayerId_Mouse; layerId++) {
|
||||
if (pressedLayers[layerId]) {
|
||||
if (toggledLayers[layerId]) {
|
||||
if (ToggledLayer == layerId) {
|
||||
ToggledLayer = LayerId_Base;
|
||||
break;
|
||||
} else if (ToggledLayer == LayerId_Base && pressedLayers[layerId] == SwitchLayerMode_Toggle) {
|
||||
} else if (ToggledLayer == LayerId_Base && toggledLayers[layerId] == SwitchLayerMode_Toggle) {
|
||||
ToggledLayer = layerId;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "macros.h"
|
||||
#include "config_parser/parse_macro.h"
|
||||
#include "config_parser/config_globals.h"
|
||||
#include "timer.h"
|
||||
|
||||
macro_reference_t AllMacros[MAX_MACRO_NUM];
|
||||
uint8_t AllMacrosCount;
|
||||
@@ -18,69 +19,102 @@ uint8_t characterToScancode(char character)
|
||||
{
|
||||
switch (character) {
|
||||
case 'A' ... 'Z':
|
||||
return 0;
|
||||
case 'a' ... 'z':
|
||||
return 0;
|
||||
return HID_KEYBOARD_SC_A - 1 + (character & 0x1F);
|
||||
case '1' ... '9':
|
||||
return 0;
|
||||
return HID_KEYBOARD_SC_1_AND_EXCLAMATION - 1 + (character & 0x0F);
|
||||
case ')':
|
||||
case '0':
|
||||
return 0;
|
||||
return HID_KEYBOARD_SC_0_AND_CLOSING_PARENTHESIS;
|
||||
case '!':
|
||||
return 0;
|
||||
return HID_KEYBOARD_SC_1_AND_EXCLAMATION;
|
||||
case '@':
|
||||
return 0;
|
||||
return HID_KEYBOARD_SC_2_AND_AT;
|
||||
case '#':
|
||||
return 0;
|
||||
return HID_KEYBOARD_SC_3_AND_HASHMARK;
|
||||
case '$':
|
||||
return 0;
|
||||
return HID_KEYBOARD_SC_4_AND_DOLLAR;
|
||||
case '%':
|
||||
return 0;
|
||||
return HID_KEYBOARD_SC_5_AND_PERCENTAGE;
|
||||
case '^':
|
||||
return 0;
|
||||
return HID_KEYBOARD_SC_6_AND_CARET;
|
||||
case '&':
|
||||
return 0;
|
||||
return HID_KEYBOARD_SC_7_AND_AMPERSAND;
|
||||
case '*':
|
||||
return 0;
|
||||
return HID_KEYBOARD_SC_8_AND_ASTERISK;
|
||||
case '(':
|
||||
return 0;
|
||||
return HID_KEYBOARD_SC_9_AND_OPENING_PARENTHESIS;
|
||||
case '`':
|
||||
case '~':
|
||||
return 0;
|
||||
return HID_KEYBOARD_SC_GRAVE_ACCENT_AND_TILDE;
|
||||
case '[':
|
||||
case '{':
|
||||
return 0;
|
||||
return HID_KEYBOARD_SC_OPENING_BRACKET_AND_OPENING_BRACE;
|
||||
case ']':
|
||||
case '}':
|
||||
return 0;
|
||||
return HID_KEYBOARD_SC_CLOSING_BRACKET_AND_CLOSING_BRACE;
|
||||
case ';':
|
||||
case ':':
|
||||
return 0;
|
||||
return HID_KEYBOARD_SC_SEMICOLON_AND_COLON;
|
||||
case '\'':
|
||||
case '\"':
|
||||
return 0;
|
||||
return HID_KEYBOARD_SC_APOSTROPHE_AND_QUOTE;
|
||||
case '+':
|
||||
case '=':
|
||||
return 0;
|
||||
return HID_KEYBOARD_SC_EQUAL_AND_PLUS;
|
||||
case '\\':
|
||||
case '|':
|
||||
return 0;
|
||||
return HID_KEYBOARD_SC_BACKSLASH_AND_PIPE;
|
||||
case '.':
|
||||
case '>':
|
||||
return 0;
|
||||
return HID_KEYBOARD_SC_DOT_AND_GREATER_THAN_SIGN;
|
||||
case ',':
|
||||
case '<':
|
||||
return 0;
|
||||
return HID_KEYBOARD_SC_COMMA_AND_LESS_THAN_SIGN;
|
||||
case '/':
|
||||
case '\?':
|
||||
return 0;
|
||||
return HID_KEYBOARD_SC_SLASH_AND_QUESTION_MARK;
|
||||
case '-':
|
||||
case '_':
|
||||
return 0;
|
||||
return HID_KEYBOARD_SC_MINUS_AND_UNDERSCORE;
|
||||
case '\n':
|
||||
return HID_KEYBOARD_SC_ENTER;
|
||||
case ' ':
|
||||
return HID_KEYBOARD_SC_SPACE;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool characterToShift(char character)
|
||||
{
|
||||
switch (character) {
|
||||
case 'A' ... 'Z':
|
||||
case ')':
|
||||
case '!':
|
||||
case '@':
|
||||
case '#':
|
||||
case '$':
|
||||
case '%':
|
||||
case '^':
|
||||
case '&':
|
||||
case '*':
|
||||
case '(':
|
||||
case '~':
|
||||
case '{':
|
||||
case '}':
|
||||
case ':':
|
||||
case '\"':
|
||||
case '+':
|
||||
case '|':
|
||||
case '>':
|
||||
case '<':
|
||||
case '\?':
|
||||
case '_':
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void addBasicScancode(uint8_t scancode)
|
||||
{
|
||||
if (!scancode) {
|
||||
@@ -184,89 +218,183 @@ void deleteSystemScancode(uint8_t scancode)
|
||||
}
|
||||
}
|
||||
|
||||
bool processKeyMacroAction(void)
|
||||
void addScancode(uint16_t scancode, macro_sub_action_t type)
|
||||
{
|
||||
switch (type) {
|
||||
case KeystrokeType_Basic:
|
||||
addBasicScancode(scancode);
|
||||
break;
|
||||
case KeystrokeType_Media:
|
||||
addMediaScancode(scancode);
|
||||
break;
|
||||
case KeystrokeType_System:
|
||||
addSystemScancode(scancode);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void deleteScancode(uint16_t scancode, macro_sub_action_t type)
|
||||
{
|
||||
switch (type) {
|
||||
case KeystrokeType_Basic:
|
||||
deleteBasicScancode(scancode);
|
||||
break;
|
||||
case KeystrokeType_Media:
|
||||
deleteMediaScancode(scancode);
|
||||
break;
|
||||
case KeystrokeType_System:
|
||||
deleteSystemScancode(scancode);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool processKeyAction(void)
|
||||
{
|
||||
static bool pressStarted;
|
||||
|
||||
switch (currentMacroAction.key.action) {
|
||||
case MacroSubAction_Press:
|
||||
case MacroSubAction_Tap:
|
||||
if (!pressStarted) {
|
||||
pressStarted = true;
|
||||
addModifiers(currentMacroAction.key.modifierMask);
|
||||
switch (currentMacroAction.key.type) {
|
||||
case KeystrokeType_Basic:
|
||||
addBasicScancode(currentMacroAction.key.scancode);
|
||||
break;
|
||||
case KeystrokeType_Media:
|
||||
// addMediaScancode(currentMacroAction.key.scancode);
|
||||
break;
|
||||
case KeystrokeType_System:
|
||||
addSystemScancode(currentMacroAction.key.scancode);
|
||||
break;
|
||||
}
|
||||
addScancode(currentMacroAction.key.scancode, currentMacroAction.key.type);
|
||||
return true;
|
||||
}
|
||||
pressStarted = false;
|
||||
deleteModifiers(currentMacroAction.key.modifierMask);
|
||||
switch (currentMacroAction.key.type) {
|
||||
case KeystrokeType_Basic:
|
||||
deleteBasicScancode(currentMacroAction.key.scancode);
|
||||
break;
|
||||
case KeystrokeType_Media:
|
||||
// deleteMediaScancode(currentMacroAction.key.scancode);
|
||||
break;
|
||||
case KeystrokeType_System:
|
||||
deleteSystemScancode(currentMacroAction.key.scancode);
|
||||
break;
|
||||
}
|
||||
deleteScancode(currentMacroAction.key.scancode, currentMacroAction.key.type);
|
||||
break;
|
||||
case MacroSubAction_Release:
|
||||
deleteModifiers(currentMacroAction.key.modifierMask);
|
||||
switch (currentMacroAction.key.type) {
|
||||
case KeystrokeType_Basic:
|
||||
deleteBasicScancode(currentMacroAction.key.scancode);
|
||||
break;
|
||||
case KeystrokeType_Media:
|
||||
// deleteMediaScancode(currentMacroAction.key.scancode);
|
||||
break;
|
||||
case KeystrokeType_System:
|
||||
deleteSystemScancode(currentMacroAction.key.scancode);
|
||||
break;
|
||||
}
|
||||
deleteScancode(currentMacroAction.key.scancode, currentMacroAction.key.type);
|
||||
break;
|
||||
case MacroSubAction_Hold:
|
||||
case MacroSubAction_Press:
|
||||
addModifiers(currentMacroAction.key.modifierMask);
|
||||
switch (currentMacroAction.key.type) {
|
||||
case KeystrokeType_Basic:
|
||||
addBasicScancode(currentMacroAction.key.scancode);
|
||||
break;
|
||||
case KeystrokeType_Media:
|
||||
// addMediaScancode(currentMacroAction.key.scancode);
|
||||
break;
|
||||
case KeystrokeType_System:
|
||||
addSystemScancode(currentMacroAction.key.scancode);
|
||||
break;
|
||||
}
|
||||
addScancode(currentMacroAction.key.scancode, currentMacroAction.key.type);
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool processDelayAction(void)
|
||||
{
|
||||
static bool inDelay;
|
||||
static uint32_t delayStart;
|
||||
|
||||
if (inDelay) {
|
||||
if (Timer_GetElapsedTime(&delayStart) >= currentMacroAction.delay.delay) {
|
||||
inDelay = false;
|
||||
}
|
||||
} else {
|
||||
delayStart = CurrentTime;
|
||||
inDelay = true;
|
||||
}
|
||||
return inDelay;
|
||||
}
|
||||
|
||||
bool processMouseButtonAction(void)
|
||||
{
|
||||
static bool pressStarted;
|
||||
|
||||
switch (currentMacroAction.key.action) {
|
||||
case MacroSubAction_Tap:
|
||||
if (!pressStarted) {
|
||||
pressStarted = true;
|
||||
MacroMouseReport.buttons |= currentMacroAction.mouseButton.mouseButtonsMask;
|
||||
return true;
|
||||
}
|
||||
pressStarted = false;
|
||||
MacroMouseReport.buttons &= ~currentMacroAction.mouseButton.mouseButtonsMask;
|
||||
break;
|
||||
case MacroSubAction_Release:
|
||||
MacroMouseReport.buttons &= ~currentMacroAction.mouseButton.mouseButtonsMask;
|
||||
break;
|
||||
case MacroSubAction_Press:
|
||||
MacroMouseReport.buttons |= currentMacroAction.mouseButton.mouseButtonsMask;
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool processMoveMouseAction(void)
|
||||
{
|
||||
static bool inMotion;
|
||||
|
||||
if (inMotion) {
|
||||
MacroMouseReport.x = 0;
|
||||
MacroMouseReport.y = 0;
|
||||
inMotion = false;
|
||||
} else {
|
||||
MacroMouseReport.x = currentMacroAction.moveMouse.x;
|
||||
MacroMouseReport.y = currentMacroAction.moveMouse.y;
|
||||
inMotion = true;
|
||||
}
|
||||
return inMotion;
|
||||
}
|
||||
|
||||
bool processScrollMouseAction(void)
|
||||
{
|
||||
static bool inMotion;
|
||||
|
||||
if (inMotion) {
|
||||
MacroMouseReport.wheelX = 0;
|
||||
MacroMouseReport.wheelY = 0;
|
||||
inMotion = false;
|
||||
} else {
|
||||
MacroMouseReport.wheelX = currentMacroAction.scrollMouse.x;
|
||||
MacroMouseReport.wheelY = currentMacroAction.scrollMouse.y;
|
||||
inMotion = true;
|
||||
}
|
||||
return inMotion;
|
||||
}
|
||||
|
||||
bool processTextAction(void)
|
||||
{
|
||||
static uint16_t textIndex;
|
||||
static uint8_t reportIndex = USB_BASIC_KEYBOARD_MAX_KEYS;
|
||||
char character;
|
||||
uint8_t scancode;
|
||||
|
||||
if (textIndex == currentMacroAction.text.textLen) {
|
||||
textIndex = 0;
|
||||
reportIndex = USB_BASIC_KEYBOARD_MAX_KEYS;
|
||||
memset(&MacroBasicKeyboardReport, 0, sizeof MacroBasicKeyboardReport);
|
||||
return false;
|
||||
}
|
||||
if (reportIndex == USB_BASIC_KEYBOARD_MAX_KEYS) {
|
||||
reportIndex = 0;
|
||||
memset(&MacroBasicKeyboardReport, 0, sizeof MacroBasicKeyboardReport);
|
||||
return true;
|
||||
}
|
||||
character = currentMacroAction.text.text[textIndex];
|
||||
scancode = characterToScancode(character);
|
||||
for (uint8_t i = 0; i < reportIndex; i++) {
|
||||
if (MacroBasicKeyboardReport.scancodes[i] == scancode) {
|
||||
reportIndex = USB_BASIC_KEYBOARD_MAX_KEYS;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
MacroBasicKeyboardReport.scancodes[reportIndex++] = scancode;
|
||||
MacroBasicKeyboardReport.modifiers = characterToShift(character) ? HID_KEYBOARD_MODIFIER_LEFTSHIFT : 0;
|
||||
++textIndex;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool processCurrentMacroAction(void)
|
||||
{
|
||||
switch (currentMacroAction.type) {
|
||||
case MacroActionType_Delay:
|
||||
return false;
|
||||
return processDelayAction();
|
||||
case MacroActionType_Key:
|
||||
return processKeyMacroAction();
|
||||
return processKeyAction();
|
||||
case MacroActionType_MouseButton:
|
||||
return false;
|
||||
return processMouseButtonAction();
|
||||
case MacroActionType_MoveMouse:
|
||||
return false;
|
||||
return processMoveMouseAction();
|
||||
case MacroActionType_ScrollMouse:
|
||||
return false;
|
||||
return processScrollMouseAction();
|
||||
case MacroActionType_Text:
|
||||
return false;
|
||||
return processTextAction();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -20,8 +20,8 @@
|
||||
} macro_reference_t;
|
||||
|
||||
typedef enum {
|
||||
MacroSubAction_Tap,
|
||||
MacroSubAction_Press,
|
||||
MacroSubAction_Hold,
|
||||
MacroSubAction_Release,
|
||||
} macro_sub_action_t;
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
int16_t y;
|
||||
} ATTR_PACKED scrollMouse;
|
||||
struct {
|
||||
int16_t delay;
|
||||
uint16_t delay;
|
||||
} ATTR_PACKED delay;
|
||||
struct {
|
||||
const char *text;
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#include "bus_pal_hardware.h"
|
||||
#include "command.h"
|
||||
#include "eeprom.h"
|
||||
#include "key_scanner.h"
|
||||
#include "right_key_matrix.h"
|
||||
#include "usb_commands/usb_command_apply_config.h"
|
||||
#include "peripherals/reset_button.h"
|
||||
#include "config_parser/config_globals.h"
|
||||
@@ -44,8 +44,6 @@ int main(void)
|
||||
} else {
|
||||
InitSlaveScheduler();
|
||||
KeyMatrix_Init(&RightKeyMatrix);
|
||||
InitKeyScanner();
|
||||
UpdateUsbReports();
|
||||
InitUsb();
|
||||
|
||||
while (1) {
|
||||
@@ -53,6 +51,8 @@ int main(void)
|
||||
UsbCommand_ApplyConfig();
|
||||
IsConfigInitialized = true;
|
||||
}
|
||||
KeyMatrix_ScanRow(&RightKeyMatrix);
|
||||
++MatrixScanCounter;
|
||||
UpdateUsbReports();
|
||||
__WFI();
|
||||
}
|
||||
|
||||
@@ -17,12 +17,4 @@
|
||||
#define PIT_TIMER_IRQ_ID PIT1_IRQn
|
||||
#define PIT_TIMER_CHANNEL kPIT_Chnl_1
|
||||
|
||||
#define PIT_KEY_SCANNER_HANDLER PIT2_IRQHandler
|
||||
#define PIT_KEY_SCANNER_IRQ_ID PIT2_IRQn
|
||||
#define PIT_KEY_SCANNER_CHANNEL kPIT_Chnl_2
|
||||
|
||||
#define PIT_KEY_DEBOUNCER_HANDLER PIT3_IRQHandler
|
||||
#define PIT_KEY_DEBOUNCER_IRQ_ID PIT3_IRQn
|
||||
#define PIT_KEY_DEBOUNCER_CHANNEL kPIT_Chnl_3
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,10 +1,31 @@
|
||||
#include "test_led.h"
|
||||
#include "fsl_port.h"
|
||||
#include "timer.h"
|
||||
|
||||
void InitTestLed(void)
|
||||
void TestLed_Init(void)
|
||||
{
|
||||
CLOCK_EnableClock(TEST_LED_CLOCK);
|
||||
PORT_SetPinMux(TEST_LED_GPIO_PORT, TEST_LED_GPIO_PIN, kPORT_MuxAsGpio);
|
||||
GPIO_PinInit(TEST_LED_GPIO, TEST_LED_GPIO_PIN, &(gpio_pin_config_t){kGPIO_DigitalOutput, 1});
|
||||
TEST_LED_ON();
|
||||
TestLed_On();
|
||||
}
|
||||
|
||||
void TestLed_Blink(uint8_t times)
|
||||
{
|
||||
TestLed_Off();
|
||||
Timer_Delay(500);
|
||||
if (!times) {
|
||||
TestLed_On();
|
||||
Timer_Delay(500);
|
||||
TestLed_Off();
|
||||
Timer_Delay(500);
|
||||
return;
|
||||
}
|
||||
while (times--) {
|
||||
TestLed_On();
|
||||
Timer_Delay(100);
|
||||
TestLed_Off();
|
||||
Timer_Delay(100);
|
||||
}
|
||||
Timer_Delay(400);
|
||||
}
|
||||
|
||||
@@ -15,13 +15,29 @@
|
||||
#define TEST_LED_CLOCK kCLOCK_PortD
|
||||
#define TEST_LED_GPIO_PIN 7U
|
||||
|
||||
#define TEST_LED_ON() GPIO_SetPinsOutput(TEST_LED_GPIO, 1U << TEST_LED_GPIO_PIN)
|
||||
#define TEST_LED_OFF() GPIO_ClearPinsOutput(TEST_LED_GPIO, 1U << TEST_LED_GPIO_PIN)
|
||||
#define TEST_LED_SET(state) GPIO_WritePinOutput(TEST_LED_GPIO, TEST_LED_GPIO_PIN, (state))
|
||||
#define TEST_LED_TOGGLE() GPIO_TogglePinsOutput(TEST_LED_GPIO, 1U << TEST_LED_GPIO_PIN)
|
||||
static inline void TestLed_On(void)
|
||||
{
|
||||
GPIO_SetPinsOutput(TEST_LED_GPIO, 1U << TEST_LED_GPIO_PIN);
|
||||
}
|
||||
|
||||
static inline void TestLed_Off(void)
|
||||
{
|
||||
GPIO_ClearPinsOutput(TEST_LED_GPIO, 1U << TEST_LED_GPIO_PIN);
|
||||
}
|
||||
|
||||
static inline void TestLed_Set(bool state)
|
||||
{
|
||||
GPIO_WritePinOutput(TEST_LED_GPIO, TEST_LED_GPIO_PIN, state);
|
||||
}
|
||||
|
||||
static inline void TestLed_Toggle(void)
|
||||
{
|
||||
GPIO_TogglePinsOutput(TEST_LED_GPIO, 1U << TEST_LED_GPIO_PIN);
|
||||
}
|
||||
|
||||
// Functions:
|
||||
|
||||
void InitTestLed(void);
|
||||
void TestLed_Init(void);
|
||||
void TestLed_Blink(uint8_t times);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#include "right_key_matrix.h"
|
||||
|
||||
uint32_t MatrixScanCounter;
|
||||
|
||||
key_matrix_t RightKeyMatrix = {
|
||||
.colNum = RIGHT_KEY_MATRIX_COLS_NUM,
|
||||
.rowNum = RIGHT_KEY_MATRIX_ROWS_NUM,
|
||||
|
||||
@@ -14,5 +14,6 @@
|
||||
// Variables:
|
||||
|
||||
extern key_matrix_t RightKeyMatrix;
|
||||
extern uint32_t MatrixScanCounter;
|
||||
|
||||
#endif
|
||||
|
||||
113
right/src/test_switches.c
Normal file
113
right/src/test_switches.c
Normal file
@@ -0,0 +1,113 @@
|
||||
#include "test_switches.h"
|
||||
#include "led_display.h"
|
||||
#include "key_action.h"
|
||||
#include "keymap.h"
|
||||
|
||||
bool TestSwitches = false;
|
||||
|
||||
static const key_action_t TestKeymap[1][2][MAX_KEY_COUNT_PER_MODULE] = {
|
||||
// Base layer
|
||||
{
|
||||
// Right keyboard half
|
||||
{
|
||||
// Row 1
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_7_AND_AMPERSAND } },
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_8_AND_ASTERISK } },
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_9_AND_OPENING_PARENTHESIS } },
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_0_AND_CLOSING_PARENTHESIS } },
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_MINUS_AND_UNDERSCORE } },
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_EQUAL_AND_PLUS } },
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_BACKSPACE } },
|
||||
|
||||
// Row 2
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_U } },
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_I } },
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_O } },
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_P } },
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_OPENING_BRACKET_AND_OPENING_BRACE } },
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_CLOSING_BRACKET_AND_CLOSING_BRACE } },
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_BACKSLASH_AND_PIPE } },
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_Y } },
|
||||
|
||||
// Row 3
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_J } },
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_K } },
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_L } },
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_SEMICOLON_AND_COLON } },
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_APOSTROPHE_AND_QUOTE } },
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_KEYPAD_PLUS } },
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_H } },
|
||||
|
||||
// Row 4
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_N } },
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_M } },
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_COMMA_AND_LESS_THAN_SIGN } },
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_DOT_AND_GREATER_THAN_SIGN } },
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_SLASH_AND_QUESTION_MARK } },
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_RIGHT_SHIFT } },
|
||||
{ .type = KeyActionType_None },
|
||||
|
||||
// Row 5
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_KEYPAD_6_AND_RIGHT_ARROW } },
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_KEYPAD_ASTERISK } },
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_KEYPAD_7_AND_HOME } },
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_KEYPAD_8_AND_UP_ARROW } },
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_KEYPAD_9_AND_PAGE_UP } },
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_KEYPAD_0_AND_INSERT } },
|
||||
},
|
||||
|
||||
// Left keyboard half
|
||||
{
|
||||
// Row 1
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_GRAVE_ACCENT_AND_TILDE } },
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_1_AND_EXCLAMATION } },
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_2_AND_AT } },
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_3_AND_HASHMARK } },
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_4_AND_DOLLAR } },
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_5_AND_PERCENTAGE } },
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_6_AND_CARET } },
|
||||
|
||||
// Row 2
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_ESCAPE } },
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_Q } },
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_W } },
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_E } },
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_R } },
|
||||
{ .type = KeyActionType_None },
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_T } },
|
||||
|
||||
// Row 3
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_KEYPAD_MINUS } },
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_A } },
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_S } },
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_D } },
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_F } },
|
||||
{ .type = KeyActionType_None },
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_G } },
|
||||
|
||||
// Row 4
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_LEFT_SHIFT } },
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_NON_US_BACKSLASH_AND_PIPE } },
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_Z } },
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_X } },
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_C } },
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_V } },
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_B } },
|
||||
|
||||
// Row 5
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_KEYPAD_1_AND_END } },
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_KEYPAD_2_AND_DOWN_ARROW } },
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_KEYPAD_3_AND_PAGE_DOWN } },
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_KEYPAD_4_AND_LEFT_ARROW } },
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_KEYPAD_SLASH } },
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_KEYPAD_5 } },
|
||||
{ .type = KeyActionType_None },
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void TestSwitches_Activate(void)
|
||||
{
|
||||
memcpy(&CurrentKeymap, &TestKeymap, sizeof TestKeymap);
|
||||
LedDisplay_SetText(3, "TES");
|
||||
}
|
||||
16
right/src/test_switches.h
Normal file
16
right/src/test_switches.h
Normal file
@@ -0,0 +1,16 @@
|
||||
#ifndef __TEST_MODE_H__
|
||||
#define __TEST_MODE_H__
|
||||
|
||||
// Includes:
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
// Functions:
|
||||
|
||||
void TestSwitches_Activate(void);
|
||||
|
||||
// Variables:
|
||||
|
||||
extern bool TestSwitches;
|
||||
|
||||
#endif
|
||||
@@ -1,12 +1,18 @@
|
||||
#include "fsl_pit.h"
|
||||
#include "timer.h"
|
||||
#include "peripherals/test_led.h"
|
||||
|
||||
static volatile uint32_t CurrentTime;
|
||||
volatile uint32_t CurrentTime;
|
||||
static uint32_t timerClockFrequency;
|
||||
static volatile uint32_t delayLength;
|
||||
|
||||
void PIT_TIMER_HANDLER(void)
|
||||
{
|
||||
CurrentTime++;
|
||||
PIT_ClearStatusFlags(PIT, PIT_TIMER_CHANNEL, PIT_TFLG_TIF_MASK);
|
||||
if (delayLength) {
|
||||
--delayLength;
|
||||
}
|
||||
PIT_ClearStatusFlags(PIT, PIT_TIMER_CHANNEL, kPIT_TimerFlag);
|
||||
}
|
||||
|
||||
void Timer_Init(void)
|
||||
@@ -15,28 +21,39 @@ void Timer_Init(void)
|
||||
PIT_GetDefaultConfig(&pitConfig);
|
||||
PIT_Init(PIT, &pitConfig);
|
||||
|
||||
// TODO: Why the interval needs to be multiplied by two to arrive to the correct timing?
|
||||
// Figure it out and clean this up.
|
||||
PIT_SetTimerPeriod(PIT, PIT_TIMER_CHANNEL, MSEC_TO_COUNT(TIMER_INTERVAL_MSEC*2, PIT_SOURCE_CLOCK));
|
||||
timerClockFrequency = PIT_SOURCE_CLOCK;
|
||||
PIT_SetTimerPeriod(PIT, PIT_TIMER_CHANNEL, MSEC_TO_COUNT(TIMER_INTERVAL_MSEC, timerClockFrequency));
|
||||
|
||||
PIT_EnableInterrupts(PIT, PIT_TIMER_CHANNEL, kPIT_TimerInterruptEnable);
|
||||
EnableIRQ(PIT_TIMER_IRQ_ID);
|
||||
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
|
||||
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
|
||||
uint32_t us = 1000U * TIMER_INTERVAL_MSEC - COUNT_TO_USEC(count, timerClockFrequency);
|
||||
return ms * 1000U * TIMER_INTERVAL_MSEC + us;
|
||||
}
|
||||
|
||||
void Timer_SetCurrentTime(uint32_t *time)
|
||||
void Timer_SetCurrentTimeMicros(uint32_t *time)
|
||||
{
|
||||
*time = CurrentTime;
|
||||
*time = Timer_GetCurrentTimeMicros();
|
||||
}
|
||||
|
||||
uint32_t Timer_GetElapsedTime(uint32_t *time)
|
||||
{
|
||||
uint32_t elapsedTime = CurrentTime - *time;
|
||||
return elapsedTime;
|
||||
return CurrentTime - *time;
|
||||
}
|
||||
|
||||
uint32_t Timer_GetElapsedTimeMicros(uint32_t *time)
|
||||
{
|
||||
return Timer_GetCurrentTimeMicros() - *time;
|
||||
}
|
||||
|
||||
uint32_t Timer_GetElapsedTimeAndSetCurrent(uint32_t *time)
|
||||
@@ -45,3 +62,18 @@ uint32_t Timer_GetElapsedTimeAndSetCurrent(uint32_t *time)
|
||||
*time = CurrentTime;
|
||||
return elapsedTime;
|
||||
}
|
||||
|
||||
uint32_t Timer_GetElapsedTimeAndSetCurrentMicros(uint32_t *time)
|
||||
{
|
||||
uint32_t elapsedTime = Timer_GetElapsedTimeMicros(time);
|
||||
*time = Timer_GetCurrentTimeMicros();
|
||||
return elapsedTime;
|
||||
}
|
||||
|
||||
void Timer_Delay(uint32_t length)
|
||||
{
|
||||
delayLength = length;
|
||||
while (delayLength) {
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,12 +9,19 @@
|
||||
|
||||
#define TIMER_INTERVAL_MSEC 1
|
||||
|
||||
// Variables:
|
||||
|
||||
extern volatile uint32_t CurrentTime;
|
||||
|
||||
// Functions:
|
||||
|
||||
void Timer_Init(void);
|
||||
uint32_t Timer_GetCurrentTime();
|
||||
void Timer_SetCurrentTime(uint32_t *time);
|
||||
uint32_t Timer_GetCurrentTimeMicros();
|
||||
void Timer_SetCurrentTimeMicros(uint32_t *time);
|
||||
uint32_t Timer_GetElapsedTime(uint32_t *time);
|
||||
uint32_t Timer_GetElapsedTimeMicros(uint32_t *time);
|
||||
uint32_t Timer_GetElapsedTimeAndSetCurrent(uint32_t *time);
|
||||
uint32_t Timer_GetElapsedTimeAndSetCurrentMicros(uint32_t *time);
|
||||
void Timer_Delay(uint32_t length);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include "i2c_watchdog.h"
|
||||
#include "buffer.h"
|
||||
#include "timer.h"
|
||||
#include "key_scanner.h"
|
||||
#include "right_key_matrix.h"
|
||||
#include "usb_report_updater.h"
|
||||
#include "usb_interfaces/usb_interface_basic_keyboard.h"
|
||||
#include "usb_interfaces/usb_interface_media_keyboard.h"
|
||||
@@ -20,9 +20,9 @@ void UsbCommand_GetDebugBuffer(void)
|
||||
SetDebugBufferUint32(5, I2cSlaveScheduler_Counter);
|
||||
SetDebugBufferUint32(9, I2cWatchdog_WatchCounter);
|
||||
SetDebugBufferUint32(13, I2cWatchdog_RecoveryCounter);
|
||||
SetDebugBufferUint32(17, KeyScannerCounter);
|
||||
SetDebugBufferUint32(17, MatrixScanCounter);
|
||||
SetDebugBufferUint32(21, UsbReportUpdateCounter);
|
||||
SetDebugBufferUint32(25, Timer_GetCurrentTime());
|
||||
SetDebugBufferUint32(25, CurrentTime);
|
||||
SetDebugBufferUint32(29, UsbGenericHidActionCounter);
|
||||
SetDebugBufferUint32(33, UsbBasicKeyboardActionCounter);
|
||||
SetDebugBufferUint32(37, UsbMediaKeyboardActionCounter);
|
||||
|
||||
@@ -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);
|
||||
|
||||
28
right/src/usb_commands/usb_command_get_variable.c
Normal file
28
right/src/usb_commands/usb_command_get_variable.c
Normal file
@@ -0,0 +1,28 @@
|
||||
#include "usb_protocol_handler.h"
|
||||
#include "usb_commands/usb_command_get_variable.h"
|
||||
#include "key_matrix.h"
|
||||
#include "test_switches.h"
|
||||
#include "usb_report_updater.h"
|
||||
|
||||
void UsbCommand_GetVariable(void)
|
||||
{
|
||||
usb_variable_id_t variableId = GetUsbRxBufferUint8(1);
|
||||
|
||||
switch (variableId) {
|
||||
case UsbVariable_TestSwitches:
|
||||
SetUsbTxBufferUint8(1, TestSwitches);
|
||||
break;
|
||||
case UsbVariable_TestUsbStack:
|
||||
SetUsbTxBufferUint8(1, TestUsbStack);
|
||||
break;
|
||||
case UsbVariable_DebounceTimePress:
|
||||
SetUsbTxBufferUint8(1, DebounceTimePress);
|
||||
break;
|
||||
case UsbVariable_DebounceTimeRelease:
|
||||
SetUsbTxBufferUint8(1, DebounceTimeRelease);
|
||||
break;
|
||||
case UsbVariable_UsbReportSemaphore:
|
||||
SetUsbTxBufferUint8(1, UsbReportUpdateSemaphore);
|
||||
break;
|
||||
}
|
||||
}
|
||||
8
right/src/usb_commands/usb_command_get_variable.h
Normal file
8
right/src/usb_commands/usb_command_get_variable.h
Normal file
@@ -0,0 +1,8 @@
|
||||
#ifndef __USB_COMMAND_GET_VARIABLE_H__
|
||||
#define __USB_COMMAND_GET_VARIABLE_H__
|
||||
|
||||
// Functions:
|
||||
|
||||
void UsbCommand_GetVariable(void);
|
||||
|
||||
#endif
|
||||
@@ -6,6 +6,6 @@
|
||||
void UsbCommand_SetTestLed(void)
|
||||
{
|
||||
bool isTestLedOn = GetUsbRxBufferUint8(1);
|
||||
TEST_LED_SET(isTestLedOn);
|
||||
TestLed_Set(isTestLedOn);
|
||||
UhkModuleStates[UhkModuleDriverId_LeftKeyboardHalf].sourceVars.isTestLedOn = isTestLedOn;
|
||||
}
|
||||
|
||||
31
right/src/usb_commands/usb_command_set_variable.c
Normal file
31
right/src/usb_commands/usb_command_set_variable.c
Normal file
@@ -0,0 +1,31 @@
|
||||
#include "usb_protocol_handler.h"
|
||||
#include "usb_commands/usb_command_set_variable.h"
|
||||
#include "key_matrix.h"
|
||||
#include "test_switches.h"
|
||||
#include "usb_report_updater.h"
|
||||
|
||||
void UsbCommand_SetVariable(void)
|
||||
{
|
||||
usb_variable_id_t variableId = GetUsbRxBufferUint8(1);
|
||||
|
||||
switch (variableId) {
|
||||
case UsbVariable_TestSwitches:
|
||||
if (GetUsbRxBufferUint8(2)) {
|
||||
TestSwitches = true;
|
||||
TestSwitches_Activate();
|
||||
}
|
||||
break;
|
||||
case UsbVariable_TestUsbStack:
|
||||
TestUsbStack = GetUsbRxBufferUint8(2);
|
||||
break;
|
||||
case UsbVariable_DebounceTimePress:
|
||||
DebounceTimePress = GetUsbRxBufferUint8(2);
|
||||
break;
|
||||
case UsbVariable_DebounceTimeRelease:
|
||||
DebounceTimeRelease = GetUsbRxBufferUint8(2);
|
||||
break;
|
||||
case UsbVariable_UsbReportSemaphore:
|
||||
UsbReportUpdateSemaphore = GetUsbRxBufferUint8(2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
8
right/src/usb_commands/usb_command_set_variable.h
Normal file
8
right/src/usb_commands/usb_command_set_variable.h
Normal file
@@ -0,0 +1,8 @@
|
||||
#ifndef __USB_COMMAND_SET_VARIABLE_H__
|
||||
#define __USB_COMMAND_SET_VARIABLE_H__
|
||||
|
||||
// Functions:
|
||||
|
||||
void UsbCommand_SetVariable(void);
|
||||
|
||||
#endif
|
||||
@@ -163,23 +163,30 @@ 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.
|
||||
// Send resume signal - this will call USB_DeviceKhciControl(khciHandle, kUSB_DeviceControlResume, NULL);
|
||||
USB_DeviceSetStatus(UsbCompositeDevice.deviceHandle, kUSB_DeviceStatusBus, NULL);
|
||||
}
|
||||
|
||||
IsHostSleeping = false;
|
||||
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) {
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
static usb_status_t usbDeviceCallback(usb_device_handle handle, uint32_t event, void *param)
|
||||
{
|
||||
usb_status_t status = kStatus_USB_Error;
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -12,7 +12,13 @@
|
||||
// Macros:
|
||||
|
||||
#define USB_COMPOSITE_CONFIGURATION_INDEX 1
|
||||
#define USB_CONFIGURATION_DESCRIPTOR_TOTAL_LENGTH 141
|
||||
#define USB_CONFIGURATION_DESCRIPTOR_TOTAL_LENGTH \
|
||||
(5 * USB_DESCRIPTOR_LENGTH_INTERFACE + 5 * USB_DESCRIPTOR_LENGTH_HID + \
|
||||
6 * USB_DESCRIPTOR_LENGTH_ENDPOINT + USB_DESCRIPTOR_LENGTH_CONFIGURE)
|
||||
|
||||
// Variables:
|
||||
|
||||
extern uint8_t UsbConfigurationDescriptor[USB_CONFIGURATION_DESCRIPTOR_TOTAL_LENGTH];
|
||||
|
||||
// Functions:
|
||||
|
||||
|
||||
@@ -2,33 +2,80 @@
|
||||
#include "usb_descriptor_hid.h"
|
||||
#include "usb_descriptor_mouse_report.h"
|
||||
#include "usb_descriptor_generic_hid_report.h"
|
||||
#include "usb_descriptor_configuration.h"
|
||||
|
||||
#define USB_GENERIC_HID_DESCRIPTOR_INDEX \
|
||||
(USB_DESCRIPTOR_LENGTH_CONFIGURE + USB_DESCRIPTOR_LENGTH_INTERFACE)
|
||||
|
||||
#define USB_BASIC_KEYBOARD_HID_DESCRIPTOR_INDEX \
|
||||
(USB_GENERIC_HID_DESCRIPTOR_INDEX + USB_DESCRIPTOR_LENGTH_HID + \
|
||||
2 * USB_DESCRIPTOR_LENGTH_ENDPOINT + USB_DESCRIPTOR_LENGTH_INTERFACE)
|
||||
|
||||
#define USB_MEDIA_KEYBOARD_HID_DESCRIPTOR_INDEX \
|
||||
(USB_BASIC_KEYBOARD_HID_DESCRIPTOR_INDEX + USB_DESCRIPTOR_LENGTH_HID + \
|
||||
USB_DESCRIPTOR_LENGTH_ENDPOINT + USB_DESCRIPTOR_LENGTH_INTERFACE)
|
||||
|
||||
#define USB_SYSTEM_KEYBOARD_HID_DESCRIPTOR_INDEX \
|
||||
(USB_MEDIA_KEYBOARD_HID_DESCRIPTOR_INDEX + USB_DESCRIPTOR_LENGTH_HID + \
|
||||
USB_DESCRIPTOR_LENGTH_ENDPOINT + USB_DESCRIPTOR_LENGTH_INTERFACE)
|
||||
|
||||
#define USB_MOUSE_HID_DESCRIPTOR_INDEX \
|
||||
(USB_SYSTEM_KEYBOARD_HID_DESCRIPTOR_INDEX + USB_DESCRIPTOR_LENGTH_HID + \
|
||||
USB_DESCRIPTOR_LENGTH_ENDPOINT + USB_DESCRIPTOR_LENGTH_INTERFACE)
|
||||
|
||||
usb_status_t USB_DeviceGetHidDescriptor(
|
||||
usb_device_handle handle, usb_device_get_hid_descriptor_struct_t *hidDescriptor)
|
||||
{
|
||||
return kStatus_USB_InvalidRequest;
|
||||
hidDescriptor->length = USB_DESCRIPTOR_LENGTH_HID;
|
||||
|
||||
switch (hidDescriptor->interfaceNumber) {
|
||||
case USB_GENERIC_HID_INTERFACE_INDEX:
|
||||
hidDescriptor->buffer = &UsbConfigurationDescriptor[USB_GENERIC_HID_DESCRIPTOR_INDEX];
|
||||
break;
|
||||
case USB_BASIC_KEYBOARD_INTERFACE_INDEX:
|
||||
hidDescriptor->buffer = &UsbConfigurationDescriptor[USB_BASIC_KEYBOARD_HID_DESCRIPTOR_INDEX];
|
||||
break;
|
||||
case USB_MEDIA_KEYBOARD_INTERFACE_INDEX:
|
||||
hidDescriptor->buffer = &UsbConfigurationDescriptor[USB_MEDIA_KEYBOARD_HID_DESCRIPTOR_INDEX];
|
||||
break;
|
||||
case USB_SYSTEM_KEYBOARD_INTERFACE_INDEX:
|
||||
hidDescriptor->buffer = &UsbConfigurationDescriptor[USB_SYSTEM_KEYBOARD_HID_DESCRIPTOR_INDEX];
|
||||
break;
|
||||
case USB_MOUSE_INTERFACE_INDEX:
|
||||
hidDescriptor->buffer = &UsbConfigurationDescriptor[USB_MOUSE_HID_DESCRIPTOR_INDEX];
|
||||
break;
|
||||
default:
|
||||
return kStatus_USB_InvalidRequest;
|
||||
}
|
||||
return kStatus_USB_Success;
|
||||
}
|
||||
|
||||
usb_status_t USB_DeviceGetHidReportDescriptor(
|
||||
usb_device_handle handle, usb_device_get_hid_report_descriptor_struct_t *hidReportDescriptor)
|
||||
{
|
||||
if (USB_GENERIC_HID_INTERFACE_INDEX == hidReportDescriptor->interfaceNumber) {
|
||||
hidReportDescriptor->buffer = UsbGenericHidReportDescriptor;
|
||||
hidReportDescriptor->length = USB_GENERIC_HID_REPORT_DESCRIPTOR_LENGTH;
|
||||
} else if (USB_BASIC_KEYBOARD_INTERFACE_INDEX == hidReportDescriptor->interfaceNumber) {
|
||||
hidReportDescriptor->buffer = UsbBasicKeyboardReportDescriptor;
|
||||
hidReportDescriptor->length = USB_BASIC_KEYBOARD_REPORT_DESCRIPTOR_LENGTH;
|
||||
} else if (USB_MEDIA_KEYBOARD_INTERFACE_INDEX == hidReportDescriptor->interfaceNumber) {
|
||||
hidReportDescriptor->buffer = UsbMediaKeyboardReportDescriptor;
|
||||
hidReportDescriptor->length = USB_MEDIA_KEYBOARD_REPORT_DESCRIPTOR_LENGTH;
|
||||
} else if (USB_SYSTEM_KEYBOARD_INTERFACE_INDEX == hidReportDescriptor->interfaceNumber) {
|
||||
hidReportDescriptor->buffer = UsbSystemKeyboardReportDescriptor;
|
||||
hidReportDescriptor->length = USB_MEDIA_KEYBOARD_REPORT_DESCRIPTOR_LENGTH;
|
||||
} else if (USB_MOUSE_INTERFACE_INDEX == hidReportDescriptor->interfaceNumber) {
|
||||
hidReportDescriptor->buffer = UsbMouseReportDescriptor;
|
||||
hidReportDescriptor->length = USB_MOUSE_REPORT_DESCRIPTOR_LENGTH;
|
||||
} else {
|
||||
return kStatus_USB_InvalidRequest;
|
||||
switch (hidReportDescriptor->interfaceNumber) {
|
||||
case USB_GENERIC_HID_INTERFACE_INDEX:
|
||||
hidReportDescriptor->buffer = UsbGenericHidReportDescriptor;
|
||||
hidReportDescriptor->length = USB_GENERIC_HID_REPORT_DESCRIPTOR_LENGTH;
|
||||
break;
|
||||
case USB_BASIC_KEYBOARD_INTERFACE_INDEX:
|
||||
hidReportDescriptor->buffer = UsbBasicKeyboardReportDescriptor;
|
||||
hidReportDescriptor->length = USB_BASIC_KEYBOARD_REPORT_DESCRIPTOR_LENGTH;
|
||||
break;
|
||||
case USB_MEDIA_KEYBOARD_INTERFACE_INDEX:
|
||||
hidReportDescriptor->buffer = UsbMediaKeyboardReportDescriptor;
|
||||
hidReportDescriptor->length = USB_MEDIA_KEYBOARD_REPORT_DESCRIPTOR_LENGTH;
|
||||
break;
|
||||
case USB_SYSTEM_KEYBOARD_INTERFACE_INDEX:
|
||||
hidReportDescriptor->buffer = UsbSystemKeyboardReportDescriptor;
|
||||
hidReportDescriptor->length = USB_MEDIA_KEYBOARD_REPORT_DESCRIPTOR_LENGTH;
|
||||
break;
|
||||
case USB_MOUSE_INTERFACE_INDEX:
|
||||
hidReportDescriptor->buffer = UsbMouseReportDescriptor;
|
||||
hidReportDescriptor->length = USB_MOUSE_REPORT_DESCRIPTOR_LENGTH;
|
||||
break;
|
||||
default:
|
||||
return kStatus_USB_InvalidRequest;
|
||||
}
|
||||
return kStatus_USB_Success;
|
||||
}
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
#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;
|
||||
usb_basic_keyboard_report_t* ActiveUsbBasicKeyboardReport = usbBasicKeyboardReports;
|
||||
volatile bool IsUsbBasicKeyboardReportSent = false;
|
||||
static uint8_t usbBasicKeyboardInBuffer[USB_BASIC_KEYBOARD_REPORT_LENGTH];
|
||||
|
||||
static usb_basic_keyboard_report_t* getInactiveUsbBasicKeyboardReport(void)
|
||||
usb_basic_keyboard_report_t* GetInactiveUsbBasicKeyboardReport(void)
|
||||
{
|
||||
return ActiveUsbBasicKeyboardReport == usbBasicKeyboardReports ? usbBasicKeyboardReports+1 : usbBasicKeyboardReports;
|
||||
}
|
||||
|
||||
void SwitchActiveUsbBasicKeyboardReport(void)
|
||||
static void SwitchActiveUsbBasicKeyboardReport(void)
|
||||
{
|
||||
ActiveUsbBasicKeyboardReport = getInactiveUsbBasicKeyboardReport();
|
||||
ActiveUsbBasicKeyboardReport = GetInactiveUsbBasicKeyboardReport();
|
||||
}
|
||||
|
||||
void ResetActiveUsbBasicKeyboardReport(void)
|
||||
@@ -22,14 +22,20 @@ void ResetActiveUsbBasicKeyboardReport(void)
|
||||
bzero(ActiveUsbBasicKeyboardReport, USB_BASIC_KEYBOARD_REPORT_LENGTH);
|
||||
}
|
||||
|
||||
static usb_status_t UsbBasicKeyboardAction(void)
|
||||
usb_status_t UsbBasicKeyboardAction(void)
|
||||
{
|
||||
usb_status_t status = USB_DeviceHidSend(
|
||||
if (!UsbCompositeDevice.attach) {
|
||||
return kStatus_USB_Error; // The device is not attached
|
||||
}
|
||||
|
||||
usb_status_t usb_status = USB_DeviceHidSend(
|
||||
UsbCompositeDevice.basicKeyboardHandle, USB_BASIC_KEYBOARD_ENDPOINT_INDEX,
|
||||
(uint8_t*)getInactiveUsbBasicKeyboardReport(), USB_BASIC_KEYBOARD_REPORT_LENGTH);
|
||||
IsUsbBasicKeyboardReportSent = true;
|
||||
UsbBasicKeyboardActionCounter++;
|
||||
return status;
|
||||
(uint8_t *)ActiveUsbBasicKeyboardReport, USB_BASIC_KEYBOARD_REPORT_LENGTH);
|
||||
if (usb_status == kStatus_USB_Success) {
|
||||
UsbBasicKeyboardActionCounter++;
|
||||
SwitchActiveUsbBasicKeyboardReport();
|
||||
}
|
||||
return usb_status;
|
||||
}
|
||||
|
||||
usb_status_t UsbBasicKeyboardCallback(class_handle_t handle, uint32_t event, void *param)
|
||||
@@ -37,11 +43,14 @@ usb_status_t UsbBasicKeyboardCallback(class_handle_t handle, uint32_t event, voi
|
||||
usb_status_t error = kStatus_USB_Error;
|
||||
|
||||
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) {
|
||||
return UsbBasicKeyboardAction();
|
||||
error = kStatus_USB_Success;
|
||||
}
|
||||
break;
|
||||
case kUSB_DeviceHidEventRecvResponse:
|
||||
case kUSB_DeviceHidEventGetReport:
|
||||
error = kStatus_USB_InvalidRequest;
|
||||
break;
|
||||
@@ -61,7 +70,7 @@ usb_status_t UsbBasicKeyboardCallback(class_handle_t handle, uint32_t event, voi
|
||||
report->reportBuffer = usbBasicKeyboardInBuffer;
|
||||
error = kStatus_USB_Success;
|
||||
} else {
|
||||
error = kStatus_USB_InvalidRequest;
|
||||
error = kStatus_USB_AllocFail;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -79,16 +88,10 @@ usb_status_t UsbBasicKeyboardCallback(class_handle_t handle, uint32_t event, voi
|
||||
|
||||
usb_status_t UsbBasicKeyboardSetConfiguration(class_handle_t handle, uint8_t configuration)
|
||||
{
|
||||
if (USB_COMPOSITE_CONFIGURATION_INDEX == configuration) {
|
||||
return UsbBasicKeyboardAction();
|
||||
}
|
||||
return kStatus_USB_Error;
|
||||
}
|
||||
|
||||
usb_status_t UsbBasicKeyboardSetInterface(class_handle_t handle, uint8_t interface, uint8_t alternateSetting)
|
||||
{
|
||||
if (USB_BASIC_KEYBOARD_INTERFACE_INDEX == interface) {
|
||||
return UsbBasicKeyboardAction();
|
||||
}
|
||||
return kStatus_USB_Error;
|
||||
}
|
||||
|
||||
@@ -31,7 +31,6 @@
|
||||
|
||||
// Variables:
|
||||
|
||||
extern volatile bool IsUsbBasicKeyboardReportSent;
|
||||
extern uint32_t UsbBasicKeyboardActionCounter;
|
||||
extern usb_basic_keyboard_report_t* ActiveUsbBasicKeyboardReport;
|
||||
|
||||
@@ -42,6 +41,7 @@
|
||||
usb_status_t UsbBasicKeyboardSetInterface(class_handle_t handle, uint8_t interface, uint8_t alternateSetting);
|
||||
|
||||
void ResetActiveUsbBasicKeyboardReport(void);
|
||||
void SwitchActiveUsbBasicKeyboardReport(void);
|
||||
usb_basic_keyboard_report_t* GetInactiveUsbBasicKeyboardReport(void);
|
||||
usb_status_t UsbBasicKeyboardAction(void);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -7,6 +7,10 @@ uint8_t GenericHidOutBuffer[USB_GENERIC_HID_OUT_BUFFER_LENGTH];
|
||||
|
||||
static usb_status_t UsbReceiveData(void)
|
||||
{
|
||||
if (!UsbCompositeDevice.attach) {
|
||||
return kStatus_USB_Error; // The device is not attached
|
||||
}
|
||||
|
||||
return USB_DeviceHidRecv(UsbCompositeDevice.genericHidHandle,
|
||||
USB_GENERIC_HID_ENDPOINT_OUT_INDEX,
|
||||
GenericHidInBuffer,
|
||||
@@ -18,7 +22,11 @@ usb_status_t UsbGenericHidCallback(class_handle_t handle, uint32_t event, void *
|
||||
usb_status_t error = kStatus_USB_Error;
|
||||
|
||||
switch (event) {
|
||||
// This event is received when the report has been sent
|
||||
case kUSB_DeviceHidEventSendResponse:
|
||||
if (UsbCompositeDevice.attach) {
|
||||
error = kStatus_USB_Success;
|
||||
}
|
||||
break;
|
||||
case kUSB_DeviceHidEventRecvResponse:
|
||||
UsbProtocolHandler();
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
#include "usb_composite_device.h"
|
||||
#include "usb_report_updater.h"
|
||||
|
||||
uint32_t UsbMediaKeyboardActionCounter;
|
||||
static usb_media_keyboard_report_t usbMediaKeyboardReports[2];
|
||||
usb_media_keyboard_report_t* ActiveUsbMediaKeyboardReport = usbMediaKeyboardReports;
|
||||
volatile bool IsUsbMediaKeyboardReportSent = false;
|
||||
|
||||
static usb_media_keyboard_report_t* getInactiveUsbMediaKeyboardReport(void)
|
||||
usb_media_keyboard_report_t* GetInactiveUsbMediaKeyboardReport(void)
|
||||
{
|
||||
return ActiveUsbMediaKeyboardReport == usbMediaKeyboardReports ? usbMediaKeyboardReports+1 : usbMediaKeyboardReports;
|
||||
}
|
||||
|
||||
void SwitchActiveUsbMediaKeyboardReport(void)
|
||||
static void SwitchActiveUsbMediaKeyboardReport(void)
|
||||
{
|
||||
ActiveUsbMediaKeyboardReport = getInactiveUsbMediaKeyboardReport();
|
||||
ActiveUsbMediaKeyboardReport = GetInactiveUsbMediaKeyboardReport();
|
||||
}
|
||||
|
||||
void ResetActiveUsbMediaKeyboardReport(void)
|
||||
@@ -20,14 +20,20 @@ void ResetActiveUsbMediaKeyboardReport(void)
|
||||
bzero(ActiveUsbMediaKeyboardReport, USB_MEDIA_KEYBOARD_REPORT_LENGTH);
|
||||
}
|
||||
|
||||
static usb_status_t UsbMediaKeyboardAction(void)
|
||||
usb_status_t UsbMediaKeyboardAction(void)
|
||||
{
|
||||
usb_status_t status = USB_DeviceHidSend(
|
||||
if (!UsbCompositeDevice.attach) {
|
||||
return kStatus_USB_Error; // The device is not attached
|
||||
}
|
||||
|
||||
usb_status_t usb_status = USB_DeviceHidSend(
|
||||
UsbCompositeDevice.mediaKeyboardHandle, USB_MEDIA_KEYBOARD_ENDPOINT_INDEX,
|
||||
(uint8_t*)getInactiveUsbMediaKeyboardReport(), USB_MEDIA_KEYBOARD_REPORT_LENGTH);
|
||||
IsUsbMediaKeyboardReportSent = true;
|
||||
UsbMediaKeyboardActionCounter++;
|
||||
return status;
|
||||
(uint8_t *)ActiveUsbMediaKeyboardReport, USB_MEDIA_KEYBOARD_REPORT_LENGTH);
|
||||
if (usb_status == kStatus_USB_Success) {
|
||||
UsbMediaKeyboardActionCounter++;
|
||||
SwitchActiveUsbMediaKeyboardReport();
|
||||
}
|
||||
return usb_status;
|
||||
}
|
||||
|
||||
usb_status_t UsbMediaKeyboardCallback(class_handle_t handle, uint32_t event, void *param)
|
||||
@@ -35,11 +41,14 @@ usb_status_t UsbMediaKeyboardCallback(class_handle_t handle, uint32_t event, voi
|
||||
usb_status_t error = kStatus_USB_Error;
|
||||
|
||||
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) {
|
||||
return UsbMediaKeyboardAction();
|
||||
error = kStatus_USB_Success;
|
||||
}
|
||||
break;
|
||||
case kUSB_DeviceHidEventRecvResponse:
|
||||
case kUSB_DeviceHidEventGetReport:
|
||||
case kUSB_DeviceHidEventSetReport:
|
||||
case kUSB_DeviceHidEventRequestReportBuffer:
|
||||
@@ -59,16 +68,10 @@ usb_status_t UsbMediaKeyboardCallback(class_handle_t handle, uint32_t event, voi
|
||||
|
||||
usb_status_t UsbMediaKeyboardSetConfiguration(class_handle_t handle, uint8_t configuration)
|
||||
{
|
||||
if (USB_COMPOSITE_CONFIGURATION_INDEX == configuration) {
|
||||
return UsbMediaKeyboardAction();
|
||||
}
|
||||
return kStatus_USB_Error;
|
||||
}
|
||||
|
||||
usb_status_t UsbMediaKeyboardSetInterface(class_handle_t handle, uint8_t interface, uint8_t alternateSetting)
|
||||
{
|
||||
if (USB_MEDIA_KEYBOARD_INTERFACE_INDEX == interface) {
|
||||
return UsbMediaKeyboardAction();
|
||||
}
|
||||
return kStatus_USB_Error;
|
||||
}
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
|
||||
// Variables:
|
||||
|
||||
extern volatile bool IsUsbMediaKeyboardReportSent;
|
||||
extern uint32_t UsbMediaKeyboardActionCounter;
|
||||
extern usb_media_keyboard_report_t* ActiveUsbMediaKeyboardReport;
|
||||
|
||||
@@ -39,6 +38,7 @@
|
||||
usb_status_t UsbMediaKeyboardSetInterface(class_handle_t handle, uint8_t interface, uint8_t alternateSetting);
|
||||
|
||||
void ResetActiveUsbMediaKeyboardReport(void);
|
||||
void SwitchActiveUsbMediaKeyboardReport(void);
|
||||
usb_media_keyboard_report_t* GetInactiveUsbMediaKeyboardReport(void);
|
||||
usb_status_t UsbMediaKeyboardAction();
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
#include "usb_composite_device.h"
|
||||
#include "usb_report_updater.h"
|
||||
|
||||
uint32_t UsbMouseActionCounter;
|
||||
static usb_mouse_report_t usbMouseReports[2];
|
||||
usb_mouse_report_t* ActiveUsbMouseReport = usbMouseReports;
|
||||
volatile bool IsUsbMouseReportSent = false;
|
||||
|
||||
static usb_mouse_report_t* getInactiveUsbMouseReport(void)
|
||||
usb_mouse_report_t* GetInactiveUsbMouseReport(void)
|
||||
{
|
||||
return ActiveUsbMouseReport == usbMouseReports ? usbMouseReports+1 : usbMouseReports;
|
||||
}
|
||||
|
||||
void SwitchActiveUsbMouseReport(void)
|
||||
static void SwitchActiveUsbMouseReport(void)
|
||||
{
|
||||
ActiveUsbMouseReport = getInactiveUsbMouseReport();
|
||||
ActiveUsbMouseReport = GetInactiveUsbMouseReport();
|
||||
}
|
||||
|
||||
void ResetActiveUsbMouseReport(void)
|
||||
@@ -20,25 +20,35 @@ void ResetActiveUsbMouseReport(void)
|
||||
bzero(ActiveUsbMouseReport, USB_MOUSE_REPORT_LENGTH);
|
||||
}
|
||||
|
||||
static volatile usb_status_t usbMouseAction(void)
|
||||
usb_status_t UsbMouseAction(void)
|
||||
{
|
||||
usb_mouse_report_t *mouseReport = getInactiveUsbMouseReport();
|
||||
IsUsbMouseReportSent = true;
|
||||
return USB_DeviceHidSend(UsbCompositeDevice.mouseHandle, USB_MOUSE_ENDPOINT_INDEX,
|
||||
(uint8_t*)mouseReport, USB_MOUSE_REPORT_LENGTH);
|
||||
if (!UsbCompositeDevice.attach) {
|
||||
return kStatus_USB_Error; // The device is not attached
|
||||
}
|
||||
|
||||
usb_status_t usb_status = USB_DeviceHidSend(
|
||||
UsbCompositeDevice.mouseHandle, USB_MOUSE_ENDPOINT_INDEX,
|
||||
(uint8_t *)ActiveUsbMouseReport, USB_MOUSE_REPORT_LENGTH);
|
||||
if (usb_status == kStatus_USB_Success) {
|
||||
UsbMouseActionCounter++;
|
||||
SwitchActiveUsbMouseReport();
|
||||
}
|
||||
return usb_status;
|
||||
}
|
||||
|
||||
usb_status_t UsbMouseCallback(class_handle_t handle, uint32_t event, void *param)
|
||||
{
|
||||
UsbMouseActionCounter++;
|
||||
usb_status_t error = kStatus_USB_Error;
|
||||
|
||||
switch (event) {
|
||||
// This event is received when the report has been sent
|
||||
case kUSB_DeviceHidEventSendResponse:
|
||||
UsbReportUpdateSemaphore &= ~(1 << USB_MOUSE_INTERFACE_INDEX);
|
||||
if (UsbCompositeDevice.attach) {
|
||||
return usbMouseAction();
|
||||
error = kStatus_USB_Success;
|
||||
}
|
||||
break;
|
||||
case kUSB_DeviceHidEventRecvResponse:
|
||||
case kUSB_DeviceHidEventGetReport:
|
||||
case kUSB_DeviceHidEventSetReport:
|
||||
case kUSB_DeviceHidEventRequestReportBuffer:
|
||||
@@ -58,16 +68,10 @@ usb_status_t UsbMouseCallback(class_handle_t handle, uint32_t event, void *param
|
||||
|
||||
usb_status_t UsbMouseSetConfiguration(class_handle_t handle, uint8_t configuration)
|
||||
{
|
||||
if (USB_COMPOSITE_CONFIGURATION_INDEX == configuration) {
|
||||
return usbMouseAction();
|
||||
}
|
||||
return kStatus_USB_Error;
|
||||
}
|
||||
|
||||
usb_status_t UsbMouseSetInterface(class_handle_t handle, uint8_t interface, uint8_t alternateSetting)
|
||||
{
|
||||
if (USB_MOUSE_INTERFACE_INDEX == interface) {
|
||||
return usbMouseAction();
|
||||
}
|
||||
return kStatus_USB_Error;
|
||||
}
|
||||
|
||||
@@ -31,7 +31,6 @@
|
||||
|
||||
// Variables:
|
||||
|
||||
extern volatile bool IsUsbMouseReportSent;
|
||||
extern uint32_t UsbMouseActionCounter;
|
||||
extern usb_mouse_report_t* ActiveUsbMouseReport;
|
||||
|
||||
@@ -42,6 +41,7 @@
|
||||
usb_status_t UsbMouseSetInterface(class_handle_t handle, uint8_t interface, uint8_t alternateSetting);
|
||||
|
||||
void ResetActiveUsbMouseReport(void);
|
||||
void SwitchActiveUsbMouseReport(void);
|
||||
usb_mouse_report_t* GetInactiveUsbMouseReport(void);
|
||||
usb_status_t UsbMouseAction(void);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
#include "usb_composite_device.h"
|
||||
#include "usb_report_updater.h"
|
||||
|
||||
uint32_t UsbSystemKeyboardActionCounter;
|
||||
static usb_system_keyboard_report_t usbSystemKeyboardReports[2];
|
||||
usb_system_keyboard_report_t* ActiveUsbSystemKeyboardReport = usbSystemKeyboardReports;
|
||||
volatile bool IsUsbSystemKeyboardReportSent = false;
|
||||
|
||||
static usb_system_keyboard_report_t* getInactiveUsbSystemKeyboardReport()
|
||||
usb_system_keyboard_report_t* GetInactiveUsbSystemKeyboardReport()
|
||||
{
|
||||
return ActiveUsbSystemKeyboardReport == usbSystemKeyboardReports ? usbSystemKeyboardReports+1 : usbSystemKeyboardReports;
|
||||
}
|
||||
|
||||
void SwitchActiveUsbSystemKeyboardReport(void)
|
||||
static void SwitchActiveUsbSystemKeyboardReport(void)
|
||||
{
|
||||
ActiveUsbSystemKeyboardReport = getInactiveUsbSystemKeyboardReport();
|
||||
ActiveUsbSystemKeyboardReport = GetInactiveUsbSystemKeyboardReport();
|
||||
}
|
||||
|
||||
void ResetActiveUsbSystemKeyboardReport(void)
|
||||
@@ -20,14 +20,20 @@ void ResetActiveUsbSystemKeyboardReport(void)
|
||||
bzero(ActiveUsbSystemKeyboardReport, USB_SYSTEM_KEYBOARD_REPORT_LENGTH);
|
||||
}
|
||||
|
||||
static usb_status_t UsbSystemKeyboardAction(void)
|
||||
usb_status_t UsbSystemKeyboardAction(void)
|
||||
{
|
||||
usb_status_t status = USB_DeviceHidSend(
|
||||
if (!UsbCompositeDevice.attach) {
|
||||
return kStatus_USB_Error; // The device is not attached
|
||||
}
|
||||
|
||||
usb_status_t usb_status = USB_DeviceHidSend(
|
||||
UsbCompositeDevice.systemKeyboardHandle, USB_SYSTEM_KEYBOARD_ENDPOINT_INDEX,
|
||||
(uint8_t*)getInactiveUsbSystemKeyboardReport(), USB_SYSTEM_KEYBOARD_REPORT_LENGTH);
|
||||
IsUsbSystemKeyboardReportSent = true;
|
||||
UsbSystemKeyboardActionCounter++;
|
||||
return status;
|
||||
(uint8_t *)ActiveUsbSystemKeyboardReport, USB_SYSTEM_KEYBOARD_REPORT_LENGTH);
|
||||
if (usb_status == kStatus_USB_Success) {
|
||||
UsbSystemKeyboardActionCounter++;
|
||||
SwitchActiveUsbSystemKeyboardReport();
|
||||
}
|
||||
return usb_status;
|
||||
}
|
||||
|
||||
usb_status_t UsbSystemKeyboardCallback(class_handle_t handle, uint32_t event, void *param)
|
||||
@@ -35,11 +41,14 @@ usb_status_t UsbSystemKeyboardCallback(class_handle_t handle, uint32_t event, vo
|
||||
usb_status_t error = kStatus_USB_Error;
|
||||
|
||||
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) {
|
||||
return UsbSystemKeyboardAction();
|
||||
error = kStatus_USB_Success;
|
||||
}
|
||||
break;
|
||||
case kUSB_DeviceHidEventRecvResponse:
|
||||
case kUSB_DeviceHidEventGetReport:
|
||||
case kUSB_DeviceHidEventSetReport:
|
||||
case kUSB_DeviceHidEventRequestReportBuffer:
|
||||
@@ -59,16 +68,10 @@ usb_status_t UsbSystemKeyboardCallback(class_handle_t handle, uint32_t event, vo
|
||||
|
||||
usb_status_t UsbSystemKeyboardSetConfiguration(class_handle_t handle, uint8_t configuration)
|
||||
{
|
||||
if (USB_COMPOSITE_CONFIGURATION_INDEX == configuration) {
|
||||
return UsbSystemKeyboardAction();
|
||||
}
|
||||
return kStatus_USB_Error;
|
||||
}
|
||||
|
||||
usb_status_t UsbSystemKeyboardSetInterface(class_handle_t handle, uint8_t interface, uint8_t alternateSetting)
|
||||
{
|
||||
if (USB_SYSTEM_KEYBOARD_INTERFACE_INDEX == interface) {
|
||||
return UsbSystemKeyboardAction();
|
||||
}
|
||||
return kStatus_USB_Error;
|
||||
}
|
||||
|
||||
@@ -29,7 +29,6 @@
|
||||
|
||||
// Variables:
|
||||
|
||||
extern volatile bool IsUsbSystemKeyboardReportSent;
|
||||
extern uint32_t UsbSystemKeyboardActionCounter;
|
||||
extern usb_system_keyboard_report_t* ActiveUsbSystemKeyboardReport;
|
||||
|
||||
@@ -40,6 +39,7 @@
|
||||
usb_status_t UsbSystemKeyboardSetInterface(class_handle_t handle, uint8_t interface, uint8_t alternateSetting);
|
||||
|
||||
void ResetActiveUsbSystemKeyboardReport(void);
|
||||
void SwitchActiveUsbSystemKeyboardReport(void);
|
||||
usb_system_keyboard_report_t* GetInactiveUsbSystemKeyboardReport();
|
||||
usb_status_t UsbSystemKeyboardAction(void);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
#include "usb_commands/usb_command_get_slave_i2c_errors.h"
|
||||
#include "usb_commands/usb_command_set_i2c_baud_rate.h"
|
||||
#include "usb_commands/usb_command_switch_keymap.h"
|
||||
#include "usb_commands/usb_command_get_variable.h"
|
||||
#include "usb_commands/usb_command_set_variable.h"
|
||||
|
||||
void UsbProtocolHandler(void)
|
||||
{
|
||||
@@ -77,6 +79,12 @@ void UsbProtocolHandler(void)
|
||||
case UsbCommandId_SwitchKeymap:
|
||||
UsbCommand_SwitchKeymap();
|
||||
break;
|
||||
case UsbCommandId_GetVariable:
|
||||
UsbCommand_GetVariable();
|
||||
break;
|
||||
case UsbCommandId_SetVariable:
|
||||
UsbCommand_SetVariable();
|
||||
break;
|
||||
default:
|
||||
SetUsbTxBufferUint8(0, UsbStatusCode_InvalidCommand);
|
||||
break;
|
||||
|
||||
@@ -34,8 +34,18 @@
|
||||
UsbCommandId_GetSlaveI2cErrors = 0x0f,
|
||||
UsbCommandId_SetI2cBaudRate = 0x10,
|
||||
UsbCommandId_SwitchKeymap = 0x11,
|
||||
UsbCommandId_GetVariable = 0x12,
|
||||
UsbCommandId_SetVariable = 0x13,
|
||||
} usb_command_id_t;
|
||||
|
||||
typedef enum {
|
||||
UsbVariable_TestSwitches,
|
||||
UsbVariable_TestUsbStack,
|
||||
UsbVariable_DebounceTimePress,
|
||||
UsbVariable_DebounceTimeRelease,
|
||||
UsbVariable_UsbReportSemaphore,
|
||||
} usb_variable_id_t;
|
||||
|
||||
typedef enum {
|
||||
UsbStatusCode_Success = 0,
|
||||
UsbStatusCode_InvalidCommand = 1,
|
||||
|
||||
@@ -13,17 +13,22 @@
|
||||
#include "layer.h"
|
||||
#include "usb_report_updater.h"
|
||||
#include "timer.h"
|
||||
#include "key_debouncer.h"
|
||||
#include "config_parser/parse_keymap.h"
|
||||
#include "usb_commands/usb_command_get_debug_buffer.h"
|
||||
#include "arduino_hid/ConsumerAPI.h"
|
||||
|
||||
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;
|
||||
|
||||
mouse_kinetic_state_t MouseMoveState = {
|
||||
.isScroll = false,
|
||||
@@ -123,7 +128,7 @@ static void processMouseKineticState(mouse_kinetic_state_t *kineticState)
|
||||
kineticState->xOut = xSumInt;
|
||||
|
||||
if (kineticState->isScroll && !kineticState->wasMoveAction && kineticState->xOut == 0 && horizontalMovement) {
|
||||
kineticState->xOut = kineticState->xSum > 0 ? 1 : -1;
|
||||
kineticState->xOut = kineticState->xSum ? copysignf(1.0, kineticState->xSum) : 0;
|
||||
kineticState->xSum = 0;
|
||||
}
|
||||
|
||||
@@ -144,7 +149,7 @@ static void processMouseKineticState(mouse_kinetic_state_t *kineticState)
|
||||
kineticState->yOut = ySumInt;
|
||||
|
||||
if (kineticState->isScroll && !kineticState->wasMoveAction && kineticState->yOut == 0 && verticalMovement) {
|
||||
kineticState->yOut = kineticState->ySum > 0 ? 1 : -1;
|
||||
kineticState->yOut = kineticState->ySum ? copysignf(1.0, kineticState->ySum) : 0;
|
||||
kineticState->ySum = 0;
|
||||
}
|
||||
} else {
|
||||
@@ -191,28 +196,71 @@ static void processMouseActions()
|
||||
}
|
||||
|
||||
static layer_id_t previousLayer = LayerId_Base;
|
||||
static uint8_t basicScancodeIndex = 0;
|
||||
static uint8_t mediaScancodeIndex = 0;
|
||||
static uint8_t systemScancodeIndex = 0;
|
||||
|
||||
static void applyKeyAction(key_state_t *keyState, key_action_t *action)
|
||||
static void handleSwitchLayerAction(key_state_t *keyState, key_action_t *action)
|
||||
{
|
||||
static key_state_t *doubleTapSwitchLayerKey;
|
||||
static uint32_t doubleTapSwitchLayerStartTime;
|
||||
static uint32_t doubleTapSwitchLayerTriggerTime;
|
||||
|
||||
if (keyState->suppressed) {
|
||||
return;
|
||||
}
|
||||
static bool isLayerDoubleTapToggled;
|
||||
|
||||
if (doubleTapSwitchLayerKey && doubleTapSwitchLayerKey != keyState && !keyState->previous) {
|
||||
doubleTapSwitchLayerKey = NULL;
|
||||
}
|
||||
|
||||
if (action->type != KeyActionType_SwitchLayer) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!keyState->previous && isLayerDoubleTapToggled && ToggledLayer == action->switchLayer.layer) {
|
||||
ToggledLayer = LayerId_Base;
|
||||
isLayerDoubleTapToggled = false;
|
||||
}
|
||||
|
||||
if (keyState->previous && doubleTapSwitchLayerKey == keyState &&
|
||||
Timer_GetElapsedTime(&doubleTapSwitchLayerTriggerTime) > DoubleTapSwitchLayerReleaseTimeout)
|
||||
{
|
||||
ToggledLayer = LayerId_Base;
|
||||
}
|
||||
|
||||
if (!keyState->previous && previousLayer == LayerId_Base && action->switchLayer.mode == SwitchLayerMode_HoldAndDoubleTapToggle) {
|
||||
if (doubleTapSwitchLayerKey && Timer_GetElapsedTimeAndSetCurrent(&doubleTapSwitchLayerStartTime) < DoubleTapSwitchLayerTimeout) {
|
||||
ToggledLayer = action->switchLayer.layer;
|
||||
isLayerDoubleTapToggled = true;
|
||||
doubleTapSwitchLayerTriggerTime = CurrentTime;
|
||||
} else {
|
||||
doubleTapSwitchLayerKey = keyState;
|
||||
}
|
||||
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)
|
||||
{
|
||||
if (keyState->suppressed) {
|
||||
return;
|
||||
}
|
||||
|
||||
handleSwitchLayerAction(keyState, action);
|
||||
|
||||
switch (action->type) {
|
||||
case KeyActionType_Keystroke:
|
||||
ActiveUsbBasicKeyboardReport->modifiers |= action->keystroke.modifiers;
|
||||
|
||||
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) {
|
||||
@@ -235,52 +283,47 @@ 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:
|
||||
if (keyState->previous && doubleTapSwitchLayerKey == keyState &&
|
||||
Timer_GetElapsedTime(&doubleTapSwitchLayerTriggerTime) > DoubleTapSwitchLayerReleaseTimeout)
|
||||
{
|
||||
ToggledLayer = LayerId_Base;
|
||||
}
|
||||
|
||||
if (!keyState->previous && previousLayer == LayerId_Base && action->switchLayer.mode == SwitchLayerMode_HoldAndDoubleTapToggle) {
|
||||
if (doubleTapSwitchLayerKey && Timer_GetElapsedTimeAndSetCurrent(&doubleTapSwitchLayerStartTime) < DoubleTapSwitchLayerTimeout) {
|
||||
ToggledLayer = action->switchLayer.layer;
|
||||
doubleTapSwitchLayerTriggerTime = Timer_GetCurrentTime();
|
||||
} else {
|
||||
doubleTapSwitchLayerKey = keyState;
|
||||
}
|
||||
doubleTapSwitchLayerStartTime = Timer_GetCurrentTime();
|
||||
}
|
||||
// Handled by handleSwitchLayerAction()
|
||||
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)
|
||||
{
|
||||
memset(activeMouseStates, 0, ACTIVE_MOUSE_STATES_COUNT);
|
||||
if (MacroPlaying) {
|
||||
Macros_ContinueMacro();
|
||||
memcpy(ActiveUsbMouseReport, &MacroMouseReport, sizeof MacroMouseReport);
|
||||
memcpy(ActiveUsbBasicKeyboardReport, &MacroBasicKeyboardReport, sizeof MacroBasicKeyboardReport);
|
||||
memcpy(ActiveUsbMediaKeyboardReport, &MacroMediaKeyboardReport, sizeof MacroMediaKeyboardReport);
|
||||
memcpy(ActiveUsbSystemKeyboardReport, &MacroSystemKeyboardReport, sizeof MacroSystemKeyboardReport);
|
||||
return;
|
||||
}
|
||||
|
||||
static uint8_t previousModifiers = 0;
|
||||
memset(activeMouseStates, 0, ACTIVE_MOUSE_STATES_COUNT);
|
||||
|
||||
basicScancodeIndex = 0;
|
||||
mediaScancodeIndex = 0;
|
||||
systemScancodeIndex = 0;
|
||||
|
||||
for (uint8_t keyId=0; keyId < RIGHT_KEY_MATRIX_KEY_COUNT; keyId++) {
|
||||
KeyStates[SlotId_RightKeyboardHalf][keyId].current = RightKeyMatrix.keyStates[keyId];
|
||||
}
|
||||
|
||||
layer_id_t activeLayer = LayerId_Base;
|
||||
if (secondaryRoleState == SecondaryRoleState_Triggered && IS_SECONDARY_ROLE_LAYER_SWITCHER(secondaryRole)) {
|
||||
activeLayer = SECONDARY_ROLE_LAYER_TO_LAYER_ID(secondaryRole);
|
||||
@@ -288,38 +331,70 @@ 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 (MacroPlaying) {
|
||||
Macros_ContinueMacro();
|
||||
memcpy(&ActiveUsbMouseReport, &MacroMouseReport, sizeof MacroMouseReport);
|
||||
memcpy(&ActiveUsbBasicKeyboardReport, &MacroBasicKeyboardReport, sizeof MacroBasicKeyboardReport);
|
||||
memcpy(&ActiveUsbMediaKeyboardReport, &MacroMediaKeyboardReport, sizeof MacroMediaKeyboardReport);
|
||||
memcpy(&ActiveUsbSystemKeyboardReport, &MacroSystemKeyboardReport, sizeof MacroSystemKeyboardReport);
|
||||
return;
|
||||
if (TestUsbStack) {
|
||||
static bool simulateKeypresses, isEven, isEvenMedia;
|
||||
static uint32_t mediaCounter = 0;
|
||||
key_state_t *testKeyState = &KeyStates[SlotId_LeftKeyboardHalf][0];
|
||||
|
||||
if (activeLayer == LayerId_Fn && testKeyState->current && !testKeyState->previous) {
|
||||
simulateKeypresses = !simulateKeypresses;
|
||||
}
|
||||
if (simulateKeypresses) {
|
||||
isEven = !isEven;
|
||||
ActiveUsbBasicKeyboardReport->scancodes[basicScancodeIndex++] = isEven ? HID_KEYBOARD_SC_A : HID_KEYBOARD_SC_BACKSPACE;
|
||||
if (++mediaCounter % 200 == 0) {
|
||||
isEvenMedia = !isEvenMedia;
|
||||
ActiveUsbMediaKeyboardReport->scancodes[mediaScancodeIndex++] = isEvenMedia ? MEDIA_VOLUME_DOWN : MEDIA_VOLUME_UP;
|
||||
}
|
||||
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->debounceCounter < KEY_DEBOUNCER_TIMEOUT_MSEC) {
|
||||
keyState->current = keyState->previous;
|
||||
} else if (!keyState->previous && keyState->current) {
|
||||
keyState->debounceCounter = 0;
|
||||
if (keyState->debouncing) {
|
||||
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 = 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;
|
||||
@@ -327,22 +402,16 @@ static void updateActiveUsbReports(void)
|
||||
keyState->suppressed = true;
|
||||
}
|
||||
} else {
|
||||
// Trigger secondary role.
|
||||
if (!keyState->previous && secondaryRoleState == SecondaryRoleState_Pressed) {
|
||||
secondaryRoleState = SecondaryRoleState_Triggered;
|
||||
} else {
|
||||
applyKeyAction(keyState, action);
|
||||
}
|
||||
applyKeyAction(keyState, action);
|
||||
}
|
||||
} else {
|
||||
if (keyState->suppressed) {
|
||||
keyState->suppressed = false;
|
||||
}
|
||||
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;
|
||||
@@ -358,41 +427,29 @@ 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;
|
||||
}
|
||||
|
||||
uint32_t UsbReportUpdateCounter;
|
||||
static uint32_t lastMouseUpdateTime;
|
||||
|
||||
void UpdateUsbReports(void)
|
||||
{
|
||||
UsbReportUpdateCounter++;
|
||||
|
||||
// Process the key inputs at a constant rate when moving the mouse, so the mouse speed is consistent.
|
||||
bool hasActiveMouseState = false;
|
||||
for (uint8_t i=0; i<ACTIVE_MOUSE_STATES_COUNT; i++) {
|
||||
hasActiveMouseState = true;
|
||||
break;
|
||||
for (uint8_t keyId = 0; keyId < RIGHT_KEY_MATRIX_KEY_COUNT; keyId++) {
|
||||
KeyStates[SlotId_RightKeyboardHalf][keyId].current = RightKeyMatrix.keyStates[keyId];
|
||||
}
|
||||
|
||||
if (hasActiveMouseState) {
|
||||
if (Timer_GetElapsedTime(&lastMouseUpdateTime) < USB_MOUSE_INTERRUPT_IN_INTERVAL) {
|
||||
return;
|
||||
}
|
||||
Timer_SetCurrentTime(&lastMouseUpdateTime);
|
||||
} else if (!IsUsbBasicKeyboardReportSent || !IsUsbMediaKeyboardReportSent || !IsUsbSystemKeyboardReportSent || !IsUsbMouseReportSent) {
|
||||
if (UsbReportUpdateSemaphore && !SleepModeActive) {
|
||||
return;
|
||||
}
|
||||
|
||||
UsbReportUpdateCounter++;
|
||||
|
||||
ResetActiveUsbBasicKeyboardReport();
|
||||
ResetActiveUsbMediaKeyboardReport();
|
||||
ResetActiveUsbSystemKeyboardReport();
|
||||
@@ -400,35 +457,38 @@ void UpdateUsbReports(void)
|
||||
|
||||
updateActiveUsbReports();
|
||||
|
||||
static usb_basic_keyboard_report_t last_basic_report = { .scancodes[0] = 0xFF };
|
||||
if (memcmp(ActiveUsbBasicKeyboardReport, &last_basic_report, sizeof(usb_basic_keyboard_report_t)) != 0) {
|
||||
last_basic_report = *ActiveUsbBasicKeyboardReport;
|
||||
SwitchActiveUsbBasicKeyboardReport();
|
||||
IsUsbBasicKeyboardReportSent = false;
|
||||
bool HasUsbBasicKeyboardReportChanged = memcmp(ActiveUsbBasicKeyboardReport, GetInactiveUsbBasicKeyboardReport(), sizeof(usb_basic_keyboard_report_t)) != 0;
|
||||
bool HasUsbMediaKeyboardReportChanged = memcmp(ActiveUsbMediaKeyboardReport, GetInactiveUsbMediaKeyboardReport(), sizeof(usb_media_keyboard_report_t)) != 0;
|
||||
bool HasUsbSystemKeyboardReportChanged = memcmp(ActiveUsbSystemKeyboardReport, GetInactiveUsbSystemKeyboardReport(), sizeof(usb_system_keyboard_report_t)) != 0;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
static usb_media_keyboard_report_t last_media_report = { .scancodes[0] = 0xFF };
|
||||
if (memcmp(ActiveUsbMediaKeyboardReport, &last_media_report, sizeof(usb_media_keyboard_report_t)) != 0) {
|
||||
last_media_report = *ActiveUsbMediaKeyboardReport;
|
||||
SwitchActiveUsbMediaKeyboardReport();
|
||||
IsUsbMediaKeyboardReportSent = false;
|
||||
if (HasUsbMediaKeyboardReportChanged) {
|
||||
usb_status_t status = UsbMediaKeyboardAction();
|
||||
if (status == kStatus_USB_Success) {
|
||||
UsbReportUpdateSemaphore |= 1 << USB_MEDIA_KEYBOARD_INTERFACE_INDEX;
|
||||
}
|
||||
}
|
||||
|
||||
static usb_system_keyboard_report_t last_system_report = { .scancodes[0] = 0xFF };
|
||||
if (memcmp(ActiveUsbSystemKeyboardReport, &last_system_report, sizeof(usb_system_keyboard_report_t)) != 0) {
|
||||
last_system_report = *ActiveUsbSystemKeyboardReport;
|
||||
SwitchActiveUsbSystemKeyboardReport();
|
||||
IsUsbSystemKeyboardReportSent = false;
|
||||
if (HasUsbSystemKeyboardReportChanged) {
|
||||
usb_status_t status = UsbSystemKeyboardAction();
|
||||
if (status == kStatus_USB_Success) {
|
||||
UsbReportUpdateSemaphore |= 1 << USB_SYSTEM_KEYBOARD_INTERFACE_INDEX;
|
||||
}
|
||||
}
|
||||
|
||||
static usb_mouse_report_t last_mouse_report = { .buttons = 0xFF };
|
||||
if (memcmp(ActiveUsbMouseReport, &last_mouse_report, sizeof(usb_mouse_report_t)) != 0) {
|
||||
last_mouse_report = *ActiveUsbMouseReport;
|
||||
SwitchActiveUsbMouseReport();
|
||||
IsUsbMouseReportSent = false;
|
||||
}
|
||||
|
||||
if ((previousLayer != LayerId_Base || !IsUsbBasicKeyboardReportSent || !IsUsbMediaKeyboardReportSent || !IsUsbSystemKeyboardReportSent || !IsUsbMouseReportSent) && IsHostSleeping) {
|
||||
WakeUpHost(true); // Wake up the host if any key is pressed and the computer is sleeping.
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,6 +70,9 @@
|
||||
extern mouse_kinetic_state_t MouseMoveState;
|
||||
extern mouse_kinetic_state_t MouseScrollState;
|
||||
extern uint32_t UsbReportUpdateCounter;
|
||||
extern volatile uint8_t UsbReportUpdateSemaphore;
|
||||
extern bool TestUsbStack;
|
||||
extern bool KeymapChanged;
|
||||
|
||||
// Functions:
|
||||
|
||||
|
||||
@@ -15,10 +15,10 @@
|
||||
"commander": "^2.11.0",
|
||||
"shelljs": "^0.7.8"
|
||||
},
|
||||
"firmwareVersion": "8.2.4",
|
||||
"deviceProtocolVersion": "4.3.1",
|
||||
"firmwareVersion": "8.5.0",
|
||||
"deviceProtocolVersion": "4.5.0",
|
||||
"moduleProtocolVersion": "4.0.0",
|
||||
"userConfigVersion": "4.0.1",
|
||||
"userConfigVersion": "4.1.0",
|
||||
"hardwareConfigVersion": "1.0.0",
|
||||
"devices": [
|
||||
{
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#include "fsl_gpio.h"
|
||||
#include "key_matrix.h"
|
||||
|
||||
uint8_t DebounceTimePress = 50, DebounceTimeRelease = 50;
|
||||
|
||||
void KeyMatrix_Init(key_matrix_t *keyMatrix)
|
||||
{
|
||||
for (key_matrix_pin_t *row = keyMatrix->rows; row < keyMatrix->rows + keyMatrix->rowNum; row++) {
|
||||
|
||||
@@ -28,6 +28,10 @@
|
||||
uint8_t keyStates[MAX_KEYS_IN_MATRIX];
|
||||
} key_matrix_t;
|
||||
|
||||
// Variables:
|
||||
|
||||
extern uint8_t DebounceTimePress, DebounceTimeRelease;
|
||||
|
||||
// Functions:
|
||||
|
||||
void KeyMatrix_Init(key_matrix_t *keyMatrix);
|
||||
|
||||
@@ -19,20 +19,20 @@
|
||||
// Variables:
|
||||
|
||||
#define FIRMWARE_MAJOR_VERSION 8
|
||||
#define FIRMWARE_MINOR_VERSION 2
|
||||
#define FIRMWARE_PATCH_VERSION 4
|
||||
#define FIRMWARE_MINOR_VERSION 5
|
||||
#define FIRMWARE_PATCH_VERSION 0
|
||||
|
||||
#define DEVICE_PROTOCOL_MAJOR_VERSION 4
|
||||
#define DEVICE_PROTOCOL_MINOR_VERSION 3
|
||||
#define DEVICE_PROTOCOL_PATCH_VERSION 1
|
||||
#define DEVICE_PROTOCOL_MINOR_VERSION 5
|
||||
#define DEVICE_PROTOCOL_PATCH_VERSION 0
|
||||
|
||||
#define MODULE_PROTOCOL_MAJOR_VERSION 4
|
||||
#define MODULE_PROTOCOL_MINOR_VERSION 0
|
||||
#define MODULE_PROTOCOL_PATCH_VERSION 0
|
||||
|
||||
#define USER_CONFIG_MAJOR_VERSION 4
|
||||
#define USER_CONFIG_MINOR_VERSION 0
|
||||
#define USER_CONFIG_PATCH_VERSION 1
|
||||
#define USER_CONFIG_MINOR_VERSION 1
|
||||
#define USER_CONFIG_PATCH_VERSION 0
|
||||
|
||||
#define HARDWARE_CONFIG_MAJOR_VERSION 1
|
||||
#define HARDWARE_CONFIG_MINOR_VERSION 0
|
||||
|
||||
Reference in New Issue
Block a user