Compare commits
51 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6881f8e340 | ||
|
|
00cd1f65e8 | ||
|
|
2c9a6c0bd2 | ||
|
|
0c94cbb256 | ||
|
|
275bfee860 | ||
|
|
8a655e3cfd | ||
|
|
8521619783 | ||
|
|
62184240df | ||
|
|
0b210ac68e | ||
|
|
56f7753afc | ||
|
|
a0803875c4 | ||
|
|
f5716bdadc | ||
|
|
b76b3c0e4f | ||
|
|
2661c3d909 | ||
|
|
c854e98d84 | ||
|
|
72d8e49717 | ||
|
|
0fd95b71b2 | ||
|
|
4d83bc2e75 | ||
|
|
cf7b05ab72 | ||
|
|
055f1945d0 | ||
|
|
fa4a3abf84 | ||
|
|
96c7ccd758 | ||
|
|
76d319ec19 | ||
|
|
aab0e8473f | ||
|
|
4a4c471b9e | ||
|
|
fcd75b2af2 | ||
|
|
f318c6872e | ||
|
|
ae1240c103 | ||
|
|
e75d366245 | ||
|
|
da20cdacc4 | ||
|
|
5a986d367e | ||
|
|
f6b66283a7 | ||
|
|
6ad425cbf9 | ||
|
|
33e501cd83 | ||
|
|
fa558abef3 | ||
|
|
25a2b3af93 | ||
|
|
43587c2e1f | ||
|
|
c51542795f | ||
|
|
7eb83173ed | ||
|
|
5581dd26b5 | ||
|
|
1ac637af0f | ||
|
|
36951d1a34 | ||
|
|
5190265a2c | ||
|
|
40bf252852 | ||
|
|
85e92d21b4 | ||
|
|
fd43e81e46 | ||
|
|
c994a97d03 | ||
|
|
d59ba83d99 | ||
|
|
c1b887cea8 | ||
|
|
bd53b73685 | ||
|
|
beb7c3d4ee |
33
CHANGELOG.md
33
CHANGELOG.md
@@ -5,6 +5,39 @@ All notable changes to this project will be documented in this file.
|
||||
The format is loosely based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
|
||||
and this project adheres to the [UHK Versioning](VERSIONING.md) conventions.
|
||||
|
||||
## [8.1.1] - 2018-02-11
|
||||
|
||||
Device Protocol: 4.2.0 | Module Protocol: 4.0.0 | User Config: 4.0.0 | Hardware Config: 1.0.0
|
||||
|
||||
- Lock layers every time when double-tapping their layer switcher keys, regardless of how many times the layer switcher key was tapped before.
|
||||
- Only lock layers via double-tapping if the second tap gets released within 100ms.
|
||||
|
||||
## [8.1.0] - 2018-01-15
|
||||
|
||||
Device Protocol: 4.**2**.0 | Module Protocol: 4.0.0 | User Config: 4.0.0 | Hardware Config: 1.0.0
|
||||
|
||||
- Enable left-half watchdog in reinit mode which seems to prevent freezes.
|
||||
- Slow down main bus I2C baud rate to 30kHz when BusPal is on to make firmware transfer more robust.
|
||||
- Implement UsbCommandId_GetSlaveI2cErrors. `DEVICEPROTOCOL:MINOR`
|
||||
- Implement UsbCommandId_SetI2cBaudRate. `DEVICEPROTOCOL:MINOR`
|
||||
- Implement DevicePropertyId_CurrentKbootCommand. `DEVICEPROTOCOL:MINOR`
|
||||
- Implement DevicePropertyId_I2cMainBusBaudRate. `DEVICEPROTOCOL:MINOR`
|
||||
- Implement DevicePropertyId_Uptime. `DEVICEPROTOCOL:MINOR`
|
||||
|
||||
## [8.0.1] - 2017-12-25
|
||||
|
||||
Device Protocol: 4.1.0 | Module Protocol: 4.0.0 | User Config: 4.0.0 | Hardware Config: 1.0.0
|
||||
|
||||
- Implement I2C watchdog for the left keyboard half which should resolve the occasional hangs of the left keyboard half.
|
||||
|
||||
## [8.0.0] - 2017-12-15
|
||||
|
||||
Device Protocol: 4.**1.0** | Module Protocol: **4.0.0** | User Config: 4.0.0 | Hardware Config: 1.0.0
|
||||
|
||||
- Make the modules transfer the module protocol version and firmware version composed of a major, a minor and a patch number. `MODULEPROTOCOL:MAJOR`
|
||||
- Query module key count and pointer count in separate messages instead of a combined message for improved clarity. `MODULEPROTOCOL:MAJOR`
|
||||
- Add new UsbCommand_GetModuleProperties() device protocol command. `DEVICEPROTOCOL:MINOR`
|
||||
|
||||
## [7.0.0] - 2017-12-14
|
||||
|
||||
Device Protocol: **4.0.0** | Module Protocol: 3.0.0 | User Config: 4.0.0 | Hardware Config: 1.0.0
|
||||
|
||||
12
README.md
12
README.md
@@ -4,6 +4,10 @@
|
||||
|
||||
This repository hosts the firmware of the [Ultimate Hacking Keyboard](https://ultimatehackingkeyboard.com/).
|
||||
|
||||
## Updating to the latest firmware
|
||||
|
||||
Want to update your UHK to the latest firmware version? Simply download the [latest release of Agent](https://github.com/UltimateHackingKeyboard/agent/releases/latest) which includes the latest firmware version. You'll be easily able to update the firmware within Agent.
|
||||
|
||||
## Cloning the repository
|
||||
|
||||
Please make sure to clone this repo with:
|
||||
@@ -18,9 +22,13 @@ Install [Kinetis Design Studio](http://www.nxp.com/products/software-and-tools/r
|
||||
|
||||
## Building and flashing the firmware
|
||||
|
||||
For the left keyboard half, make sure to power it via the right keyboard half (which must be powered via USB). Also connect the left keyboard half to your SEGGER J-Link USB debug probe (which must also be connected via USB). Then in KDS, click on *Run -> Run Configurations*, select *GDB SEGGER J-Link Debugging -> uhk-left release jlink*, and click on the *Debug* button.
|
||||
For the left keyboard half, make sure to power it via the right keyboard half (which must be powered via USB). Also connect the left keyboard half to your SEGGER J-Link USB debug probe (which must also be connected via USB). Then in KDS, click on *Run -> Run Configurations*, select *GDB SEGGER J-Link Debugging -> uhk60-left_release_jlink*, and click on the *Debug* button.
|
||||
|
||||
For the right keyboard half, flash [the bootloader](https://github.com/UltimateHackingKeyboard/bootloader) first. Then in KDS, click on *Run -> Run Configurations*, select *C/C++ Application -> uhk-right release blhost*, and click on the *Debug* button. Please note that this update method only works on Linux out of the box. On other operating systems, you have to execute the relevant commands of the [blhost-unix.sh](right/build/kds/blhost-unix.sh) script.
|
||||
For the right keyboard half, flash [the bootloader](https://github.com/UltimateHackingKeyboard/bootloader) first.
|
||||
|
||||
At this point, you can flash the right firmware via USB from KDS. To achieve this, you must build [Agent](https://github.com/UltimateHackingKeyboard/agent) that is Git submodule of the this repo and located in the `lib/agent` directory. Then in KDS, click on *Run -> Run Configurations*, select *C/C++ Application -> uhk60-right_release_kboot*, and click on the *Run* button.
|
||||
|
||||
From this point on, you can upgrade the firmwares of both halves via USB by using the uhk60-left_release_kboot and uhk60-right_release_kboot run configurations. Alternatively, you can use your SEGGER J-Link probe.
|
||||
|
||||
## Contributing
|
||||
|
||||
|
||||
@@ -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="false"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setStopAt" value="true"/>
|
||||
<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=""/>
|
||||
@@ -77,6 +77,6 @@
|
||||
<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>
|
||||
|
||||
@@ -77,6 +77,6 @@
|
||||
<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>
|
||||
|
||||
@@ -3,6 +3,11 @@
|
||||
|
||||
// Macros:
|
||||
|
||||
#define I2C_WATCHDOG_VALUE_REINIT 1
|
||||
#define I2C_WATCHDOG_VALUE_REBOOT 2
|
||||
|
||||
// #define DEBUG_OVER_SPI
|
||||
#define I2C_WATCHDOG I2C_WATCHDOG_VALUE_REINIT
|
||||
// #define I2C_WATCHDOG I2C_WATCHDOG_VALUE_REBOOT
|
||||
|
||||
#endif
|
||||
|
||||
@@ -3,36 +3,40 @@
|
||||
#include "i2c_watchdog.h"
|
||||
#include "test_led.h"
|
||||
#include "init_peripherals.h"
|
||||
#include "config.h"
|
||||
|
||||
//static uint32_t prevWatchdogCounter = 0;
|
||||
uint32_t I2cWatchdog_RecoveryCounter;
|
||||
volatile uint32_t I2cWatchdog_WatchCounter;
|
||||
/* NOTE: Because of a bug in the ROM bootloader of the KL03Z, the watchdog timer is disabled and cannot be re-enabled.
|
||||
* See https://community.nxp.com/thread/457893
|
||||
* Therefore the hardware watchdog timer cannot be used without an extra way to enter bootloader or application mode.
|
||||
*/
|
||||
#ifdef I2C_WATCHDOG
|
||||
static uint32_t prevWatchdogCounter = 0;
|
||||
static uint32_t I2cWatchdog_RecoveryCounter; /* counter for how many times we had to recover and restart */
|
||||
|
||||
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)
|
||||
void RunWatchdog(void)
|
||||
{
|
||||
static volatile uint32_t I2cWatchdog_WatchCounter = 0; /* counter for timer */
|
||||
static int cntr = 0;
|
||||
|
||||
cntr++;
|
||||
if (cntr==100) { /* we get called from KEY_SCANNER_HANDLER() which runs at 1ms, thus scaling down by 100 here to get 100 ms period */
|
||||
cntr=0;
|
||||
TEST_LED_TOGGLE();
|
||||
I2cWatchdog_WatchCounter++;
|
||||
|
||||
if (I2C_Watchdog == prevWatchdogCounter) { // Restart I2C if there hasn't been any interrupt during 100 ms
|
||||
// NVIC_SystemReset();
|
||||
if (I2cWatchdog_WatchCounter>10) { /* do not check within the first 1000 ms, as I2C might not be running yet */
|
||||
if (I2C_Watchdog == prevWatchdogCounter) { // Restart I2C if there hasn't been any interrupt during 100 ms. I2C_Watchdog gets incremented for every I2C transaction
|
||||
I2cWatchdog_RecoveryCounter++;
|
||||
#if I2C_WATCHDOG == I2C_WATCHDOG_VALUE_REBOOT
|
||||
NVIC_SystemReset();
|
||||
#endif
|
||||
#if I2C_WATCHDOG == I2C_WATCHDOG_VALUE_REINIT
|
||||
I2C_SlaveDeinit(I2C_BUS_BASEADDR);
|
||||
InitI2c();
|
||||
initI2c();
|
||||
#endif
|
||||
}
|
||||
|
||||
prevWatchdogCounter = I2C_Watchdog;
|
||||
|
||||
LPTMR_ClearStatusFlags(LPTMR0, kLPTMR_TimerCompareFlag);
|
||||
}
|
||||
*/
|
||||
prevWatchdogCounter = I2C_Watchdog; /* remember previous counter */
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
|
||||
// Functions:
|
||||
|
||||
void InitI2cWatchdog(void);
|
||||
void RunWatchdog(void);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "slave_protocol_handler.h"
|
||||
#include "i2c_watchdog.h"
|
||||
#include "debug_over_spi.h"
|
||||
#include "main.h"
|
||||
|
||||
i2c_slave_config_t slaveConfig;
|
||||
i2c_slave_handle_t slaveHandle;
|
||||
@@ -44,14 +45,14 @@ static void i2cSlaveCallback(I2C_Type *base, i2c_slave_transfer_t *xfer, void *u
|
||||
}
|
||||
}
|
||||
|
||||
void InitInterruptPriorities(void)
|
||||
void initInterruptPriorities(void)
|
||||
{
|
||||
NVIC_SetPriority(I2C0_IRQn, 1);
|
||||
NVIC_SetPriority(TPM1_IRQn, 1);
|
||||
NVIC_SetPriority(SPI0_IRQn, 1);
|
||||
}
|
||||
|
||||
void InitI2c(void)
|
||||
void initI2c(void)
|
||||
{
|
||||
port_pin_config_t pinConfig = {
|
||||
.pullSelect = kPORT_PullUp,
|
||||
@@ -81,11 +82,10 @@ void InitLedDriver(void)
|
||||
|
||||
void InitPeripherals(void)
|
||||
{
|
||||
InitInterruptPriorities();
|
||||
initInterruptPriorities();
|
||||
InitLedDriver();
|
||||
InitTestLed();
|
||||
LedPwm_Init();
|
||||
// InitI2cWatchdog();
|
||||
DebugOverSpi_Init();
|
||||
InitI2c();
|
||||
initI2c();
|
||||
}
|
||||
|
||||
@@ -11,6 +11,6 @@
|
||||
// Functions:
|
||||
|
||||
void InitPeripherals(void);
|
||||
void InitI2c(void);
|
||||
void initI2c(void);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,10 +1,14 @@
|
||||
#include "fsl_lptmr.h"
|
||||
#include "key_scanner.h"
|
||||
#include "main.h"
|
||||
#include "config.h"
|
||||
#include "i2c_watchdog.h"
|
||||
|
||||
void KEY_SCANNER_HANDLER(void)
|
||||
{
|
||||
KeyMatrix_ScanRow(&keyMatrix);
|
||||
#ifdef I2C_WATCHDOG
|
||||
RunWatchdog();
|
||||
#endif
|
||||
LPTMR_ClearStatusFlags(KEY_SCANNER_LPTMR_BASEADDR, kLPTMR_TimerCompareFlag);
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,6 @@
|
||||
#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
|
||||
#define MODULE_POINTER_COUNT 0
|
||||
|
||||
#endif
|
||||
|
||||
@@ -10,10 +10,23 @@
|
||||
#include "bool_array_converter.h"
|
||||
#include "bootloader.h"
|
||||
#include "module.h"
|
||||
#include "versions.h"
|
||||
|
||||
i2c_message_t RxMessage;
|
||||
i2c_message_t TxMessage;
|
||||
|
||||
static version_t moduleProtocolVersion = {
|
||||
MODULE_PROTOCOL_MAJOR_VERSION,
|
||||
MODULE_PROTOCOL_MINOR_VERSION,
|
||||
MODULE_PROTOCOL_PATCH_VERSION,
|
||||
};
|
||||
|
||||
static version_t firmwareVersion = {
|
||||
FIRMWARE_MAJOR_VERSION,
|
||||
FIRMWARE_MINOR_VERSION,
|
||||
FIRMWARE_PATCH_VERSION,
|
||||
};
|
||||
|
||||
void SlaveRxHandler(void)
|
||||
{
|
||||
if (!CRC16_IsMessageValid(&RxMessage)) {
|
||||
@@ -51,21 +64,29 @@ void SlaveTxHandler(void)
|
||||
TxMessage.length = SLAVE_SYNC_STRING_LENGTH;
|
||||
break;
|
||||
}
|
||||
case SlaveProperty_ModuleProtocolVersion: {
|
||||
memcpy(TxMessage.data, &moduleProtocolVersion, sizeof(version_t));
|
||||
TxMessage.length = sizeof(version_t);
|
||||
break;
|
||||
}
|
||||
case SlaveProperty_FirmwareVersion: {
|
||||
memcpy(TxMessage.data, &firmwareVersion, sizeof(version_t));
|
||||
TxMessage.length = sizeof(version_t);
|
||||
break;
|
||||
}
|
||||
case SlaveProperty_ModuleId: {
|
||||
TxMessage.data[0] = MODULE_ID;
|
||||
TxMessage.length = 1;
|
||||
break;
|
||||
}
|
||||
case SlaveProperty_ProtocolVersion: {
|
||||
TxMessage.data[0] = MODULE_PROTOCOL_VERSION;
|
||||
case SlaveProperty_KeyCount: {
|
||||
TxMessage.data[0] = MODULE_KEY_COUNT;
|
||||
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);
|
||||
case SlaveProperty_PointerCount: {
|
||||
TxMessage.data[0] = MODULE_POINTER_COUNT;
|
||||
TxMessage.length = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Submodule lib/KSDK_2.0_MK22FN512xxx12 updated: 7142722eed...9fbf2bbf08
Submodule lib/agent updated: 2702a74035...dd973c80ea
@@ -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="uhk60-right_debug/uhk-right.elf"/>
|
||||
<stringAttribute key="org.eclipse.cdt.launch.PROGRAM_NAME" value="uhk60-right_debug_standalone/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="ilg.gnuarmeclipse.managedbuild.cross.config.elf.release.1939339834.1692217331.1297236062.2081695142"/>
|
||||
<stringAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_ID_ATTR" value=""/>
|
||||
<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>
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
// Macros:
|
||||
|
||||
#define I2C_WATCHDOG
|
||||
#define LED_DRIVERS_ENABLED
|
||||
// #define LED_DRIVER_STRESS_TEST
|
||||
|
||||
#endif
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "led_display.h"
|
||||
#include "slave_scheduler.h"
|
||||
#include "slave_drivers/is31fl3731_driver.h"
|
||||
#include "config.h"
|
||||
|
||||
static parser_error_t parseModuleConfiguration(config_buffer_t *buffer)
|
||||
{
|
||||
@@ -142,9 +143,10 @@ parser_error_t ParseConfig(config_buffer_t *buffer)
|
||||
IconsAndLayerTextsBrightness = iconsAndLayerTextsBrightness;
|
||||
AlphanumericSegmentsBrightness = alphanumericSegmentsBrightness;
|
||||
KeyBacklightBrightness = keyBacklightBrightness;
|
||||
#ifdef LED_DRIVERS_ENABLED
|
||||
Slaves[SlaveId_LeftLedDriver].isConnected = false;
|
||||
Slaves[SlaveId_RightLedDriver].isConnected = false;
|
||||
|
||||
#endif
|
||||
// Update mouse key speeds
|
||||
|
||||
MouseMoveState.initialSpeed = mouseMoveInitialSpeed;
|
||||
|
||||
@@ -13,7 +13,8 @@
|
||||
#define I2C_MAIN_BUS_BASEADDR I2C0
|
||||
#define I2C_MAIN_BUS_IRQ_ID I2C0_IRQn
|
||||
#define I2C_MAIN_BUS_CLK_SRC I2C0_CLK_SRC
|
||||
#define I2C_MAIN_BUS_BAUD_RATE 100000 // 100 kHz works even with a 20 meter long bridge cable.
|
||||
#define I2C_MAIN_BUS_NORMAL_BAUD_RATE 100000
|
||||
#define I2C_MAIN_BUS_BUSPAL_BAUD_RATE 30000
|
||||
#define I2C_MAIN_BUS_MUX kPORT_MuxAlt7
|
||||
|
||||
#define I2C_MAIN_BUS_SDA_GPIO GPIOD
|
||||
|
||||
25
right/src/i2c_error_logger.c
Normal file
25
right/src/i2c_error_logger.c
Normal file
@@ -0,0 +1,25 @@
|
||||
#include "fsl_i2c.h"
|
||||
#include "i2c_error_logger.h"
|
||||
|
||||
i2c_slave_error_counter_t I2cSlaveErrorCounters[MAX_SLAVE_COUNT];
|
||||
|
||||
void LogI2cError(uint8_t slaveId, status_t status)
|
||||
{
|
||||
i2c_slave_error_counter_t *i2cSlaveErrorCounter = I2cSlaveErrorCounters + slaveId;
|
||||
uint8_t errorIdx;
|
||||
|
||||
for (errorIdx=0; errorIdx<i2cSlaveErrorCounter->errorTypeCount; errorIdx++) {
|
||||
i2c_error_count_t *currentI2cError = i2cSlaveErrorCounter->errors + errorIdx;
|
||||
if (currentI2cError->status == status) {
|
||||
currentI2cError->count++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (errorIdx == i2cSlaveErrorCounter->errorTypeCount && errorIdx < MAX_LOGGED_I2C_ERROR_TYPES_PER_SLAVE) {
|
||||
i2cSlaveErrorCounter->errorTypeCount++;
|
||||
i2c_error_count_t *currentI2cError = i2cSlaveErrorCounter->errors + errorIdx;
|
||||
currentI2cError->status = status;
|
||||
currentI2cError->count = 1;
|
||||
}
|
||||
}
|
||||
33
right/src/i2c_error_logger.h
Normal file
33
right/src/i2c_error_logger.h
Normal file
@@ -0,0 +1,33 @@
|
||||
#ifndef __I2C_ERROR_LOGGER_H__
|
||||
#define __I2C_ERROR_LOGGER_H__
|
||||
|
||||
// Includes:
|
||||
|
||||
#include "fsl_common.h"
|
||||
#include "slave_scheduler.h"
|
||||
|
||||
// Macros:
|
||||
|
||||
#define MAX_LOGGED_I2C_ERROR_TYPES_PER_SLAVE 7
|
||||
|
||||
// Typedefs:
|
||||
|
||||
typedef struct {
|
||||
status_t status;
|
||||
uint32_t count;
|
||||
} i2c_error_count_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t errorTypeCount;
|
||||
i2c_error_count_t errors[MAX_LOGGED_I2C_ERROR_TYPES_PER_SLAVE];
|
||||
} i2c_slave_error_counter_t;
|
||||
|
||||
// Variables:
|
||||
|
||||
extern i2c_slave_error_counter_t I2cSlaveErrorCounters[MAX_SLAVE_COUNT];
|
||||
|
||||
// Functions:
|
||||
|
||||
void LogI2cError(uint8_t slaveId, status_t status);
|
||||
|
||||
#endif
|
||||
@@ -5,7 +5,6 @@
|
||||
#include "fsl_gpio.h"
|
||||
#include "i2c.h"
|
||||
#include "i2c_watchdog.h"
|
||||
#include "slave_scheduler.h"
|
||||
#include "init_peripherals.h"
|
||||
|
||||
uint32_t I2cWatchdog_WatchCounter;
|
||||
@@ -19,17 +18,13 @@ static uint32_t prevWatchdogCounter;
|
||||
void PIT_I2C_WATCHDOG_HANDLER(void)
|
||||
{
|
||||
I2cWatchdog_WatchCounter++;
|
||||
|
||||
if (I2C_Watchdog == prevWatchdogCounter) { // Restart I2C if there haven't been any interrupts recently
|
||||
I2cWatchdog_RecoveryCounter++;
|
||||
i2c_master_config_t masterConfig;
|
||||
I2C_MasterGetDefaultConfig(&masterConfig);
|
||||
I2C_MasterDeinit(I2C_MAIN_BUS_BASEADDR);
|
||||
InitI2cMainBus();
|
||||
InitSlaveScheduler();
|
||||
ReinitI2cMainBus();
|
||||
}
|
||||
|
||||
prevWatchdogCounter = I2C_Watchdog;
|
||||
|
||||
PIT_ClearStatusFlags(PIT, PIT_I2C_WATCHDOG_CHANNEL, PIT_TFLG_TIF_MASK);
|
||||
}
|
||||
|
||||
|
||||
@@ -14,8 +14,22 @@
|
||||
#include "timer.h"
|
||||
#include "key_debouncer.h"
|
||||
#include "usb_api.h"
|
||||
#include "slave_scheduler.h"
|
||||
#include "bootloader/wormhole.h"
|
||||
|
||||
void InitInterruptPriorities(void)
|
||||
bool IsBusPalOn;
|
||||
uint32_t I2cMainBusRequestedBaudRateBps = I2C_MAIN_BUS_NORMAL_BAUD_RATE;
|
||||
uint32_t I2cMainBusActualBaudRateBps;
|
||||
|
||||
void initBusPalState(void) {
|
||||
IsBusPalOn = Wormhole.magicNumber == WORMHOLE_MAGIC_NUMBER && Wormhole.enumerationMode == EnumerationMode_BusPal;
|
||||
if (IsBusPalOn) {
|
||||
Wormhole.magicNumber = 0;
|
||||
I2cMainBusRequestedBaudRateBps = I2C_MAIN_BUS_BUSPAL_BAUD_RATE;
|
||||
}
|
||||
}
|
||||
|
||||
void initInterruptPriorities(void)
|
||||
{
|
||||
NVIC_SetPriority(PIT_I2C_WATCHDOG_IRQ_ID, 1);
|
||||
NVIC_SetPriority(PIT_TIMER_IRQ_ID, 2);
|
||||
@@ -60,7 +74,7 @@ void recoverI2c(void)
|
||||
delay();
|
||||
}
|
||||
|
||||
void InitI2cMainBus(void)
|
||||
void initI2cMainBus(void)
|
||||
{
|
||||
CLOCK_EnableClock(I2C_MAIN_BUS_SDA_CLOCK);
|
||||
CLOCK_EnableClock(I2C_MAIN_BUS_SCL_CLOCK);
|
||||
@@ -78,9 +92,17 @@ void InitI2cMainBus(void)
|
||||
|
||||
i2c_master_config_t masterConfig;
|
||||
I2C_MasterGetDefaultConfig(&masterConfig);
|
||||
masterConfig.baudRate_Bps = I2C_MAIN_BUS_BAUD_RATE;
|
||||
masterConfig.baudRate_Bps = I2cMainBusRequestedBaudRateBps;
|
||||
uint32_t sourceClock = CLOCK_GetFreq(I2C_MAIN_BUS_CLK_SRC);
|
||||
I2C_MasterInit(I2C_MAIN_BUS_BASEADDR, &masterConfig, sourceClock);
|
||||
I2cMainBusActualBaudRateBps = I2C_ActualBaudRate;
|
||||
}
|
||||
|
||||
void ReinitI2cMainBus(void)
|
||||
{
|
||||
I2C_MasterDeinit(I2C_MAIN_BUS_BASEADDR);
|
||||
initI2cMainBus();
|
||||
InitSlaveScheduler();
|
||||
}
|
||||
|
||||
void initI2cEepromBus(void)
|
||||
@@ -91,7 +113,6 @@ void initI2cEepromBus(void)
|
||||
.mux = I2C_EEPROM_BUS_MUX,
|
||||
};
|
||||
|
||||
|
||||
CLOCK_EnableClock(I2C_EEPROM_BUS_SDA_CLOCK);
|
||||
CLOCK_EnableClock(I2C_EEPROM_BUS_SCL_CLOCK);
|
||||
|
||||
@@ -105,21 +126,22 @@ void initI2cEepromBus(void)
|
||||
I2C_MasterInit(I2C_EEPROM_BUS_BASEADDR, &masterConfig, sourceClock);
|
||||
}
|
||||
|
||||
void InitI2c(void)
|
||||
void initI2c(void)
|
||||
{
|
||||
InitI2cMainBus();
|
||||
initI2cMainBus();
|
||||
initI2cEepromBus();
|
||||
}
|
||||
|
||||
void InitPeripherals(void)
|
||||
{
|
||||
InitInterruptPriorities();
|
||||
initBusPalState();
|
||||
initInterruptPriorities();
|
||||
Timer_Init();
|
||||
InitLedDriver();
|
||||
InitResetButton();
|
||||
InitMergeSensor();
|
||||
ADC_Init();
|
||||
InitI2c();
|
||||
initI2c();
|
||||
InitTestLed();
|
||||
LedPwm_Init();
|
||||
#ifdef I2C_WATCHDOG
|
||||
|
||||
@@ -5,9 +5,15 @@
|
||||
|
||||
#include "fsl_common.h"
|
||||
|
||||
// Variables:
|
||||
|
||||
extern bool IsBusPalOn;
|
||||
extern uint32_t I2cMainBusRequestedBaudRateBps;
|
||||
extern uint32_t I2cMainBusActualBaudRateBps;
|
||||
|
||||
// Functions:
|
||||
|
||||
void InitPeripherals(void);
|
||||
void InitI2cMainBus(void);
|
||||
void ReinitI2cMainBus(void);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
#include "slave_scheduler.h"
|
||||
#include "bus_pal_hardware.h"
|
||||
#include "command.h"
|
||||
#include "bootloader/wormhole.h"
|
||||
#include "eeprom.h"
|
||||
#include "key_scanner.h"
|
||||
#include "usb_commands/usb_command_apply_config.h"
|
||||
@@ -34,8 +33,7 @@ void main(void)
|
||||
EEPROM_LaunchTransfer(EepromOperation_Read, ConfigBufferId_HardwareConfig, hardwareConfigurationReadFinished);
|
||||
}
|
||||
|
||||
if (Wormhole.magicNumber == WORMHOLE_MAGIC_NUMBER && Wormhole.enumerationMode == EnumerationMode_BusPal) {
|
||||
Wormhole.magicNumber = 0;
|
||||
if (IsBusPalOn) {
|
||||
init_hardware();
|
||||
handleUsbBusPalCommand();
|
||||
} else {
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
kboot_driver_state_t KbootDriverState;
|
||||
|
||||
static uint8_t rxBuffer[MAX_KBOOT_COMMAND_LENGTH];
|
||||
static uint8_t rxBuffer[KBOOT_PACKAGE_MAX_LENGTH];
|
||||
static uint8_t pingCommand[] = {0x5a, 0xa6};
|
||||
static uint8_t resetCommand[] = {0x5a, 0xa4, 0x04, 0x00, 0x6f, 0x46, 0x0b, 0x00, 0x00, 0x00};
|
||||
static uint8_t ackMessage[] = {0x5a, 0xa1};
|
||||
@@ -27,50 +27,52 @@ status_t KbootSlaveDriver_Update(uint8_t kbootInstanceId)
|
||||
{
|
||||
status_t status = kStatus_Uhk_IdleSlave;
|
||||
|
||||
switch (KbootDriverState.commandType) {
|
||||
switch (KbootDriverState.command) {
|
||||
case KbootCommand_Idle:
|
||||
break;
|
||||
case KbootCommand_Ping:
|
||||
switch (KbootDriverState.phase) {
|
||||
case 0:
|
||||
case KbootPhase_SendPing:
|
||||
status = tx(pingCommand, sizeof(pingCommand));
|
||||
KbootDriverState.phase++;
|
||||
KbootDriverState.phase = KbootPhase_CheckPingStatus;
|
||||
break;
|
||||
case 1:
|
||||
case KbootPhase_CheckPingStatus:
|
||||
KbootDriverState.status = Slaves[SlaveId_KbootDriver].previousStatus;
|
||||
KbootDriverState.phase = KbootDriverState.status == kStatus_Success ? 2 : 0;
|
||||
return kStatus_Uhk_NoTransfer;
|
||||
case 2:
|
||||
status = rx(10);
|
||||
KbootDriverState.phase++;
|
||||
KbootDriverState.phase = KbootDriverState.status == kStatus_Success
|
||||
? KbootPhase_ReceivePingResponse
|
||||
: KbootPhase_SendPing;
|
||||
return kStatus_Uhk_IdleCycle;
|
||||
case KbootPhase_ReceivePingResponse:
|
||||
status = rx(KBOOT_PACKAGE_LENGTH_PING_RESPONSE);
|
||||
KbootDriverState.phase = KbootPhase_CheckPingResponseStatus;
|
||||
break;
|
||||
case 3:
|
||||
case KbootPhase_CheckPingResponseStatus:
|
||||
KbootDriverState.status = Slaves[SlaveId_KbootDriver].previousStatus;
|
||||
if (KbootDriverState.status == kStatus_Success) {
|
||||
KbootDriverState.commandType = KbootCommand_Idle;
|
||||
KbootDriverState.command = KbootCommand_Idle;
|
||||
} else {
|
||||
KbootDriverState.phase = 0;
|
||||
return kStatus_Uhk_NoTransfer;
|
||||
KbootDriverState.phase = KbootPhase_SendPing;
|
||||
return kStatus_Uhk_IdleCycle;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case KbootCommand_Reset:
|
||||
switch (KbootDriverState.phase) {
|
||||
case 0:
|
||||
case KbootPhase_SendReset:
|
||||
status = tx(resetCommand, sizeof(resetCommand));
|
||||
KbootDriverState.phase++;
|
||||
KbootDriverState.phase = KbootPhase_ReceiveResetAck;
|
||||
break;
|
||||
case 1:
|
||||
status = rx(2);
|
||||
KbootDriverState.phase++;
|
||||
case KbootPhase_ReceiveResetAck:
|
||||
status = rx(KBOOT_PACKAGE_LENGTH_ACK);
|
||||
KbootDriverState.phase = KbootPhase_ReceiveResetGenericResponse;
|
||||
break;
|
||||
case 2:
|
||||
status = rx(18);
|
||||
KbootDriverState.phase++;
|
||||
case KbootPhase_ReceiveResetGenericResponse:
|
||||
status = rx(KBOOT_PACKAGE_LENGTH_GENERIC_RESPONSE);
|
||||
KbootDriverState.phase = KbootPhase_CheckResetSendAck;
|
||||
break;
|
||||
case 3:
|
||||
case KbootPhase_CheckResetSendAck:
|
||||
status = tx(ackMessage, sizeof(ackMessage));
|
||||
KbootDriverState.commandType = KbootCommand_Idle;
|
||||
KbootDriverState.command = KbootCommand_Idle;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -7,7 +7,10 @@
|
||||
|
||||
// Macros:
|
||||
|
||||
#define MAX_KBOOT_COMMAND_LENGTH 32
|
||||
#define KBOOT_PACKAGE_MAX_LENGTH 32
|
||||
#define KBOOT_PACKAGE_LENGTH_PING_RESPONSE 10
|
||||
#define KBOOT_PACKAGE_LENGTH_ACK 2
|
||||
#define KBOOT_PACKAGE_LENGTH_GENERIC_RESPONSE 18
|
||||
|
||||
// Typedefs:
|
||||
|
||||
@@ -21,8 +24,22 @@
|
||||
KbootCommand_Reset,
|
||||
} kboot_command_t;
|
||||
|
||||
typedef enum {
|
||||
KbootPhase_SendPing,
|
||||
KbootPhase_CheckPingStatus,
|
||||
KbootPhase_ReceivePingResponse,
|
||||
KbootPhase_CheckPingResponseStatus,
|
||||
} kboot_ping_phase_t;
|
||||
|
||||
typedef enum {
|
||||
KbootPhase_SendReset,
|
||||
KbootPhase_ReceiveResetAck,
|
||||
KbootPhase_ReceiveResetGenericResponse,
|
||||
KbootPhase_CheckResetSendAck,
|
||||
} kboot_reset_phase_t;
|
||||
|
||||
typedef struct {
|
||||
kboot_command_t commandType;
|
||||
kboot_command_t command;
|
||||
uint8_t i2cAddress;
|
||||
uint8_t phase;
|
||||
uint32_t status;
|
||||
|
||||
@@ -91,32 +91,54 @@ status_t UhkModuleSlaveDriver_Update(uint8_t uhkModuleDriverId)
|
||||
case UhkModulePhase_ProcessSync: {
|
||||
bool isMessageValid = CRC16_IsMessageValid(rxMessage);
|
||||
bool isSyncValid = memcmp(rxMessage->data, SlaveSyncString, SLAVE_SYNC_STRING_LENGTH) == 0;
|
||||
status = kStatus_Uhk_NoTransfer;
|
||||
status = kStatus_Uhk_IdleCycle;
|
||||
*uhkModulePhase = isSyncValid && isMessageValid
|
||||
? UhkModulePhase_RequestProtocolVersion
|
||||
? UhkModulePhase_RequestModuleProtocolVersion
|
||||
: UhkModulePhase_RequestSync;
|
||||
break;
|
||||
}
|
||||
|
||||
// Get protocol version
|
||||
case UhkModulePhase_RequestProtocolVersion:
|
||||
// Get module protocol version
|
||||
case UhkModulePhase_RequestModuleProtocolVersion:
|
||||
txMessage.data[0] = SlaveCommand_RequestProperty;
|
||||
txMessage.data[1] = SlaveProperty_ProtocolVersion;
|
||||
txMessage.data[1] = SlaveProperty_ModuleProtocolVersion;
|
||||
txMessage.length = 2;
|
||||
status = tx(i2cAddress);
|
||||
*uhkModulePhase = UhkModulePhase_ReceiveProtocolVersion;
|
||||
*uhkModulePhase = UhkModulePhase_ReceiveModuleProtocolVersion;
|
||||
break;
|
||||
case UhkModulePhase_ReceiveProtocolVersion:
|
||||
case UhkModulePhase_ReceiveModuleProtocolVersion:
|
||||
status = rx(rxMessage, i2cAddress);
|
||||
*uhkModulePhase = UhkModulePhase_ProcessProtocolVersion;
|
||||
*uhkModulePhase = UhkModulePhase_ProcessModuleProtocolVersion;
|
||||
break;
|
||||
case UhkModulePhase_ProcessProtocolVersion: {
|
||||
case UhkModulePhase_ProcessModuleProtocolVersion: {
|
||||
bool isMessageValid = CRC16_IsMessageValid(rxMessage);
|
||||
if (isMessageValid) {
|
||||
uhkModuleState->protocolVersion = rxMessage->data[0];
|
||||
memcpy(&uhkModuleState->moduleProtocolVersion, rxMessage->data, sizeof(version_t));
|
||||
}
|
||||
status = kStatus_Uhk_NoTransfer;
|
||||
*uhkModulePhase = isMessageValid ? UhkModulePhase_RequestModuleId : UhkModulePhase_RequestProtocolVersion;
|
||||
status = kStatus_Uhk_IdleCycle;
|
||||
*uhkModulePhase = isMessageValid ? UhkModulePhase_RequestFirmwareVersion : UhkModulePhase_RequestModuleProtocolVersion;
|
||||
break;
|
||||
}
|
||||
|
||||
// Get firmware version
|
||||
case UhkModulePhase_RequestFirmwareVersion:
|
||||
txMessage.data[0] = SlaveCommand_RequestProperty;
|
||||
txMessage.data[1] = SlaveProperty_FirmwareVersion;
|
||||
txMessage.length = 2;
|
||||
status = tx(i2cAddress);
|
||||
*uhkModulePhase = UhkModulePhase_ReceiveFirmwareVersion;
|
||||
break;
|
||||
case UhkModulePhase_ReceiveFirmwareVersion:
|
||||
status = rx(rxMessage, i2cAddress);
|
||||
*uhkModulePhase = UhkModulePhase_ProcessFirmwareVersion;
|
||||
break;
|
||||
case UhkModulePhase_ProcessFirmwareVersion: {
|
||||
bool isMessageValid = CRC16_IsMessageValid(rxMessage);
|
||||
if (isMessageValid) {
|
||||
memcpy(&uhkModuleState->firmwareVersion, rxMessage->data, sizeof(version_t));
|
||||
}
|
||||
status = kStatus_Uhk_IdleCycle;
|
||||
*uhkModulePhase = isMessageValid ? UhkModulePhase_RequestModuleId : UhkModulePhase_RequestFirmwareVersion;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -137,30 +159,52 @@ status_t UhkModuleSlaveDriver_Update(uint8_t uhkModuleDriverId)
|
||||
if (isMessageValid) {
|
||||
uhkModuleState->moduleId = rxMessage->data[0];
|
||||
}
|
||||
status = kStatus_Uhk_NoTransfer;
|
||||
*uhkModulePhase = isMessageValid ? UhkModulePhase_RequestModuleFeatures : UhkModulePhase_RequestModuleId;
|
||||
status = kStatus_Uhk_IdleCycle;
|
||||
*uhkModulePhase = isMessageValid ? UhkModulePhase_RequestModuleKeyCount : UhkModulePhase_RequestModuleId;
|
||||
break;
|
||||
}
|
||||
|
||||
// Get module features
|
||||
case UhkModulePhase_RequestModuleFeatures:
|
||||
// Get module key count
|
||||
case UhkModulePhase_RequestModuleKeyCount:
|
||||
txMessage.data[0] = SlaveCommand_RequestProperty;
|
||||
txMessage.data[1] = SlaveProperty_Features;
|
||||
txMessage.data[1] = SlaveProperty_KeyCount;
|
||||
txMessage.length = 2;
|
||||
status = tx(i2cAddress);
|
||||
*uhkModulePhase = UhkModulePhase_ReceiveModuleFeatures;
|
||||
*uhkModulePhase = UhkModulePhase_ReceiveModuleKeyCount;
|
||||
break;
|
||||
case UhkModulePhase_ReceiveModuleFeatures:
|
||||
case UhkModulePhase_ReceiveModuleKeyCount:
|
||||
status = rx(rxMessage, i2cAddress);
|
||||
*uhkModulePhase = UhkModulePhase_ProcessModuleFeatures;
|
||||
*uhkModulePhase = UhkModulePhase_ProcessModuleKeyCount;
|
||||
break;
|
||||
case UhkModulePhase_ProcessModuleFeatures: {
|
||||
case UhkModulePhase_ProcessModuleKeyCount: {
|
||||
bool isMessageValid = CRC16_IsMessageValid(rxMessage);
|
||||
if (isMessageValid) {
|
||||
memcpy(&uhkModuleState->features, rxMessage->data, sizeof(uhk_module_features_t));
|
||||
uhkModuleState->keyCount = rxMessage->data[0];
|
||||
}
|
||||
status = kStatus_Uhk_NoTransfer;
|
||||
*uhkModulePhase = isMessageValid ? UhkModulePhase_RequestKeyStates : UhkModulePhase_RequestModuleFeatures;
|
||||
status = kStatus_Uhk_IdleCycle;
|
||||
*uhkModulePhase = isMessageValid ? UhkModulePhase_RequestModulePointerCount : UhkModulePhase_RequestModuleKeyCount;
|
||||
break;
|
||||
}
|
||||
|
||||
// Get module pointer count
|
||||
case UhkModulePhase_RequestModulePointerCount:
|
||||
txMessage.data[0] = SlaveCommand_RequestProperty;
|
||||
txMessage.data[1] = SlaveProperty_PointerCount;
|
||||
txMessage.length = 2;
|
||||
status = tx(i2cAddress);
|
||||
*uhkModulePhase = UhkModulePhase_ReceiveModulePointerCount;
|
||||
break;
|
||||
case UhkModulePhase_ReceiveModulePointerCount:
|
||||
status = rx(rxMessage, i2cAddress);
|
||||
*uhkModulePhase = UhkModulePhase_ProcessModulePointerCount;
|
||||
break;
|
||||
case UhkModulePhase_ProcessModulePointerCount: {
|
||||
bool isMessageValid = CRC16_IsMessageValid(rxMessage);
|
||||
if (isMessageValid) {
|
||||
uhkModuleState->pointerCount = rxMessage->data[0];
|
||||
}
|
||||
status = kStatus_Uhk_IdleCycle;
|
||||
*uhkModulePhase = isMessageValid ? UhkModulePhase_RequestKeyStates : UhkModulePhase_RequestModulePointerCount;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -178,19 +222,19 @@ status_t UhkModuleSlaveDriver_Update(uint8_t uhkModuleDriverId)
|
||||
case UhkModulePhase_ProcessKeystates:
|
||||
if (CRC16_IsMessageValid(rxMessage)) {
|
||||
uint8_t slotId = uhkModuleDriverId + 1;
|
||||
BoolBitsToBytes(rxMessage->data, keyStatesBuffer, uhkModuleState->features.keyCount);
|
||||
for (uint8_t keyId=0; keyId<uhkModuleState->features.keyCount; keyId++) {
|
||||
BoolBitsToBytes(rxMessage->data, keyStatesBuffer, uhkModuleState->keyCount);
|
||||
for (uint8_t keyId=0; keyId<uhkModuleState->keyCount; keyId++) {
|
||||
KeyStates[slotId][keyId].current = keyStatesBuffer[keyId];
|
||||
}
|
||||
}
|
||||
status = kStatus_Uhk_NoTransfer;
|
||||
status = kStatus_Uhk_IdleCycle;
|
||||
*uhkModulePhase = UhkModulePhase_SetTestLed;
|
||||
break;
|
||||
|
||||
// Set test LED
|
||||
case UhkModulePhase_SetTestLed:
|
||||
if (uhkModuleSourceVars->isTestLedOn == uhkModuleTargetVars->isTestLedOn) {
|
||||
status = kStatus_Uhk_NoTransfer;
|
||||
status = kStatus_Uhk_IdleCycle;
|
||||
} else {
|
||||
txMessage.data[0] = SlaveCommand_SetTestLed;
|
||||
txMessage.data[1] = uhkModuleSourceVars->isTestLedOn;
|
||||
@@ -204,7 +248,7 @@ status_t UhkModuleSlaveDriver_Update(uint8_t uhkModuleDriverId)
|
||||
// Set PWM brightness
|
||||
case UhkModulePhase_SetLedPwmBrightness:
|
||||
if (uhkModuleSourceVars->ledPwmBrightness == uhkModuleTargetVars->ledPwmBrightness) {
|
||||
status = kStatus_Uhk_NoTransfer;
|
||||
status = kStatus_Uhk_IdleCycle;
|
||||
} else {
|
||||
txMessage.data[0] = SlaveCommand_SetLedPwmBrightness;
|
||||
txMessage.data[1] = uhkModuleSourceVars->ledPwmBrightness;
|
||||
@@ -221,8 +265,10 @@ status_t UhkModuleSlaveDriver_Update(uint8_t uhkModuleDriverId)
|
||||
|
||||
void UhkModuleSlaveDriver_Disconnect(uint8_t uhkModuleDriverId)
|
||||
{
|
||||
#ifdef LED_DRIVERS_ENABLED
|
||||
if (uhkModuleDriverId == SlaveId_LeftKeyboardHalf) {
|
||||
Slaves[SlaveId_LeftLedDriver].isConnected = false;
|
||||
}
|
||||
UhkModuleStates[uhkModuleDriverId].moduleId = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
#include "fsl_common.h"
|
||||
#include "crc16.h"
|
||||
#include "versions.h"
|
||||
|
||||
// Macros:
|
||||
|
||||
@@ -29,19 +30,29 @@
|
||||
UhkModulePhase_ProcessSync,
|
||||
|
||||
// Get protocol version
|
||||
UhkModulePhase_RequestProtocolVersion,
|
||||
UhkModulePhase_ReceiveProtocolVersion,
|
||||
UhkModulePhase_ProcessProtocolVersion,
|
||||
UhkModulePhase_RequestModuleProtocolVersion,
|
||||
UhkModulePhase_ReceiveModuleProtocolVersion,
|
||||
UhkModulePhase_ProcessModuleProtocolVersion,
|
||||
|
||||
// Get firmware version
|
||||
UhkModulePhase_RequestFirmwareVersion,
|
||||
UhkModulePhase_ReceiveFirmwareVersion,
|
||||
UhkModulePhase_ProcessFirmwareVersion,
|
||||
|
||||
// Get module id
|
||||
UhkModulePhase_RequestModuleId,
|
||||
UhkModulePhase_ReceiveModuleId,
|
||||
UhkModulePhase_ProcessModuleId,
|
||||
|
||||
// Get module features
|
||||
UhkModulePhase_RequestModuleFeatures,
|
||||
UhkModulePhase_ReceiveModuleFeatures,
|
||||
UhkModulePhase_ProcessModuleFeatures,
|
||||
// Get module key count
|
||||
UhkModulePhase_RequestModuleKeyCount,
|
||||
UhkModulePhase_ReceiveModuleKeyCount,
|
||||
UhkModulePhase_ProcessModuleKeyCount,
|
||||
|
||||
// Get module key count
|
||||
UhkModulePhase_RequestModulePointerCount,
|
||||
UhkModulePhase_ReceiveModulePointerCount,
|
||||
UhkModulePhase_ProcessModulePointerCount,
|
||||
|
||||
// Get key states
|
||||
UhkModulePhase_RequestKeyStates,
|
||||
@@ -62,14 +73,16 @@
|
||||
|
||||
typedef struct {
|
||||
uint8_t moduleId;
|
||||
uint8_t protocolVersion;
|
||||
version_t moduleProtocolVersion;
|
||||
version_t firmwareVersion;
|
||||
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;
|
||||
uint8_t keyCount;
|
||||
uint8_t pointerCount;
|
||||
} uhk_module_state_t;
|
||||
|
||||
typedef struct {
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
#include "slave_drivers/kboot_driver.h"
|
||||
#include "i2c.h"
|
||||
#include "i2c_addresses.h"
|
||||
#include "config.h"
|
||||
#include "i2c_error_logger.h"
|
||||
|
||||
uint32_t I2cSlaveScheduler_Counter;
|
||||
|
||||
@@ -29,6 +31,7 @@ uhk_slave_t Slaves[] = {
|
||||
.update = UhkModuleSlaveDriver_Update,
|
||||
.perDriverId = UhkModuleDriverId_RightAddon,
|
||||
},
|
||||
#ifdef LED_DRIVERS_ENABLED
|
||||
{
|
||||
.init = LedSlaveDriver_Init,
|
||||
.update = LedSlaveDriver_Update,
|
||||
@@ -39,6 +42,7 @@ uhk_slave_t Slaves[] = {
|
||||
.update = LedSlaveDriver_Update,
|
||||
.perDriverId = LedDriverId_Left,
|
||||
},
|
||||
#endif
|
||||
{
|
||||
.init = KbootSlaveDriver_Init,
|
||||
.update = KbootSlaveDriver_Update,
|
||||
@@ -48,23 +52,27 @@ uhk_slave_t Slaves[] = {
|
||||
|
||||
static void slaveSchedulerCallback(I2C_Type *base, i2c_master_handle_t *handle, status_t previousStatus, void *userData)
|
||||
{
|
||||
bool isFirstIteration = true;
|
||||
bool isFirstCycle = true;
|
||||
bool isTransferScheduled = false;
|
||||
I2cSlaveScheduler_Counter++;
|
||||
|
||||
do {
|
||||
uhk_slave_t *previousSlave = Slaves + previousSlaveId;
|
||||
uhk_slave_t *currentSlave = Slaves + currentSlaveId;
|
||||
|
||||
if (isFirstCycle) {
|
||||
uhk_slave_t *previousSlave = Slaves + previousSlaveId;
|
||||
previousSlave->previousStatus = previousStatus;
|
||||
if (IS_STATUS_I2C_ERROR(previousStatus)) {
|
||||
LogI2cError(previousSlaveId, previousStatus);
|
||||
}
|
||||
|
||||
if (isFirstIteration) {
|
||||
bool wasPreviousSlaveConnected = previousSlave->isConnected;
|
||||
previousSlave->isConnected = previousStatus == kStatus_Success;
|
||||
if (wasPreviousSlaveConnected && !previousSlave->isConnected && previousSlave->disconnect) {
|
||||
previousSlave->disconnect(previousSlaveId);
|
||||
}
|
||||
isFirstIteration = false;
|
||||
|
||||
isFirstCycle = false;
|
||||
}
|
||||
|
||||
if (!currentSlave->isConnected) {
|
||||
@@ -72,18 +80,21 @@ static void slaveSchedulerCallback(I2C_Type *base, i2c_master_handle_t *handle,
|
||||
}
|
||||
|
||||
status_t currentStatus = currentSlave->update(currentSlave->perDriverId);
|
||||
isTransferScheduled = currentStatus != kStatus_Uhk_IdleSlave && currentStatus != kStatus_Uhk_NoTransfer;
|
||||
if (IS_STATUS_I2C_ERROR(currentStatus)) {
|
||||
LogI2cError(currentSlaveId, currentStatus);
|
||||
}
|
||||
isTransferScheduled = currentStatus != kStatus_Uhk_IdleSlave && currentStatus != kStatus_Uhk_IdleCycle;
|
||||
if (isTransferScheduled) {
|
||||
currentSlave->isConnected = true;
|
||||
}
|
||||
|
||||
if (currentStatus != kStatus_Uhk_NoTransfer) {
|
||||
if (currentStatus != kStatus_Uhk_IdleCycle) {
|
||||
previousSlaveId = currentSlaveId++;
|
||||
}
|
||||
|
||||
if (currentSlaveId >= (sizeof(Slaves) / sizeof(uhk_slave_t))) {
|
||||
if (currentSlaveId >= SLAVE_COUNT) {
|
||||
currentSlaveId = 0;
|
||||
}
|
||||
}
|
||||
|
||||
} while (!isTransferScheduled);
|
||||
}
|
||||
|
||||
@@ -92,7 +103,7 @@ void InitSlaveScheduler(void)
|
||||
previousSlaveId = 0;
|
||||
currentSlaveId = 0;
|
||||
|
||||
for (uint8_t i=0; i<sizeof(Slaves) / sizeof(uhk_slave_t); i++) {
|
||||
for (uint8_t i=0; i<SLAVE_COUNT; i++) {
|
||||
uhk_slave_t *currentSlave = Slaves + i;
|
||||
currentSlave->isConnected = false;
|
||||
}
|
||||
|
||||
@@ -4,6 +4,14 @@
|
||||
// Includes:
|
||||
|
||||
#include "fsl_common.h"
|
||||
#include "config.h"
|
||||
|
||||
// Macros:
|
||||
|
||||
#define SLAVE_COUNT (sizeof(Slaves) / sizeof(uhk_slave_t))
|
||||
#define MAX_SLAVE_COUNT 6
|
||||
#define IS_VALID_SLAVE_ID(slaveId) (0 <= slaveId && slaveId <= MAX_SLAVE_COUNT)
|
||||
#define IS_STATUS_I2C_ERROR(status) (kStatus_I2C_Busy <= status && status <= kStatus_I2C_Timeout)
|
||||
|
||||
// Typedefs:
|
||||
|
||||
@@ -11,8 +19,10 @@
|
||||
SlaveId_LeftKeyboardHalf,
|
||||
SlaveId_LeftAddon,
|
||||
SlaveId_RightAddon,
|
||||
#ifdef LED_DRIVERS_ENABLED
|
||||
SlaveId_RightLedDriver,
|
||||
SlaveId_LeftLedDriver,
|
||||
#endif
|
||||
SlaveId_KbootDriver,
|
||||
} slave_id_t;
|
||||
|
||||
@@ -30,12 +40,12 @@
|
||||
} uhk_slave_t;
|
||||
|
||||
typedef enum {
|
||||
kStatusGroup_Uhk = -1,
|
||||
kStatusGroup_Uhk = 200,
|
||||
} uhk_status_group_t;
|
||||
|
||||
typedef enum {
|
||||
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
|
||||
kStatus_Uhk_IdleCycle = MAKE_STATUS(kStatusGroup_Uhk, 1), // The same slave should be rescheduled
|
||||
} uhk_status_t;
|
||||
|
||||
// Variables:
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
// Macros:
|
||||
|
||||
#define SLOT_COUNT 4
|
||||
#define IS_VALID_SLAVE_SLOT(slotId) (SlotId_LeftKeyboardHalf <= (slotId) && (slotId) <= SlotId_RightModule)
|
||||
#define IS_VALID_MODULE_SLOT(slotId) (SlotId_LeftKeyboardHalf <= (slotId) && (slotId) <= SlotId_RightModule)
|
||||
|
||||
// Typedefs:
|
||||
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
#include "fsl_common.h"
|
||||
#include "usb_commands/usb_command_get_property.h"
|
||||
#include "usb_commands/usb_command_get_device_property.h"
|
||||
#include "usb_protocol_handler.h"
|
||||
#include "eeprom.h"
|
||||
#include "versions.h"
|
||||
#include "slave_drivers/kboot_driver.h"
|
||||
#include "i2c.h"
|
||||
#include "init_peripherals.h"
|
||||
#include "fsl_i2c.h"
|
||||
#include "timer.h"
|
||||
|
||||
version_t deviceProtocolVersion = {
|
||||
DEVICE_PROTOCOL_MAJOR_VERSION,
|
||||
@@ -41,7 +46,7 @@ version_t protocolVersions[] =
|
||||
|
||||
uint16_t configSizes[] = {HARDWARE_CONFIG_SIZE, USER_CONFIG_SIZE};
|
||||
|
||||
void UsbCommand_GetProperty(void)
|
||||
void UsbCommand_GetDeviceProperty(void)
|
||||
{
|
||||
uint8_t propertyId = GetUsbRxBufferUint8(1);
|
||||
|
||||
@@ -55,8 +60,19 @@ void UsbCommand_GetProperty(void)
|
||||
case DevicePropertyId_ConfigSizes:
|
||||
memcpy(GenericHidOutBuffer+1, (uint8_t*)&configSizes, sizeof(configSizes));
|
||||
break;
|
||||
case DevicePropertyId_CurrentKbootCommand:
|
||||
GenericHidOutBuffer[1] = KbootDriverState.command;
|
||||
break;
|
||||
case DevicePropertyId_I2cMainBusBaudRate:
|
||||
GenericHidOutBuffer[1] = I2C_MAIN_BUS_BASEADDR->F;
|
||||
SetUsbTxBufferUint32(2, I2cMainBusRequestedBaudRateBps);
|
||||
SetUsbTxBufferUint32(6, I2cMainBusActualBaudRateBps);
|
||||
break;
|
||||
case DevicePropertyId_Uptime:
|
||||
SetUsbTxBufferUint32(1, CurrentTime);
|
||||
break;
|
||||
default:
|
||||
SetUsbTxBufferUint8(0, UsbStatusCode_GetProperty_InvalidProperty);
|
||||
SetUsbTxBufferUint8(0, UsbStatusCode_GetDeviceProperty_InvalidProperty);
|
||||
break;
|
||||
}
|
||||
}
|
||||
23
right/src/usb_commands/usb_command_get_device_property.h
Normal file
23
right/src/usb_commands/usb_command_get_device_property.h
Normal file
@@ -0,0 +1,23 @@
|
||||
#ifndef __USB_COMMAND_GET_DEVICE_PROPERTY_H__
|
||||
#define __USB_COMMAND_GET_DEVICE_PROPERTY_H__
|
||||
|
||||
// Typedefs:
|
||||
|
||||
typedef enum {
|
||||
DevicePropertyId_DeviceProtocolVersion = 0,
|
||||
DevicePropertyId_ProtocolVersions = 1,
|
||||
DevicePropertyId_ConfigSizes = 2,
|
||||
DevicePropertyId_CurrentKbootCommand = 3,
|
||||
DevicePropertyId_I2cMainBusBaudRate = 4,
|
||||
DevicePropertyId_Uptime = 5,
|
||||
} device_property_t;
|
||||
|
||||
typedef enum {
|
||||
UsbStatusCode_GetDeviceProperty_InvalidProperty = 2,
|
||||
} usb_status_code_get_device_property_t;
|
||||
|
||||
// Functions:
|
||||
|
||||
void UsbCommand_GetDeviceProperty(void);
|
||||
|
||||
#endif
|
||||
@@ -1,5 +1,5 @@
|
||||
#include "fsl_common.h"
|
||||
#include "usb_commands/usb_command_get_keyboard_state.h"
|
||||
#include "usb_commands/usb_command_get_device_state.h"
|
||||
#include "usb_protocol_handler.h"
|
||||
#include "eeprom.h"
|
||||
#include "peripherals/merge_sensor.h"
|
||||
26
right/src/usb_commands/usb_command_get_module_property.c
Normal file
26
right/src/usb_commands/usb_command_get_module_property.c
Normal file
@@ -0,0 +1,26 @@
|
||||
#include "fsl_common.h"
|
||||
#include "usb_commands/usb_command_get_module_property.h"
|
||||
#include "usb_protocol_handler.h"
|
||||
#include "slot.h"
|
||||
#include "slave_drivers/uhk_module_driver.h"
|
||||
|
||||
void UsbCommand_GetModuleProperty()
|
||||
{
|
||||
slot_t slotId = GetUsbRxBufferUint8(1);
|
||||
|
||||
if (!IS_VALID_MODULE_SLOT(slotId)) {
|
||||
SetUsbTxBufferUint8(0, UsbStatusCode_GetModuleProperty_InvalidModuleSlotId);
|
||||
}
|
||||
|
||||
module_property_id_t modulePropertyId = GetUsbRxBufferUint8(2);
|
||||
switch (modulePropertyId) {
|
||||
case ModulePropertyId_VersionNumbers: {
|
||||
uint8_t moduleDriverId = SLOT_ID_TO_UHK_MODULE_DRIVER_ID(slotId);
|
||||
uhk_module_state_t *moduleState = UhkModuleStates + moduleDriverId;
|
||||
GenericHidOutBuffer[1] = moduleState->moduleId;
|
||||
memcpy(GenericHidOutBuffer + 2, &moduleState->moduleProtocolVersion, sizeof(version_t));
|
||||
memcpy(GenericHidOutBuffer + 8, &moduleState->firmwareVersion, sizeof(version_t));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
18
right/src/usb_commands/usb_command_get_module_property.h
Normal file
18
right/src/usb_commands/usb_command_get_module_property.h
Normal file
@@ -0,0 +1,18 @@
|
||||
#ifndef __USB_COMMAND_GET_MODULE_PROPERTY_H__
|
||||
#define __USB_COMMAND_GET_MODULE_PROPERTY_H__
|
||||
|
||||
// Functions:
|
||||
|
||||
void UsbCommand_GetModuleProperty();
|
||||
|
||||
// Typedefs:
|
||||
|
||||
typedef enum {
|
||||
ModulePropertyId_VersionNumbers = 0,
|
||||
} module_property_id_t;
|
||||
|
||||
typedef enum {
|
||||
UsbStatusCode_GetModuleProperty_InvalidModuleSlotId = 2,
|
||||
} usb_status_code_get_module_property_t;
|
||||
|
||||
#endif
|
||||
@@ -1,20 +0,0 @@
|
||||
#ifndef __USB_COMMAND_GET_PROPERTY_H__
|
||||
#define __USB_COMMAND_GET_PROPERTY_H__
|
||||
|
||||
// Typedefs:
|
||||
|
||||
typedef enum {
|
||||
DevicePropertyId_DeviceProtocolVersion = 0,
|
||||
DevicePropertyId_ProtocolVersions = 1,
|
||||
DevicePropertyId_ConfigSizes = 2,
|
||||
} system_property_t;
|
||||
|
||||
typedef enum {
|
||||
UsbStatusCode_GetProperty_InvalidProperty = 2,
|
||||
} usb_status_code_get_property_t;
|
||||
|
||||
// Functions:
|
||||
|
||||
void UsbCommand_GetProperty(void);
|
||||
|
||||
#endif
|
||||
19
right/src/usb_commands/usb_command_get_slave_i2c_errors.c
Normal file
19
right/src/usb_commands/usb_command_get_slave_i2c_errors.c
Normal file
@@ -0,0 +1,19 @@
|
||||
#include "fsl_common.h"
|
||||
#include "usb_commands/usb_command_get_slave_i2c_errors.h"
|
||||
#include "usb_protocol_handler.h"
|
||||
#include "slave_scheduler.h"
|
||||
#include "i2c_error_logger.h"
|
||||
|
||||
void UsbCommand_GetSlaveI2cErrors()
|
||||
{
|
||||
uint8_t slaveId = GetUsbRxBufferUint8(1);
|
||||
|
||||
if (!IS_VALID_SLAVE_ID(slaveId)) {
|
||||
SetUsbTxBufferUint8(0, UsbStatusCode_GetModuleProperty_InvalidSlaveId);
|
||||
}
|
||||
|
||||
i2c_slave_error_counter_t *i2cSlaveErrorCounter = I2cSlaveErrorCounters + slaveId;
|
||||
|
||||
GenericHidOutBuffer[1] = i2cSlaveErrorCounter->errorTypeCount;
|
||||
memcpy(GenericHidOutBuffer + 2, i2cSlaveErrorCounter->errors, sizeof(i2c_error_count_t) * MAX_LOGGED_I2C_ERROR_TYPES_PER_SLAVE);
|
||||
}
|
||||
14
right/src/usb_commands/usb_command_get_slave_i2c_errors.h
Normal file
14
right/src/usb_commands/usb_command_get_slave_i2c_errors.h
Normal file
@@ -0,0 +1,14 @@
|
||||
#ifndef __USB_COMMAND_GET_SLAVE_I2C_ERRORS_H__
|
||||
#define __USB_COMMAND_GET_SLAVE_I2C_ERRORS_H__
|
||||
|
||||
// Functions:
|
||||
|
||||
void UsbCommand_GetSlaveI2cErrors();
|
||||
|
||||
// Typedefs:
|
||||
|
||||
typedef enum {
|
||||
UsbStatusCode_GetModuleProperty_InvalidSlaveId = 2,
|
||||
} usb_status_code_get_slave_i2c_errors_t;
|
||||
|
||||
#endif
|
||||
@@ -7,7 +7,7 @@ void UsbCommand_JumpToModuleBootloader(void)
|
||||
{
|
||||
uint8_t slotId = GetUsbRxBufferUint8(1);
|
||||
|
||||
if (!IS_VALID_SLAVE_SLOT(slotId)) {
|
||||
if (!IS_VALID_MODULE_SLOT(slotId)) {
|
||||
SetUsbTxBufferUint8(0, UsbStatusCode_JumpToModuleBootloader_InvalidSlaveSlotId);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -6,5 +6,5 @@ void UsbCommand_SendKbootCommandToModule(void)
|
||||
{
|
||||
KbootDriverState.phase = 0;
|
||||
KbootDriverState.i2cAddress = GetUsbRxBufferUint8(2);
|
||||
KbootDriverState.commandType = GetUsbRxBufferUint8(1); // Command should be set last.
|
||||
KbootDriverState.command = GetUsbRxBufferUint8(1); // Command should be set last.
|
||||
}
|
||||
|
||||
11
right/src/usb_commands/usb_command_set_i2c_baud_rate.c
Normal file
11
right/src/usb_commands/usb_command_set_i2c_baud_rate.c
Normal file
@@ -0,0 +1,11 @@
|
||||
#include "usb_protocol_handler.h"
|
||||
#include "usb_commands/usb_command_set_i2c_baud_rate.h"
|
||||
#include "init_peripherals.h"
|
||||
#include "fsl_i2c.h"
|
||||
|
||||
void UsbCommand_SetI2cBaudRate(void)
|
||||
{
|
||||
uint32_t i2cBaudRate = GetUsbRxBufferUint32(1);
|
||||
I2cMainBusRequestedBaudRateBps = i2cBaudRate;
|
||||
ReinitI2cMainBus();
|
||||
}
|
||||
8
right/src/usb_commands/usb_command_set_i2c_baud_rate.h
Normal file
8
right/src/usb_commands/usb_command_set_i2c_baud_rate.h
Normal file
@@ -0,0 +1,8 @@
|
||||
#ifndef __USB_COMMAND_SET_I2C_BAUD_RATE__
|
||||
#define __USB_COMMAND_SET_I2C_BAUD_RATE__
|
||||
|
||||
// Functions:
|
||||
|
||||
void UsbCommand_SetI2cBaudRate(void);
|
||||
|
||||
#endif
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "usb_protocol_handler.h"
|
||||
#include "buffer.h"
|
||||
#include "usb_commands/usb_command_get_property.h"
|
||||
#include "usb_commands/usb_command_get_device_property.h"
|
||||
#include "usb_commands/usb_command_get_module_property.h"
|
||||
#include "usb_commands/usb_command_reenumerate.h"
|
||||
#include "usb_commands/usb_command_set_test_led.h"
|
||||
#include "usb_commands/usb_command_write_config.h"
|
||||
@@ -9,18 +10,20 @@
|
||||
#include "usb_commands/usb_command_get_adc_value.h"
|
||||
#include "usb_commands/usb_command_launch_eeprom_transfer.h"
|
||||
#include "usb_commands/usb_command_read_config.h"
|
||||
#include "usb_commands/usb_command_get_keyboard_state.h"
|
||||
#include "usb_commands/usb_command_get_device_state.h"
|
||||
#include "usb_commands/usb_command_get_debug_buffer.h"
|
||||
#include "usb_commands/usb_command_jump_to_module_bootloader.h"
|
||||
#include "usb_commands/usb_command_send_kboot_command_to_module.h"
|
||||
#include "usb_commands/usb_command_get_slave_i2c_errors.h"
|
||||
#include "usb_commands/usb_command_set_i2c_baud_rate.h"
|
||||
|
||||
void UsbProtocolHandler(void)
|
||||
{
|
||||
bzero(GenericHidOutBuffer, USB_GENERIC_HID_OUT_BUFFER_LENGTH);
|
||||
uint8_t command = GetUsbRxBufferUint8(0);
|
||||
switch (command) {
|
||||
case UsbCommandId_GetProperty:
|
||||
UsbCommand_GetProperty();
|
||||
case UsbCommandId_GetDeviceProperty:
|
||||
UsbCommand_GetDeviceProperty();
|
||||
break;
|
||||
case UsbCommandId_Reenumerate:
|
||||
UsbCommand_Reenumerate();
|
||||
@@ -61,6 +64,15 @@ void UsbProtocolHandler(void)
|
||||
case UsbCommandId_SetLedPwmBrightness:
|
||||
UsbCommand_SetLedPwmBrightness();
|
||||
break;
|
||||
case UsbCommandId_GetModuleProperty:
|
||||
UsbCommand_GetModuleProperty();
|
||||
break;
|
||||
case UsbCommandId_GetSlaveI2cErrors:
|
||||
UsbCommand_GetSlaveI2cErrors();
|
||||
break;
|
||||
case UsbCommandId_SetI2cBaudRate:
|
||||
UsbCommand_SetI2cBaudRate();
|
||||
break;
|
||||
default:
|
||||
SetUsbTxBufferUint8(0, UsbStatusCode_InvalidCommand);
|
||||
break;
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
// Typedefs:
|
||||
|
||||
typedef enum {
|
||||
UsbCommandId_GetProperty = 0x00,
|
||||
UsbCommandId_GetDeviceProperty = 0x00,
|
||||
|
||||
UsbCommandId_Reenumerate = 0x01,
|
||||
UsbCommandId_JumpToModuleBootloader = 0x02,
|
||||
@@ -30,6 +30,9 @@
|
||||
UsbCommandId_GetDebugBuffer = 0x0b,
|
||||
UsbCommandId_GetAdcValue = 0x0c,
|
||||
UsbCommandId_SetLedPwmBrightness = 0x0d,
|
||||
UsbCommandId_GetModuleProperty = 0x0e,
|
||||
UsbCommandId_GetSlaveI2cErrors = 0x0f,
|
||||
UsbCommandId_SetI2cBaudRate = 0x10,
|
||||
} usb_command_id_t;
|
||||
|
||||
typedef enum {
|
||||
|
||||
@@ -21,6 +21,7 @@ uint32_t UsbReportUpdateTime = 0;
|
||||
static uint32_t elapsedTime;
|
||||
|
||||
uint16_t DoubleTapSwitchLayerTimeout = 250;
|
||||
uint16_t DoubleTapSwitchLayerReleaseTimeout = 100;
|
||||
|
||||
static bool activeMouseStates[ACTIVE_MOUSE_STATES_COUNT];
|
||||
|
||||
@@ -191,11 +192,13 @@ static layer_id_t previousLayer = LayerId_Base;
|
||||
static uint8_t basicScancodeIndex = 0;
|
||||
static uint8_t mediaScancodeIndex = 0;
|
||||
static uint8_t systemScancodeIndex = 0;
|
||||
key_state_t *doubleTapSwitchLayerKey;
|
||||
uint32_t doubleTapSwitchLayerStartTime;
|
||||
|
||||
void applyKeyAction(key_state_t *keyState, key_action_t *action)
|
||||
{
|
||||
static key_state_t *doubleTapSwitchLayerKey;
|
||||
static uint32_t doubleTapSwitchLayerStartTime;
|
||||
static uint32_t doubleTapSwitchLayerTriggerTime;
|
||||
|
||||
if (keyState->suppressed) {
|
||||
return;
|
||||
}
|
||||
@@ -233,16 +236,20 @@ void applyKeyAction(key_state_t *keyState, key_action_t *action)
|
||||
activeMouseStates[action->mouseAction] = true;
|
||||
break;
|
||||
case KeyActionType_SwitchLayer:
|
||||
if (!keyState->previous && previousLayer == LayerId_Base && action->switchLayer.mode == SwitchLayerMode_HoldAndDoubleTapToggle) {
|
||||
if (doubleTapSwitchLayerKey) {
|
||||
if (Timer_GetElapsedTimeAndSetCurrent(&doubleTapSwitchLayerStartTime) < DoubleTapSwitchLayerTimeout) {
|
||||
ToggledLayer = action->switchLayer.layer;
|
||||
if (keyState->previous && doubleTapSwitchLayerKey == keyState &&
|
||||
Timer_GetElapsedTime(&doubleTapSwitchLayerTriggerTime) > DoubleTapSwitchLayerReleaseTimeout)
|
||||
{
|
||||
ToggledLayer = LayerId_Base;
|
||||
}
|
||||
doubleTapSwitchLayerKey = NULL;
|
||||
|
||||
if (!keyState->previous && previousLayer == LayerId_Base && action->switchLayer.mode == SwitchLayerMode_HoldAndDoubleTapToggle) {
|
||||
if (doubleTapSwitchLayerKey && Timer_GetElapsedTimeAndSetCurrent(&doubleTapSwitchLayerStartTime) < DoubleTapSwitchLayerTimeout) {
|
||||
ToggledLayer = action->switchLayer.layer;
|
||||
doubleTapSwitchLayerTriggerTime = CurrentTime;
|
||||
} else {
|
||||
doubleTapSwitchLayerKey = keyState;
|
||||
doubleTapSwitchLayerStartTime = CurrentTime;
|
||||
}
|
||||
doubleTapSwitchLayerStartTime = CurrentTime;
|
||||
}
|
||||
break;
|
||||
case KeyActionType_SwitchKeymap:
|
||||
|
||||
@@ -15,9 +15,9 @@
|
||||
"commander": "^2.11.0",
|
||||
"shelljs": "^0.7.8"
|
||||
},
|
||||
"firmwareVersion": "7.0.0",
|
||||
"deviceProtocolVersion": "4.0.0",
|
||||
"moduleProtocolVersion": "3.0.0",
|
||||
"firmwareVersion": "8.1.1",
|
||||
"deviceProtocolVersion": "4.2.0",
|
||||
"moduleProtocolVersion": "4.0.0",
|
||||
"userConfigVersion": "4.0.0",
|
||||
"hardwareConfigVersion": "1.0.0",
|
||||
"devices": [
|
||||
|
||||
@@ -27,9 +27,11 @@
|
||||
|
||||
typedef enum {
|
||||
SlaveProperty_Sync,
|
||||
SlaveProperty_ProtocolVersion,
|
||||
SlaveProperty_ModuleProtocolVersion,
|
||||
SlaveProperty_FirmwareVersion,
|
||||
SlaveProperty_ModuleId,
|
||||
SlaveProperty_Features,
|
||||
SlaveProperty_KeyCount,
|
||||
SlaveProperty_PointerCount,
|
||||
} slave_property_t;
|
||||
|
||||
typedef enum {
|
||||
@@ -40,11 +42,6 @@
|
||||
ModuleId_TouchpadRight = 5,
|
||||
} module_id_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t keyCount;
|
||||
bool hasPointer;
|
||||
} uhk_module_features_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t length;
|
||||
uint16_t crc;
|
||||
|
||||
@@ -18,15 +18,15 @@
|
||||
|
||||
// Variables:
|
||||
|
||||
#define FIRMWARE_MAJOR_VERSION 6
|
||||
#define FIRMWARE_MINOR_VERSION 0
|
||||
#define FIRMWARE_PATCH_VERSION 0
|
||||
#define FIRMWARE_MAJOR_VERSION 8
|
||||
#define FIRMWARE_MINOR_VERSION 1
|
||||
#define FIRMWARE_PATCH_VERSION 1
|
||||
|
||||
#define DEVICE_PROTOCOL_MAJOR_VERSION 3
|
||||
#define DEVICE_PROTOCOL_MINOR_VERSION 0
|
||||
#define DEVICE_PROTOCOL_MAJOR_VERSION 4
|
||||
#define DEVICE_PROTOCOL_MINOR_VERSION 2
|
||||
#define DEVICE_PROTOCOL_PATCH_VERSION 0
|
||||
|
||||
#define MODULE_PROTOCOL_MAJOR_VERSION 3
|
||||
#define MODULE_PROTOCOL_MAJOR_VERSION 4
|
||||
#define MODULE_PROTOCOL_MINOR_VERSION 0
|
||||
#define MODULE_PROTOCOL_PATCH_VERSION 0
|
||||
|
||||
|
||||
Reference in New Issue
Block a user