Compare commits
193 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4563d26a5c | ||
|
|
0b120a3286 | ||
|
|
d4200524d7 | ||
|
|
ef34094004 | ||
|
|
d2fd7bc613 | ||
|
|
7da33c606b | ||
|
|
0f3ceef332 | ||
|
|
908102855b | ||
|
|
a216d400ca | ||
|
|
8959dde107 | ||
|
|
a2e20e6b32 | ||
|
|
ef7ae5dd42 | ||
|
|
24377e6778 | ||
|
|
e3958cdca6 | ||
|
|
9d5588a6c2 | ||
|
|
8c42074534 | ||
|
|
fce054eb9c | ||
|
|
fb320ee4bd | ||
|
|
6595884c99 | ||
|
|
7b7af0c5bc | ||
|
|
1d4c8d3019 | ||
|
|
3dd9744e4d | ||
|
|
859a770ca3 | ||
|
|
6b0ebb1385 | ||
|
|
302a750621 | ||
|
|
457894ecd8 | ||
|
|
8dba4df6f6 | ||
|
|
215d4c33bb | ||
|
|
9f411dc1d4 | ||
|
|
3d443a8bfc | ||
|
|
1cc01c4f48 | ||
|
|
fd7f2c3b25 | ||
|
|
8c067b9190 | ||
|
|
bea13f063a | ||
|
|
9842a6ff60 | ||
|
|
f8e83b139d | ||
|
|
6be45c4521 | ||
|
|
a9ba8a1907 | ||
|
|
12c055aec7 | ||
|
|
96eb2ef7a3 | ||
|
|
bd76fb44c2 | ||
|
|
21beb59cb6 | ||
|
|
3ed3272fa3 | ||
|
|
377fe4a2b2 | ||
|
|
259f4d3299 | ||
|
|
8e420f8592 | ||
|
|
63674e02b7 | ||
|
|
e27fb83693 | ||
|
|
b0e706d894 | ||
|
|
4295793fb9 | ||
|
|
f348aec97a | ||
|
|
9ecdfc0b71 | ||
|
|
1bca95d366 | ||
|
|
a84d184da4 | ||
|
|
c965fe185b | ||
|
|
af52c017d8 | ||
|
|
316602bb02 | ||
|
|
6658d62805 | ||
|
|
c707f0e408 | ||
|
|
efb0f982d2 | ||
|
|
2027940b4c | ||
|
|
e5595bc757 | ||
|
|
72812724ef | ||
|
|
1daf43b751 | ||
|
|
2804d3e447 | ||
|
|
ff1d5dffaa | ||
|
|
5de396bb68 | ||
|
|
7af8042c93 | ||
|
|
51a9acbb68 | ||
|
|
f1a8d9a330 | ||
|
|
b5f1bcc4d6 | ||
|
|
7061345ec2 | ||
|
|
90bad68287 | ||
|
|
f921753b63 | ||
|
|
724d72132a | ||
|
|
858586ef2a | ||
|
|
ecc2d2db9a | ||
|
|
6edf4113a4 | ||
|
|
1b1111e9da | ||
|
|
b443b56357 | ||
|
|
4ade25d739 | ||
|
|
0ba979a658 | ||
|
|
42e17ca1bf | ||
|
|
37cf632f2a | ||
|
|
3079d527b1 | ||
|
|
320923b41c | ||
|
|
b49cb30070 | ||
|
|
894103a944 | ||
|
|
b87042a44a | ||
|
|
cec8bbfe01 | ||
|
|
3e5767e141 | ||
|
|
ea71253d6a | ||
|
|
abc1923897 | ||
|
|
c23d327384 | ||
|
|
a7b0dfef1d | ||
|
|
d8de4f0b3e | ||
|
|
01ef8f59c2 | ||
|
|
04047eb128 | ||
|
|
e7a1d27cde | ||
|
|
877cb78b0a | ||
|
|
fad17aeb32 | ||
|
|
0624d088b6 | ||
|
|
1ab984413a | ||
|
|
92c0da9695 | ||
|
|
07142c3ce2 | ||
|
|
81de51244a | ||
|
|
2b6762d3e0 | ||
|
|
28f0cdd2c0 | ||
|
|
eb2d7ada3a | ||
|
|
76a80c3090 | ||
|
|
67c4b413b4 | ||
|
|
b42fc8b3f1 | ||
|
|
8909bb6a16 | ||
|
|
d6254b6903 | ||
|
|
7313d8d87e | ||
|
|
7d1cecc2b4 | ||
|
|
1889f78b98 | ||
|
|
827ad7e08e | ||
|
|
508ef870ae | ||
|
|
69f3c86185 | ||
|
|
8b180d94b0 | ||
|
|
96eeb97a04 | ||
|
|
55e0872967 | ||
|
|
c04c5de504 | ||
|
|
5eb82c262a | ||
|
|
6c2e806d6d | ||
|
|
8136acf63c | ||
|
|
6ec5140eca | ||
|
|
f80a88c419 | ||
|
|
3fda14df27 | ||
|
|
ef2c4a1e7f | ||
|
|
de21cfc07e | ||
|
|
9ecf04cf11 | ||
|
|
4666b24c69 | ||
|
|
8b5b224bf3 | ||
|
|
9309c1e954 | ||
|
|
8d57968575 | ||
|
|
9a42123648 | ||
|
|
d578b7aba8 | ||
|
|
e3faa5ade4 | ||
|
|
d844264ad9 | ||
|
|
751810ec4c | ||
|
|
ecf1ad2468 | ||
|
|
41c2556386 | ||
|
|
5473c102ec | ||
|
|
d43bbbbf51 | ||
|
|
9a4c49e9a6 | ||
|
|
d4124d8331 | ||
|
|
790a2e0a65 | ||
|
|
5769f66994 | ||
|
|
8f830f7d9f | ||
|
|
145443c65c | ||
|
|
1839be81b6 | ||
|
|
9dde9ee917 | ||
|
|
065a19fdc8 | ||
|
|
3bd943aa85 | ||
|
|
3b3e40af83 | ||
|
|
b88c6e4291 | ||
|
|
ef9d9ee9a7 | ||
|
|
2aa74853b5 | ||
|
|
cc57daa674 | ||
|
|
2e33a83e29 | ||
|
|
43c07dde21 | ||
|
|
ac138d2da6 | ||
|
|
2227508130 | ||
|
|
962705a017 | ||
|
|
92647b36a9 | ||
|
|
d210f46983 | ||
|
|
dbada9dd5d | ||
|
|
50207a288d | ||
|
|
444e9d58d0 | ||
|
|
4e665b5701 | ||
|
|
ccc93f48cc | ||
|
|
228bebcd59 | ||
|
|
5dd3b8e0be | ||
|
|
cc3208a947 | ||
|
|
e7362a057c | ||
|
|
97ee339827 | ||
|
|
11d9e85cb7 | ||
|
|
36be965db9 | ||
|
|
8924c36cb3 | ||
|
|
e7330f5d61 | ||
|
|
02ae123acc | ||
|
|
2086138d9c | ||
|
|
5c8138f123 | ||
|
|
4d5214fdc9 | ||
|
|
d7b3aee50e | ||
|
|
57e6a6c067 | ||
|
|
e3d407e14d | ||
|
|
2f90e40c92 | ||
|
|
aea07f8605 | ||
|
|
e6b5b3b3a5 | ||
|
|
399847510e |
@@ -4,16 +4,15 @@ cache:
|
||||
directories:
|
||||
- $HOME/Library/Caches/Homebrew/Cask
|
||||
install:
|
||||
- brew cask install eclipse-cpp gcc-arm-embedded
|
||||
- /Applications/Eclipse.app/Contents/MacOS/eclipse -noSplash
|
||||
- brew update && brew bundle -v
|
||||
- /Applications/Eclipse\ CPP.app/Contents/MacOS/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
|
||||
script:
|
||||
- /Applications/Eclipse.app/Contents/MacOS/eclipse -noSplash
|
||||
- /Applications/Eclipse\ CPP.app/Contents/MacOS/eclipse -noSplash
|
||||
-application org.eclipse.cdt.managedbuilder.core.headlessbuild
|
||||
-import $TRAVIS_BUILD_DIR/left/build/kds
|
||||
-import $TRAVIS_BUILD_DIR/right/build/kds
|
||||
-build all
|
||||
|
||||
|
||||
33
CHANGELOG.md
Normal file
33
CHANGELOG.md
Normal file
@@ -0,0 +1,33 @@
|
||||
# Changelog
|
||||
|
||||
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.
|
||||
|
||||
## [2.1.0] - 2017-10-13
|
||||
|
||||
Data Model: 1.0.0 (unchanged) | USB Protocol: 1.2.0 (minor bump) | Slave Protocol: 2.1.0 (minor bump)
|
||||
|
||||
- Add jumpToSlaveBootloader USB and slave protocol command. `USBPROTOCOL:MINOR` `SLAVEPROTOCOL:MINOR`
|
||||
- Fix generic HID descriptor enumeration error.
|
||||
|
||||
## [2.0.0] - 2017-10-10
|
||||
|
||||
Data Model: 1.0.0 (unchanged) | USB Protocol: 1.1.0 (minor bump) | Slave Protocol: 2.0.0 (major bump)
|
||||
|
||||
- Read the hardware and user configuration area of the EEPROM upon startup and set the default keymap.
|
||||
- Greatly improve the I2C watchdog and drivers. Communication between the halves or the add-ons should never fail again.
|
||||
- Implement generic enumeration sequence and per-slave state for UHK modules, allowing add-ons to be added. `SLAVEPROTOCOL:MAJOR`
|
||||
- Make the master cache the output fields of slave modules, allowing for more frequent input updates.
|
||||
- Optimize I2C protocol scheduler resulting in increased roustness and more efficient use of I2C bandwidth.
|
||||
- Add I2C message headers containing a length header, allowing for variable-length messages and a CRC16-CCITT checksum, allowing for robust communication. `SLAVEPROTOCOL:MAJOR`
|
||||
- Add mechanism to dump the internal state of the KL03 via SPI for debugging purposes.
|
||||
- Add merge sensor state and attached module IDs to GetDebugInfo(). `USBPROTOCOL:PATCH`
|
||||
- Throw ParserError_InvalidKeymapCount if keymapCount == 0. `DATAMODEL:PATCH`
|
||||
|
||||
## [1.0.0] - 2017-08-30
|
||||
|
||||
Data Model: 1.0.0 | USB Protocol: 1.0.0 | Slave Protocol: 1.0.0
|
||||
|
||||
- First Release
|
||||
@@ -17,8 +17,8 @@ Function names are composed of a verb followed by a noun.
|
||||
Non-extern functions must be declared as static.
|
||||
|
||||
```
|
||||
DoThisExtern();
|
||||
static doThisNonExtern();
|
||||
DoThisExtern(void);
|
||||
static doThisNonExtern(void);
|
||||
uint8 ExternVariable;
|
||||
uint8 nonExternVariable;
|
||||
```
|
||||
@@ -60,6 +60,18 @@ if (something) {
|
||||
...
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
for (uint8_t i = 0; i < j; i++) {
|
||||
...
|
||||
}
|
||||
@@ -72,7 +84,7 @@ while (condition) {
|
||||
## Function declaration
|
||||
|
||||
```
|
||||
void doThis()
|
||||
void doThis(void)
|
||||
{
|
||||
...
|
||||
}
|
||||
@@ -117,7 +129,7 @@ Header files are composed of sections. The order of sections is fixed. Every hea
|
||||
|
||||
// Functions:
|
||||
|
||||
extern void LedDriver_WriteBuffer(uint8_t i2cAddress, uint8_t buffer[], uint8_t size);
|
||||
void LedDriver_WriteBuffer(uint8_t i2cAddress, uint8_t buffer[], uint8_t size);
|
||||
...
|
||||
|
||||
#endif
|
||||
|
||||
47
VERSIONING.md
Normal file
47
VERSIONING.md
Normal file
@@ -0,0 +1,47 @@
|
||||
# UHK Versioning
|
||||
|
||||
This document describes the various version numbers that are used by the UHK.
|
||||
|
||||
## Version number format
|
||||
|
||||
The format of the UHK version numbers is a subset of [Semantic Versioning](http://semver.org/) that only allows major, minor, and patch numbers as part of the version number. No alpha, beta, rc, or any extensions are allowed.
|
||||
|
||||
## USB protocol version
|
||||
|
||||
The UHK USB protocol is used by the UHK to interact with the host system via USB. [Agent](https://github.com/UltimateHackingKeyboard/agent) speaks the UHK USB protocol in order to read and write the configuration of the UHK, and to query its state or manipulate it in any way. Please note that the UHK USB protocol doesn't have anything to do with standard keyboard and mouse functions which are taken care by operating system drivers.
|
||||
|
||||
* The major number is bumped upon breaking the protocol, such as changing a protocol command ID or changing an already utilized byte within the payload.
|
||||
* The minor number is bumped upon an extension of the protocol, such as adding a new protocol command ID, or utilizing a previously unutilized byte within the payload.
|
||||
* The patch number is bumped upon a protocol related implementation fix, for example adding a new validation check.
|
||||
|
||||
In order for a host application to communicate with the UHK, its major USB protocol version must match, and its minor USB protocol version must be less or equal.
|
||||
|
||||
## Slave protocol version
|
||||
|
||||
The Slave protocol is the I2C based application protocol of the UHK via which the master module (right keyboard half), and the slave modules (left keyboard half, left add-on, right add-on) communicate.
|
||||
|
||||
* The major number is bumped upon breaking the protocol, such as changing a protocol command ID or changing an already utilized byte within the payload.
|
||||
* The minor number is bumped upon an extension of the protocol, such as adding a new protocol command ID, or extending the payload.
|
||||
* The patch number is bumped upon a protocol related implementation fix, for example adding a new validation check.
|
||||
|
||||
In order for the master module to communicate with the slave modules, its major slave protocol version must match, and its minor slave protocol version must be less or equal.
|
||||
|
||||
## Data model version
|
||||
|
||||
The data model is the binary serialization format of the user configuration which includes keymaps, macros, and every other configuration item.
|
||||
|
||||
* The major number is bumped upon breaking the data model, such as adding a new item type or changing a previously utilized interval of an already exising item type.
|
||||
* The minor number is bumped upon an extension of the data model, such as using a previously unutilized interval of a type number to add a new item type.
|
||||
* The patch number is bumped upon a data model related implementation fix, for example adding a new validation check.
|
||||
|
||||
In order for a host application to parse the configuration of the UHK, its major data model version must match, and its minor data model version must be less or equal.
|
||||
|
||||
For the sake of completeness, it's worth mentioning that not only the (user) data model exists, but the hardware data model too which contains hardware-specific configuration items, such as ANSI vs ISO keyboard type. The hardware data model also has a version number field, but it's not expected to ever change so for the sake of simplicity, it's not included into changelog releases. The hardware configuration version is 1.0.0
|
||||
|
||||
## Firmware version
|
||||
|
||||
The version number of the firmware changes according to the following rules.
|
||||
|
||||
* The major number is bumped if the major number of any of the above version numbers is bumped.
|
||||
* The minor number is bumped if the minor number of any of the above version numbers is bumped.
|
||||
* The patch number is bumped if the patch number of any of the above version numbers is bumped.
|
||||
35
gcc-arm-embedded.rb
Normal file
35
gcc-arm-embedded.rb
Normal file
@@ -0,0 +1,35 @@
|
||||
cask 'gcc-arm-embedded' do
|
||||
version '4_8-2014q3'
|
||||
sha256 '6b30901738b09a8d22fdfff99e991217444b80ac492a6163af5c06a3baaa3487'
|
||||
|
||||
# launchpad.net/gcc-arm-embedded/ was verified as official when first introduced to the cask
|
||||
url "https://launchpad.net/gcc-arm-embedded/4.8/4.8-2014-q3-update/+download/gcc-arm-none-eabi-#{version}-20140805-mac.tar.bz2"
|
||||
name 'GCC ARM Embedded'
|
||||
homepage 'https://developer.arm.com/open-source/gnu-toolchain/gnu-rm'
|
||||
|
||||
binary "gcc-arm-none-eabi-#{version}/bin/arm-none-eabi-addr2line"
|
||||
binary "gcc-arm-none-eabi-#{version}/bin/arm-none-eabi-ar"
|
||||
binary "gcc-arm-none-eabi-#{version}/bin/arm-none-eabi-as"
|
||||
binary "gcc-arm-none-eabi-#{version}/bin/arm-none-eabi-c++"
|
||||
binary "gcc-arm-none-eabi-#{version}/bin/arm-none-eabi-c++filt"
|
||||
binary "gcc-arm-none-eabi-#{version}/bin/arm-none-eabi-cpp"
|
||||
binary "gcc-arm-none-eabi-#{version}/bin/arm-none-eabi-elfedit"
|
||||
binary "gcc-arm-none-eabi-#{version}/bin/arm-none-eabi-g++"
|
||||
binary "gcc-arm-none-eabi-#{version}/bin/arm-none-eabi-gcc"
|
||||
binary "gcc-arm-none-eabi-#{version}/bin/arm-none-eabi-gcc-ar"
|
||||
binary "gcc-arm-none-eabi-#{version}/bin/arm-none-eabi-gcc-nm"
|
||||
binary "gcc-arm-none-eabi-#{version}/bin/arm-none-eabi-gcc-ranlib"
|
||||
binary "gcc-arm-none-eabi-#{version}/bin/arm-none-eabi-gcov"
|
||||
binary "gcc-arm-none-eabi-#{version}/bin/arm-none-eabi-gdb"
|
||||
binary "gcc-arm-none-eabi-#{version}/bin/arm-none-eabi-gprof"
|
||||
binary "gcc-arm-none-eabi-#{version}/bin/arm-none-eabi-ld"
|
||||
binary "gcc-arm-none-eabi-#{version}/bin/arm-none-eabi-ld.bfd"
|
||||
binary "gcc-arm-none-eabi-#{version}/bin/arm-none-eabi-nm"
|
||||
binary "gcc-arm-none-eabi-#{version}/bin/arm-none-eabi-objcopy"
|
||||
binary "gcc-arm-none-eabi-#{version}/bin/arm-none-eabi-objdump"
|
||||
binary "gcc-arm-none-eabi-#{version}/bin/arm-none-eabi-ranlib"
|
||||
binary "gcc-arm-none-eabi-#{version}/bin/arm-none-eabi-readelf"
|
||||
binary "gcc-arm-none-eabi-#{version}/bin/arm-none-eabi-size"
|
||||
binary "gcc-arm-none-eabi-#{version}/bin/arm-none-eabi-strings"
|
||||
binary "gcc-arm-none-eabi-#{version}/bin/arm-none-eabi-strip"
|
||||
end
|
||||
@@ -133,7 +133,7 @@
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.cref.6563555683" name="Cross reference (-Xlinker --cref)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.cref" value="false" valueType="boolean"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.printgcsections.8052175158" name="Print removed sections (-Xlinker --print-gc-sections)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.printgcsections" value="false" valueType="boolean"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.strip.4023108413" name="Omit all symbol information (-s)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.strip" value="false" valueType="boolean"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.other.255052480" name="Other linker flags" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.other" value="-mapcs -Xlinker -static -Xlinker -z -Xlinker muldefs" valueType="string"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.other.255052480" name="Other linker flags" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.other" value="-mapcs -Xlinker -static -Xlinker -z -Xlinker muldefs -Xlinker -defsym=__heap_size__=0" valueType="string"/>
|
||||
<inputType id="ilg.gnuarmeclipse.managedbuild.cross.tool.cpp.linker.input.658447495" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.cpp.linker.input">
|
||||
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
|
||||
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
|
||||
@@ -656,11 +656,11 @@
|
||||
<configuration configurationName="v7-debug-srec">
|
||||
<resource resourceType="PROJECT" workspacePath="/uhk-left"/>
|
||||
</configuration>
|
||||
<configuration configurationName="v7-debug"/>
|
||||
<configuration configurationName="release">
|
||||
<resource resourceType="PROJECT" workspacePath="/uhk-left"/>
|
||||
</configuration>
|
||||
<configuration configurationName="v6-release"/>
|
||||
<configuration configurationName="v7-debug"/>
|
||||
<configuration configurationName="uhk-left-release">
|
||||
<resource resourceType="PROJECT" workspacePath="/uhk-left"/>
|
||||
</configuration>
|
||||
|
||||
@@ -81,6 +81,16 @@
|
||||
<type>1</type>
|
||||
<locationURI>PARENT-3-PROJECT_LOC/lib/KSDK_2.0_MKL03Z8xxx4/devices/MKL03Z4/drivers/fsl_i2c.h</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>drivers/fsl_lptmr.c</name>
|
||||
<type>1</type>
|
||||
<locationURI>PARENT-3-PROJECT_LOC/lib/KSDK_2.0_MKL03Z8xxx4/devices/MKL03Z4/drivers/fsl_lptmr.c</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>drivers/fsl_lptmr.h</name>
|
||||
<type>1</type>
|
||||
<locationURI>PARENT-3-PROJECT_LOC/lib/KSDK_2.0_MKL03Z8xxx4/devices/MKL03Z4/drivers/fsl_lptmr.h</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>drivers/fsl_port.h</name>
|
||||
<type>1</type>
|
||||
@@ -96,6 +106,16 @@
|
||||
<type>1</type>
|
||||
<locationURI>PARENT-3-PROJECT_LOC/lib/KSDK_2.0_MKL03Z8xxx4/devices/MKL03Z4/drivers/fsl_smc.h</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>drivers/fsl_spi.c</name>
|
||||
<type>1</type>
|
||||
<locationURI>PARENT-3-PROJECT_LOC/lib/KSDK_2.0_MKL03Z8xxx4/devices/MKL03Z4/drivers/fsl_spi.c</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>drivers/fsl_spi.h</name>
|
||||
<type>1</type>
|
||||
<locationURI>PARENT-3-PROJECT_LOC/lib/KSDK_2.0_MKL03Z8xxx4/devices/MKL03Z4/drivers/fsl_spi.h</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>drivers/fsl_tpm.c</name>
|
||||
<type>1</type>
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
<intAttribute key="org.eclipse.cdt.debug.gdbjtag.core.portNumber" value="2331"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setPcRegister" value="false"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setResume" value="false"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setStopAt" value="true"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setStopAt" value="false"/>
|
||||
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.stopAt" value="main"/>
|
||||
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.symbolsFileName" value=""/>
|
||||
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.symbolsOffset" value=""/>
|
||||
@@ -70,13 +70,13 @@
|
||||
<stringAttribute key="org.eclipse.cdt.launch.PROGRAM_NAME" value="uhk-left-debug/uhk-left.elf"/>
|
||||
<stringAttribute key="org.eclipse.cdt.launch.PROJECT_ATTR" value="uhk-left"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_AUTO_ATTR" value="false"/>
|
||||
<stringAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_ID_ATTR" value=""/>
|
||||
<stringAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_ID_ATTR" value="ilg.gnuarmeclipse.managedbuild.cross.config.elf.debug.1792027861"/>
|
||||
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
|
||||
<listEntry value="/uhk-left"/>
|
||||
</listAttribute>
|
||||
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
|
||||
<listEntry value="4"/>
|
||||
</listAttribute>
|
||||
<stringAttribute key="org.eclipse.dsf.launch.MEMORY_BLOCKS" value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <memoryBlockExpressionList context="Context string"/> "/>
|
||||
<stringAttribute key="org.eclipse.dsf.launch.MEMORY_BLOCKS" value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <memoryBlockExpressionList context="Context string"/> "/>
|
||||
<stringAttribute key="process_factory_id" value="org.eclipse.cdt.dsf.gdb.GdbProcessFactory"/>
|
||||
</launchConfiguration>
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
#include "bootloader.h"
|
||||
|
||||
/* bits for enabledPeripherals */
|
||||
#define ENABLE_PERIPHERAL_UART (1<<0)
|
||||
#define ENABLE_PERIPHERAL_I2C (1<<1)
|
||||
#define ENABLE_PERIPHERAL_SPI (1<<2)
|
||||
#define ENABLE_PERIPHERAL_CAN (1<<3)
|
||||
#define ENABLE_PERIPHERAL_USB_HID (1<<4)
|
||||
#define ENABLE_PERIPHERAL_USB_MSC (1<<7)
|
||||
|
||||
__attribute__((used, section(".BootloaderConfig"))) const bootloader_config_t BootloaderConfig = {
|
||||
.tag = 0x6766636B, // Magic Number
|
||||
.enabledPeripherals = ENABLE_PERIPHERAL_I2C /*0xE2*/, // Enabled Peripheral: I2C
|
||||
.i2cSlaveAddress = 0x10, // Use user-defined I2C address
|
||||
.peripheralDetectionTimeoutMs = 300, // Use user-defined timeout (ms)
|
||||
.clockFlags = 0xFF, // Disable High speed mode
|
||||
.clockDivider = 0xFF, // Use clock divider (0)
|
||||
};
|
||||
|
||||
void JumpToBootloader(void) {
|
||||
uint32_t runBootloaderAddress;
|
||||
void (*runBootloader)(void *arg);
|
||||
|
||||
/* Read the function address from the ROM API tree. */
|
||||
runBootloaderAddress = **(uint32_t **)(0x1c00001c);
|
||||
runBootloader = (void (*)(void * arg))runBootloaderAddress;
|
||||
|
||||
/* Start the bootloader. */
|
||||
runBootloader(NULL);
|
||||
}
|
||||
8
left/src/config.h
Normal file
8
left/src/config.h
Normal file
@@ -0,0 +1,8 @@
|
||||
#ifndef __CONFIG_H__
|
||||
#define __CONFIG_H__
|
||||
|
||||
// Macros:
|
||||
|
||||
// #define DEBUG_OVER_SPI
|
||||
|
||||
#endif
|
||||
62
left/src/debug_over_spi.c
Normal file
62
left/src/debug_over_spi.c
Normal file
@@ -0,0 +1,62 @@
|
||||
#include "debug_over_spi.h"
|
||||
#include "config.h"
|
||||
#include "fsl_gpio.h"
|
||||
|
||||
#ifdef DEBUG_OVER_SPI
|
||||
|
||||
#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;
|
||||
|
||||
#endif
|
||||
|
||||
static void masterCallback(SPI_Type *base, spi_master_handle_t *masterHandle, status_t status, void *userData)
|
||||
{
|
||||
#ifdef DEBUG_OVER_SPI
|
||||
masterFinished = true;
|
||||
#endif
|
||||
}
|
||||
|
||||
void DebugOverSpi_Init(void)
|
||||
{
|
||||
#ifdef DEBUG_OVER_SPI
|
||||
|
||||
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);
|
||||
#endif
|
||||
}
|
||||
|
||||
void DebugOverSpi_Send(uint8_t *tx, uint8_t len)
|
||||
{
|
||||
#ifdef DEBUG_OVER_SPI
|
||||
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
|
||||
}
|
||||
27
left/src/debug_over_spi.h
Normal file
27
left/src/debug_over_spi.h
Normal file
@@ -0,0 +1,27 @@
|
||||
#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
|
||||
37
left/src/i2c_watchdog.c
Normal file
37
left/src/i2c_watchdog.c
Normal file
@@ -0,0 +1,37 @@
|
||||
#include "fsl_i2c.h"
|
||||
#include "i2c.h"
|
||||
#include "i2c_watchdog.h"
|
||||
#include "test_led.h"
|
||||
#include "init_peripherals.h"
|
||||
|
||||
static uint32_t prevWatchdogCounter = 0;
|
||||
uint32_t I2cWatchdog_InnerCounter;
|
||||
volatile uint32_t I2cWatchdog_OuterCounter;
|
||||
|
||||
void InitI2cWatchdog(void)
|
||||
{
|
||||
lptmr_config_t lptmrConfig;
|
||||
LPTMR_GetDefaultConfig(&lptmrConfig);
|
||||
LPTMR_Init(LPTMR0, &lptmrConfig);
|
||||
LPTMR_SetTimerPeriod(LPTMR0, USEC_TO_COUNT(LPTMR_USEC_COUNT, LPTMR_SOURCE_CLOCK));
|
||||
LPTMR_EnableInterrupts(LPTMR0, kLPTMR_TimerInterruptEnable);
|
||||
EnableIRQ(LPTMR0_IRQn);
|
||||
LPTMR_StartTimer(LPTMR0);
|
||||
}
|
||||
|
||||
void I2C_WATCHDOG_LPTMR_HANDLER(void)
|
||||
{
|
||||
TEST_LED_TOGGLE();
|
||||
I2cWatchdog_OuterCounter++;
|
||||
|
||||
if (I2C_Watchdog == prevWatchdogCounter) { // Restart I2C if there hasn't been any interrupt during 100 ms
|
||||
// NVIC_SystemReset();
|
||||
I2cWatchdog_InnerCounter++;
|
||||
I2C_SlaveDeinit(I2C_BUS_BASEADDR);
|
||||
InitI2c();
|
||||
}
|
||||
|
||||
prevWatchdogCounter = I2C_Watchdog;
|
||||
|
||||
LPTMR_ClearStatusFlags(LPTMR0, kLPTMR_TimerCompareFlag);
|
||||
}
|
||||
19
left/src/i2c_watchdog.h
Normal file
19
left/src/i2c_watchdog.h
Normal file
@@ -0,0 +1,19 @@
|
||||
#ifndef __I2C_WATCHDOG_H__
|
||||
#define __I2C_WATCHDOG_H__
|
||||
|
||||
// Includes:
|
||||
|
||||
#include "fsl_lptmr.h"
|
||||
|
||||
// Macros:
|
||||
|
||||
#define I2C_WATCHDOG_LPTMR_HANDLER LPTMR0_IRQHandler
|
||||
#define LPTMR_SOURCE_CLOCK CLOCK_GetFreq(kCLOCK_LpoClk)
|
||||
#define LPTMR_USEC_COUNT 100000U
|
||||
|
||||
// Functions:
|
||||
|
||||
void InitI2cWatchdog(void);
|
||||
void RunWatchdog(void);
|
||||
|
||||
#endif
|
||||
@@ -8,33 +8,51 @@
|
||||
#include "i2c.h"
|
||||
#include "led_pwm.h"
|
||||
#include "slave_protocol_handler.h"
|
||||
#include "i2c_watchdog.h"
|
||||
#include "debug_over_spi.h"
|
||||
|
||||
static void i2cSlaveCallback(I2C_Type *base, i2c_slave_transfer_t *xfer, void *userData)
|
||||
{
|
||||
switch (xfer->event)
|
||||
i2c_slave_config_t slaveConfig;
|
||||
i2c_slave_handle_t slaveHandle;
|
||||
|
||||
uint8_t userData;
|
||||
uint8_t rxMessagePos;
|
||||
uint8_t dosBuffer[2];
|
||||
|
||||
static void i2cSlaveCallback(I2C_Type *base, i2c_slave_transfer_t *xfer, void *userDataArg)
|
||||
{
|
||||
dosBuffer[0] = xfer->event;
|
||||
dosBuffer[1] = userData;
|
||||
DebugOverSpi_Send(dosBuffer, 2);
|
||||
|
||||
switch (xfer->event) {
|
||||
case kI2C_SlaveTransmitEvent:
|
||||
SlaveProtocolHandler();
|
||||
xfer->data = SlaveTxBuffer;
|
||||
xfer->dataSize = SlaveTxSize;
|
||||
SlaveTxHandler();
|
||||
xfer->data = (uint8_t*)&TxMessage;
|
||||
xfer->dataSize = TxMessage.length + I2C_MESSAGE_HEADER_LENGTH;
|
||||
break;
|
||||
case kI2C_SlaveAddressMatchEvent:
|
||||
rxMessagePos = 0;
|
||||
break;
|
||||
case kI2C_SlaveReceiveEvent:
|
||||
SlaveProtocolHandler();
|
||||
xfer->data = SlaveRxBuffer;
|
||||
xfer->dataSize = SLAVE_RX_BUFFER_SIZE;
|
||||
break;
|
||||
case kI2C_SlaveCompletionEvent:
|
||||
xfer->data = NULL;
|
||||
xfer->dataSize = 0;
|
||||
break;
|
||||
case kI2C_SlaveTransmitAckEvent:
|
||||
((uint8_t*)&RxMessage)[rxMessagePos++] = userData;
|
||||
if (RxMessage.length == rxMessagePos-I2C_MESSAGE_HEADER_LENGTH) {
|
||||
SlaveRxHandler();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void InitI2c(void) {
|
||||
void InitInterruptPriorities(void)
|
||||
{
|
||||
NVIC_SetPriority(I2C0_IRQn, 1);
|
||||
NVIC_SetPriority(TPM1_IRQn, 1);
|
||||
NVIC_SetPriority(SPI0_IRQn, 1);
|
||||
}
|
||||
|
||||
void InitI2c(void)
|
||||
{
|
||||
port_pin_config_t pinConfig = {
|
||||
.pullSelect = kPORT_PullUp,
|
||||
};
|
||||
@@ -46,18 +64,15 @@ void InitI2c(void) {
|
||||
PORT_SetPinConfig(I2C_BUS_SDA_PORT, I2C_BUS_SDA_PIN, &pinConfig);
|
||||
PORT_SetPinConfig(I2C_BUS_SCL_PORT, I2C_BUS_SCL_PIN, &pinConfig);
|
||||
|
||||
i2c_slave_config_t slaveConfig;
|
||||
i2c_slave_handle_t slaveHandle;
|
||||
|
||||
I2C_SlaveGetDefaultConfig(&slaveConfig);
|
||||
slaveConfig.slaveAddress = I2C_ADDRESS_LEFT_KEYBOARD_HALF;
|
||||
slaveConfig.slaveAddress = I2C_ADDRESS_LEFT_KEYBOARD_HALF_FIRMWARE;
|
||||
I2C_SlaveInit(I2C_BUS_BASEADDR, &slaveConfig);
|
||||
I2C_SlaveTransferCreateHandle(I2C_BUS_BASEADDR, &slaveHandle, i2cSlaveCallback, NULL);
|
||||
slaveHandle.eventMask |= kI2C_SlaveCompletionEvent;
|
||||
I2C_SlaveTransferNonBlocking(I2C_BUS_BASEADDR, &slaveHandle, kI2C_SlaveCompletionEvent);
|
||||
I2C_SlaveTransferCreateHandle(I2C_BUS_BASEADDR, &slaveHandle, i2cSlaveCallback, &userData);
|
||||
I2C_SlaveTransferNonBlocking(I2C_BUS_BASEADDR, &slaveHandle, kI2C_SlaveAddressMatchEvent);
|
||||
}
|
||||
|
||||
void InitLedDriver(void) {
|
||||
void InitLedDriver(void)
|
||||
{
|
||||
CLOCK_EnableClock(LED_DRIVER_SDB_CLOCK);
|
||||
PORT_SetPinMux(LED_DRIVER_SDB_PORT, LED_DRIVER_SDB_PIN, kPORT_MuxAsGpio);
|
||||
GPIO_PinInit(LED_DRIVER_SDB_GPIO, LED_DRIVER_SDB_PIN, &(gpio_pin_config_t){kGPIO_DigitalOutput, 0});
|
||||
@@ -66,8 +81,11 @@ void InitLedDriver(void) {
|
||||
|
||||
void InitPeripherals(void)
|
||||
{
|
||||
InitInterruptPriorities();
|
||||
InitLedDriver();
|
||||
InitTestLed();
|
||||
LedPwm_Init();
|
||||
// InitI2cWatchdog();
|
||||
DebugOverSpi_Init();
|
||||
InitI2c();
|
||||
}
|
||||
|
||||
@@ -11,5 +11,6 @@
|
||||
// Functions:
|
||||
|
||||
void InitPeripherals(void);
|
||||
void InitI2c(void);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
// Functions:
|
||||
|
||||
extern void LedPwm_Init(void);
|
||||
void LedPwm_Init(void);
|
||||
void LedPwm_SetBrightness(uint8_t brightnessPercent);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -2,6 +2,10 @@
|
||||
#include "init_clock.h"
|
||||
#include "init_peripherals.h"
|
||||
#include "bootloader.h"
|
||||
#include <stdio.h>
|
||||
#include "config.h"
|
||||
|
||||
DEFINE_BOOTLOADER_CONFIG_AREA(I2C_ADDRESS_LEFT_KEYBOARD_HALF_BOOTLOADER)
|
||||
|
||||
key_matrix_t keyMatrix = {
|
||||
.colNum = KEYBOARD_MATRIX_COLS_NUM,
|
||||
@@ -10,7 +14,11 @@ 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}
|
||||
@@ -19,13 +27,15 @@ 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}
|
||||
}
|
||||
};
|
||||
|
||||
volatile bool DisableKeyMatrixScanState;
|
||||
|
||||
#define ALWAYS_ENTER_BOOTLOADER (0)
|
||||
/*! set to 1 for easier bootloader debugging. With this, the KL03 always enters bootloader mode after reset */
|
||||
|
||||
@@ -34,14 +44,11 @@ int main(void)
|
||||
InitClock();
|
||||
InitPeripherals();
|
||||
KeyMatrix_Init(&keyMatrix);
|
||||
|
||||
#if ALWAYS_ENTER_BOOTLOADER
|
||||
JumpToBootloader(); /* << EST: \todo Temporary only */
|
||||
#endif
|
||||
while (1) {
|
||||
if (!DisableKeyMatrixScanState) {
|
||||
KeyMatrix_Scan(&keyMatrix);
|
||||
}
|
||||
asm("wfi");
|
||||
__WFI();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,5 @@
|
||||
// Variables:
|
||||
|
||||
extern key_matrix_t keyMatrix;
|
||||
extern volatile bool DisableKeyMatrixScanState;
|
||||
|
||||
#endif
|
||||
|
||||
11
left/src/module.h
Normal file
11
left/src/module.h
Normal file
@@ -0,0 +1,11 @@
|
||||
#ifndef __MODULE_H__
|
||||
#define __MODULE_H__
|
||||
|
||||
// Macros:
|
||||
|
||||
#define MODULE_PROTOCOL_VERSION 1
|
||||
#define MODULE_ID ModuleId_LeftKeyboardHalf
|
||||
#define MODULE_KEY_COUNT (KEYBOARD_MATRIX_ROWS_NUM * KEYBOARD_MATRIX_COLS_NUM)
|
||||
#define MODULE_HAS_POINTER false
|
||||
|
||||
#endif
|
||||
@@ -8,13 +8,18 @@
|
||||
#include "main.h"
|
||||
#include "init_peripherals.h"
|
||||
#include "bool_array_converter.h"
|
||||
#include "bootloader.h"
|
||||
#include "module.h"
|
||||
|
||||
i2c_message_t RxMessage;
|
||||
i2c_message_t TxMessage;
|
||||
|
||||
void SetError(uint8_t error);
|
||||
void SetGenericError(void);
|
||||
void SetResponseByte(uint8_t response);
|
||||
|
||||
void SetError(uint8_t error) {
|
||||
SlaveTxBuffer[0] = error;
|
||||
TxMessage.data[0] = error;
|
||||
}
|
||||
|
||||
void SetGenericError(void)
|
||||
@@ -25,27 +30,71 @@ void SetGenericError(void)
|
||||
// Set a single byte as the response.
|
||||
void SetResponseByte(uint8_t response)
|
||||
{
|
||||
SlaveTxBuffer[1] = response;
|
||||
TxMessage.data[1] = response;
|
||||
}
|
||||
|
||||
void SlaveProtocolHandler(void)
|
||||
void SlaveRxHandler(void)
|
||||
{
|
||||
uint8_t commandId = SlaveRxBuffer[0];
|
||||
if (!CRC16_IsMessageValid(&RxMessage)) {
|
||||
TxMessage.length = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t commandId = RxMessage.data[0];
|
||||
switch (commandId) {
|
||||
case SlaveCommand_GetKeyStates:
|
||||
SlaveTxSize = KEY_STATE_BUFFER_SIZE;
|
||||
BoolBytesToBits(keyMatrix.keyStates, SlaveTxBuffer, LEFT_KEYBOARD_HALF_KEY_COUNT);
|
||||
CRC16_AppendToMessage(SlaveTxBuffer, KEY_STATE_SIZE);
|
||||
case SlaveCommand_JumpToBootloader:
|
||||
JumpToBootloader();
|
||||
break;
|
||||
case SlaveCommand_SetTestLed:
|
||||
SlaveTxSize = 0;
|
||||
bool isLedOn = SlaveRxBuffer[1];
|
||||
TxMessage.length = 0;
|
||||
bool isLedOn = RxMessage.data[1];
|
||||
TEST_LED_SET(isLedOn);
|
||||
break;
|
||||
case SlaveCommand_SetLedPwmBrightness:
|
||||
SlaveTxSize = 0;
|
||||
uint8_t brightnessPercent = SlaveRxBuffer[1];
|
||||
TxMessage.length = 0;
|
||||
uint8_t brightnessPercent = RxMessage.data[1];
|
||||
LedPwm_SetBrightness(brightnessPercent);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void SlaveTxHandler(void)
|
||||
{
|
||||
uint8_t commandId = RxMessage.data[0];
|
||||
switch (commandId) {
|
||||
case SlaveCommand_RequestProperty: {
|
||||
uint8_t propertyId = RxMessage.data[1];
|
||||
switch (propertyId) {
|
||||
case SlaveProperty_Sync: {
|
||||
memcpy(TxMessage.data, SlaveSyncString, SLAVE_SYNC_STRING_LENGTH);
|
||||
TxMessage.length = SLAVE_SYNC_STRING_LENGTH;
|
||||
break;
|
||||
}
|
||||
case SlaveProperty_ModuleId: {
|
||||
TxMessage.data[0] = MODULE_ID;
|
||||
TxMessage.length = 1;
|
||||
break;
|
||||
}
|
||||
case SlaveProperty_ProtocolVersion: {
|
||||
TxMessage.data[0] = MODULE_PROTOCOL_VERSION;
|
||||
TxMessage.length = 1;
|
||||
break;
|
||||
}
|
||||
case SlaveProperty_Features: {
|
||||
uhk_module_features_t *moduleFeatures = (uhk_module_features_t*)&TxMessage.data;
|
||||
moduleFeatures->keyCount = MODULE_KEY_COUNT;
|
||||
moduleFeatures->hasPointer = MODULE_HAS_POINTER;
|
||||
TxMessage.length = sizeof(uhk_module_features_t);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SlaveCommand_RequestKeyStates:
|
||||
BoolBytesToBits(keyMatrix.keyStates, TxMessage.data, MODULE_KEY_COUNT);
|
||||
TxMessage.length = BOOL_BYTES_TO_BITS_COUNT(MODULE_KEY_COUNT);
|
||||
break;
|
||||
}
|
||||
|
||||
CRC16_UpdateMessageChecksum(&TxMessage);
|
||||
}
|
||||
|
||||
@@ -5,27 +5,21 @@
|
||||
|
||||
#include "fsl_port.h"
|
||||
#include "crc16.h"
|
||||
#include "slave_protocol.h"
|
||||
|
||||
// Macros:
|
||||
|
||||
#define SLAVE_RX_BUFFER_SIZE 100
|
||||
#define SLAVE_TX_BUFFER_SIZE 100
|
||||
|
||||
#define PROTOCOL_RESPONSE_SUCCESS 0
|
||||
#define PROTOCOL_RESPONSE_GENERIC_ERROR 1
|
||||
|
||||
#define LEFT_KEYBOARD_HALF_KEY_COUNT (KEYBOARD_MATRIX_COLS_NUM*KEYBOARD_MATRIX_ROWS_NUM)
|
||||
#define KEY_STATE_SIZE (LEFT_KEYBOARD_HALF_KEY_COUNT/8 + 1)
|
||||
#define KEY_STATE_BUFFER_SIZE (KEY_STATE_SIZE + CRC16_HASH_LENGTH)
|
||||
|
||||
// Variables:
|
||||
|
||||
uint8_t SlaveRxBuffer[SLAVE_RX_BUFFER_SIZE];
|
||||
uint8_t SlaveTxBuffer[SLAVE_TX_BUFFER_SIZE];
|
||||
uint8_t SlaveTxSize;
|
||||
extern i2c_message_t RxMessage;
|
||||
extern i2c_message_t TxMessage;
|
||||
|
||||
// Functions:
|
||||
|
||||
extern void SlaveProtocolHandler(void);
|
||||
void SlaveRxHandler(void);
|
||||
void SlaveTxHandler(void);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -22,6 +22,6 @@
|
||||
|
||||
// Functions:
|
||||
|
||||
extern void InitTestLed(void);
|
||||
void InitTestLed(void);
|
||||
|
||||
#endif
|
||||
|
||||
Submodule lib/KSDK_2.0_MK22FN512xxx12 updated: cd173f98d1...7142722eed
Submodule lib/KSDK_2.0_MKL03Z8xxx4 updated: c02d0df05b...49e20a5798
Submodule lib/bootloader updated: 74a37a8d9e...b754ecbe68
18
package.json
Normal file
18
package.json
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"name": "uhk-firmware",
|
||||
"homepage": "https://UltimateHackingKeyboard.com",
|
||||
"description": "The firmware of the Ultimate Hacking Keyboard",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+ssh://git@github.com/UltimateHackingKeyboard/firmware.git"
|
||||
},
|
||||
"author": "Ultimate Gadget Laboratories",
|
||||
"license": "GPL-3.0",
|
||||
"bugs": {
|
||||
"url": "https://github.com/UltimateHackingKeyboard/firmware/issues"
|
||||
},
|
||||
"version": "2.1.0",
|
||||
"dataModelVersion": "1.0.0",
|
||||
"usbProtocolVersion": "1.2.0",
|
||||
"slaveProtocolVersion": "2.1.0"
|
||||
}
|
||||
@@ -74,6 +74,7 @@
|
||||
<listOptionValue builtIn="false" value="../../../src/ksdk_usb"/>
|
||||
<listOptionValue builtIn="false" value="../../../src/buspal"/>
|
||||
<listOptionValue builtIn="false" value="../../../src/buspal/bm_usb"/>
|
||||
<listOptionValue builtIn="false" value="../../../../lib/bootloader/src"/>
|
||||
<listOptionValue builtIn="false" value="../../../../lib/KSDK_2.0_MK22FN512xxx12/middleware/usb_1.0.0"/>
|
||||
<listOptionValue builtIn="false" value="../../../../lib/KSDK_2.0_MK22FN512xxx12/middleware/usb_1.0.0/osa"/>
|
||||
<listOptionValue builtIn="false" value="../../../../lib/KSDK_2.0_MK22FN512xxx12/middleware/usb_1.0.0/include"/>
|
||||
@@ -214,6 +215,7 @@
|
||||
<listOptionValue builtIn="false" value="../../../src/ksdk_usb"/>
|
||||
<listOptionValue builtIn="false" value="../../../src/buspal"/>
|
||||
<listOptionValue builtIn="false" value="../../../src/buspal/bm_usb"/>
|
||||
<listOptionValue builtIn="false" value="../../../../lib/bootloader/src"/>
|
||||
<listOptionValue builtIn="false" value="../../../../lib/KSDK_2.0_MK22FN512xxx12/middleware/usb_1.0.0"/>
|
||||
<listOptionValue builtIn="false" value="../../../../lib/KSDK_2.0_MK22FN512xxx12/middleware/usb_1.0.0/osa"/>
|
||||
<listOptionValue builtIn="false" value="../../../../lib/KSDK_2.0_MK22FN512xxx12/middleware/usb_1.0.0/include"/>
|
||||
@@ -282,6 +284,149 @@
|
||||
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
|
||||
<storageModule moduleId="ilg.gnuarmeclipse.managedbuild.packs"/>
|
||||
</cconfiguration>
|
||||
<cconfiguration id="ilg.gnuarmeclipse.managedbuild.cross.config.elf.release.1939339834.1692217331.1297236062.2081695142">
|
||||
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="ilg.gnuarmeclipse.managedbuild.cross.config.elf.release.1939339834.1692217331.1297236062.2081695142" moduleId="org.eclipse.cdt.core.settings" name="uhk-right-debug">
|
||||
<externalSettings/>
|
||||
<extensions>
|
||||
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
|
||||
</extensions>
|
||||
</storageModule>
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
<configuration artifactExtension="elf" artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release,org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe" cleanCommand="${cross_rm} -rf" description="Debug version of uhk-right without the bootloader" id="ilg.gnuarmeclipse.managedbuild.cross.config.elf.release.1939339834.1692217331.1297236062.2081695142" name="uhk-right-debug" parent="ilg.gnuarmeclipse.managedbuild.cross.config.elf.release">
|
||||
<folderInfo id="ilg.gnuarmeclipse.managedbuild.cross.config.elf.release.1939339834.1692217331.1297236062.2081695142." name="/" resourcePath="">
|
||||
<toolChain id="ilg.gnuarmeclipse.managedbuild.cross.toolchain.elf.release.788475280" name="Cross ARM GCC" superClass="ilg.gnuarmeclipse.managedbuild.cross.toolchain.elf.release">
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.level.402546001" name="Optimization Level" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.level" value="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.level.none" valueType="enumerated"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.messagelength.1839833218" name="Message length (-fmessage-length=0)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.messagelength" value="true" valueType="boolean"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.signedchar.1475099775" name="'char' is signed (-fsigned-char)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.signedchar" value="true" valueType="boolean"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.functionsections.1549408718" name="Function sections (-ffunction-sections)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.functionsections" value="true" valueType="boolean"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.datasections.183503224" name="Data sections (-fdata-sections)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.datasections" value="true" valueType="boolean"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.allwarn.836126004" name="Enable all common warnings (-Wall)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.allwarn" value="true" valueType="boolean"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.level.429491563" name="Debug level" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.level" value="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.level.max" valueType="enumerated"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.format.992104704" name="Debug format" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.format" value="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.format.default" valueType="enumerated"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.toolchain.name.1094670097" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.toolchain.name" value="Custom" valueType="string"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.architecture.1258520433" name="Architecture" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.architecture" value="ilg.gnuarmeclipse.managedbuild.cross.option.architecture.arm" valueType="enumerated"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.family.289189251" name="ARM family" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.family" value="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.mcpu.cortex-m4" valueType="enumerated"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.instructionset.791051424" name="Instruction set" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.instructionset" value="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.instructionset.thumb" valueType="enumerated"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.prefix.1261958015" name="Prefix" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.prefix" value="arm-none-eabi-" valueType="string"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.c.1795060393" name="C compiler" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.c" value="gcc" valueType="string"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.cpp.1234971975" name="C++ compiler" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.cpp" value="g++" valueType="string"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.objcopy.553998332" name="Hex/Bin converter" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.objcopy" value="objcopy" valueType="string"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.objdump.93408500" name="Listing generator" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.objdump" value="objdump" valueType="string"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.size.450860801" name="Size command" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.size" value="size" valueType="string"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.make.2090968095" name="Build command" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.make" value="make" valueType="string"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.rm.8859913" name="Remove command" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.rm" value="rm" valueType="string"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.addtools.createflash.137743124" name="Create flash image" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.addtools.createflash" value="true" valueType="boolean"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.addtools.printsize.658937193" name="Print size" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.addtools.printsize" value="true" valueType="boolean"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.toolchain.useglobalpath.2084940020" name="Use global path" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.toolchain.useglobalpath" value="true" valueType="boolean"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.ar.2031734167" name="Archiver" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.ar" value="ar" valueType="string"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.fpu.abi.1755024630" name="Float ABI" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.fpu.abi" value="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.fpu.abi.hard" valueType="enumerated"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.fpu.unit.1357885913" name="FPU Type" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.fpu.unit" value="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.fpu.unit.fpv4spd16" valueType="enumerated"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.nowarn.833619448" name="Inhibit all warnings (-w)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.nowarn" value="false" valueType="boolean"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.extrawarn.761562053" name="Enable extra warnings (-Wextra)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.extrawarn" value="false" valueType="boolean"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.conversion.1546201520" name="Warn on implicit conversions (-Wconversion)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.conversion" value="false" valueType="boolean"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.unitialized.4924656765.50064147.1540162301.1394771404" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.unitialized" value="false" valueType="boolean"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.floatequal.935064570" name="Warn if floats are compared as equal (-Wfloat-equal)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.floatequal" value="false" valueType="boolean"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.shadow.338843720" name="Warn if shadowed variable (-Wshadow)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.shadow" value="false" valueType="boolean"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.pointerarith.1222207584" name="Warn if pointer arithmetic (-Wpointer-arith)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.pointerarith" value="false" valueType="boolean"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.badfunctioncast.8875744698.1971488845.1311283180.123216109" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.badfunctioncast" value="false" valueType="boolean"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.logicalop.1653831341" name="Warn if suspicious logical ops (-Wlogical-op)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.logicalop" value="false" valueType="boolean"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.agreggatereturn.905748615" name="Warn if struct is returned (-Wagreggate-return)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.agreggatereturn" value="false" valueType="boolean"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.missingdeclaration.1896351702" name="Warn on undeclared global function (-Wmissing-declaration)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.missingdeclaration" value="false" valueType="boolean"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.toerrors.2124713168" name="Generate errors instead of warnings (-Werror)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.toerrors" value="false" valueType="boolean"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.addtools.createlisting.1228214828" name="Create extended listing" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.addtools.createlisting" value="false" valueType="boolean"/>
|
||||
<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="ilg.gnuarmeclipse.managedbuild.cross.targetPlatform.1911575583" isAbstract="false" osList="all" superClass="ilg.gnuarmeclipse.managedbuild.cross.targetPlatform"/>
|
||||
<builder buildPath="${workspace_loc:/k64f}/release" id="ilg.gnuarmeclipse.managedbuild.cross.builder.1942759303" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="optimal" stopOnErr="false" superClass="ilg.gnuarmeclipse.managedbuild.cross.builder"/>
|
||||
<tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.assembler.1355758441" name="Cross ARM GNU Assembler" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.assembler">
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.assembler.usepreprocessor.511724221" name="Use preprocessor" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.assembler.usepreprocessor" value="true" valueType="boolean"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.assembler.include.paths.1130167410" name="Include paths (-I)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.assembler.include.paths"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.assembler.defs.1008105723" name="Defined symbols (-D)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.assembler.defs" valueType="definedSymbols">
|
||||
<listOptionValue builtIn="false" value="DEBUG"/>
|
||||
<listOptionValue builtIn="false" value="__STARTUP_CLEAR_BSS"/>
|
||||
</option>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.assembler.nostdinc.1636290514" name="Do not search system directories (-nostdinc)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.assembler.nostdinc" value="false" valueType="boolean"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.assembler.other.1569513234" name="Other assembler flags" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.assembler.other" value=" -fno-common -ffunction-sections -fdata-sections -ffreestanding -fno-builtin -mapcs " valueType="string"/>
|
||||
<inputType id="ilg.gnuarmeclipse.managedbuild.cross.tool.assembler.input.458571433" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.assembler.input"/>
|
||||
</tool>
|
||||
<tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.c.compiler.1999160366" name="Cross ARM C Compiler" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.c.compiler">
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.compiler.include.paths.2002225588" name="Include paths (-I)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.compiler.include.paths" useByScannerDiscovery="false" valueType="includePath">
|
||||
<listOptionValue builtIn="false" value="../../../src"/>
|
||||
<listOptionValue builtIn="false" value="../../../src/ksdk_usb"/>
|
||||
<listOptionValue builtIn="false" value="../../../src/buspal"/>
|
||||
<listOptionValue builtIn="false" value="../../../src/buspal/bm_usb"/>
|
||||
<listOptionValue builtIn="false" value="../../../../lib/bootloader/src"/>
|
||||
<listOptionValue builtIn="false" value="../../../../lib/KSDK_2.0_MK22FN512xxx12/middleware/usb_1.0.0"/>
|
||||
<listOptionValue builtIn="false" value="../../../../lib/KSDK_2.0_MK22FN512xxx12/middleware/usb_1.0.0/osa"/>
|
||||
<listOptionValue builtIn="false" value="../../../../lib/KSDK_2.0_MK22FN512xxx12/middleware/usb_1.0.0/include"/>
|
||||
<listOptionValue builtIn="false" value="../../../../lib/KSDK_2.0_MK22FN512xxx12/middleware/usb_1.0.0/device"/>
|
||||
<listOptionValue builtIn="false" value="../../../../lib/KSDK_2.0_MK22FN512xxx12/CMSIS/Include"/>
|
||||
<listOptionValue builtIn="false" value="../../../../lib/KSDK_2.0_MK22FN512xxx12/devices/MK22F51212/drivers"/>
|
||||
<listOptionValue builtIn="false" value="../../../../lib/KSDK_2.0_MK22FN512xxx12/devices/MK22F51212"/>
|
||||
<listOptionValue builtIn="false" value="../../../../shared"/>
|
||||
</option>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.compiler.std.2080930720" name="Language standard" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.compiler.std" useByScannerDiscovery="true" value="ilg.gnuarmeclipse.managedbuild.cross.option.c.compiler.std.gnu99" valueType="enumerated"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.compiler.defs.1448177506" name="Defined symbols (-D)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.compiler.defs" useByScannerDiscovery="false" valueType="definedSymbols">
|
||||
<listOptionValue builtIn="false" value="DEBUG"/>
|
||||
<listOptionValue builtIn="false" value="CPU_MK22FN512VLH12"/>
|
||||
<listOptionValue builtIn="false" value="USB_STACK_BM"/>
|
||||
</option>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.compiler.nostdinc.1843660798" name="Do not search system directories (-nostdinc)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.compiler.nostdinc" useByScannerDiscovery="true" value="false" valueType="boolean"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.compiler.other.631746931" name="Other compiler flags" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.compiler.other" useByScannerDiscovery="true" value=" -fno-common -ffreestanding -fno-builtin -mapcs " valueType="string"/>
|
||||
<inputType id="ilg.gnuarmeclipse.managedbuild.cross.tool.c.compiler.input.205216042" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.c.compiler.input"/>
|
||||
</tool>
|
||||
<tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.cpp.compiler.2030696373" name="Cross ARM C++ Compiler" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.cpp.compiler"/>
|
||||
<tool commandLinePattern="${COMMAND} ${cross_toolchain_flags} ${FLAGS} ${OUTPUT_FLAG} ${OUTPUT_PREFIX}${OUTPUT} -Xlinker --start-group ${INPUTS} -Xlinker --end-group" id="ilg.gnuarmeclipse.managedbuild.cross.tool.c.linker.366566059" name="Cross ARM C Linker" outputPrefix="" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.c.linker">
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.gcsections.140326164" name="Remove unused sections (-Xlinker --gc-sections)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.gcsections" value="true" valueType="boolean"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.otherobjs.1879260923" name="Other objects" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.otherobjs"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.scriptfile.14607513" name="Script files (-T)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.scriptfile" valueType="stringList">
|
||||
<listOptionValue builtIn="false" value="../MK22FN512xxx12_flash.original.ld"/>
|
||||
</option>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.nostart.1152332755" name="Do not use standard start files (-nostartfiles)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.nostart" value="false" valueType="boolean"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.nodeflibs.447688448" name="Do not use default libraries (-nodefaultlibs)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.nodeflibs" value="false" valueType="boolean"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.libs.354124850" name="Libraries (-l)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.libs" valueType="libs">
|
||||
<listOptionValue builtIn="false" value="m"/>
|
||||
<listOptionValue builtIn="false" value="g"/>
|
||||
<listOptionValue builtIn="false" value="gcc"/>
|
||||
<listOptionValue builtIn="false" value="nosys"/>
|
||||
</option>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.cref.1783306987" name="Cross reference (-Xlinker --cref)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.cref" value="false" valueType="boolean"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.printgcsections.326337512" name="Print removed sections (-Xlinker --print-gc-sections)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.printgcsections" value="false" valueType="boolean"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.strip.1800573586" name="Omit all symbol information (-s)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.strip" value="false" valueType="boolean"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.other.1551124015" name="Other linker flags" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.other" value=" -Wall -fno-common -ffunction-sections -fdata-sections -ffreestanding -fno-builtin -mapcs -Xlinker -static -Xlinker -z -Xlinker muldefs " valueType="string"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.usenewlibnano.1416620259" name="Use newlib-nano (--specs=nano.specs)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.usenewlibnano" value="true" valueType="boolean"/>
|
||||
<inputType id="ilg.gnuarmeclipse.managedbuild.cross.tool.c.linker.input.969772289" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.c.linker.input">
|
||||
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
|
||||
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
|
||||
</inputType>
|
||||
</tool>
|
||||
<tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.cpp.linker.1391791236" name="Cross ARM C++ Linker" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.cpp.linker">
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.gcsections.949374537" name="Remove unused sections (-Xlinker --gc-sections)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.gcsections" value="true" valueType="boolean"/>
|
||||
</tool>
|
||||
<tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.archiver.1139673330" name="Cross ARM GNU Archiver" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.archiver"/>
|
||||
<tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.createflash.1204515045" name="Cross ARM GNU Create Flash Image" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.createflash">
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.createflash.choice.333655217" name="Output file format (-O)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.createflash.choice" value="ilg.gnuarmeclipse.managedbuild.cross.option.createflash.choice.srec" valueType="enumerated"/>
|
||||
</tool>
|
||||
<tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.createlisting.48170535" name="Cross ARM GNU Create Listing" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.createlisting">
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.source.2054726000" name="Display source (--source|-S)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.source" value="true" valueType="boolean"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.allheaders.1341408150" name="Display all headers (--all-headers|-x)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.allheaders" value="true" valueType="boolean"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.demangle.244264060" name="Demangle names (--demangle|-C)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.demangle" value="true" valueType="boolean"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.linenumbers.1270077678" name="Display line numbers (--line-numbers|-l)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.linenumbers" value="true" valueType="boolean"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.wide.1744044416" name="Wide lines (--wide|-w)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.wide" value="true" valueType="boolean"/>
|
||||
</tool>
|
||||
<tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.printsize.1706335486" name="Cross ARM GNU Print Size" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.printsize">
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.printsize.format.1292503518" name="Size format" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.printsize.format"/>
|
||||
</tool>
|
||||
</toolChain>
|
||||
</folderInfo>
|
||||
</configuration>
|
||||
</storageModule>
|
||||
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
|
||||
<storageModule moduleId="ilg.gnuarmeclipse.managedbuild.packs"/>
|
||||
</cconfiguration>
|
||||
</storageModule>
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
<project id="k64f.ilg.gnuarmeclipse.managedbuild.cross.target.elf.1537007018" name="Executable" projectType="ilg.gnuarmeclipse.managedbuild.cross.target.elf"/>
|
||||
@@ -304,6 +449,9 @@
|
||||
</configuration>
|
||||
<configuration configurationName="v7-release-srec"/>
|
||||
<configuration configurationName="v6-debug"/>
|
||||
<configuration configurationName="uhk-right-debug">
|
||||
<resource resourceType="PROJECT" workspacePath="/uhk-right"/>
|
||||
</configuration>
|
||||
<configuration configurationName="v7-debug-srec">
|
||||
<resource resourceType="PROJECT" workspacePath="/uhk-right"/>
|
||||
</configuration>
|
||||
|
||||
1
right/build/kds/.gitignore
vendored
1
right/build/kds/.gitignore
vendored
@@ -13,3 +13,4 @@ perf.data
|
||||
/uhk-right-debug-srec
|
||||
/uhk-right-release-srec/
|
||||
/.settings/
|
||||
/uhk-right-debug/
|
||||
|
||||
@@ -30,6 +30,11 @@
|
||||
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
|
||||
</natures>
|
||||
<linkedResources>
|
||||
<link>
|
||||
<name>bootloader-shared</name>
|
||||
<type>2</type>
|
||||
<locationURI>virtual:/virtual</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>drivers</name>
|
||||
<type>2</type>
|
||||
@@ -60,6 +65,16 @@
|
||||
<type>2</type>
|
||||
<locationURI>virtual:/virtual</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>bootloader-shared/wormhole.c</name>
|
||||
<type>1</type>
|
||||
<locationURI>PARENT-3-PROJECT_LOC/lib/bootloader/src/bootloader/src/wormhole.c</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>bootloader-shared/wormhole.h</name>
|
||||
<type>1</type>
|
||||
<locationURI>PARENT-3-PROJECT_LOC/lib/bootloader/src/bootloader/wormhole.h</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>drivers/fsl_adc16.c</name>
|
||||
<type>1</type>
|
||||
|
||||
@@ -62,7 +62,8 @@ MEMORY
|
||||
m_flash_config (RX) : ORIGIN = 0x00000400, LENGTH = 0x00000010
|
||||
m_text (RX) : ORIGIN = 0x00000410, LENGTH = 0x0007FBF0
|
||||
m_data (RW) : ORIGIN = 0x1FFF0000, LENGTH = 0x00010000
|
||||
m_data_2 (RW) : ORIGIN = 0x20000000, LENGTH = 0x00010000
|
||||
m_data_2 (RW) : ORIGIN = 0x20000000, LENGTH = 0x0000FF00
|
||||
m_noinit (RW) : ORIGIN = 0x2000FF00, LENGTH = 0x000000FF
|
||||
}
|
||||
|
||||
/* Define output sections */
|
||||
@@ -222,6 +223,13 @@ SECTIONS
|
||||
__END_BSS = .;
|
||||
} > m_data
|
||||
|
||||
.m_data_2 :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
*(.m_data_2) /* This is an User defined section */
|
||||
. = ALIGN(4);
|
||||
} > m_data_2
|
||||
|
||||
.heap :
|
||||
{
|
||||
. = ALIGN(8);
|
||||
@@ -258,5 +266,21 @@ SECTIONS
|
||||
.ARM.attributes 0 : { *(.ARM.attributes) }
|
||||
|
||||
ASSERT(__StackLimit >= __HeapLimit, "region m_data_2 overflowed with stack and heap")
|
||||
}
|
||||
|
||||
.noinit (NOLOAD):
|
||||
{
|
||||
. = ALIGN(4);
|
||||
_noinit = .;
|
||||
|
||||
*(.noinit .noinit.*)
|
||||
|
||||
. = ALIGN(4) ;
|
||||
_end_noinit = .;
|
||||
} > m_noinit
|
||||
|
||||
/* Mandatory to be word aligned, _sbrk assumes this */
|
||||
PROVIDE ( end = _end_noinit ); /* was _ebss */
|
||||
PROVIDE ( _end = _end_noinit );
|
||||
PROVIDE ( __end = _end_noinit );
|
||||
PROVIDE ( __end__ = _end_noinit );
|
||||
}
|
||||
|
||||
@@ -64,10 +64,10 @@
|
||||
<intAttribute key="org.eclipse.cdt.launch.ATTR_BUILD_BEFORE_LAUNCH_ATTR" value="2"/>
|
||||
<stringAttribute key="org.eclipse.cdt.launch.COREFILE_PATH" value=""/>
|
||||
<stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_REGISTER_GROUPS" value=""/>
|
||||
<stringAttribute key="org.eclipse.cdt.launch.PROGRAM_NAME" value="debug/uhk-right.elf"/>
|
||||
<stringAttribute key="org.eclipse.cdt.launch.PROGRAM_NAME" value="uhk-right-debug/uhk-right.elf"/>
|
||||
<stringAttribute key="org.eclipse.cdt.launch.PROJECT_ATTR" value="uhk-right"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_AUTO_ATTR" value="false"/>
|
||||
<stringAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_ID_ATTR" value=""/>
|
||||
<stringAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_ID_ATTR" value="ilg.gnuarmeclipse.managedbuild.cross.config.elf.release.1939339834.1692217331.1297236062.2081695142"/>
|
||||
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
|
||||
<listEntry value="/uhk-right"/>
|
||||
</listAttribute>
|
||||
@@ -77,6 +77,6 @@
|
||||
<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
|
||||
<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
|
||||
</listAttribute>
|
||||
<stringAttribute key="org.eclipse.dsf.launch.MEMORY_BLOCKS" value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <memoryBlockExpressionList context="Context string"/> "/>
|
||||
<stringAttribute key="org.eclipse.dsf.launch.MEMORY_BLOCKS" value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <memoryBlockExpressionList context="Context string"/> "/>
|
||||
<stringAttribute key="process_factory_id" value="org.eclipse.cdt.dsf.gdb.GdbProcessFactory"/>
|
||||
</launchConfiguration>
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
|
||||
// Macros:
|
||||
|
||||
#define I2C_WATCHDOG 1
|
||||
#define LED_DRIVER_STRESS_TEST 1
|
||||
#define I2C_WATCHDOG
|
||||
// #define LED_DRIVER_STRESS_TEST
|
||||
#define FIXED_BUSPAL_BOOTLOADER 1 // Used to mark the fixed BusPal bootloader. Macro usage can be removed in the future.
|
||||
// #define FORCE_BUSPAL 1
|
||||
|
||||
|
||||
@@ -1,11 +1,27 @@
|
||||
#include "config_globals.h"
|
||||
#include "attributes.h"
|
||||
#include "eeprom.h"
|
||||
|
||||
static uint8_t hardwareConfig[HARDWARE_CONFIG_SIZE];
|
||||
config_buffer_t HardwareConfigBuffer = {hardwareConfig};
|
||||
static uint8_t ATTR_DATA2 stagingUserConfig[USER_CONFIG_SIZE];
|
||||
static uint8_t validatedUserConfig[USER_CONFIG_SIZE];
|
||||
|
||||
static uint8_t userConfig1[USER_CONFIG_SIZE];
|
||||
static uint8_t __attribute__((section (".m_data_2"))) userConfig2[USER_CONFIG_SIZE];
|
||||
config_buffer_t UserConfigBuffer = { userConfig1 };
|
||||
config_buffer_t StagingUserConfigBuffer = { userConfig2 };
|
||||
config_buffer_t HardwareConfigBuffer = { hardwareConfig };
|
||||
config_buffer_t StagingUserConfigBuffer = { stagingUserConfig };
|
||||
config_buffer_t ValidatedUserConfigBuffer = { validatedUserConfig };
|
||||
|
||||
bool ParserRunDry;
|
||||
|
||||
config_buffer_t* ConfigBufferIdToConfigBuffer(config_buffer_id_t configBufferId)
|
||||
{
|
||||
switch (configBufferId) {
|
||||
case ConfigBufferId_HardwareConfig:
|
||||
return &HardwareConfigBuffer;
|
||||
case ConfigBufferId_StagingUserConfig:
|
||||
return &StagingUserConfigBuffer;
|
||||
case ConfigBufferId_ValidatedUserConfig:
|
||||
return &ValidatedUserConfigBuffer;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,22 +1,28 @@
|
||||
#ifndef __CONFIG_STATE_H__
|
||||
#define __CONFIG_STATE_H__
|
||||
#ifndef __CONFIG_GLOBALS_H__
|
||||
#define __CONFIG_GLOBALS_H__
|
||||
|
||||
// Includes:
|
||||
|
||||
#include "fsl_common.h"
|
||||
#include "eeprom.h"
|
||||
#include "basic_types.h"
|
||||
|
||||
// Macros:
|
||||
// Typedefs:
|
||||
|
||||
#define HARDWARE_CONFIG_SIZE 64
|
||||
#define USER_CONFIG_SIZE (EEPROM_SIZE - HARDWARE_CONFIG_SIZE)
|
||||
typedef enum {
|
||||
ConfigBufferId_HardwareConfig,
|
||||
ConfigBufferId_StagingUserConfig,
|
||||
ConfigBufferId_ValidatedUserConfig,
|
||||
} config_buffer_id_t;
|
||||
|
||||
// Variables:
|
||||
|
||||
extern bool ParserRunDry;
|
||||
extern config_buffer_t HardwareConfigBuffer;
|
||||
extern config_buffer_t UserConfigBuffer;
|
||||
extern config_buffer_t StagingUserConfigBuffer;
|
||||
extern config_buffer_t ValidatedUserConfigBuffer;
|
||||
|
||||
// Functions:
|
||||
|
||||
config_buffer_t* ConfigBufferIdToConfigBuffer(config_buffer_id_t configBufferId);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -28,38 +28,46 @@ parser_error_t ParseConfig(config_buffer_t *buffer)
|
||||
uint16_t keymapCount;
|
||||
|
||||
(void)dataModelVersion;
|
||||
|
||||
if (moduleConfigurationCount > 255) {
|
||||
return ParserError_InvalidModuleConfigurationCount;
|
||||
}
|
||||
|
||||
for (uint8_t moduleConfigurationIdx = 0; moduleConfigurationIdx < moduleConfigurationCount; moduleConfigurationIdx++) {
|
||||
errorCode = parseModuleConfiguration(buffer);
|
||||
if (errorCode != ParserError_Success) {
|
||||
return errorCode;
|
||||
}
|
||||
}
|
||||
|
||||
macroCount = readCompactLength(buffer);
|
||||
if (macroCount > MAX_MACRO_NUM) {
|
||||
return ParserError_InvalidMacroCount;
|
||||
}
|
||||
|
||||
for (uint8_t macroIdx = 0; macroIdx < macroCount; macroIdx++) {
|
||||
errorCode = ParseMacro(buffer, macroIdx);
|
||||
if (errorCode != ParserError_Success) {
|
||||
return errorCode;
|
||||
}
|
||||
}
|
||||
|
||||
keymapCount = readCompactLength(buffer);
|
||||
if (keymapCount > MAX_KEYMAP_NUM) {
|
||||
if (keymapCount == 0 || keymapCount > MAX_KEYMAP_NUM) {
|
||||
return ParserError_InvalidKeymapCount;
|
||||
}
|
||||
|
||||
for (uint8_t keymapIdx = 0; keymapIdx < keymapCount; keymapIdx++) {
|
||||
errorCode = ParseKeymap(buffer, keymapIdx, keymapCount, macroCount);
|
||||
if (errorCode != ParserError_Success) {
|
||||
return errorCode;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ParserRunDry) {
|
||||
AllKeymapsCount = keymapCount;
|
||||
AllMacrosCount = macroCount;
|
||||
}
|
||||
|
||||
return ParserError_Success;
|
||||
}
|
||||
|
||||
@@ -3,10 +3,13 @@
|
||||
#include "i2c_addresses.h"
|
||||
#include "i2c.h"
|
||||
#include "eeprom.h"
|
||||
#include "config_parser/config_globals.h"
|
||||
|
||||
bool IsEepromBusy;
|
||||
eeprom_transfer_t CurrentEepromTransfer;
|
||||
static eeprom_operation_t CurrentEepromOperation;
|
||||
static config_buffer_id_t CurrentConfigBufferId;
|
||||
status_t LastEepromTransferStatus;
|
||||
void (*SuccessCallback)();
|
||||
|
||||
static i2c_master_handle_t i2cHandle;
|
||||
static i2c_master_transfer_t i2cTransfer;
|
||||
@@ -37,7 +40,7 @@ static status_t i2cAsyncRead(uint8_t *data, size_t dataSize)
|
||||
return I2C_MasterTransferNonBlocking(I2C_EEPROM_BUS_BASEADDR, &i2cHandle, &i2cTransfer);
|
||||
}
|
||||
|
||||
static status_t writePage()
|
||||
static status_t writePage(void)
|
||||
{
|
||||
static uint8_t buffer[EEPROM_BUFFER_SIZE];
|
||||
uint16_t targetEepromOffset = sourceOffset + eepromStartAddress;
|
||||
@@ -53,28 +56,31 @@ static void i2cCallback(I2C_Type *base, i2c_master_handle_t *handle, status_t st
|
||||
{
|
||||
LastEepromTransferStatus = status;
|
||||
|
||||
bool isHardwareConfig = CurrentEepromTransfer == EepromTransfer_ReadHardwareConfiguration;
|
||||
switch (CurrentEepromTransfer) {
|
||||
case EepromTransfer_ReadHardwareConfiguration:
|
||||
case EepromTransfer_ReadUserConfiguration:
|
||||
switch (CurrentEepromOperation) {
|
||||
case EepromOperation_Read:
|
||||
if (isReadSent) {
|
||||
IsEepromBusy = false;
|
||||
if (SuccessCallback) {
|
||||
SuccessCallback();
|
||||
}
|
||||
return;
|
||||
}
|
||||
LastEepromTransferStatus = i2cAsyncRead(
|
||||
isHardwareConfig ? HardwareConfigBuffer.buffer : UserConfigBuffer.buffer,
|
||||
isHardwareConfig ? HARDWARE_CONFIG_SIZE : USER_CONFIG_SIZE
|
||||
ConfigBufferIdToConfigBuffer(CurrentConfigBufferId)->buffer,
|
||||
CurrentConfigBufferId == ConfigBufferId_HardwareConfig ? HARDWARE_CONFIG_SIZE : USER_CONFIG_SIZE
|
||||
);
|
||||
IsEepromBusy = true;
|
||||
isReadSent = true;
|
||||
break;
|
||||
case EepromTransfer_WriteHardwareConfiguration:
|
||||
case EepromTransfer_WriteUserConfiguration:
|
||||
case EepromOperation_Write:
|
||||
if (status == kStatus_Success) {
|
||||
sourceOffset += writeLength;
|
||||
}
|
||||
IsEepromBusy = sourceOffset < sourceLength;
|
||||
if (!IsEepromBusy) {
|
||||
if (SuccessCallback) {
|
||||
SuccessCallback();
|
||||
}
|
||||
return;
|
||||
}
|
||||
LastEepromTransferStatus = writePage();
|
||||
@@ -90,28 +96,28 @@ void EEPROM_Init(void)
|
||||
I2C_MasterTransferCreateHandle(I2C_EEPROM_BUS_BASEADDR, &i2cHandle, i2cCallback, NULL);
|
||||
}
|
||||
|
||||
status_t EEPROM_LaunchTransfer(eeprom_transfer_t transferType)
|
||||
status_t EEPROM_LaunchTransfer(eeprom_operation_t operation, config_buffer_id_t config_buffer_id, void (*successCallback))
|
||||
{
|
||||
if (IsEepromBusy) {
|
||||
return kStatus_I2C_Busy;
|
||||
}
|
||||
|
||||
CurrentEepromTransfer = transferType;
|
||||
bool isHardwareConfig = CurrentEepromTransfer == EepromTransfer_ReadHardwareConfiguration ||
|
||||
CurrentEepromTransfer == EepromTransfer_WriteHardwareConfiguration;
|
||||
CurrentEepromOperation = operation;
|
||||
CurrentConfigBufferId = config_buffer_id;
|
||||
|
||||
SuccessCallback = successCallback;
|
||||
bool isHardwareConfig = CurrentConfigBufferId == ConfigBufferId_HardwareConfig;
|
||||
eepromStartAddress = isHardwareConfig ? 0 : HARDWARE_CONFIG_SIZE;
|
||||
addressBuffer[0] = eepromStartAddress >> 8;
|
||||
addressBuffer[1] = eepromStartAddress & 0xff;
|
||||
|
||||
switch (transferType) {
|
||||
case EepromTransfer_ReadHardwareConfiguration:
|
||||
case EepromTransfer_ReadUserConfiguration:
|
||||
switch (CurrentEepromOperation) {
|
||||
case EepromOperation_Read:
|
||||
isReadSent = false;
|
||||
LastEepromTransferStatus = i2cAsyncWrite(addressBuffer, EEPROM_ADDRESS_LENGTH);
|
||||
break;
|
||||
case EepromTransfer_WriteHardwareConfiguration:
|
||||
case EepromTransfer_WriteUserConfiguration:
|
||||
sourceBuffer = isHardwareConfig ? HardwareConfigBuffer.buffer : UserConfigBuffer.buffer;
|
||||
case EepromOperation_Write:
|
||||
sourceBuffer = ConfigBufferIdToConfigBuffer(CurrentConfigBufferId)->buffer;
|
||||
sourceOffset = 0;
|
||||
sourceLength = isHardwareConfig ? HARDWARE_CONFIG_SIZE : USER_CONFIG_SIZE;
|
||||
LastEepromTransferStatus = writePage();
|
||||
|
||||
@@ -1,9 +1,16 @@
|
||||
#ifndef __EEPROM_H__
|
||||
#define __EEPROM_H__
|
||||
|
||||
// Includes:
|
||||
|
||||
#include "config_parser/config_globals.h"
|
||||
|
||||
// Macros:
|
||||
|
||||
#define EEPROM_SIZE (32*1024)
|
||||
#define HARDWARE_CONFIG_SIZE 64
|
||||
#define USER_CONFIG_SIZE (EEPROM_SIZE - HARDWARE_CONFIG_SIZE)
|
||||
|
||||
#define EEPROM_ADDRESS_LENGTH 2
|
||||
#define EEPROM_PAGE_SIZE 64
|
||||
#define EEPROM_BUFFER_SIZE (EEPROM_ADDRESS_LENGTH + EEPROM_PAGE_SIZE)
|
||||
@@ -11,21 +18,18 @@
|
||||
// Typedefs:
|
||||
|
||||
typedef enum {
|
||||
EepromTransfer_ReadHardwareConfiguration,
|
||||
EepromTransfer_WriteHardwareConfiguration,
|
||||
EepromTransfer_ReadUserConfiguration,
|
||||
EepromTransfer_WriteUserConfiguration,
|
||||
} eeprom_transfer_t;
|
||||
EepromOperation_Read,
|
||||
EepromOperation_Write,
|
||||
} eeprom_operation_t;
|
||||
|
||||
// Variables:
|
||||
|
||||
extern bool IsEepromBusy;
|
||||
extern eeprom_transfer_t CurrentEepromTransfer;
|
||||
extern status_t EepromTransferStatus;
|
||||
|
||||
// Functions:
|
||||
|
||||
extern void EEPROM_Init(void);
|
||||
extern status_t EEPROM_LaunchTransfer(eeprom_transfer_t transferType);
|
||||
void EEPROM_Init(void);
|
||||
status_t EEPROM_LaunchTransfer(eeprom_operation_t operation, config_buffer_id_t config_buffer_id, void (*successCallback));
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "i2c.h"
|
||||
#include "crc16.h"
|
||||
|
||||
i2c_master_handle_t I2cMasterHandle;
|
||||
i2c_master_transfer_t masterTransfer;
|
||||
@@ -9,8 +10,19 @@ status_t I2cAsyncWrite(uint8_t i2cAddress, uint8_t *data, size_t dataSize)
|
||||
masterTransfer.direction = kI2C_Write;
|
||||
masterTransfer.data = data;
|
||||
masterTransfer.dataSize = dataSize;
|
||||
status_t status = I2C_MasterTransferNonBlocking(I2C_MAIN_BUS_BASEADDR, &I2cMasterHandle, &masterTransfer);
|
||||
return status;
|
||||
I2cMasterHandle.userData = NULL;
|
||||
return I2C_MasterTransferNonBlocking(I2C_MAIN_BUS_BASEADDR, &I2cMasterHandle, &masterTransfer);
|
||||
}
|
||||
|
||||
status_t I2cAsyncWriteMessage(uint8_t i2cAddress, i2c_message_t *message)
|
||||
{
|
||||
masterTransfer.slaveAddress = i2cAddress;
|
||||
masterTransfer.direction = kI2C_Write;
|
||||
masterTransfer.data = (uint8_t*)message;
|
||||
masterTransfer.dataSize = I2C_MESSAGE_HEADER_LENGTH + message->length;
|
||||
I2cMasterHandle.userData = NULL;
|
||||
CRC16_UpdateMessageChecksum(message);
|
||||
return I2C_MasterTransferNonBlocking(I2C_MAIN_BUS_BASEADDR, &I2cMasterHandle, &masterTransfer);
|
||||
}
|
||||
|
||||
status_t I2cAsyncRead(uint8_t i2cAddress, uint8_t *data, size_t dataSize)
|
||||
@@ -19,6 +31,16 @@ status_t I2cAsyncRead(uint8_t i2cAddress, uint8_t *data, size_t dataSize)
|
||||
masterTransfer.direction = kI2C_Read;
|
||||
masterTransfer.data = data;
|
||||
masterTransfer.dataSize = dataSize;
|
||||
status_t status = I2C_MasterTransferNonBlocking(I2C_MAIN_BUS_BASEADDR, &I2cMasterHandle, &masterTransfer);
|
||||
return status;
|
||||
I2cMasterHandle.userData = NULL;
|
||||
return I2C_MasterTransferNonBlocking(I2C_MAIN_BUS_BASEADDR, &I2cMasterHandle, &masterTransfer);
|
||||
}
|
||||
|
||||
status_t I2cAsyncReadMessage(uint8_t i2cAddress, i2c_message_t *message)
|
||||
{
|
||||
masterTransfer.slaveAddress = i2cAddress;
|
||||
masterTransfer.direction = kI2C_Read;
|
||||
masterTransfer.data = (uint8_t*)message;
|
||||
masterTransfer.dataSize = I2C_MESSAGE_MAX_TOTAL_LENGTH;
|
||||
I2cMasterHandle.userData = (void*)1;
|
||||
return I2C_MasterTransferNonBlocking(I2C_MAIN_BUS_BASEADDR, &I2cMasterHandle, &masterTransfer);
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
// Includes:
|
||||
|
||||
#include "fsl_i2c.h"
|
||||
#include "slave_protocol.h"
|
||||
|
||||
// Macros:
|
||||
|
||||
@@ -14,10 +15,12 @@
|
||||
#define I2C_MAIN_BUS_BAUD_RATE 100000 // 100 kHz works even with a 20 meter long bridge cable.
|
||||
#define I2C_MAIN_BUS_MUX kPORT_MuxAlt7
|
||||
|
||||
#define I2C_MAIN_BUS_SDA_GPIO GPIOD
|
||||
#define I2C_MAIN_BUS_SDA_PORT PORTD
|
||||
#define I2C_MAIN_BUS_SDA_CLOCK kCLOCK_PortD
|
||||
#define I2C_MAIN_BUS_SDA_PIN 3
|
||||
|
||||
#define I2C_MAIN_BUS_SCL_GPIO GPIOD
|
||||
#define I2C_MAIN_BUS_SCL_PORT PORTD
|
||||
#define I2C_MAIN_BUS_SCL_CLOCK kCLOCK_PortD
|
||||
#define I2C_MAIN_BUS_SCL_PIN 2
|
||||
@@ -45,5 +48,7 @@
|
||||
|
||||
status_t I2cAsyncWrite(uint8_t i2cAddress, uint8_t *data, size_t dataSize);
|
||||
status_t I2cAsyncRead(uint8_t i2cAddress, uint8_t *data, size_t dataSize);
|
||||
status_t I2cAsyncWriteMessage(uint8_t i2cAddress, i2c_message_t *message);
|
||||
status_t I2cAsyncReadMessage(uint8_t i2cAddress, i2c_message_t *message);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,31 +1,30 @@
|
||||
#include "fsl_pit.h"
|
||||
#include "fsl_i2c.h"
|
||||
#include "fsl_clock.h"
|
||||
#include "fsl_port.h"
|
||||
#include "fsl_gpio.h"
|
||||
#include "i2c.h"
|
||||
#include "i2c_watchdog.h"
|
||||
#include "slave_scheduler.h"
|
||||
#include "init_peripherals.h"
|
||||
|
||||
#define PIT_I2C_WATCHDOG_HANDLER PIT0_IRQHandler
|
||||
#define PIT_I2C_WATCHDOG_IRQ_ID PIT0_IRQn
|
||||
#define PIT_SOURCE_CLOCK CLOCK_GetFreq(kCLOCK_BusClk)
|
||||
uint32_t I2cWatchdog_OuterCounter;
|
||||
uint32_t I2cWatchdog_InnerCounter;
|
||||
|
||||
static uint32_t prevWatchdogCounter = 0;
|
||||
uint32_t I2C_WatchdogInnerCounter;
|
||||
uint32_t I2C_WatchdogOuterCounter;
|
||||
static uint32_t prevWatchdogCounter;
|
||||
|
||||
// This function restarts and reinstalls the I2C handler when the I2C bus gets unresponsive
|
||||
// by a misbehaving I2C slave, or by disconnecting the left keyboard half or an add-on module.
|
||||
// This method relies on a patched KSDK which increments I2C_Watchdog upon I2C transfers.
|
||||
void PIT_I2C_WATCHDOG_HANDLER(void)
|
||||
{
|
||||
I2C_WatchdogOuterCounter++;
|
||||
if (I2C_Watchdog == prevWatchdogCounter) { // Restart I2C if there hasn't be any interrupt during 100 ms
|
||||
I2C_WatchdogInnerCounter++;
|
||||
I2cWatchdog_OuterCounter++;
|
||||
if (I2C_Watchdog == prevWatchdogCounter) { // Restart I2C if there haven't been any interrupts recently
|
||||
I2cWatchdog_InnerCounter++;
|
||||
i2c_master_config_t masterConfig;
|
||||
I2C_MasterGetDefaultConfig(&masterConfig);
|
||||
I2C_MasterDeinit(I2C_MAIN_BUS_BASEADDR);
|
||||
uint32_t sourceClock = CLOCK_GetFreq(I2C_MASTER_BUS_CLK_SRC);
|
||||
I2C_MasterInit(I2C_MAIN_BUS_BASEADDR, &masterConfig, sourceClock);
|
||||
InitI2cMainBus();
|
||||
InitSlaveScheduler();
|
||||
}
|
||||
|
||||
@@ -34,12 +33,12 @@ void PIT_I2C_WATCHDOG_HANDLER(void)
|
||||
PIT_ClearStatusFlags(PIT, kPIT_Chnl_0, PIT_TFLG_TIF_MASK);
|
||||
}
|
||||
|
||||
void InitI2cWatchdog()
|
||||
void InitI2cWatchdog(void)
|
||||
{
|
||||
pit_config_t pitConfig;
|
||||
PIT_GetDefaultConfig(&pitConfig);
|
||||
PIT_Init(PIT, &pitConfig);
|
||||
PIT_SetTimerPeriod(PIT, kPIT_Chnl_0, USEC_TO_COUNT(100000U, PIT_SOURCE_CLOCK));
|
||||
PIT_SetTimerPeriod(PIT, kPIT_Chnl_0, USEC_TO_COUNT(I2C_WATCHDOG_INTERVAL_USEC, PIT_SOURCE_CLOCK));
|
||||
PIT_EnableInterrupts(PIT, kPIT_Chnl_0, kPIT_TimerInterruptEnable);
|
||||
EnableIRQ(PIT_I2C_WATCHDOG_IRQ_ID);
|
||||
PIT_StartTimer(PIT, kPIT_Chnl_0);
|
||||
|
||||
@@ -1,9 +1,21 @@
|
||||
#ifndef __I2C_WATCHDOG_H__
|
||||
#define __I2C_WATCHDOG_H__
|
||||
|
||||
// Macros:
|
||||
|
||||
#define I2C_WATCHDOG_INTERVAL_USEC 100000
|
||||
|
||||
#define PIT_I2C_WATCHDOG_HANDLER PIT0_IRQHandler
|
||||
#define PIT_I2C_WATCHDOG_IRQ_ID PIT0_IRQn
|
||||
#define PIT_SOURCE_CLOCK CLOCK_GetFreq(kCLOCK_BusClk)
|
||||
|
||||
// Variables:
|
||||
|
||||
extern uint32_t I2cWatchdog_InnerCounter;
|
||||
extern uint32_t I2cWatchdog_OuterCounter;
|
||||
|
||||
// Functions:
|
||||
|
||||
extern void InitI2cWatchdog();
|
||||
extern uint32_t I2C_WatchdogInnerCounter;
|
||||
extern uint32_t I2C_WatchdogOuterCounter;
|
||||
void InitI2cWatchdog(void);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -3,6 +3,6 @@
|
||||
|
||||
// Functions:
|
||||
|
||||
void InitClock();
|
||||
void InitClock(void);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -14,45 +14,100 @@
|
||||
#include "eeprom.h"
|
||||
#include "microseconds/microseconds_pit.c"
|
||||
|
||||
void InitI2c() {
|
||||
port_pin_config_t pinConfig = {
|
||||
.pullSelect = kPORT_PullUp,
|
||||
.openDrainEnable = kPORT_OpenDrainEnable
|
||||
};
|
||||
void InitInterruptPriorities(void)
|
||||
{
|
||||
NVIC_SetPriority(I2C0_IRQn, 1);
|
||||
NVIC_SetPriority(I2C1_IRQn, 1);
|
||||
NVIC_SetPriority(USB0_IRQn, 1);
|
||||
}
|
||||
|
||||
i2c_master_config_t masterConfig;
|
||||
I2C_MasterGetDefaultConfig(&masterConfig);
|
||||
uint32_t sourceClock;
|
||||
void delay(void)
|
||||
{
|
||||
for (volatile uint32_t i=0; i<62; i++);
|
||||
}
|
||||
|
||||
// Initialize main bus
|
||||
void recoverI2c(void)
|
||||
{
|
||||
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});
|
||||
|
||||
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});
|
||||
|
||||
if (isSdaHigh) {
|
||||
return;
|
||||
}
|
||||
|
||||
GPIO_WritePinOutput(I2C_MAIN_BUS_SCL_GPIO, I2C_MAIN_BUS_SCL_PIN, isOn);
|
||||
delay();
|
||||
isOn = !isOn;
|
||||
}
|
||||
|
||||
GPIO_WritePinOutput(I2C_MAIN_BUS_SDA_GPIO, I2C_MAIN_BUS_SDA_PIN, 0);
|
||||
delay();
|
||||
GPIO_WritePinOutput(I2C_MAIN_BUS_SCL_GPIO, I2C_MAIN_BUS_SCL_PIN, 1);
|
||||
delay();
|
||||
GPIO_WritePinOutput(I2C_MAIN_BUS_SDA_GPIO, I2C_MAIN_BUS_SDA_PIN, 1);
|
||||
delay();
|
||||
}
|
||||
|
||||
void InitI2cMainBus(void)
|
||||
{
|
||||
CLOCK_EnableClock(I2C_MAIN_BUS_SDA_CLOCK);
|
||||
CLOCK_EnableClock(I2C_MAIN_BUS_SCL_CLOCK);
|
||||
|
||||
pinConfig.mux = I2C_MAIN_BUS_MUX;
|
||||
recoverI2c();
|
||||
|
||||
port_pin_config_t pinConfig = {
|
||||
.pullSelect = kPORT_PullUp,
|
||||
.openDrainEnable = kPORT_OpenDrainEnable,
|
||||
.mux = I2C_MAIN_BUS_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);
|
||||
|
||||
i2c_master_config_t masterConfig;
|
||||
I2C_MasterGetDefaultConfig(&masterConfig);
|
||||
masterConfig.baudRate_Bps = I2C_MAIN_BUS_BAUD_RATE;
|
||||
sourceClock = CLOCK_GetFreq(I2C_MASTER_BUS_CLK_SRC);
|
||||
I2C_MasterInit(I2C_MAIN_BUS_BASEADDR, &masterConfig, sourceClock);
|
||||
uint32_t sourceClock = CLOCK_GetFreq(I2C_MASTER_BUS_CLK_SRC);
|
||||
I2C_MasterInit(I2C_MAIN_BUS_BASEADDR, &masterConfig, sourceClock);}
|
||||
|
||||
void initI2cEepromBus(void)
|
||||
{
|
||||
port_pin_config_t pinConfig = {
|
||||
.pullSelect = kPORT_PullUp,
|
||||
.openDrainEnable = kPORT_OpenDrainEnable,
|
||||
.mux = I2C_EEPROM_BUS_MUX,
|
||||
};
|
||||
|
||||
// Initialize EEPROM bus
|
||||
|
||||
CLOCK_EnableClock(I2C_EEPROM_BUS_SDA_CLOCK);
|
||||
CLOCK_EnableClock(I2C_EEPROM_BUS_SCL_CLOCK);
|
||||
|
||||
pinConfig.mux = I2C_EEPROM_BUS_MUX;
|
||||
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;
|
||||
sourceClock = CLOCK_GetFreq(I2C_EEPROM_BUS_CLK_SRC);
|
||||
uint32_t sourceClock = CLOCK_GetFreq(I2C_EEPROM_BUS_CLK_SRC);
|
||||
I2C_MasterInit(I2C_EEPROM_BUS_BASEADDR, &masterConfig, sourceClock);
|
||||
}
|
||||
|
||||
void InitI2c(void)
|
||||
{
|
||||
InitI2cMainBus();
|
||||
initI2cEepromBus();
|
||||
}
|
||||
|
||||
void InitPeripherals(void)
|
||||
{
|
||||
InitInterruptPriorities();
|
||||
InitLedDriver();
|
||||
InitResetButton();
|
||||
InitMergeSensor();
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
#ifndef __INIT_PERIPHERALS_H__
|
||||
#define __INIT_PERIPHERALS_H__
|
||||
|
||||
// Includes
|
||||
|
||||
#include "fsl_common.h"
|
||||
|
||||
// Functions:
|
||||
|
||||
extern void InitPeripherals();
|
||||
void InitPeripherals(void);
|
||||
void InitI2cMainBus(void);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
// Includes:
|
||||
|
||||
#include <stdint.h>
|
||||
#include "attributes.h"
|
||||
#include "lufa/HIDClassCommon.h"
|
||||
#include "usb_composite_device.h"
|
||||
#include "main.h"
|
||||
@@ -69,27 +70,27 @@
|
||||
uint8_t longPressAction;
|
||||
uint8_t modifiers;
|
||||
uint16_t scancode;
|
||||
} __attribute__ ((packed)) keystroke;
|
||||
} ATTR_PACKED keystroke;
|
||||
struct {
|
||||
mouse_button_t buttonActions;
|
||||
mouse_scroll_t scrollActions;
|
||||
mouse_move_action_t moveActions;
|
||||
} __attribute__ ((packed)) mouse;
|
||||
} ATTR_PACKED mouse;
|
||||
struct {
|
||||
bool isToggle;
|
||||
uint8_t layer;
|
||||
} __attribute__ ((packed)) switchLayer;
|
||||
} ATTR_PACKED switchLayer;
|
||||
struct {
|
||||
uint8_t keymapId;
|
||||
} __attribute__ ((packed)) switchKeymap;
|
||||
} ATTR_PACKED switchKeymap;
|
||||
struct {
|
||||
uint8_t macroId;
|
||||
} __attribute__ ((packed)) playMacro;
|
||||
} ATTR_PACKED playMacro;
|
||||
};
|
||||
} __attribute__ ((packed)) key_action_t;
|
||||
} ATTR_PACKED key_action_t;
|
||||
|
||||
// Variables:
|
||||
|
||||
extern void UpdateActiveUsbReports();
|
||||
void UpdateActiveUsbReports(void);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -16,8 +16,8 @@ uint8_t CurrentKeymapIndex = 0;
|
||||
void Keymaps_Switch(uint8_t index)
|
||||
{
|
||||
CurrentKeymapIndex = index;
|
||||
UserConfigBuffer.offset = AllKeymaps[index].offset;
|
||||
ParseKeymap(&UserConfigBuffer, index, AllKeymapsCount, AllMacrosCount);
|
||||
ValidatedUserConfigBuffer.offset = AllKeymaps[index].offset;
|
||||
ParseKeymap(&ValidatedUserConfigBuffer, index, AllKeymapsCount, AllMacrosCount);
|
||||
LedDisplay_SetText(AllKeymaps[index].abbreviationLen, AllKeymaps[index].abbreviation);
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
// Macros:
|
||||
|
||||
#define MAX_KEYMAP_NUM 255
|
||||
#define KEYMAP_ABBREVIATION_LENGTH 3
|
||||
|
||||
// Typedefs:
|
||||
|
||||
|
||||
@@ -65,27 +65,29 @@ void LedDisplay_SetText(uint8_t length, const char* text) {
|
||||
case 1:
|
||||
allSegmentSets |= characterToSegmentSet(text[0]);
|
||||
}
|
||||
LedDriverStates[LedDriverId_Left].sourceLedValues[11] = allSegmentSets & 0b00000001 ? 255 : 0;
|
||||
LedDriverStates[LedDriverId_Left].sourceLedValues[12] = allSegmentSets & 0b00000010 ? 255 : 0;
|
||||
|
||||
LedDriverValues[LedDriverId_Left][11] = allSegmentSets & 0b00000001 ? LED_BRIGHTNESS_LEVEL : 0;
|
||||
LedDriverValues[LedDriverId_Left][12] = allSegmentSets & 0b00000010 ? LED_BRIGHTNESS_LEVEL : 0;
|
||||
allSegmentSets >>= 2;
|
||||
|
||||
for (uint8_t i = 24; i <= 136; i += 16) {
|
||||
for (uint8_t j = 0; j < 5; j++) {
|
||||
LedDriverStates[LedDriverId_Left].sourceLedValues[i + j] = allSegmentSets & 1 << j ? 255 : 0;
|
||||
LedDriverValues[LedDriverId_Left][i + j] = allSegmentSets & 1 << j ? LED_BRIGHTNESS_LEVEL : 0;
|
||||
}
|
||||
allSegmentSets >>= 5;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void LedDisplay_SetLayer(uint8_t layerId) {
|
||||
for (uint8_t i = 13; i <= 45; i += 16) {
|
||||
LedDriverStates[LedDriverId_Left].sourceLedValues[i] = 0;
|
||||
LedDriverValues[LedDriverId_Left][i] = 0;
|
||||
}
|
||||
|
||||
if (layerId >= LAYER_ID_MOD && layerId <= LAYER_ID_MOUSE) {
|
||||
LedDriverStates[LedDriverId_Left].sourceLedValues[16 * layerId - 3] = 255;
|
||||
LedDriverValues[LedDriverId_Left][16 * layerId - 3] = LED_BRIGHTNESS_LEVEL;
|
||||
}
|
||||
}
|
||||
|
||||
void LedDisplay_SetIcon(led_display_icon_t icon, bool isEnabled) {
|
||||
LedDriverStates[LedDriverId_Left].sourceLedValues[8 + icon] = isEnabled ? 255 : 0;
|
||||
LedDriverValues[LedDriverId_Left][8 + icon] = isEnabled ? LED_BRIGHTNESS_LEVEL : 0;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "led_pwm.h"
|
||||
#include "fsl_port.h"
|
||||
|
||||
void LedPwm_Init() {
|
||||
void LedPwm_Init(void) {
|
||||
CLOCK_EnableClock(LED_PWM_CLOCK);
|
||||
PORT_SetPinMux(LED_PWM_PORT, LED_PWM_PIN, kPORT_MuxAlt4);
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
// Functions:
|
||||
|
||||
extern void LedPwm_Init();
|
||||
void LedPwm_Init(void);
|
||||
void LedPwm_SetBrightness(uint8_t brightnessPercent);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -276,8 +276,8 @@ void Macros_StartMacro(uint8_t index)
|
||||
MacroPlaying = true;
|
||||
currentMacroIndex = index;
|
||||
currentMacroActionIndex = 0;
|
||||
UserConfigBuffer.offset = AllMacros[index].firstMacroActionOffset;
|
||||
ParseMacroAction(&UserConfigBuffer, ¤tMacroAction);
|
||||
ValidatedUserConfigBuffer.offset = AllMacros[index].firstMacroActionOffset;
|
||||
ParseMacroAction(&ValidatedUserConfigBuffer, ¤tMacroAction);
|
||||
memset(&MacroMouseReport, 0, sizeof MacroMouseReport);
|
||||
memset(&MacroBasicKeyboardReport, 0, sizeof MacroBasicKeyboardReport);
|
||||
memset(&MacroMediaKeyboardReport, 0, sizeof MacroMediaKeyboardReport);
|
||||
@@ -293,6 +293,5 @@ void Macros_ContinueMacro(void)
|
||||
MacroPlaying = false;
|
||||
return;
|
||||
}
|
||||
ParseMacroAction(&UserConfigBuffer, ¤tMacroAction);
|
||||
ParseMacroAction(&ValidatedUserConfigBuffer, ¤tMacroAction);
|
||||
}
|
||||
|
||||
|
||||
@@ -41,29 +41,29 @@
|
||||
keystroke_type_t type;
|
||||
uint8_t scancode;
|
||||
uint8_t modifierMask;
|
||||
} __attribute__ ((packed)) key;
|
||||
} ATTR_PACKED key;
|
||||
struct {
|
||||
macro_sub_action_t action;
|
||||
uint8_t mouseButtonsMask;
|
||||
} __attribute__ ((packed)) mouseButton;
|
||||
} ATTR_PACKED mouseButton;
|
||||
struct {
|
||||
int16_t x;
|
||||
int16_t y;
|
||||
} __attribute__ ((packed)) moveMouse;
|
||||
} ATTR_PACKED moveMouse;
|
||||
struct {
|
||||
int16_t x;
|
||||
int16_t y;
|
||||
} __attribute__ ((packed)) scrollMouse;
|
||||
} ATTR_PACKED scrollMouse;
|
||||
struct {
|
||||
int16_t delay;
|
||||
} __attribute__ ((packed)) delay;
|
||||
} ATTR_PACKED delay;
|
||||
struct {
|
||||
const char *text;
|
||||
uint16_t textLen;
|
||||
} __attribute__ ((packed)) text;
|
||||
} ATTR_PACKED text;
|
||||
};
|
||||
macro_action_type_t type;
|
||||
} __attribute__ ((packed)) macro_action_t;
|
||||
} ATTR_PACKED macro_action_t;
|
||||
|
||||
// Variables:
|
||||
|
||||
|
||||
@@ -12,7 +12,8 @@
|
||||
#include "bus_pal_hardware.h"
|
||||
#include "bootloader_config.h"
|
||||
#include "command.h"
|
||||
#include "wormhole.h"
|
||||
#include "bootloader/wormhole.h"
|
||||
#include "eeprom.h"
|
||||
|
||||
key_matrix_t KeyMatrix = {
|
||||
.colNum = KEYBOARD_MATRIX_COLS_NUM,
|
||||
@@ -37,7 +38,7 @@ key_matrix_t KeyMatrix = {
|
||||
|
||||
uint8_t CurrentKeyStates[SLOT_COUNT][MAX_KEY_COUNT_PER_MODULE];
|
||||
|
||||
void UpdateUsbReports()
|
||||
void UpdateUsbReports(void)
|
||||
{
|
||||
if (!IsUsbBasicKeyboardReportSent) {
|
||||
return;
|
||||
@@ -49,7 +50,7 @@ void UpdateUsbReports()
|
||||
|
||||
KeyMatrix_Scan(&KeyMatrix);
|
||||
|
||||
memcpy(CurrentKeyStates[SLOT_ID_RIGHT_KEYBOARD_HALF], KeyMatrix.keyStates, MAX_KEY_COUNT_PER_MODULE);
|
||||
memcpy(CurrentKeyStates[SlotId_RightKeyboardHalf], KeyMatrix.keyStates, MAX_KEY_COUNT_PER_MODULE);
|
||||
UpdateActiveUsbReports();
|
||||
|
||||
SwitchActiveUsbBasicKeyboardReport();
|
||||
@@ -59,9 +60,24 @@ void UpdateUsbReports()
|
||||
IsUsbBasicKeyboardReportSent = false;
|
||||
}
|
||||
|
||||
void main() {
|
||||
bool IsEepromInitialized = false;
|
||||
bool IsConfigInitialized = false;
|
||||
|
||||
void userConfigurationReadFinished(void)
|
||||
{
|
||||
IsEepromInitialized = true;
|
||||
}
|
||||
|
||||
void hardwareConfigurationReadFinished(void)
|
||||
{
|
||||
EEPROM_LaunchTransfer(EepromOperation_Read, ConfigBufferId_StagingUserConfig, userConfigurationReadFinished);
|
||||
}
|
||||
|
||||
void main(void)
|
||||
{
|
||||
InitClock();
|
||||
InitPeripherals();
|
||||
EEPROM_LaunchTransfer(EepromOperation_Read, ConfigBufferId_HardwareConfig, hardwareConfigurationReadFinished);
|
||||
|
||||
#ifdef FORCE_BUSPAL
|
||||
Wormhole.magicNumber = WORMHOLE_MAGIC_NUMBER;
|
||||
@@ -79,8 +95,12 @@ void main() {
|
||||
InitUsb();
|
||||
|
||||
while (1) {
|
||||
if (!IsConfigInitialized && IsEepromInitialized) {
|
||||
ApplyConfig();
|
||||
IsConfigInitialized = true;
|
||||
}
|
||||
UpdateUsbReports();
|
||||
asm("wfi");
|
||||
__WFI();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,13 +11,12 @@
|
||||
|
||||
#define KEYBOARD_MATRIX_COLS_NUM 7
|
||||
#define KEYBOARD_MATRIX_ROWS_NUM 5
|
||||
#define LEFT_KEYBOARD_HALF_KEY_COUNT (5*7)
|
||||
|
||||
// Variables:
|
||||
|
||||
extern key_matrix_t KeyMatrix;
|
||||
extern uint8_t PreviousKeyStates[SLOT_COUNT][MAX_KEY_COUNT_PER_MODULE];
|
||||
extern uint8_t CurrentKeyStates[SLOT_COUNT][MAX_KEY_COUNT_PER_MODULE];
|
||||
extern void UpdateUsbReports();
|
||||
extern void UpdateUsbReports(void);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -8,29 +8,7 @@
|
||||
|
||||
// Macros:
|
||||
|
||||
#define MODULE_ID_LEFT_KEYBOARD_HALF 0
|
||||
#define MODULE_ID_KEY_CLUSTER_LEFT 1
|
||||
#define MODULE_ID_TRACKBALL_RIGHT 2
|
||||
#define MODULE_ID_TRACKPOINT_RIGHT 3
|
||||
#define MODULE_ID_TOUCHPAD 4
|
||||
|
||||
#define MODULE_REQUEST_GET_PROTOCOL_VERSION 0
|
||||
#define MODULE_REQUEST_GET_MODULE_ID 1
|
||||
#define MODULE_REQUEST_GET_MODULE_NAME 2
|
||||
#define MODULE_REQUEST_GET_FEATURES 3
|
||||
#define MODULE_REQUEST_GET_FACTORY_LAYER 4
|
||||
#define MODULE_REQUEST_GET_POINTER_INFO 5
|
||||
#define MODULE_REQUEST_GET_STATE 6
|
||||
#define MODULE_REQUEST_GET_GRAPHICS 7
|
||||
|
||||
#define MODULE_STATUS_ATTACHED MODULE_REQUEST_GET_STATE
|
||||
|
||||
#define POINTER_ROLE_MOVE 0
|
||||
#define POINTER_ROLE_SCROLL 1
|
||||
|
||||
#define MAX_MODULE_NAME_LENGTH 64
|
||||
#define MAX_KEY_COUNT_PER_MODULE 64
|
||||
#define MAX_POINTER_COUNT_PER_MODULE 2
|
||||
|
||||
// Typedefs:
|
||||
|
||||
@@ -40,19 +18,4 @@
|
||||
uint8_t roles[LAYER_COUNT];
|
||||
} pointer_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t enumerationState;
|
||||
uint8_t enumerationSubstate;
|
||||
uint8_t moduleId;
|
||||
char moduleName[MAX_MODULE_NAME_LENGTH];
|
||||
uint8_t pointerCount;
|
||||
uint8_t keyCount;
|
||||
uint8_t keyStates[MAX_KEY_COUNT_PER_MODULE];
|
||||
uint8_t pointerRole;
|
||||
} module_t;
|
||||
|
||||
// Variables:
|
||||
|
||||
extern module_t AttachedModules[SLOT_COUNT];
|
||||
|
||||
#endif
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
// Functions:
|
||||
|
||||
extern void ADC_Init(void);
|
||||
extern uint32_t ADC_Measure(void);
|
||||
void ADC_Init(void);
|
||||
uint32_t ADC_Measure(void);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "peripherals/led_driver.h"
|
||||
#include "i2c_addresses.h"
|
||||
|
||||
void InitLedDriver()
|
||||
void InitLedDriver(void)
|
||||
{
|
||||
CLOCK_EnableClock(LED_DRIVER_SDB_CLOCK);
|
||||
PORT_SetPinMux(LED_DRIVER_SDB_PORT, LED_DRIVER_SDB_PIN, kPORT_MuxAsGpio);
|
||||
|
||||
@@ -44,6 +44,6 @@
|
||||
|
||||
// Functions:
|
||||
|
||||
extern void InitLedDriver();
|
||||
void InitLedDriver(void);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "merge_sensor.h"
|
||||
#include "fsl_port.h"
|
||||
|
||||
void InitMergeSensor() {
|
||||
void InitMergeSensor(void) {
|
||||
CLOCK_EnableClock(MERGE_SENSOR_CLOCK);
|
||||
PORT_SetPinConfig(MERGE_SENSOR_PORT, MERGE_SENSOR_PIN,
|
||||
&(port_pin_config_t){.pullSelect=kPORT_PullUp, .mux=kPORT_MuxAsGpio});
|
||||
|
||||
@@ -18,6 +18,6 @@
|
||||
|
||||
// Functions:
|
||||
|
||||
extern void InitMergeSensor();
|
||||
void InitMergeSensor(void);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "reset_button.h"
|
||||
#include "fsl_port.h"
|
||||
|
||||
void InitResetButton() {
|
||||
void InitResetButton(void) {
|
||||
CLOCK_EnableClock(RESET_BUTTON_CLOCK);
|
||||
PORT_SetPinConfig(RESET_BUTTON_PORT, RESET_BUTTON_PIN,
|
||||
&(port_pin_config_t){.pullSelect=kPORT_PullUp, .mux=kPORT_MuxAsGpio});
|
||||
|
||||
@@ -18,6 +18,6 @@
|
||||
|
||||
// Functions:
|
||||
|
||||
extern void InitResetButton();
|
||||
void InitResetButton(void);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "test_led.h"
|
||||
#include "fsl_port.h"
|
||||
|
||||
extern void InitTestLed()
|
||||
void InitTestLed(void)
|
||||
{
|
||||
CLOCK_EnableClock(TEST_LED_CLOCK);
|
||||
PORT_SetPinMux(TEST_LED_GPIO_PORT, TEST_LED_GPIO_PIN, kPORT_MuxAsGpio);
|
||||
|
||||
@@ -22,6 +22,6 @@
|
||||
|
||||
// Functions:
|
||||
|
||||
extern void InitTestLed();
|
||||
void InitTestLed(void);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -3,9 +3,11 @@
|
||||
#include "slave_scheduler.h"
|
||||
#include "led_display.h"
|
||||
|
||||
led_driver_state_t LedDriverStates[LED_DRIVER_MAX_COUNT] = {
|
||||
uint8_t LedDriverValues[LED_DRIVER_MAX_COUNT][LED_DRIVER_LED_COUNT];
|
||||
|
||||
static led_driver_state_t ledDriverStates[LED_DRIVER_MAX_COUNT] = {
|
||||
{
|
||||
.i2cAddress = I2C_ADDRESS_LED_DRIVER_RIGHT,
|
||||
.i2cAddress = I2C_ADDRESS_IS31FL3731_RIGHT,
|
||||
.setupLedControlRegistersCommand = {
|
||||
FRAME_REGISTER_LED_CONTROL_FIRST,
|
||||
0b01111111, // key row 1
|
||||
@@ -29,7 +31,7 @@ led_driver_state_t LedDriverStates[LED_DRIVER_MAX_COUNT] = {
|
||||
}
|
||||
},
|
||||
{
|
||||
.i2cAddress = I2C_ADDRESS_LED_DRIVER_LEFT,
|
||||
.i2cAddress = I2C_ADDRESS_IS31FL3731_LEFT,
|
||||
.setupLedControlRegistersCommand = {
|
||||
FRAME_REGISTER_LED_CONTROL_FIRST,
|
||||
0b01111111, // key row 1
|
||||
@@ -54,23 +56,27 @@ led_driver_state_t LedDriverStates[LED_DRIVER_MAX_COUNT] = {
|
||||
},
|
||||
};
|
||||
|
||||
uint8_t setFunctionFrameBuffer[] = {LED_DRIVER_REGISTER_FRAME, LED_DRIVER_FRAME_FUNCTION};
|
||||
uint8_t setShutdownModeNormalBuffer[] = {LED_DRIVER_REGISTER_SHUTDOWN, SHUTDOWN_MODE_NORMAL};
|
||||
uint8_t setFrame1Buffer[] = {LED_DRIVER_REGISTER_FRAME, LED_DRIVER_FRAME_1};
|
||||
uint8_t updatePwmRegistersBuffer[PWM_REGISTER_BUFFER_LENGTH];
|
||||
static uint8_t setFunctionFrameBuffer[] = {LED_DRIVER_REGISTER_FRAME, LED_DRIVER_FRAME_FUNCTION};
|
||||
static uint8_t setShutdownModeNormalBuffer[] = {LED_DRIVER_REGISTER_SHUTDOWN, SHUTDOWN_MODE_NORMAL};
|
||||
static uint8_t setFrame1Buffer[] = {LED_DRIVER_REGISTER_FRAME, LED_DRIVER_FRAME_1};
|
||||
static uint8_t updatePwmRegistersBuffer[PWM_REGISTER_BUFFER_LENGTH];
|
||||
|
||||
void LedSlaveDriver_Init(uint8_t ledDriverId) {
|
||||
led_driver_state_t *currentLedDriverState = LedDriverStates + ledDriverId;
|
||||
if (ledDriverId == ISO_KEY_LED_DRIVER_ID && IS_ISO) {
|
||||
ledDriverStates[LedDriverId_Left].setupLedControlRegistersCommand[ISO_KEY_CONTROL_REGISTER_POS] |= 1 << ISO_KEY_CONTROL_REGISTER_BIT;
|
||||
}
|
||||
|
||||
led_driver_state_t *currentLedDriverState = ledDriverStates + ledDriverId;
|
||||
currentLedDriverState->phase = LedDriverPhase_SetFunctionFrame;
|
||||
currentLedDriverState->ledIndex = 0;
|
||||
LedDriverStates[LedDriverId_Left].setupLedControlRegistersCommand[7] |= 0b00000010; // Enable the LED of the ISO key.
|
||||
SetLeds(0xff);
|
||||
memset(LedDriverValues[ledDriverId], LED_BRIGHTNESS_LEVEL, LED_DRIVER_LED_COUNT);
|
||||
LedDisplay_SetText(3, "ABC");
|
||||
}
|
||||
|
||||
status_t LedSlaveDriver_Update(uint8_t ledDriverId) {
|
||||
status_t status = kStatus_Uhk_IdleSlave;
|
||||
led_driver_state_t *currentLedDriverState = LedDriverStates + ledDriverId;
|
||||
uint8_t *ledValues = LedDriverValues[ledDriverId];
|
||||
led_driver_state_t *currentLedDriverState = ledDriverStates + ledDriverId;
|
||||
uint8_t *ledDriverPhase = ¤tLedDriverState->phase;
|
||||
uint8_t ledDriverAddress = currentLedDriverState->i2cAddress;
|
||||
uint8_t *ledIndex = ¤tLedDriverState->ledIndex;
|
||||
@@ -98,19 +104,18 @@ status_t LedSlaveDriver_Update(uint8_t ledDriverId) {
|
||||
case LedDriverPhase_InitLedValues:
|
||||
updatePwmRegistersBuffer[0] = FRAME_REGISTER_PWM_FIRST + *ledIndex;
|
||||
uint8_t chunkSize = MIN(LED_DRIVER_LED_COUNT - *ledIndex, PMW_REGISTER_UPDATE_CHUNK_SIZE);
|
||||
memcpy(updatePwmRegistersBuffer+1, currentLedDriverState->sourceLedValues + *ledIndex, chunkSize);
|
||||
memcpy(updatePwmRegistersBuffer+1, ledValues + *ledIndex, chunkSize);
|
||||
status = I2cAsyncWrite(ledDriverAddress, updatePwmRegistersBuffer, chunkSize + 1);
|
||||
*ledIndex += chunkSize;
|
||||
if (*ledIndex >= LED_DRIVER_LED_COUNT) {
|
||||
*ledIndex = 0;
|
||||
#ifndef LED_DRIVER_FORCE_UPDATE
|
||||
memcpy(currentLedDriverState->targetLedValues, currentLedDriverState->sourceLedValues, LED_DRIVER_LED_COUNT);
|
||||
#ifndef LED_DRIVER_STRESS_TEST
|
||||
memcpy(currentLedDriverState->targetLedValues, ledValues, LED_DRIVER_LED_COUNT);
|
||||
*ledDriverPhase = LedDriverPhase_UpdateChangedLedValues;
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
case LedDriverPhase_UpdateChangedLedValues: {
|
||||
uint8_t *sourceLedValues = currentLedDriverState->sourceLedValues;
|
||||
uint8_t *targetLedValues = currentLedDriverState->targetLedValues;
|
||||
|
||||
uint8_t lastLedChunkStartIndex = LED_DRIVER_LED_COUNT - PMW_REGISTER_UPDATE_CHUNK_SIZE;
|
||||
@@ -118,7 +123,7 @@ status_t LedSlaveDriver_Update(uint8_t ledDriverId) {
|
||||
|
||||
uint8_t count;
|
||||
for (count=0; count<LED_DRIVER_LED_COUNT; count++) {
|
||||
if (sourceLedValues[startLedIndex] != targetLedValues[startLedIndex]) {
|
||||
if (ledValues[startLedIndex] != targetLedValues[startLedIndex]) {
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -137,15 +142,15 @@ status_t LedSlaveDriver_Update(uint8_t ledDriverId) {
|
||||
uint8_t maxEndLedIndex = startLedIndex + maxChunkSize - 1;
|
||||
uint8_t endLedIndex = startLedIndex;
|
||||
for (uint8_t index=startLedIndex; index<=maxEndLedIndex; index++) {
|
||||
if (sourceLedValues[index] != targetLedValues[index]) {
|
||||
if (ledValues[index] != targetLedValues[index]) {
|
||||
endLedIndex = index;
|
||||
}
|
||||
}
|
||||
|
||||
updatePwmRegistersBuffer[0] = FRAME_REGISTER_PWM_FIRST + startLedIndex;
|
||||
uint8_t length = endLedIndex - startLedIndex + 1;
|
||||
memcpy(updatePwmRegistersBuffer+1, currentLedDriverState->sourceLedValues + startLedIndex, length);
|
||||
memcpy(currentLedDriverState->targetLedValues + startLedIndex, currentLedDriverState->sourceLedValues + startLedIndex, length);
|
||||
memcpy(updatePwmRegistersBuffer+1, ledValues + startLedIndex, length);
|
||||
memcpy(currentLedDriverState->targetLedValues + startLedIndex, ledValues + startLedIndex, length);
|
||||
status = I2cAsyncWrite(ledDriverAddress, updatePwmRegistersBuffer, length+1);
|
||||
*ledIndex += length;
|
||||
if (*ledIndex >= LED_DRIVER_LED_COUNT) {
|
||||
@@ -157,10 +162,3 @@ status_t LedSlaveDriver_Update(uint8_t ledDriverId) {
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
void SetLeds(uint8_t ledBrightness)
|
||||
{
|
||||
for (uint8_t i=0; i<LED_DRIVER_MAX_COUNT; i++) {
|
||||
memset(&LedDriverStates[i].sourceLedValues, ledBrightness, LED_DRIVER_LED_COUNT);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,10 +9,15 @@
|
||||
// Macros:
|
||||
|
||||
#define LED_DRIVER_MAX_COUNT 2
|
||||
#define BUFFER_SIZE (LED_DRIVER_LED_COUNT + 1)
|
||||
#define LED_CONTROL_REGISTERS_COMMAND_LENGTH 19
|
||||
#define PMW_REGISTER_UPDATE_CHUNK_SIZE 8
|
||||
#define PWM_REGISTER_BUFFER_LENGTH (1 + PMW_REGISTER_UPDATE_CHUNK_SIZE)
|
||||
#define LED_BRIGHTNESS_LEVEL 0xff
|
||||
|
||||
#define IS_ISO true
|
||||
#define ISO_KEY_LED_DRIVER_ID LedDriverId_Left
|
||||
#define ISO_KEY_CONTROL_REGISTER_POS 7
|
||||
#define ISO_KEY_CONTROL_REGISTER_BIT 1
|
||||
|
||||
// Typedefs:
|
||||
|
||||
@@ -32,7 +37,6 @@
|
||||
|
||||
typedef struct {
|
||||
led_driver_phase_t phase;
|
||||
uint8_t sourceLedValues[LED_DRIVER_LED_COUNT];
|
||||
uint8_t targetLedValues[LED_DRIVER_LED_COUNT];
|
||||
uint8_t ledIndex;
|
||||
uint8_t i2cAddress;
|
||||
@@ -41,12 +45,11 @@
|
||||
|
||||
// Variables:
|
||||
|
||||
extern led_driver_state_t LedDriverStates[LED_DRIVER_MAX_COUNT];
|
||||
extern uint8_t LedDriverValues[LED_DRIVER_MAX_COUNT][LED_DRIVER_LED_COUNT];
|
||||
|
||||
// Functions:
|
||||
|
||||
extern void LedSlaveDriver_Init(uint8_t ledDriverId);
|
||||
extern status_t LedSlaveDriver_Update(uint8_t ledDriverId);
|
||||
extern void SetLeds(uint8_t ledBrightness);
|
||||
void LedSlaveDriver_Init(uint8_t ledDriverId);
|
||||
status_t LedSlaveDriver_Update(uint8_t ledDriverId);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -9,48 +9,223 @@
|
||||
#include "crc16.h"
|
||||
|
||||
uhk_module_state_t UhkModuleStates[UHK_MODULE_MAX_COUNT];
|
||||
uhk_module_phase_t uhkModulePhase = UhkModulePhase_SendKeystatesRequestCommand;
|
||||
uint8_t txBuffer[2];
|
||||
uint8_t rxBuffer[KEY_STATE_BUFFER_SIZE];
|
||||
|
||||
void UhkModuleSlaveDriver_Init(uint8_t uhkModuleId)
|
||||
static i2c_message_t txMessage;
|
||||
|
||||
static uhk_module_i2c_addresses_t moduleIdsToI2cAddresses[] = {
|
||||
{ // UhkModuleDriverId_LeftKeyboardHalf
|
||||
.firmwareI2cAddress = I2C_ADDRESS_LEFT_KEYBOARD_HALF_FIRMWARE,
|
||||
.bootloaderI2cAddress = I2C_ADDRESS_LEFT_KEYBOARD_HALF_BOOTLOADER
|
||||
},
|
||||
{ // UhkModuleDriverId_LeftAddon
|
||||
.firmwareI2cAddress = I2C_ADDRESS_LEFT_ADDON_FIRMWARE,
|
||||
.bootloaderI2cAddress = I2C_ADDRESS_LEFT_ADDON_BOOTLOADER
|
||||
},
|
||||
{ // UhkModuleDriverId_RightAddon
|
||||
.firmwareI2cAddress = I2C_ADDRESS_RIGHT_ADDON_FIRMWARE,
|
||||
.bootloaderI2cAddress = I2C_ADDRESS_RIGHT_ADDON_BOOTLOADER
|
||||
},
|
||||
};
|
||||
|
||||
static status_t tx(uint8_t i2cAddress)
|
||||
{
|
||||
uhk_module_state_t* uhkModuleState = UhkModuleStates + uhkModuleId;
|
||||
uhkModuleState->isTestLedOn = true;
|
||||
uhkModuleState->ledPwmBrightness = 0x64;
|
||||
return I2cAsyncWriteMessage(i2cAddress, &txMessage);
|
||||
}
|
||||
|
||||
status_t UhkModuleSlaveDriver_Update(uint8_t uhkModuleId)
|
||||
static status_t rx(i2c_message_t *rxMessage, uint8_t i2cAddress)
|
||||
{
|
||||
return I2cAsyncReadMessage(i2cAddress, rxMessage);
|
||||
}
|
||||
|
||||
void UhkModuleSlaveDriver_Init(uint8_t uhkModuleDriverId)
|
||||
{
|
||||
uhk_module_state_t *uhkModuleState = UhkModuleStates + uhkModuleDriverId;
|
||||
uhk_module_vars_t *uhkModuleSourceVars = &uhkModuleState->sourceVars;
|
||||
uhk_module_vars_t *uhkModuleTargetVars = &uhkModuleState->targetVars;
|
||||
|
||||
uhkModuleSourceVars->isTestLedOn = true;
|
||||
uhkModuleTargetVars->isTestLedOn = false;
|
||||
|
||||
uhkModuleSourceVars->ledPwmBrightness = MAX_PWM_BRIGHTNESS;
|
||||
uhkModuleTargetVars->ledPwmBrightness = 0;
|
||||
|
||||
uhk_module_phase_t *uhkModulePhase = &uhkModuleState->phase;
|
||||
*uhkModulePhase = UhkModulePhase_RequestSync;
|
||||
|
||||
uhk_module_i2c_addresses_t *uhkModuleI2cAddresses = moduleIdsToI2cAddresses + uhkModuleDriverId;
|
||||
uhkModuleState->firmwareI2cAddress = uhkModuleI2cAddresses->firmwareI2cAddress;
|
||||
uhkModuleState->bootloaderI2cAddress = uhkModuleI2cAddresses->bootloaderI2cAddress;
|
||||
}
|
||||
|
||||
status_t UhkModuleSlaveDriver_Update(uint8_t uhkModuleDriverId)
|
||||
{
|
||||
status_t status = kStatus_Uhk_IdleSlave;
|
||||
uhk_module_state_t *uhkModuleInternalState = UhkModuleStates + uhkModuleId;
|
||||
uhk_module_state_t *uhkModuleState = UhkModuleStates + uhkModuleDriverId;
|
||||
uhk_module_vars_t *uhkModuleSourceVars = &uhkModuleState->sourceVars;
|
||||
uhk_module_vars_t *uhkModuleTargetVars = &uhkModuleState->targetVars;
|
||||
uhk_module_phase_t *uhkModulePhase = &uhkModuleState->phase;
|
||||
uint8_t i2cAddress = uhkModuleState->firmwareI2cAddress;
|
||||
i2c_message_t *rxMessage = &uhkModuleState->rxMessage;
|
||||
|
||||
switch (uhkModulePhase) {
|
||||
case UhkModulePhase_SendKeystatesRequestCommand:
|
||||
txBuffer[0] = SlaveCommand_GetKeyStates;
|
||||
status = I2cAsyncWrite(I2C_ADDRESS_LEFT_KEYBOARD_HALF, txBuffer, 1);
|
||||
uhkModulePhase = UhkModulePhase_ReceiveKeystates;
|
||||
switch (*uhkModulePhase) {
|
||||
|
||||
// Sync communication
|
||||
case UhkModulePhase_RequestSync:
|
||||
txMessage.data[0] = SlaveCommand_RequestProperty;
|
||||
txMessage.data[1] = SlaveProperty_Sync;
|
||||
txMessage.length = 2;
|
||||
status = tx(i2cAddress);
|
||||
*uhkModulePhase = UhkModulePhase_ReceiveSync;
|
||||
break;
|
||||
case UhkModulePhase_ReceiveSync:
|
||||
status = rx(rxMessage, i2cAddress);
|
||||
*uhkModulePhase = UhkModulePhase_ProcessSync;
|
||||
break;
|
||||
case UhkModulePhase_ProcessSync: {
|
||||
bool isMessageValid = CRC16_IsMessageValid(rxMessage);
|
||||
bool isSyncValid = memcmp(rxMessage->data, SlaveSyncString, SLAVE_SYNC_STRING_LENGTH) == 0;
|
||||
status = kStatus_Uhk_NoTransfer;
|
||||
*uhkModulePhase = isSyncValid && isMessageValid
|
||||
? UhkModulePhase_RequestProtocolVersion
|
||||
: UhkModulePhase_RequestSync;
|
||||
break;
|
||||
}
|
||||
|
||||
// Get protocol version
|
||||
case UhkModulePhase_RequestProtocolVersion:
|
||||
txMessage.data[0] = SlaveCommand_RequestProperty;
|
||||
txMessage.data[1] = SlaveProperty_ProtocolVersion;
|
||||
txMessage.length = 2;
|
||||
status = tx(i2cAddress);
|
||||
*uhkModulePhase = UhkModulePhase_ReceiveProtocolVersion;
|
||||
break;
|
||||
case UhkModulePhase_ReceiveProtocolVersion:
|
||||
status = rx(rxMessage, i2cAddress);
|
||||
*uhkModulePhase = UhkModulePhase_ProcessProtocolVersion;
|
||||
break;
|
||||
case UhkModulePhase_ProcessProtocolVersion: {
|
||||
bool isMessageValid = CRC16_IsMessageValid(rxMessage);
|
||||
if (isMessageValid) {
|
||||
uhkModuleState->protocolVersion = rxMessage->data[0];
|
||||
}
|
||||
status = kStatus_Uhk_NoTransfer;
|
||||
*uhkModulePhase = isMessageValid ? UhkModulePhase_RequestModuleId : UhkModulePhase_RequestProtocolVersion;
|
||||
break;
|
||||
}
|
||||
|
||||
// Get module id
|
||||
case UhkModulePhase_RequestModuleId:
|
||||
txMessage.data[0] = SlaveCommand_RequestProperty;
|
||||
txMessage.data[1] = SlaveProperty_ModuleId;
|
||||
txMessage.length = 2;
|
||||
status = tx(i2cAddress);
|
||||
*uhkModulePhase = UhkModulePhase_ReceiveModuleId;
|
||||
break;
|
||||
case UhkModulePhase_ReceiveModuleId:
|
||||
status = rx(rxMessage, i2cAddress);
|
||||
*uhkModulePhase = UhkModulePhase_ProcessModuleId;
|
||||
break;
|
||||
case UhkModulePhase_ProcessModuleId: {
|
||||
bool isMessageValid = CRC16_IsMessageValid(rxMessage);
|
||||
if (isMessageValid) {
|
||||
uhkModuleState->moduleId = rxMessage->data[0];
|
||||
}
|
||||
status = kStatus_Uhk_NoTransfer;
|
||||
*uhkModulePhase = isMessageValid ? UhkModulePhase_RequestModuleFeatures : UhkModulePhase_RequestModuleId;
|
||||
break;
|
||||
}
|
||||
|
||||
// Get module features
|
||||
case UhkModulePhase_RequestModuleFeatures:
|
||||
txMessage.data[0] = SlaveCommand_RequestProperty;
|
||||
txMessage.data[1] = SlaveProperty_Features;
|
||||
txMessage.length = 2;
|
||||
status = tx(i2cAddress);
|
||||
*uhkModulePhase = UhkModulePhase_ReceiveModuleFeatures;
|
||||
break;
|
||||
case UhkModulePhase_ReceiveModuleFeatures:
|
||||
status = rx(rxMessage, i2cAddress);
|
||||
*uhkModulePhase = UhkModulePhase_ProcessModuleFeatures;
|
||||
break;
|
||||
case UhkModulePhase_ProcessModuleFeatures: {
|
||||
bool isMessageValid = CRC16_IsMessageValid(rxMessage);
|
||||
if (isMessageValid) {
|
||||
memcpy(&uhkModuleState->features, rxMessage->data, sizeof(uhk_module_features_t));
|
||||
}
|
||||
status = kStatus_Uhk_NoTransfer;
|
||||
*uhkModulePhase = isMessageValid ? UhkModulePhase_RequestKeyStates : UhkModulePhase_RequestModuleFeatures;
|
||||
break;
|
||||
}
|
||||
|
||||
// Get key states
|
||||
case UhkModulePhase_RequestKeyStates:
|
||||
txMessage.data[0] = SlaveCommand_RequestKeyStates;
|
||||
txMessage.length = 1;
|
||||
status = tx(i2cAddress);
|
||||
*uhkModulePhase = UhkModulePhase_ReceiveKeystates;
|
||||
break;
|
||||
case UhkModulePhase_ReceiveKeystates:
|
||||
status = I2cAsyncRead(I2C_ADDRESS_LEFT_KEYBOARD_HALF, rxBuffer, KEY_STATE_BUFFER_SIZE);
|
||||
uhkModulePhase = UhkModulePhase_SendPwmBrightnessCommand;
|
||||
status = rx(rxMessage, i2cAddress);
|
||||
*uhkModulePhase = UhkModulePhase_ProcessKeystates;
|
||||
break;
|
||||
case UhkModulePhase_SendPwmBrightnessCommand:
|
||||
if (CRC16_IsMessageValid(rxBuffer, KEY_STATE_SIZE)) {
|
||||
BoolBitsToBytes(rxBuffer, CurrentKeyStates[SLOT_ID_LEFT_KEYBOARD_HALF], LEFT_KEYBOARD_HALF_KEY_COUNT);
|
||||
case UhkModulePhase_ProcessKeystates:
|
||||
if (CRC16_IsMessageValid(rxMessage)) {
|
||||
uint8_t slotId = uhkModuleDriverId + 1;
|
||||
BoolBitsToBytes(rxMessage->data, CurrentKeyStates[slotId], uhkModuleState->features.keyCount);
|
||||
}
|
||||
txBuffer[0] = SlaveCommand_SetLedPwmBrightness;
|
||||
txBuffer[1] = uhkModuleInternalState->ledPwmBrightness;
|
||||
status = I2cAsyncWrite(I2C_ADDRESS_LEFT_KEYBOARD_HALF, txBuffer, 2);
|
||||
uhkModulePhase = UhkModulePhase_SendTestLedCommand;
|
||||
status = kStatus_Uhk_NoTransfer;
|
||||
*uhkModulePhase = UhkModulePhase_JumpToBootloader;
|
||||
break;
|
||||
case UhkModulePhase_SendTestLedCommand:
|
||||
txBuffer[0] = SlaveCommand_SetTestLed;
|
||||
txBuffer[1] = uhkModuleInternalState->isTestLedOn;
|
||||
status = I2cAsyncWrite(I2C_ADDRESS_LEFT_KEYBOARD_HALF, txBuffer, 2);
|
||||
uhkModulePhase = UhkModulePhase_SendKeystatesRequestCommand;
|
||||
|
||||
// Jump to bootloader
|
||||
case UhkModulePhase_JumpToBootloader:
|
||||
if (uhkModuleState->jumpToBootloader) {
|
||||
txMessage.data[0] = SlaveCommand_JumpToBootloader;
|
||||
txMessage.length = 1;
|
||||
status = tx(i2cAddress);
|
||||
uhkModuleState->jumpToBootloader = false;
|
||||
} else {
|
||||
status = kStatus_Uhk_NoTransfer;
|
||||
}
|
||||
*uhkModulePhase = UhkModulePhase_SetTestLed;
|
||||
break;
|
||||
|
||||
// Set test LED
|
||||
case UhkModulePhase_SetTestLed:
|
||||
if (uhkModuleSourceVars->isTestLedOn == uhkModuleTargetVars->isTestLedOn) {
|
||||
status = kStatus_Uhk_NoTransfer;
|
||||
} else {
|
||||
txMessage.data[0] = SlaveCommand_SetTestLed;
|
||||
txMessage.data[1] = uhkModuleSourceVars->isTestLedOn;
|
||||
txMessage.length = 2;
|
||||
status = tx(i2cAddress);
|
||||
uhkModuleTargetVars->isTestLedOn = uhkModuleSourceVars->isTestLedOn;
|
||||
}
|
||||
*uhkModulePhase = UhkModulePhase_SetLedPwmBrightness;
|
||||
break;
|
||||
|
||||
// Set PWM brightness
|
||||
case UhkModulePhase_SetLedPwmBrightness:
|
||||
if (uhkModuleSourceVars->ledPwmBrightness == uhkModuleTargetVars->ledPwmBrightness) {
|
||||
status = kStatus_Uhk_NoTransfer;
|
||||
} else {
|
||||
txMessage.data[0] = SlaveCommand_SetLedPwmBrightness;
|
||||
txMessage.data[1] = uhkModuleSourceVars->ledPwmBrightness;
|
||||
txMessage.length = 2;
|
||||
status = tx(i2cAddress);
|
||||
uhkModuleTargetVars->ledPwmBrightness = uhkModuleSourceVars->ledPwmBrightness;
|
||||
}
|
||||
*uhkModulePhase = UhkModulePhase_RequestKeyStates;
|
||||
break;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
void UhkModuleSlaveDriver_Disconnect(uint8_t uhkModuleDriverId)
|
||||
{
|
||||
if (uhkModuleDriverId == SlaveId_LeftKeyboardHalf) {
|
||||
Slaves[SlaveId_LeftLedDriver].isConnected = false;
|
||||
}
|
||||
UhkModuleStates[uhkModuleDriverId].moduleId = 0;
|
||||
}
|
||||
|
||||
@@ -9,36 +9,81 @@
|
||||
// Macros:
|
||||
|
||||
#define UHK_MODULE_MAX_COUNT 3
|
||||
#define KEY_STATE_SIZE (LEFT_KEYBOARD_HALF_KEY_COUNT/8 + 1)
|
||||
#define KEY_STATE_BUFFER_SIZE (KEY_STATE_SIZE + CRC16_HASH_LENGTH)
|
||||
#define MAX_PWM_BRIGHTNESS 0x64
|
||||
|
||||
// Typedefs:
|
||||
|
||||
typedef enum {
|
||||
UhkModuleId_LeftKeyboardHalf,
|
||||
UhkModuleId_LeftAddon,
|
||||
UhkModuleId_RightAddon,
|
||||
UhkModuleDriverId_LeftKeyboardHalf,
|
||||
UhkModuleDriverId_LeftAddon,
|
||||
UhkModuleDriverId_RightAddon,
|
||||
} uhk_module_id_t;
|
||||
|
||||
typedef enum {
|
||||
UhkModulePhase_SendKeystatesRequestCommand,
|
||||
|
||||
// Sync communication
|
||||
UhkModulePhase_RequestSync,
|
||||
UhkModulePhase_ReceiveSync,
|
||||
UhkModulePhase_ProcessSync,
|
||||
|
||||
// Get protocol version
|
||||
UhkModulePhase_RequestProtocolVersion,
|
||||
UhkModulePhase_ReceiveProtocolVersion,
|
||||
UhkModulePhase_ProcessProtocolVersion,
|
||||
|
||||
// Get module id
|
||||
UhkModulePhase_RequestModuleId,
|
||||
UhkModulePhase_ReceiveModuleId,
|
||||
UhkModulePhase_ProcessModuleId,
|
||||
|
||||
// Get module features
|
||||
UhkModulePhase_RequestModuleFeatures,
|
||||
UhkModulePhase_ReceiveModuleFeatures,
|
||||
UhkModulePhase_ProcessModuleFeatures,
|
||||
|
||||
// Get key states
|
||||
UhkModulePhase_RequestKeyStates,
|
||||
UhkModulePhase_ReceiveKeystates,
|
||||
UhkModulePhase_SendPwmBrightnessCommand,
|
||||
UhkModulePhase_SendTestLedCommand,
|
||||
UhkModulePhase_ProcessKeystates,
|
||||
|
||||
// Misc phases
|
||||
UhkModulePhase_JumpToBootloader,
|
||||
UhkModulePhase_SetTestLed,
|
||||
UhkModulePhase_SetLedPwmBrightness,
|
||||
|
||||
} uhk_module_phase_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t ledPwmBrightness;
|
||||
bool isTestLedOn;
|
||||
} uhk_module_vars_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t moduleId;
|
||||
uint8_t protocolVersion;
|
||||
uhk_module_phase_t phase;
|
||||
uhk_module_vars_t sourceVars;
|
||||
uhk_module_vars_t targetVars;
|
||||
i2c_message_t rxMessage;
|
||||
uint8_t firmwareI2cAddress;
|
||||
uint8_t bootloaderI2cAddress;
|
||||
uhk_module_features_t features;
|
||||
bool jumpToBootloader;
|
||||
} uhk_module_state_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t firmwareI2cAddress;
|
||||
uint8_t bootloaderI2cAddress;
|
||||
} uhk_module_i2c_addresses_t;
|
||||
|
||||
// Variables:
|
||||
|
||||
extern uhk_module_state_t UhkModuleStates[UHK_MODULE_MAX_COUNT];
|
||||
|
||||
// Functions:
|
||||
|
||||
extern void UhkModuleSlaveDriver_Init(uint8_t uhkModuleId);
|
||||
extern status_t UhkModuleSlaveDriver_Update(uint8_t uhkModuleId);
|
||||
void UhkModuleSlaveDriver_Init(uint8_t uhkModuleDriverId);
|
||||
status_t UhkModuleSlaveDriver_Update(uint8_t uhkModuleDriverId);
|
||||
void UhkModuleSlaveDriver_Disconnect(uint8_t uhkModuleDriverId);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -7,41 +7,72 @@
|
||||
#include "i2c.h"
|
||||
#include "i2c_addresses.h"
|
||||
|
||||
uint8_t previousSlaveId;
|
||||
uint8_t currentSlaveId;
|
||||
uint32_t BridgeCounter;
|
||||
uint32_t I2cSchedulerCounter;
|
||||
|
||||
static uint8_t previousSlaveId;
|
||||
static uint8_t currentSlaveId;
|
||||
|
||||
uhk_slave_t Slaves[] = {
|
||||
{ .init = UhkModuleSlaveDriver_Init, .update = UhkModuleSlaveDriver_Update, .perDriverId = UhkModuleId_LeftKeyboardHalf },
|
||||
{ .init = LedSlaveDriver_Init, .update = LedSlaveDriver_Update, .perDriverId = LedDriverId_Right },
|
||||
{ .init = LedSlaveDriver_Init, .update = LedSlaveDriver_Update, .perDriverId = LedDriverId_Left },
|
||||
{
|
||||
.init = UhkModuleSlaveDriver_Init,
|
||||
.update = UhkModuleSlaveDriver_Update,
|
||||
.disconnect = UhkModuleSlaveDriver_Disconnect,
|
||||
.perDriverId = UhkModuleDriverId_LeftKeyboardHalf,
|
||||
},
|
||||
{
|
||||
.init = UhkModuleSlaveDriver_Init,
|
||||
.update = UhkModuleSlaveDriver_Update,
|
||||
.perDriverId = UhkModuleDriverId_LeftAddon,
|
||||
},
|
||||
{
|
||||
.init = UhkModuleSlaveDriver_Init,
|
||||
.update = UhkModuleSlaveDriver_Update,
|
||||
.perDriverId = UhkModuleDriverId_RightAddon,
|
||||
},
|
||||
{
|
||||
.init = LedSlaveDriver_Init,
|
||||
.update = LedSlaveDriver_Update,
|
||||
.perDriverId = LedDriverId_Right,
|
||||
},
|
||||
{
|
||||
.init = LedSlaveDriver_Init,
|
||||
.update = LedSlaveDriver_Update,
|
||||
.perDriverId = LedDriverId_Left,
|
||||
},
|
||||
};
|
||||
|
||||
static void masterCallback(I2C_Type *base, i2c_master_handle_t *handle, status_t previousStatus, void *userData)
|
||||
static void slaveSchedulerCallback(I2C_Type *base, i2c_master_handle_t *handle, status_t previousStatus, void *userData)
|
||||
{
|
||||
bool isFirstIteration = true;
|
||||
bool isTransferScheduled = false;
|
||||
I2cSchedulerCounter++;
|
||||
|
||||
do {
|
||||
BridgeCounter++;
|
||||
|
||||
uhk_slave_t *previousSlave = Slaves + previousSlaveId;
|
||||
uhk_slave_t *currentSlave = Slaves + currentSlaveId;
|
||||
|
||||
if (isFirstIteration) {
|
||||
bool wasPreviousSlaveConnected = previousSlave->isConnected;
|
||||
previousSlave->isConnected = previousStatus == kStatus_Success;
|
||||
if (wasPreviousSlaveConnected && !previousSlave->isConnected && previousSlave->disconnect) {
|
||||
previousSlave->disconnect(previousSlaveId);
|
||||
}
|
||||
isFirstIteration = false;
|
||||
}
|
||||
|
||||
if (!currentSlave->isConnected) {
|
||||
currentSlave->init(currentSlave->perDriverId);
|
||||
}
|
||||
|
||||
status_t currentStatus = currentSlave->update(currentSlave->perDriverId);
|
||||
isTransferScheduled = currentStatus != kStatus_Uhk_IdleSlave;
|
||||
//isTransferScheduled = currentStatus == kStatus_Success // Why it is not working?
|
||||
isTransferScheduled = currentStatus != kStatus_Uhk_IdleSlave && currentStatus != kStatus_Uhk_NoTransfer;
|
||||
if (isTransferScheduled) {
|
||||
currentSlave->isConnected = true;
|
||||
}
|
||||
|
||||
previousSlaveId = currentSlaveId;
|
||||
currentSlaveId++;
|
||||
if (currentStatus != kStatus_Uhk_NoTransfer) {
|
||||
previousSlaveId = currentSlaveId++;
|
||||
}
|
||||
|
||||
if (currentSlaveId >= (sizeof(Slaves) / sizeof(uhk_slave_t))) {
|
||||
currentSlaveId = 0;
|
||||
@@ -49,17 +80,18 @@ static void masterCallback(I2C_Type *base, i2c_master_handle_t *handle, status_t
|
||||
} while (!isTransferScheduled);
|
||||
}
|
||||
|
||||
void InitSlaveScheduler()
|
||||
void InitSlaveScheduler(void)
|
||||
{
|
||||
previousSlaveId = 0;
|
||||
currentSlaveId = 0;
|
||||
|
||||
for (uint8_t i=0; i<sizeof(Slaves) / sizeof(uhk_slave_t); i++) {
|
||||
Slaves[i].isConnected = false;
|
||||
uhk_slave_t *currentSlave = Slaves + i;
|
||||
currentSlave->isConnected = false;
|
||||
}
|
||||
|
||||
I2C_MasterTransferCreateHandle(I2C_MAIN_BUS_BASEADDR, &I2cMasterHandle, masterCallback, NULL);
|
||||
I2C_MasterTransferCreateHandle(I2C_MAIN_BUS_BASEADDR, &I2cMasterHandle, slaveSchedulerCallback, NULL);
|
||||
|
||||
// Kickstart the scheduler by triggering the first callback.
|
||||
Slaves[currentSlaveId].update(Slaves[currentSlaveId].perDriverId);
|
||||
// Kickstart the scheduler by triggering the first transfer.
|
||||
slaveSchedulerCallback(I2C_MAIN_BUS_BASEADDR, &I2cMasterHandle, kStatus_Fail, NULL);
|
||||
}
|
||||
|
||||
@@ -7,19 +7,23 @@
|
||||
|
||||
// Typedefs:
|
||||
|
||||
typedef enum {
|
||||
typedef enum { // Slaves[] is meant to be indexed with these values
|
||||
SlaveId_LeftKeyboardHalf,
|
||||
SlaveId_LeftAddon,
|
||||
SlaveId_RightAddon,
|
||||
SlaveId_RightLedDriver,
|
||||
SlaveId_LeftLedDriver,
|
||||
} slave_id_t;
|
||||
|
||||
typedef void (slave_init_t)(uint8_t);
|
||||
typedef status_t (slave_update_t)(uint8_t);
|
||||
typedef void (slave_disconnect_t)(uint8_t);
|
||||
|
||||
typedef struct {
|
||||
uint8_t perDriverId; // Identifies the slave instance on a per-driver basis
|
||||
slave_init_t *init;
|
||||
slave_update_t *update;
|
||||
slave_disconnect_t *disconnect;
|
||||
bool isConnected;
|
||||
} uhk_slave_t;
|
||||
|
||||
@@ -28,17 +32,17 @@
|
||||
} uhk_status_group_t;
|
||||
|
||||
typedef enum {
|
||||
kStatus_Uhk_IdleSlave = MAKE_STATUS(kStatusGroup_Uhk, 0),
|
||||
kStatus_Uhk_IdleSlave = MAKE_STATUS(kStatusGroup_Uhk, 0), // Another slave should be scheduled
|
||||
kStatus_Uhk_NoTransfer = MAKE_STATUS(kStatusGroup_Uhk, 1), // The same slave should be rescheduled
|
||||
} uhk_status_t;
|
||||
|
||||
// Variables:
|
||||
|
||||
extern uhk_slave_t Slaves[];
|
||||
extern uint32_t BridgeCounter;
|
||||
extern uint32_t I2cSchedulerCounter;
|
||||
|
||||
// Functions:
|
||||
|
||||
extern void InitSlaveScheduler();
|
||||
extern void SetLeds(uint8_t ledBrightness);
|
||||
void InitSlaveScheduler(void);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,30 +1,26 @@
|
||||
#ifndef __SLOT_H__
|
||||
#define __SLOT_H__
|
||||
|
||||
// A slot is a physical space that can be occupied by a module. No more than a single module
|
||||
// can occupy a slot. Think of the pogo pin connector of the left keyboard half or the right
|
||||
// keyboard half. Given their physical design, it's impossible to mount two modules to a slot.
|
||||
// A slot is a dedicated physical space that can only be occupied by a single module.
|
||||
// Think of the pogo pin connector of the left keyboard half, for example.
|
||||
// Given its physical design, it's impossible to mount two modules to a slot.
|
||||
//
|
||||
// Slots are useful for two reasons:
|
||||
// 1. Every slot has a dedicated I2C address to avoid the I2C address collision of modules.
|
||||
// 2. Slots denote the maximum number of modules that can be mounted at a given time, allowing
|
||||
// for the allocation of static memory structures for modules.
|
||||
// 1. Every slot has a dedicated I2C address. This avoids the I2C address collision of modules.
|
||||
// 2. There are a limited number of slots available which translates to a maximum number of modules
|
||||
// that can be mounted, allowing for the allocation of static memory structures for modules.
|
||||
|
||||
// Macros:
|
||||
|
||||
#define SLOT_ID_RIGHT_KEYBOARD_HALF 0
|
||||
#define SLOT_ID_LEFT_KEYBOARD_HALF 1
|
||||
#define SLOT_ID_LEFT_MODULE 2
|
||||
#define SLOT_ID_RIGHT_MODULE 3
|
||||
|
||||
// The 7-bit I2C addresses below 0x08 are reserved.
|
||||
#define SLOT_I2C_ADDRESS_LEFT_KEYBOARD_HALF 0x08
|
||||
#define SLOT_I2C_ADDRESS_LEFT_MODULE 0x09
|
||||
#define SLOT_I2C_ADDRESS_RIGHT_MODULE 0x0A
|
||||
|
||||
#define SLOT_I2C_ADDRESS_MIN 0x08
|
||||
#define SLOT_I2C_ADDRESS_MAX 0x0A
|
||||
|
||||
#define SLOT_COUNT 4
|
||||
|
||||
// Typedefs:
|
||||
|
||||
typedef enum {
|
||||
SlotId_RightKeyboardHalf = 0,
|
||||
SlotId_LeftKeyboardHalf = 1,
|
||||
SlotId_LeftModule = 2,
|
||||
SlotId_RightModule = 3,
|
||||
} slot_t;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include "usb_descriptors/usb_descriptor_strings.h"
|
||||
#include "bootloader_config.h"
|
||||
#include "bus_pal_hardware.h"
|
||||
#include "wormhole.h"
|
||||
#include "bootloader/wormhole.h"
|
||||
|
||||
static usb_status_t UsbDeviceCallback(usb_device_handle handle, uint32_t event, void *param);
|
||||
usb_composite_device_t UsbCompositeDevice;
|
||||
@@ -106,7 +106,7 @@ void USB0_IRQHandler(void)
|
||||
: UsbCompositeDevice.deviceHandle);
|
||||
}
|
||||
|
||||
void InitUsb()
|
||||
void InitUsb(void)
|
||||
{
|
||||
uint8_t usbDeviceKhciIrq[] = USB_IRQS;
|
||||
uint8_t irqNumber = usbDeviceKhciIrq[CONTROLLER_ID - kUSB_ControllerKhci0];
|
||||
|
||||
@@ -32,6 +32,6 @@
|
||||
|
||||
//Functions:
|
||||
|
||||
extern void InitUsb();
|
||||
void InitUsb(void);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
// Functions:
|
||||
|
||||
extern usb_status_t USB_DeviceGetConfigurationDescriptor(
|
||||
usb_status_t USB_DeviceGetConfigurationDescriptor(
|
||||
usb_device_handle handle, usb_device_get_configuration_descriptor_struct_t *configurationDescriptor);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
// Functions:
|
||||
|
||||
extern usb_status_t USB_DeviceGetDeviceDescriptor(
|
||||
usb_status_t USB_DeviceGetDeviceDescriptor(
|
||||
usb_device_handle handle, usb_device_get_device_descriptor_struct_t *deviceDescriptor);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -11,13 +11,13 @@
|
||||
|
||||
// Functions:
|
||||
|
||||
extern usb_status_t USB_DeviceGetHidDescriptor(
|
||||
usb_status_t USB_DeviceGetHidDescriptor(
|
||||
usb_device_handle handle, usb_device_get_hid_descriptor_struct_t *hidDescriptor);
|
||||
|
||||
extern usb_status_t USB_DeviceGetHidReportDescriptor(
|
||||
usb_status_t USB_DeviceGetHidReportDescriptor(
|
||||
usb_device_handle handle, usb_device_get_hid_report_descriptor_struct_t *hidReportDescriptor);
|
||||
|
||||
extern usb_status_t USB_DeviceGetHidPhysicalDescriptor(
|
||||
usb_status_t USB_DeviceGetHidPhysicalDescriptor(
|
||||
usb_device_handle handle, usb_device_get_hid_physical_descriptor_struct_t *hidPhysicalDescriptor);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
// Functions:
|
||||
|
||||
extern usb_status_t USB_DeviceGetStringDescriptor(
|
||||
usb_status_t USB_DeviceGetStringDescriptor(
|
||||
usb_device_handle handle, usb_device_get_string_descriptor_struct_t *stringDescriptor);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -44,17 +44,17 @@ static usb_basic_keyboard_report_t usbBasicKeyboardReports[2];
|
||||
usb_basic_keyboard_report_t* ActiveUsbBasicKeyboardReport = usbBasicKeyboardReports;
|
||||
bool IsUsbBasicKeyboardReportSent = false;
|
||||
|
||||
usb_basic_keyboard_report_t* getInactiveUsbBasicKeyboardReport()
|
||||
usb_basic_keyboard_report_t* getInactiveUsbBasicKeyboardReport(void)
|
||||
{
|
||||
return ActiveUsbBasicKeyboardReport == usbBasicKeyboardReports ? usbBasicKeyboardReports+1 : usbBasicKeyboardReports;
|
||||
}
|
||||
|
||||
void SwitchActiveUsbBasicKeyboardReport()
|
||||
void SwitchActiveUsbBasicKeyboardReport(void)
|
||||
{
|
||||
ActiveUsbBasicKeyboardReport = getInactiveUsbBasicKeyboardReport();
|
||||
}
|
||||
|
||||
void ResetActiveUsbBasicKeyboardReport()
|
||||
void ResetActiveUsbBasicKeyboardReport(void)
|
||||
{
|
||||
bzero(ActiveUsbBasicKeyboardReport, USB_BASIC_KEYBOARD_REPORT_LENGTH);
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
// Includes:
|
||||
|
||||
#include "fsl_common.h"
|
||||
#include "attributes.h"
|
||||
#include "usb_api.h"
|
||||
#include "usb_descriptors/usb_descriptor_basic_keyboard_report.h"
|
||||
|
||||
@@ -26,7 +27,7 @@
|
||||
uint8_t modifiers;
|
||||
uint8_t reserved; // Always must be 0
|
||||
uint8_t scancodes[USB_BASIC_KEYBOARD_MAX_KEYS];
|
||||
} __attribute__ ((packed)) usb_basic_keyboard_report_t;
|
||||
} ATTR_PACKED usb_basic_keyboard_report_t;
|
||||
|
||||
// Variables:
|
||||
|
||||
@@ -36,11 +37,11 @@
|
||||
|
||||
// Functions:
|
||||
|
||||
extern usb_status_t UsbBasicKeyboardCallback(class_handle_t handle, uint32_t event, void *param);
|
||||
extern usb_status_t UsbBasicKeyboardSetConfiguration(class_handle_t handle, uint8_t configuration);
|
||||
extern usb_status_t UsbBasicKeyboardSetInterface(class_handle_t handle, uint8_t interface, uint8_t alternateSetting);
|
||||
usb_status_t UsbBasicKeyboardCallback(class_handle_t handle, uint32_t event, void *param);
|
||||
usb_status_t UsbBasicKeyboardSetConfiguration(class_handle_t handle, uint8_t configuration);
|
||||
usb_status_t UsbBasicKeyboardSetInterface(class_handle_t handle, uint8_t interface, uint8_t alternateSetting);
|
||||
|
||||
extern void ResetActiveUsbBasicKeyboardReport();
|
||||
extern void SwitchActiveUsbBasicKeyboardReport();
|
||||
void ResetActiveUsbBasicKeyboardReport(void);
|
||||
void SwitchActiveUsbBasicKeyboardReport(void);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -44,7 +44,7 @@ usb_device_class_struct_t UsbGenericHidClass = {
|
||||
uint8_t GenericHidInBuffer[USB_GENERIC_HID_IN_BUFFER_LENGTH];
|
||||
uint8_t GenericHidOutBuffer[USB_GENERIC_HID_OUT_BUFFER_LENGTH];
|
||||
|
||||
static usb_status_t UsbReceiveData()
|
||||
static usb_status_t UsbReceiveData(void)
|
||||
{
|
||||
return USB_DeviceHidRecv(UsbCompositeDevice.genericHidHandle,
|
||||
USB_GENERIC_HID_ENDPOINT_OUT_INDEX,
|
||||
@@ -60,7 +60,7 @@ usb_status_t UsbGenericHidCallback(class_handle_t handle, uint32_t event, void *
|
||||
case kUSB_DeviceHidEventSendResponse:
|
||||
break;
|
||||
case kUSB_DeviceHidEventRecvResponse:
|
||||
usbProtocolHandler();
|
||||
UsbProtocolHandler();
|
||||
|
||||
USB_DeviceHidSend(UsbCompositeDevice.genericHidHandle,
|
||||
USB_GENERIC_HID_ENDPOINT_IN_INDEX,
|
||||
|
||||
@@ -32,9 +32,8 @@
|
||||
|
||||
// Functions:
|
||||
|
||||
extern usb_status_t UsbGenericHidCallback(class_handle_t handle, uint32_t event, void *param);
|
||||
extern usb_status_t UsbGenericHidSetConfiguration(class_handle_t handle, uint8_t configuration);
|
||||
extern usb_status_t UsbGenericHidSetInterface(class_handle_t handle, uint8_t interface, uint8_t alternateSetting);
|
||||
|
||||
usb_status_t UsbGenericHidCallback(class_handle_t handle, uint32_t event, void *param);
|
||||
usb_status_t UsbGenericHidSetConfiguration(class_handle_t handle, uint8_t configuration);
|
||||
usb_status_t UsbGenericHidSetInterface(class_handle_t handle, uint8_t interface, uint8_t alternateSetting);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -44,17 +44,17 @@ static usb_media_keyboard_report_t usbMediaKeyboardReports[2];
|
||||
usb_media_keyboard_report_t* ActiveUsbMediaKeyboardReport = usbMediaKeyboardReports;
|
||||
bool IsUsbMediaKeyboardReportSent = false;
|
||||
|
||||
usb_media_keyboard_report_t* getInactiveUsbMediaKeyboardReport()
|
||||
usb_media_keyboard_report_t* getInactiveUsbMediaKeyboardReport(void)
|
||||
{
|
||||
return ActiveUsbMediaKeyboardReport == usbMediaKeyboardReports ? usbMediaKeyboardReports+1 : usbMediaKeyboardReports;
|
||||
}
|
||||
|
||||
void SwitchActiveUsbMediaKeyboardReport()
|
||||
void SwitchActiveUsbMediaKeyboardReport(void)
|
||||
{
|
||||
ActiveUsbMediaKeyboardReport = getInactiveUsbMediaKeyboardReport();
|
||||
}
|
||||
|
||||
void ResetActiveUsbMediaKeyboardReport()
|
||||
void ResetActiveUsbMediaKeyboardReport(void)
|
||||
{
|
||||
bzero(ActiveUsbMediaKeyboardReport, USB_MEDIA_KEYBOARD_REPORT_LENGTH);
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
typedef struct {
|
||||
uint16_t scancodes[USB_MEDIA_KEYBOARD_MAX_KEYS];
|
||||
} __attribute__ ((packed)) usb_media_keyboard_report_t;
|
||||
} ATTR_PACKED usb_media_keyboard_report_t;
|
||||
|
||||
// Variables:
|
||||
|
||||
@@ -34,11 +34,11 @@
|
||||
|
||||
// Functions:
|
||||
|
||||
extern usb_status_t UsbMediaKeyboardCallback(class_handle_t handle, uint32_t event, void *param);
|
||||
extern usb_status_t UsbMediaKeyboardSetConfiguration(class_handle_t handle, uint8_t configuration);
|
||||
extern usb_status_t UsbMediaKeyboardSetInterface(class_handle_t handle, uint8_t interface, uint8_t alternateSetting);
|
||||
usb_status_t UsbMediaKeyboardCallback(class_handle_t handle, uint32_t event, void *param);
|
||||
usb_status_t UsbMediaKeyboardSetConfiguration(class_handle_t handle, uint8_t configuration);
|
||||
usb_status_t UsbMediaKeyboardSetInterface(class_handle_t handle, uint8_t interface, uint8_t alternateSetting);
|
||||
|
||||
extern void ResetActiveUsbMediaKeyboardReport();
|
||||
extern void SwitchActiveUsbMediaKeyboardReport();
|
||||
void ResetActiveUsbMediaKeyboardReport(void);
|
||||
void SwitchActiveUsbMediaKeyboardReport(void);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -39,7 +39,7 @@ usb_device_class_struct_t UsbMouseClass = {
|
||||
|
||||
usb_mouse_report_t UsbMouseReport;
|
||||
|
||||
static volatile usb_status_t usbMouseAction()
|
||||
static volatile usb_status_t usbMouseAction(void)
|
||||
{
|
||||
return USB_DeviceHidSend(UsbCompositeDevice.mouseHandle, USB_MOUSE_ENDPOINT_INDEX,
|
||||
(uint8_t*)&UsbMouseReport, USB_MOUSE_REPORT_LENGTH);
|
||||
|
||||
@@ -27,18 +27,17 @@
|
||||
int16_t y;
|
||||
int8_t wheelX;
|
||||
int8_t wheelY;
|
||||
} __attribute__ ((packed)) usb_mouse_report_t;
|
||||
} ATTR_PACKED usb_mouse_report_t;
|
||||
|
||||
// Variables:
|
||||
|
||||
extern usb_device_class_struct_t UsbMouseClass;
|
||||
extern usb_mouse_report_t UsbMouseReport;
|
||||
|
||||
// Functions:
|
||||
|
||||
extern usb_status_t UsbMouseCallback(class_handle_t handle, uint32_t event, void *param);
|
||||
extern usb_status_t UsbMouseSetConfiguration(class_handle_t handle, uint8_t configuration);
|
||||
extern usb_status_t UsbMouseSetInterface(class_handle_t handle, uint8_t interface, uint8_t alternateSetting);
|
||||
|
||||
extern usb_mouse_report_t UsbMouseReport;
|
||||
usb_status_t UsbMouseCallback(class_handle_t handle, uint32_t event, void *param);
|
||||
usb_status_t UsbMouseSetConfiguration(class_handle_t handle, uint8_t configuration);
|
||||
usb_status_t UsbMouseSetInterface(class_handle_t handle, uint8_t interface, uint8_t alternateSetting);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -49,12 +49,12 @@ usb_system_keyboard_report_t* getInactiveUsbSystemKeyboardReport()
|
||||
return ActiveUsbSystemKeyboardReport == usbSystemKeyboardReports ? usbSystemKeyboardReports+1 : usbSystemKeyboardReports;
|
||||
}
|
||||
|
||||
void SwitchActiveUsbSystemKeyboardReport()
|
||||
void SwitchActiveUsbSystemKeyboardReport(void)
|
||||
{
|
||||
ActiveUsbSystemKeyboardReport = getInactiveUsbSystemKeyboardReport();
|
||||
}
|
||||
|
||||
void ResetActiveUsbSystemKeyboardReport()
|
||||
void ResetActiveUsbSystemKeyboardReport(void)
|
||||
{
|
||||
bzero(ActiveUsbSystemKeyboardReport, USB_SYSTEM_KEYBOARD_REPORT_LENGTH);
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
// Includes:
|
||||
|
||||
#include "fsl_common.h"
|
||||
#include "attributes.h"
|
||||
#include "usb_api.h"
|
||||
#include "usb_descriptors/usb_descriptor_system_keyboard_report.h"
|
||||
|
||||
@@ -24,7 +25,7 @@
|
||||
|
||||
typedef struct {
|
||||
uint8_t scancodes[USB_SYSTEM_KEYBOARD_MAX_KEYS];
|
||||
} __attribute__ ((packed)) usb_system_keyboard_report_t;
|
||||
} ATTR_PACKED usb_system_keyboard_report_t;
|
||||
|
||||
// Variables:
|
||||
|
||||
@@ -34,11 +35,11 @@
|
||||
|
||||
// Functions:
|
||||
|
||||
extern usb_status_t UsbSystemKeyboardCallback(class_handle_t handle, uint32_t event, void *param);
|
||||
extern usb_status_t UsbSystemKeyboardSetConfiguration(class_handle_t handle, uint8_t configuration);
|
||||
extern usb_status_t UsbSystemKeyboardSetInterface(class_handle_t handle, uint8_t interface, uint8_t alternateSetting);
|
||||
usb_status_t UsbSystemKeyboardCallback(class_handle_t handle, uint32_t event, void *param);
|
||||
usb_status_t UsbSystemKeyboardSetConfiguration(class_handle_t handle, uint8_t configuration);
|
||||
usb_status_t UsbSystemKeyboardSetInterface(class_handle_t handle, uint8_t interface, uint8_t alternateSetting);
|
||||
|
||||
extern void ResetActiveUsbSystemKeyboardReport();
|
||||
extern void SwitchActiveUsbSystemKeyboardReport();
|
||||
void ResetActiveUsbSystemKeyboardReport(void);
|
||||
void SwitchActiveUsbSystemKeyboardReport(void);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#include "led_pwm.h"
|
||||
#include "slave_scheduler.h"
|
||||
#include "slave_drivers/uhk_module_driver.h"
|
||||
#include "wormhole.h"
|
||||
#include "bootloader/wormhole.h"
|
||||
#include "peripherals/adc.h"
|
||||
#include "eeprom.h"
|
||||
#include "keymaps.h"
|
||||
@@ -80,19 +80,18 @@ void setTestLed(void)
|
||||
{
|
||||
uint8_t ledState = GenericHidInBuffer[1];
|
||||
TEST_LED_SET(ledState);
|
||||
UhkModuleStates[0].isTestLedOn = ledState;
|
||||
UhkModuleStates[UhkModuleDriverId_LeftKeyboardHalf].sourceVars.isTestLedOn = ledState;
|
||||
}
|
||||
|
||||
// To be removed. Now it's already part of getKeyboardState()
|
||||
void readMergeSensor(void)
|
||||
{
|
||||
SetResponseByte(MERGE_SENSOR_IS_MERGED);
|
||||
}
|
||||
|
||||
void applyConfig(void)
|
||||
void ApplyConfig(void)
|
||||
{
|
||||
uint8_t *temp;
|
||||
char oldKeymapAbbreviation[3];
|
||||
uint8_t oldKeymapAbbreviationLen;
|
||||
// Validate the staging configuration.
|
||||
|
||||
ParserRunDry = true;
|
||||
StagingUserConfigBuffer.offset = 0;
|
||||
@@ -100,23 +99,36 @@ void applyConfig(void)
|
||||
GenericHidOutBuffer[1] = StagingUserConfigBuffer.offset;
|
||||
GenericHidOutBuffer[2] = StagingUserConfigBuffer.offset >> 8;
|
||||
GenericHidOutBuffer[3] = 0;
|
||||
if (GenericHidOutBuffer[0]) {
|
||||
|
||||
if (GenericHidOutBuffer[0] != UsbResponse_Success) {
|
||||
return;
|
||||
}
|
||||
memcpy(oldKeymapAbbreviation, AllKeymaps[CurrentKeymapIndex].abbreviation, 3);
|
||||
|
||||
// Make the staging configuration the current one.
|
||||
|
||||
char oldKeymapAbbreviation[KEYMAP_ABBREVIATION_LENGTH];
|
||||
uint8_t oldKeymapAbbreviationLen;
|
||||
memcpy(oldKeymapAbbreviation, AllKeymaps[CurrentKeymapIndex].abbreviation, KEYMAP_ABBREVIATION_LENGTH);
|
||||
oldKeymapAbbreviationLen = AllKeymaps[CurrentKeymapIndex].abbreviationLen;
|
||||
ParserRunDry = false;
|
||||
temp = UserConfigBuffer.buffer;
|
||||
UserConfigBuffer.buffer = StagingUserConfigBuffer.buffer;
|
||||
|
||||
uint8_t *temp;
|
||||
temp = ValidatedUserConfigBuffer.buffer;
|
||||
ValidatedUserConfigBuffer.buffer = StagingUserConfigBuffer.buffer;
|
||||
StagingUserConfigBuffer.buffer = temp;
|
||||
UserConfigBuffer.offset = 0;
|
||||
GenericHidOutBuffer[0] = ParseConfig(&UserConfigBuffer);
|
||||
GenericHidOutBuffer[1] = UserConfigBuffer.offset;
|
||||
GenericHidOutBuffer[2] = UserConfigBuffer.offset >> 8;
|
||||
|
||||
ParserRunDry = false;
|
||||
ValidatedUserConfigBuffer.offset = 0;
|
||||
GenericHidOutBuffer[0] = ParseConfig(&ValidatedUserConfigBuffer);
|
||||
GenericHidOutBuffer[1] = ValidatedUserConfigBuffer.offset;
|
||||
GenericHidOutBuffer[2] = ValidatedUserConfigBuffer.offset >> 8;
|
||||
GenericHidOutBuffer[3] = 1;
|
||||
if (GenericHidOutBuffer[0]) {
|
||||
|
||||
if (GenericHidOutBuffer[0] != UsbResponse_Success) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Switch to the keymap of the updated configuration of the same name or the default keymap.
|
||||
|
||||
for (uint8_t i = 0; i < AllKeymapsCount; i++) {
|
||||
if (AllKeymaps[i].abbreviationLen != oldKeymapAbbreviationLen) {
|
||||
continue;
|
||||
@@ -127,6 +139,7 @@ void applyConfig(void)
|
||||
Keymaps_Switch(i);
|
||||
return;
|
||||
}
|
||||
|
||||
Keymaps_Switch(DefaultKeymapIndex);
|
||||
}
|
||||
|
||||
@@ -134,7 +147,7 @@ void setLedPwm(void)
|
||||
{
|
||||
uint8_t brightnessPercent = GenericHidInBuffer[1];
|
||||
LedPwm_SetBrightness(brightnessPercent);
|
||||
UhkModuleStates[0].ledPwmBrightness = brightnessPercent;
|
||||
UhkModuleStates[UhkModuleDriverId_LeftKeyboardHalf].sourceVars.ledPwmBrightness = brightnessPercent;
|
||||
}
|
||||
|
||||
void getAdcValue(void)
|
||||
@@ -146,10 +159,23 @@ void getAdcValue(void)
|
||||
GenericHidOutBuffer[3] = adcValue >> 24;
|
||||
}
|
||||
|
||||
void launchEepromTransfer(void)
|
||||
void legacyLaunchEepromTransfer(void)
|
||||
{
|
||||
eeprom_transfer_t transferType = GenericHidInBuffer[1];
|
||||
EEPROM_LaunchTransfer(transferType);
|
||||
uint8_t legacyEepromTransferId = GenericHidInBuffer[1];
|
||||
switch (legacyEepromTransferId) {
|
||||
case 0:
|
||||
EEPROM_LaunchTransfer(EepromOperation_Read, ConfigBufferId_HardwareConfig, NULL);
|
||||
break;
|
||||
case 1:
|
||||
EEPROM_LaunchTransfer(EepromOperation_Write, ConfigBufferId_HardwareConfig, NULL);
|
||||
break;
|
||||
case 2:
|
||||
EEPROM_LaunchTransfer(EepromOperation_Read, ConfigBufferId_ValidatedUserConfig, NULL);
|
||||
break;
|
||||
case 3:
|
||||
EEPROM_LaunchTransfer(EepromOperation_Write, ConfigBufferId_ValidatedUserConfig, NULL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void readConfiguration(bool isHardware)
|
||||
@@ -162,7 +188,7 @@ void readConfiguration(bool isHardware)
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t *buffer = isHardware ? HardwareConfigBuffer.buffer : UserConfigBuffer.buffer;
|
||||
uint8_t *buffer = isHardware ? HardwareConfigBuffer.buffer : ValidatedUserConfigBuffer.buffer;
|
||||
uint16_t bufferLength = isHardware ? HARDWARE_CONFIG_SIZE : USER_CONFIG_SIZE;
|
||||
|
||||
if (offset + length > bufferLength) {
|
||||
@@ -197,6 +223,10 @@ void writeConfiguration(bool isHardware)
|
||||
void getKeyboardState(void)
|
||||
{
|
||||
GenericHidOutBuffer[1] = IsEepromBusy;
|
||||
GenericHidOutBuffer[2] = MERGE_SENSOR_IS_MERGED;
|
||||
GenericHidOutBuffer[3] = UhkModuleStates[UhkModuleDriverId_LeftKeyboardHalf].moduleId;
|
||||
GenericHidOutBuffer[4] = UhkModuleStates[UhkModuleDriverId_LeftAddon].moduleId;
|
||||
GenericHidOutBuffer[5] = UhkModuleStates[UhkModuleDriverId_RightAddon].moduleId;
|
||||
}
|
||||
|
||||
void getDebugInfo(void)
|
||||
@@ -206,20 +236,20 @@ void getDebugInfo(void)
|
||||
GenericHidOutBuffer[3] = I2C_Watchdog >> 16;
|
||||
GenericHidOutBuffer[4] = I2C_Watchdog >> 24;
|
||||
|
||||
GenericHidOutBuffer[5] = BridgeCounter >> 0;
|
||||
GenericHidOutBuffer[6] = BridgeCounter >> 8;
|
||||
GenericHidOutBuffer[7] = BridgeCounter >> 16;
|
||||
GenericHidOutBuffer[8] = BridgeCounter >> 24;
|
||||
GenericHidOutBuffer[5] = I2cSchedulerCounter >> 0;
|
||||
GenericHidOutBuffer[6] = I2cSchedulerCounter >> 8;
|
||||
GenericHidOutBuffer[7] = I2cSchedulerCounter >> 16;
|
||||
GenericHidOutBuffer[8] = I2cSchedulerCounter >> 24;
|
||||
|
||||
GenericHidOutBuffer[9] = I2C_WatchdogOuterCounter >> 0;
|
||||
GenericHidOutBuffer[10] = I2C_WatchdogOuterCounter >> 8;
|
||||
GenericHidOutBuffer[11] = I2C_WatchdogOuterCounter >> 16;
|
||||
GenericHidOutBuffer[12] = I2C_WatchdogOuterCounter >> 24;
|
||||
GenericHidOutBuffer[9] = I2cWatchdog_OuterCounter >> 0;
|
||||
GenericHidOutBuffer[10] = I2cWatchdog_OuterCounter >> 8;
|
||||
GenericHidOutBuffer[11] = I2cWatchdog_OuterCounter >> 16;
|
||||
GenericHidOutBuffer[12] = I2cWatchdog_OuterCounter >> 24;
|
||||
|
||||
GenericHidOutBuffer[13] = I2C_WatchdogInnerCounter >> 0;
|
||||
GenericHidOutBuffer[14] = I2C_WatchdogInnerCounter >> 8;
|
||||
GenericHidOutBuffer[15] = I2C_WatchdogInnerCounter >> 16;
|
||||
GenericHidOutBuffer[16] = I2C_WatchdogInnerCounter >> 24;
|
||||
GenericHidOutBuffer[13] = I2cWatchdog_InnerCounter >> 0;
|
||||
GenericHidOutBuffer[14] = I2cWatchdog_InnerCounter >> 8;
|
||||
GenericHidOutBuffer[15] = I2cWatchdog_InnerCounter >> 16;
|
||||
GenericHidOutBuffer[16] = I2cWatchdog_InnerCounter >> 24;
|
||||
/*
|
||||
uint64_t ticks = microseconds_get_ticks();
|
||||
uint32_t microseconds = microseconds_convert_to_microseconds(ticks);
|
||||
@@ -235,9 +265,21 @@ void getDebugInfo(void)
|
||||
GenericHidOutBuffer[8] = (ticks >> 56) & 0xff;
|
||||
*/}
|
||||
|
||||
void jumpToSlaveBootloader(void)
|
||||
{
|
||||
uint8_t uhkModuleDriverId = GenericHidInBuffer[1];
|
||||
|
||||
if (uhkModuleDriverId >= UHK_MODULE_MAX_COUNT) {
|
||||
setError(JumpToBootloaderError_InvalidModuleDriverId);
|
||||
return;
|
||||
}
|
||||
|
||||
UhkModuleStates[uhkModuleDriverId].jumpToBootloader = true;
|
||||
}
|
||||
|
||||
// The main protocol handler function
|
||||
|
||||
void usbProtocolHandler(void)
|
||||
void UsbProtocolHandler(void)
|
||||
{
|
||||
bzero(GenericHidOutBuffer, USB_GENERIC_HID_OUT_BUFFER_LENGTH);
|
||||
uint8_t command = GenericHidInBuffer[0];
|
||||
@@ -260,7 +302,7 @@ void usbProtocolHandler(void)
|
||||
writeConfiguration(false);
|
||||
break;
|
||||
case UsbCommand_ApplyConfig:
|
||||
applyConfig();
|
||||
ApplyConfig();
|
||||
break;
|
||||
case UsbCommand_SetLedPwm:
|
||||
setLedPwm();
|
||||
@@ -269,7 +311,7 @@ void usbProtocolHandler(void)
|
||||
getAdcValue();
|
||||
break;
|
||||
case UsbCommand_LaunchEepromTransfer:
|
||||
launchEepromTransfer();
|
||||
legacyLaunchEepromTransfer();
|
||||
break;
|
||||
case UsbCommand_ReadHardwareConfiguration:
|
||||
readConfiguration(true);
|
||||
@@ -286,6 +328,9 @@ void usbProtocolHandler(void)
|
||||
case UsbCommand_GetDebugInfo:
|
||||
getDebugInfo();
|
||||
break;
|
||||
case UsbCommand_JumpToSlaveBootloader:
|
||||
jumpToSlaveBootloader();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
UsbCommand_ReadUserConfiguration = 15,
|
||||
UsbCommand_GetKeyboardState = 16,
|
||||
UsbCommand_GetDebugInfo = 17,
|
||||
UsbCommand_JumpToSlaveBootloader = 18,
|
||||
} usb_command_t;
|
||||
|
||||
typedef enum {
|
||||
@@ -35,8 +36,13 @@
|
||||
ConfigTransferResponse_BufferOutOfBounds = 2,
|
||||
} config_transfer_response_t;
|
||||
|
||||
typedef enum {
|
||||
JumpToBootloaderError_InvalidModuleDriverId = 1,
|
||||
} jump_to_bootloader_error_t;
|
||||
|
||||
// Functions:
|
||||
|
||||
extern void usbProtocolHandler();
|
||||
void UsbProtocolHandler(void);
|
||||
void ApplyConfig(void);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -72,7 +72,7 @@ void processMouseAction(key_action_t action)
|
||||
wasPreviousMouseActionWheelAction = isWheelAction;
|
||||
}
|
||||
|
||||
uint8_t getActiveLayer()
|
||||
uint8_t getActiveLayer(void)
|
||||
{
|
||||
uint8_t activeLayer = LAYER_ID_BASE;
|
||||
for (uint8_t slotId=0; slotId<SLOT_COUNT; slotId++) {
|
||||
@@ -88,7 +88,7 @@ uint8_t getActiveLayer()
|
||||
return activeLayer;
|
||||
}
|
||||
|
||||
void UpdateActiveUsbReports()
|
||||
void UpdateActiveUsbReports(void)
|
||||
{
|
||||
bzero(&UsbMouseReport, sizeof(usb_mouse_report_t));
|
||||
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
#include "wormhole.h"
|
||||
|
||||
wormhole_t Wormhole NO_INIT_GCC;
|
||||
@@ -1,31 +0,0 @@
|
||||
#ifndef __WORMHOLE_H__
|
||||
#define __WORMHOLE_H__
|
||||
|
||||
// Includes:
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// Macros:
|
||||
|
||||
#define WORMHOLE_MAGIC_NUMBER 0x3b04cd9e94521f9a
|
||||
#define NO_INIT_GCC __attribute__ ((section (".noinit")))
|
||||
|
||||
// Typedefs:
|
||||
|
||||
typedef enum {
|
||||
EnumerationMode_Bootloader,
|
||||
EnumerationMode_NormalKeyboard,
|
||||
EnumerationMode_CompatibleKeyboard,
|
||||
EnumerationMode_BusPal,
|
||||
} enumeration_mode_t;
|
||||
|
||||
typedef struct {
|
||||
uint64_t magicNumber;
|
||||
uint8_t enumerationMode;
|
||||
} wormhole_t;
|
||||
|
||||
// Variables:
|
||||
|
||||
extern wormhole_t Wormhole NO_INIT_GCC;
|
||||
|
||||
#endif
|
||||
11
shared/attributes.h
Normal file
11
shared/attributes.h
Normal file
@@ -0,0 +1,11 @@
|
||||
#ifndef __ATTRIBUTES_H__
|
||||
#define __ATTRIBUTES_H__
|
||||
|
||||
// Macros:
|
||||
|
||||
#define ATTR_PACKED __attribute__ ((packed))
|
||||
#define ATTR_NO_INIT __attribute__ ((section (".noinit")))
|
||||
#define ATTR_DATA2 __attribute__((section (".m_data_2")))
|
||||
#define ATTR_BOOTLOADER_CONFIG __attribute__((used, section(".BootloaderConfig")))
|
||||
|
||||
#endif
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
void BoolBytesToBits(uint8_t *srcBytes, uint8_t *dstBits, uint8_t byteCount)
|
||||
{
|
||||
memset(dstBits, 0, byteCount/8 + 1);
|
||||
memset(dstBits, 0, byteCount/8 + (byteCount % 8 ? 1 : 0));
|
||||
for (uint8_t i=0; i<byteCount; i++) {
|
||||
dstBits[i/8] |= !!srcBytes[i] << (i % 8);
|
||||
}
|
||||
|
||||
@@ -5,6 +5,10 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// Macros:
|
||||
|
||||
#define BOOL_BYTES_TO_BITS_COUNT(BYTE_COUNT) (BYTE_COUNT/8 + (BYTE_COUNT % 8 ? 1 : 0))
|
||||
|
||||
// Functions:
|
||||
|
||||
void BoolBytesToBits(uint8_t *srcBytes, uint8_t *dstBits, uint8_t byteCount);
|
||||
|
||||
12
shared/bootloader.c
Normal file
12
shared/bootloader.c
Normal file
@@ -0,0 +1,12 @@
|
||||
#include "bootloader.h"
|
||||
|
||||
void JumpToBootloader(void) {
|
||||
uint32_t runBootloaderAddress;
|
||||
void (*runBootloader)(void *arg);
|
||||
|
||||
// Read the function address from the ROM API tree.
|
||||
runBootloaderAddress = **(uint32_t **)(0x1c00001c);
|
||||
runBootloader = (void (*)(void * arg))runBootloaderAddress;
|
||||
|
||||
runBootloader(NULL);
|
||||
}
|
||||
@@ -5,9 +5,36 @@
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include "attributes.h"
|
||||
#include "i2c_addresses.h"
|
||||
|
||||
// Macros:
|
||||
|
||||
#define BOOTLOADER_TAG 0x6766636B
|
||||
#define BOOTLOADER_TIMEOUT_MS 100
|
||||
#define CLOCK_FLAG_HIGH_SPEED_MODE 0x01
|
||||
|
||||
#define DEFINE_BOOTLOADER_CONFIG_AREA(address) \
|
||||
const ATTR_BOOTLOADER_CONFIG bootloader_config_t BootloaderConfig = { \
|
||||
.tag = BOOTLOADER_TAG, \
|
||||
.enabledPeripherals = EnabledBootloaderPeripherial_I2c, \
|
||||
.i2cSlaveAddress = address, \
|
||||
.peripheralDetectionTimeoutMs = BOOTLOADER_TIMEOUT_MS, \
|
||||
.clockFlags = CLOCK_FLAG_HIGH_SPEED_MODE, \
|
||||
.clockDivider = ~0 \
|
||||
};
|
||||
|
||||
// Typedefs:
|
||||
|
||||
typedef enum {
|
||||
EnabledBootloaderPeripherial_Uart = (1<<0),
|
||||
EnabledBootloaderPeripherial_I2c = (1<<1),
|
||||
EnabledBootloaderPeripherial_Spi = (1<<2),
|
||||
EnabledBootloaderPeripherial_Can = (1<<3),
|
||||
EnabledBootloaderPeripherial_UsbHid = (1<<4),
|
||||
EnabledBootloaderPeripherial_UsbMsc = (1<<7),
|
||||
} enabled_bootloader_peripheral_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t tag; // Magic number to verify bootloader configuration is valid. Must be set to 'kcfg'.
|
||||
uint32_t reserved[3];
|
||||
@@ -24,9 +51,8 @@
|
||||
uint8_t clockDivider; // Inverted value of the divider to use for core and bus clocks when in high speed mode.
|
||||
} bootloader_config_t;
|
||||
|
||||
|
||||
// Functions:
|
||||
|
||||
extern void JumpToBootloader(void);
|
||||
void JumpToBootloader(void);
|
||||
|
||||
#endif
|
||||
@@ -36,21 +36,20 @@ void crc16_finalize(crc16_data_t *crc16Config, uint16_t *hash)
|
||||
|
||||
crc16_data_t crc16data;
|
||||
|
||||
void CRC16_AppendToMessage(uint8_t *message, uint32_t lengthInBytes)
|
||||
void CRC16_UpdateMessageChecksum(i2c_message_t *message)
|
||||
{
|
||||
uint16_t hash;
|
||||
crc16_init(&crc16data);
|
||||
crc16_update(&crc16data, message, lengthInBytes);
|
||||
crc16_update(&crc16data, message->data, message->length);
|
||||
crc16_finalize(&crc16data, &hash);
|
||||
message[lengthInBytes] = hash & 0xff;
|
||||
message[lengthInBytes+1] = hash >> 8;
|
||||
message->crc = hash;
|
||||
}
|
||||
|
||||
bool CRC16_IsMessageValid(uint8_t *message, uint32_t lengthInBytes)
|
||||
bool CRC16_IsMessageValid(i2c_message_t *message)
|
||||
{
|
||||
uint16_t hash;
|
||||
crc16_init(&crc16data);
|
||||
crc16_update(&crc16data, message, lengthInBytes);
|
||||
crc16_update(&crc16data, message->data, message->length);
|
||||
crc16_finalize(&crc16data, &hash);
|
||||
return (message[lengthInBytes] == (hash & 0xff)) && (message[lengthInBytes+1] == (hash >> 8));
|
||||
return message->crc == hash;
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user