58 Commits

Author SHA1 Message Date
László Monda
56f7753afc Bump firmware version to 8.1.0 and update changelog, package.json, and versions.h 2018-01-15 10:35:22 +01:00
László Monda
a0803875c4 Make UsbCommand_GetModuleProperty() branch based on modulePropertyId 2018-01-15 00:04:22 +01:00
László Monda
f5716bdadc Rename some private functions in init_peripherals.c from upper to lower camel case. 2018-01-14 20:30:46 +01:00
László Monda
b76b3c0e4f Slow down main bus I2C baud rate to 30kHz when BusPal is on to make firmware transfer more robust. 2018-01-14 20:27:17 +01:00
László Monda
2661c3d909 Implement DevicePropertyId_Uptime 2018-01-14 18:32:18 +01:00
László Monda
c854e98d84 Implement DevicePropertyId_I2cMainBusBaudRate 2018-01-14 18:10:04 +01:00
László Monda
72d8e49717 Make UsbProtocolHandler() invoke UsbCommand_SetI2cBaudRate() when requested. 2018-01-13 19:54:48 +01:00
László Monda
0fd95b71b2 Add usb_command_set_i2c_baud_rate.[ch] 2018-01-13 03:54:06 +01:00
László Monda
4d83bc2e75 Add I2cMainBusBaudRateBps 2018-01-13 03:29:01 +01:00
László Monda
cf7b05ab72 Make InitI2cMainBus() private. 2018-01-13 03:21:12 +01:00
László Monda
055f1945d0 Include slave_scheduler.h from init_peripherals.c instead of i2c_watchdog.c which I forgot to do in the previous commit. 2018-01-13 03:19:24 +01:00
László Monda
fa4a3abf84 Extract ReinitI2cMainBus() 2018-01-13 03:14:42 +01:00
László Monda
96c7ccd758 Remove some dead code from PIT_I2C_WATCHDOG_HANDLER 2018-01-13 03:03:42 +01:00
László Monda
76d319ec19 Remove comment that says that 100 kHz works with a 20 meter long bridge cable. It was true for UART, not so much for I2C. 2018-01-11 23:44:59 +01:00
László Monda
aab0e8473f Enable left half I2C watchdog in reinit mode because it seems to improve things. 2018-01-11 23:43:34 +01:00
László Monda
4a4c471b9e Implement DevicePropertyId_CurrentKbootCommand 2018-01-10 02:58:31 +01:00
László Monda
fcd75b2af2 Use identifiers instead of the magic numbers of kboot_driver.[ch] 2018-01-06 21:21:36 +01:00
László Monda
f318c6872e Move the definition of previousSlave within the if (isFirstCycle) block. 2018-01-06 17:25:07 +01:00
László Monda
ae1240c103 Rename isFirstIteration to isFirstCycle and kStatus_Uhk_NoTransfer to kStatus_Uhk_IdleCycle. 2018-01-06 17:05:37 +01:00
László Monda
e75d366245 Update and log previous I2C status within the if (isFirstIteration) block. 2018-01-06 17:00:59 +01:00
László Monda
da20cdacc4 Only check currentSlaveId overrun after incrementing it. 2018-01-06 16:36:57 +01:00
László Monda
5a986d367e Only call LogI2cError() if the passed status is an actual I2C error, otherwise it slows the mouse pointer down. 2018-01-06 02:04:47 +01:00
László Monda
f6b66283a7 Only count I2C errors. 2018-01-06 01:37:58 +01:00
László Monda
6ad425cbf9 Log I2C error counts on a per slave and per error type basis and expose them via USB. 2018-01-05 03:23:48 +01:00
László Monda
33e501cd83 Add SLAVE_COUNT 2018-01-04 23:16:48 +01:00
László Monda
fa558abef3 Add LED_DRIVERS_ENABLED 2017-12-28 00:08:29 +01:00
László Monda
25a2b3af93 Convert tabs to spaces. 2017-12-27 17:21:28 +01:00
László Monda
43587c2e1f Define I2C_WATCHDOG_VALUE_REINIT and I2C_WATCHDOG_VALUE_REBOOT and make them work when assigned to I2C_WATCHDOG. 2017-12-27 17:07:04 +01:00
László Monda
c51542795f Bump version to 8.0.1 2017-12-25 23:16:27 +01:00
Erich Styger
7eb83173ed changed I2C watchdog timer implementation, as LPTMR was already used by key scanner 2017-12-25 17:15:41 +01:00
Erich Styger
5581dd26b5 fixed and enabled software watchdog timer 2017-12-24 12:06:46 +01:00
László Monda
1ac637af0f Rename the GetProperty command to GetDeviceProperty. 2017-12-23 16:11:47 +01:00
László Monda
36951d1a34 Minor cleanups regarding the previous rename. 2017-12-23 16:08:45 +01:00
László Monda
5190265a2c Rename get_module_properties.[ch] to get_module_property.[ch]. It seems that the header wasn't included in usb_protocol_handler.c possibly causing issues when using these commands. 2017-12-23 16:06:24 +01:00
László Monda
40bf252852 Bump version to 8.0.0. Update version numbers. Update changelog. 2017-12-15 04:03:51 +01:00
László Monda
85e92d21b4 Add new UsbCommand_GetModuleProperties() device protocol command. 2017-12-15 02:46:30 +01:00
László Monda
fd43e81e46 Query module key count and pointer count in separate messages instead of a combined message for better clarity. 2017-12-15 02:13:58 +01:00
László Monda
c994a97d03 Make the modules transfer their firmware version to the device. Fix the message length of the module protocol version. 2017-12-15 01:42:58 +01:00
László Monda
d59ba83d99 Make the modules transfer a module protocol version composed of a major, a minor and a patch number. 2017-12-15 01:28:13 +01:00
László Monda
c1b887cea8 Rename UhkModulePhase_*ProtocolVersion to UhkModulePhase_*ModuleProtocolVersion. 2017-12-15 01:16:27 +01:00
László Monda
bd53b73685 Rename usb_command_get_keyboard_state.[ch] to usb_command_get_device_state.[ch] 2017-12-14 23:10:13 +01:00
László Monda
beb7c3d4ee Forgot to update versions.h for the previous release. Updating now. 2017-12-14 23:08:34 +01:00
László Monda
17571a5feb Bump version to 7.0.0. Update changelog and package.json 2017-12-14 21:51:07 +01:00
László Monda
83e782d74a Remove DevicePropertyId_HardwareConfigSize and DevicePropertyId_UserConfigSize 2017-12-14 21:49:15 +01:00
László Monda
312f56048b Add DevicePropertyId_ConfigSizes. 2017-12-14 16:40:44 +01:00
László Monda
494621a841 Expose version numbers via the get property interface. 2017-12-14 16:16:11 +01:00
László Monda
94af52892c Add generate-versions-h.js and versions.h. Execute generate-versions-h.js from make-release.js 2017-12-14 15:41:20 +01:00
László Monda
5862a34f18 Use const instead of let wherever possible in make-release.js 2017-12-14 04:01:13 +01:00
László Monda
9b9e5ed1b5 Rename the version property to firmwareVersion in package.json 2017-12-14 03:52:56 +01:00
László Monda
4393377365 Rename version properties in package.json 2017-12-14 03:48:59 +01:00
László Monda
1570364741 Add hardware config versions to releases. 2017-12-14 03:38:24 +01:00
László Monda
738a240860 Rename slave protocol to module protocol. 2017-12-14 03:36:29 +01:00
László Monda
43b48aa643 Rename USB protocol to device protocol. 2017-12-14 03:25:47 +01:00
László Monda
61a0540007 Rename data model to user config. 2017-12-14 03:24:29 +01:00
László Monda
f2e313dd0a Put the data model version as the last element of the version list. 2017-12-14 03:22:04 +01:00
László Monda
b239d0da50 Mark bumped version numbers by making them bold. 2017-12-14 03:14:41 +01:00
László Monda
23459e3791 Don't make horizontal scrolling and vertical scrolling affect each other. 2017-12-14 01:30:06 +01:00
László Monda
6a54944cb1 Make UsbCommand_JumpToModuleBootloader() more robust by not making it dependent on the state of the module driver. 2017-12-13 01:27:04 +01:00
52 changed files with 769 additions and 283 deletions

View File

@@ -5,38 +5,74 @@ 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/) 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. and this project adheres to the [UHK Versioning](VERSIONING.md) conventions.
## [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
- Make UsbCommand_JumpToModuleBootloader() more robust by not making it dependent on the state of the module driver.
- Don't make horizontal scrolling and vertical scrolling affect each other.
- Expose version numbers via the get property interface. `DEVICEPROTOCOL:MINOR`
- Add DevicePropertyId_ConfigSizes. `DEVICEPROTOCOL:MINOR`
- Remove DevicePropertyId_HardwareConfigSize and DevicePropertyId_UserConfigSize. `DEVICEPROTOCOL:MAJOR`
## [6.0.0] - 2017-12-12 ## [6.0.0] - 2017-12-12
Data Model: 4.0.0 (unchanged) | USB Protocol: 3.0.0 (major bump) | Slave Protocol: 3.0.0 (unchanged) Device Protocol: **3.0.0** | Module Protocol: 3.0.0 | User Config: 4.0.0 | Hardware Config: 1.0.0
- Change the value of almost every USB protocol commands because there were unused intervals between them. `USBPROTOCOL:MAJOR` - Change the value of almost every Device Protocol commands because there were unused intervals between them. `DEVICEPROTOCOL:MAJOR`
- Disable LED display icons by default. - Disable LED display icons by default.
- Update LED brightness levels upon applying the configuration. - Update LED brightness levels upon applying the configuration.
## [5.0.1] - 2017-12-09 ## [5.0.1] - 2017-12-09
Data Model: 4.0.0 (unchanged) | USB Protocol: 2.0.0 (unchanged) | Slave Protocol: 3.0.0 (unchanged) Device Protocol: 2.0.0 | Module Protocol: 3.0.0 | User Config: 4.0.0 | Hardware Config: 1.0.0
- Make key presses continue to emit scancodes even if a USB interface (typically the mouse interface) is not polled by the host anymore. - Make key presses continue to emit scancodes even if a USB interface (typically the mouse interface) is not polled by the host anymore.
- Make scrolling always immediately react to keypresses regardless of the previous internal scroll state. - Make scrolling always immediately react to keypresses regardless of the previous internal scroll state.
## [5.0.0] - 2017-12-04 ## [5.0.0] - 2017-12-04
Data Model: 4.0.0 (major bump) | USB Protocol: 2.0.0 (unchanged) | Slave Protocol: 3.0.0 (unchanged) Device Protocol: 2.0.0 | Module Protocol: 3.0.0 | User Config: **4.0.0** | Hardware Config: 1.0.0
- Move pointerRole from keymaps to module configurations as pointerMode. Add angularShift, modLayerPointerFunction, fnLayerPointerFunction, and mouseLayerPointerFunction to module configurations. `DATAMODEL:MAJOR` - Move pointerRole from keymaps to module configurations as pointerMode. Add angularShift, modLayerPointerFunction, fnLayerPointerFunction, and mouseLayerPointerFunction to module configurations. `USERCONFIG:MAJOR`
## [4.0.0] - 2017-11-30 ## [4.0.0] - 2017-11-30
Data Model: 3.0.0 (major bump) | USB Protocol: 2.0.0 (unchanged) | Slave Protocol: 3.0.0 (unchanged) Device Protocol: 2.0.0 | Module Protocol: 3.0.0 | User Config: **3.0.0** | Hardware Config: 1.0.0
- Implement mouse movement and scrolling deceleration and acceleration. - Implement mouse movement and scrolling deceleration and acceleration.
- Toggle layers upon double tapping their keys. Make the double tap timeout configurable. - Toggle layers upon double tapping their keys. Make the double tap timeout configurable.
- Make the parser read additional user configuration properties: dataModelMajorVersion, dataModelMinorVersion, dataModelPatchVersion, doubleTapSwitchLayerTimeout, iconsAndLayerTextsBrightness, alphanumericSegmentsBrightness, keyBacklightBrightness, mouseMoveInitialSpeed, mouseMoveAcceleration, mouseMoveDeceleratedSpeed, mouseMoveBaseSpeed, mouseMoveAcceleratedSpeed, mouseScrollInitialSpeed, mouseScrollAcceleration, mouseScrollDeceleratedSpeed, mouseScrollBaseSpeed, mouseScrollAcceleratedSpeed. `DATAMODEL:MAJOR` - Make the parser read additional user configuration properties: USERCONFIGMajorVersion, USERCONFIGMinorVersion, USERCONFIGPatchVersion, doubleTapSwitchLayerTimeout, iconsAndLayerTextsBrightness, alphanumericSegmentsBrightness, keyBacklightBrightness, mouseMoveInitialSpeed, mouseMoveAcceleration, mouseMoveDeceleratedSpeed, mouseMoveBaseSpeed, mouseMoveAcceleratedSpeed, mouseScrollInitialSpeed, mouseScrollAcceleration, mouseScrollDeceleratedSpeed, mouseScrollBaseSpeed, mouseScrollAcceleratedSpeed. `USERCONFIG:MAJOR`
## [3.0.0] - 2017-11-15 ## [3.0.0] - 2017-11-15
Data Model: 2.0.0 (major bump) | USB Protocol: 2.0.0 (major bump) | Slave Protocol: 3.0.0 (major bump) Device Protocol: **2.0.0** | Module Protocol: **3.0.0** | User Config: **2.0.0** | Hardware Config: 1.0.0
- Detect the use of USB interfaces and only wait for the ones that are actually used by the host. - Detect the use of USB interfaces and only wait for the ones that are actually used by the host.
- Implement key debouncer. - Implement key debouncer.
@@ -44,49 +80,49 @@ Data Model: 2.0.0 (major bump) | USB Protocol: 2.0.0 (major bump) | Slave Protoc
- Make pressing the reset button revert to the factory preset. - Make pressing the reset button revert to the factory preset.
- Revert to the factory default state when the reset button is pressed upon firmware startup. Display FTY on the display in this case. - Revert to the factory default state when the reset button is pressed upon firmware startup. Display FTY on the display in this case.
- Make the LED display show the abbreviation of the current keymap even when it gets reinitialized by the I2C watchdog. - Make the LED display show the abbreviation of the current keymap even when it gets reinitialized by the I2C watchdog.
- Swap SlaveCommand_RequestKeyStates and SlaveCommand_JumpToBootloader, thereby making SlaveCommand_JumpToBootloader the lower number because it's more essential and shouldn't change in the future. `SLAVEPROTOCOL:MAJOR` - Swap SlaveCommand_RequestKeyStates and SlaveCommand_JumpToBootloader, thereby making SlaveCommand_JumpToBootloader the lower number because it's more essential and shouldn't change in the future. `MODULEPROTOCOL:MAJOR`
- Suppress pressed keys upon layer switcher key release. - Suppress pressed keys upon layer switcher key release.
- Handle secondary role modifiers and layer switchers. - Handle secondary role modifiers and layer switchers.
- Make UsbCommand_JumpToSlaveBootloader expect a slave slot id instead of a uhkModuleDriverId. `USBPROTOCOL:MAJOR` - Make UsbCommand_JumpToSlaveBootloader expect a slave slot id instead of a uhkModuleDriverId. `DEVICEPROTOCOL:MAJOR`
- Set UsbResponse_InvalidCommand upon encountering with an invalid USB command. `USBPROTOCOL:MINOR` - Set UsbResponse_InvalidCommand upon encountering with an invalid USB command. `DEVICEPROTOCOL:MINOR`
- Remove UsbCommandId_ReadMergeSensor now that it can be queried via UsbCommandId_GetKeyboardState. `USBPROTOCOL:MAJOR` - Remove UsbCommandId_ReadMergeSensor now that it can be queried via UsbCommandId_GetKeyboardState. `DEVICEPROTOCOL:MAJOR`
- Make the getAdcValue and getDebugInfo USB commands utilize the first byte of the response to provide status as dictated by the UHK protocol. `USBPROTOCOL:MAJOR` - Make the getAdcValue and getDebugInfo USB commands utilize the first byte of the response to provide status as dictated by the UHK protocol. `DEVICEPROTOCOL:MAJOR`
- Switch keymap only upon keypress. - Switch keymap only upon keypress.
- Handle layer toggle actions. - Handle layer toggle actions.
- Keep the active layer active even if another layer switcher key gets pressed while holding it. - Keep the active layer active even if another layer switcher key gets pressed while holding it.
- Read the new UserConfig.userConfigLength user config field. `DATAMODEL:MAJOR` - Read the new UserConfig.userConfigLength user config field. `USERCONFIG:MAJOR`
- Change Ctrl and Alt back according to the official UHK factory keymap. - Change Ctrl and Alt back according to the official UHK factory keymap.
- Update system keyboard HID descriptor which doesn't make the pointer go to the top left corner on OSX anymore. - Update system keyboard HID descriptor which doesn't make the pointer go to the top left corner on OSX anymore.
- Scan keyboard matrices in a more efficient manner from timer interrupts instead of the main loop. - Scan keyboard matrices in a more efficient manner from timer interrupts instead of the main loop.
- Add UsbCommand_SendKbootCommand. `USBPROTOCOL:MINOR` - Add UsbCommand_SendKbootCommand. `DEVICEPROTOCOL:MINOR`
- Make the reenumerate USB command accept a timeout value. `USBPROTOCOL:MINOR` - Make the reenumerate USB command accept a timeout value. `DEVICEPROTOCOL:MINOR`
- Make the config parser read the device name. `DATAMODEL:MAJOR` - Make the config parser read the device name. `USERCONFIG:MAJOR`
- Update release file format containing device and module directories and hex files instead of srec. - Update release file format containing device and module directories and hex files instead of srec.
- Remove obsolete ARM GCC build files. - Remove obsolete ARM GCC build files.
## [2.1.0] - 2017-10-13 ## [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) Device Protocol: 1.**2.0** | Module Protocol: 2.**1.0** | User Config: 1.0.0 | Hardware Config: 1.0.0
- Add jumpToSlaveBootloader USB and slave protocol command. `USBPROTOCOL:MINOR` `SLAVEPROTOCOL:MINOR` - Add jumpToSlaveBootloader USB and Module Protocol command. `DEVICEPROTOCOL:MINOR` `MODULEPROTOCOL:MINOR`
- Fix generic HID descriptor enumeration error. - Fix generic HID descriptor enumeration error.
## [2.0.0] - 2017-10-10 ## [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) Device Protocol: 1.**1.0** | Module Protocol: **2.0.0** | User Config: 1.0.0 | Hardware Config: 1.0.0
- Read the hardware and user configuration area of the EEPROM upon startup and set the default keymap. - 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. - 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` - Implement generic enumeration sequence and per-slave state for UHK modules, allowing add-ons to be added. `MODULEPROTOCOL:MAJOR`
- Make the master cache the output fields of slave modules, allowing for more frequent input updates. - 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. - 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 I2C message headers containing a length header, allowing for variable-length messages and a CRC16-CCITT checksum, allowing for robust communication. `MODULEPROTOCOL:MAJOR`
- Add mechanism to dump the internal state of the KL03 via SPI for debugging purposes. - 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` - Add merge sensor state and attached module IDs to GetDebugInfo(). `DEVICEPROTOCOL:PATCH`
- Throw ParserError_InvalidKeymapCount if keymapCount == 0. `DATAMODEL:PATCH` - Throw ParserError_InvalidKeymapCount if keymapCount == 0. `USERCONFIG:PATCH`
## [1.0.0] - 2017-08-30 ## [1.0.0] - 2017-08-30
Data Model: 1.0.0 | USB Protocol: 1.0.0 | Slave Protocol: 1.0.0 Device Protocol: 1.0.0 | Module Protocol: 1.0.0 | User Config: 1.0.0 | Hardware Config: 1.0.0
- First Release - First Release

View File

@@ -50,7 +50,7 @@
<intAttribute key="org.eclipse.cdt.debug.gdbjtag.core.portNumber" value="2331"/> <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.setPcRegister" value="false"/>
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setResume" 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.stopAt" value="main"/>
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.symbolsFileName" value=""/> <stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.symbolsFileName" value=""/>
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.symbolsOffset" value=""/> <stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.symbolsOffset" value=""/>
@@ -77,6 +77,6 @@
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES"> <listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
<listEntry value="4"/> <listEntry value="4"/>
</listAttribute> </listAttribute>
<stringAttribute key="org.eclipse.dsf.launch.MEMORY_BLOCKS" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;memoryBlockExpressionList context=&quot;Context string&quot;/&gt;&#10;"/> <stringAttribute key="org.eclipse.dsf.launch.MEMORY_BLOCKS" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;memoryBlockExpressionList context=&quot;Context string&quot;/&gt;&#13;&#10;"/>
<stringAttribute key="process_factory_id" value="org.eclipse.cdt.dsf.gdb.GdbProcessFactory"/> <stringAttribute key="process_factory_id" value="org.eclipse.cdt.dsf.gdb.GdbProcessFactory"/>
</launchConfiguration> </launchConfiguration>

View File

@@ -77,6 +77,6 @@
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES"> <listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
<listEntry value="4"/> <listEntry value="4"/>
</listAttribute> </listAttribute>
<stringAttribute key="org.eclipse.dsf.launch.MEMORY_BLOCKS" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;memoryBlockExpressionList context=&quot;Context string&quot;/&gt;&#10;"/> <stringAttribute key="org.eclipse.dsf.launch.MEMORY_BLOCKS" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;memoryBlockExpressionList context=&quot;Context string&quot;/&gt;&#13;&#10;"/>
<stringAttribute key="process_factory_id" value="org.eclipse.cdt.dsf.gdb.GdbProcessFactory"/> <stringAttribute key="process_factory_id" value="org.eclipse.cdt.dsf.gdb.GdbProcessFactory"/>
</launchConfiguration> </launchConfiguration>

View File

@@ -3,6 +3,11 @@
// Macros: // Macros:
#define I2C_WATCHDOG_VALUE_REINIT 1
#define I2C_WATCHDOG_VALUE_REBOOT 2
// #define DEBUG_OVER_SPI // #define DEBUG_OVER_SPI
#define I2C_WATCHDOG I2C_WATCHDOG_VALUE_REINIT
// #define I2C_WATCHDOG I2C_WATCHDOG_VALUE_REBOOT
#endif #endif

View File

@@ -3,36 +3,40 @@
#include "i2c_watchdog.h" #include "i2c_watchdog.h"
#include "test_led.h" #include "test_led.h"
#include "init_peripherals.h" #include "init_peripherals.h"
#include "config.h"
//static uint32_t prevWatchdogCounter = 0; /* NOTE: Because of a bug in the ROM bootloader of the KL03Z, the watchdog timer is disabled and cannot be re-enabled.
uint32_t I2cWatchdog_RecoveryCounter; * See https://community.nxp.com/thread/457893
volatile uint32_t I2cWatchdog_WatchCounter; * 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) void RunWatchdog(void)
{ {
lptmr_config_t lptmrConfig; static volatile uint32_t I2cWatchdog_WatchCounter = 0; /* counter for timer */
LPTMR_GetDefaultConfig(&lptmrConfig); static int cntr = 0;
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_WatchCounter++;
if (I2C_Watchdog == prevWatchdogCounter) { // Restart I2C if there hasn't been any interrupt during 100 ms cntr++;
// NVIC_SystemReset(); 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 */
I2cWatchdog_RecoveryCounter++; cntr=0;
I2C_SlaveDeinit(I2C_BUS_BASEADDR); TEST_LED_TOGGLE();
InitI2c(); I2cWatchdog_WatchCounter++;
if (I2cWatchdog_WatchCounter>10) { /* do not check within the first 1000 ms, as I2C might not be running yet */
if (I2C_Watchdog == prevWatchdogCounter) { // Restart I2C if there hasn't been any interrupt during 100 ms. I2C_Watchdog gets incremented for every I2C transaction
I2cWatchdog_RecoveryCounter++;
#if I2C_WATCHDOG == I2C_WATCHDOG_VALUE_REBOOT
NVIC_SystemReset();
#endif
#if I2C_WATCHDOG == I2C_WATCHDOG_VALUE_REINIT
I2C_SlaveDeinit(I2C_BUS_BASEADDR);
initI2c();
#endif
}
}
prevWatchdogCounter = I2C_Watchdog; /* remember previous counter */
} }
prevWatchdogCounter = I2C_Watchdog;
LPTMR_ClearStatusFlags(LPTMR0, kLPTMR_TimerCompareFlag);
} }
*/ #endif

View File

@@ -13,7 +13,6 @@
// Functions: // Functions:
void InitI2cWatchdog(void);
void RunWatchdog(void); void RunWatchdog(void);
#endif #endif

View File

@@ -10,6 +10,7 @@
#include "slave_protocol_handler.h" #include "slave_protocol_handler.h"
#include "i2c_watchdog.h" #include "i2c_watchdog.h"
#include "debug_over_spi.h" #include "debug_over_spi.h"
#include "main.h"
i2c_slave_config_t slaveConfig; i2c_slave_config_t slaveConfig;
i2c_slave_handle_t slaveHandle; 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(I2C0_IRQn, 1);
NVIC_SetPriority(TPM1_IRQn, 1); NVIC_SetPriority(TPM1_IRQn, 1);
NVIC_SetPriority(SPI0_IRQn, 1); NVIC_SetPriority(SPI0_IRQn, 1);
} }
void InitI2c(void) void initI2c(void)
{ {
port_pin_config_t pinConfig = { port_pin_config_t pinConfig = {
.pullSelect = kPORT_PullUp, .pullSelect = kPORT_PullUp,
@@ -81,11 +82,10 @@ void InitLedDriver(void)
void InitPeripherals(void) void InitPeripherals(void)
{ {
InitInterruptPriorities(); initInterruptPriorities();
InitLedDriver(); InitLedDriver();
InitTestLed(); InitTestLed();
LedPwm_Init(); LedPwm_Init();
// InitI2cWatchdog();
DebugOverSpi_Init(); DebugOverSpi_Init();
InitI2c(); initI2c();
} }

View File

@@ -11,6 +11,6 @@
// Functions: // Functions:
void InitPeripherals(void); void InitPeripherals(void);
void InitI2c(void); void initI2c(void);
#endif #endif

View File

@@ -1,10 +1,14 @@
#include "fsl_lptmr.h" #include "fsl_lptmr.h"
#include "key_scanner.h" #include "key_scanner.h"
#include "main.h" #include "config.h"
#include "i2c_watchdog.h"
void KEY_SCANNER_HANDLER(void) void KEY_SCANNER_HANDLER(void)
{ {
KeyMatrix_ScanRow(&keyMatrix); KeyMatrix_ScanRow(&keyMatrix);
#ifdef I2C_WATCHDOG
RunWatchdog();
#endif
LPTMR_ClearStatusFlags(KEY_SCANNER_LPTMR_BASEADDR, kLPTMR_TimerCompareFlag); LPTMR_ClearStatusFlags(KEY_SCANNER_LPTMR_BASEADDR, kLPTMR_TimerCompareFlag);
} }

View File

@@ -6,6 +6,6 @@
#define MODULE_PROTOCOL_VERSION 1 #define MODULE_PROTOCOL_VERSION 1
#define MODULE_ID ModuleId_LeftKeyboardHalf #define MODULE_ID ModuleId_LeftKeyboardHalf
#define MODULE_KEY_COUNT (KEYBOARD_MATRIX_ROWS_NUM * KEYBOARD_MATRIX_COLS_NUM) #define MODULE_KEY_COUNT (KEYBOARD_MATRIX_ROWS_NUM * KEYBOARD_MATRIX_COLS_NUM)
#define MODULE_HAS_POINTER false #define MODULE_POINTER_COUNT 0
#endif #endif

View File

@@ -10,10 +10,23 @@
#include "bool_array_converter.h" #include "bool_array_converter.h"
#include "bootloader.h" #include "bootloader.h"
#include "module.h" #include "module.h"
#include "versions.h"
i2c_message_t RxMessage; i2c_message_t RxMessage;
i2c_message_t TxMessage; 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) void SlaveRxHandler(void)
{ {
if (!CRC16_IsMessageValid(&RxMessage)) { if (!CRC16_IsMessageValid(&RxMessage)) {
@@ -51,21 +64,29 @@ void SlaveTxHandler(void)
TxMessage.length = SLAVE_SYNC_STRING_LENGTH; TxMessage.length = SLAVE_SYNC_STRING_LENGTH;
break; 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: { case SlaveProperty_ModuleId: {
TxMessage.data[0] = MODULE_ID; TxMessage.data[0] = MODULE_ID;
TxMessage.length = 1; TxMessage.length = 1;
break; break;
} }
case SlaveProperty_ProtocolVersion: { case SlaveProperty_KeyCount: {
TxMessage.data[0] = MODULE_PROTOCOL_VERSION; TxMessage.data[0] = MODULE_KEY_COUNT;
TxMessage.length = 1; TxMessage.length = 1;
break; break;
} }
case SlaveProperty_Features: { case SlaveProperty_PointerCount: {
uhk_module_features_t *moduleFeatures = (uhk_module_features_t*)&TxMessage.data; TxMessage.data[0] = MODULE_POINTER_COUNT;
moduleFeatures->keyCount = MODULE_KEY_COUNT; TxMessage.length = 1;
moduleFeatures->hasPointer = MODULE_HAS_POINTER;
TxMessage.length = sizeof(uhk_module_features_t);
break; break;
} }
} }

View File

@@ -64,10 +64,10 @@
<intAttribute key="org.eclipse.cdt.launch.ATTR_BUILD_BEFORE_LAUNCH_ATTR" value="2"/> <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.COREFILE_PATH" value=""/>
<stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_REGISTER_GROUPS" 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"/> <stringAttribute key="org.eclipse.cdt.launch.PROJECT_ATTR" value="uhk-right"/>
<booleanAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_AUTO_ATTR" value="false"/> <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"> <listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
<listEntry value="/uhk-right"/> <listEntry value="/uhk-right"/>
</listAttribute> </listAttribute>
@@ -77,6 +77,6 @@
<listAttribute key="org.eclipse.debug.ui.favoriteGroups"> <listAttribute key="org.eclipse.debug.ui.favoriteGroups">
<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/> <listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
</listAttribute> </listAttribute>
<stringAttribute key="org.eclipse.dsf.launch.MEMORY_BLOCKS" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;memoryBlockExpressionList context=&quot;Context string&quot;/&gt;&#10;"/> <stringAttribute key="org.eclipse.dsf.launch.MEMORY_BLOCKS" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;memoryBlockExpressionList context=&quot;Context string&quot;/&gt;&#13;&#10;"/>
<stringAttribute key="process_factory_id" value="org.eclipse.cdt.dsf.gdb.GdbProcessFactory"/> <stringAttribute key="process_factory_id" value="org.eclipse.cdt.dsf.gdb.GdbProcessFactory"/>
</launchConfiguration> </launchConfiguration>

View File

@@ -4,6 +4,7 @@
// Macros: // Macros:
#define I2C_WATCHDOG #define I2C_WATCHDOG
#define LED_DRIVERS_ENABLED
// #define LED_DRIVER_STRESS_TEST // #define LED_DRIVER_STRESS_TEST
#endif #endif

View File

@@ -8,6 +8,7 @@
#include "led_display.h" #include "led_display.h"
#include "slave_scheduler.h" #include "slave_scheduler.h"
#include "slave_drivers/is31fl3731_driver.h" #include "slave_drivers/is31fl3731_driver.h"
#include "config.h"
static parser_error_t parseModuleConfiguration(config_buffer_t *buffer) static parser_error_t parseModuleConfiguration(config_buffer_t *buffer)
{ {
@@ -142,9 +143,10 @@ parser_error_t ParseConfig(config_buffer_t *buffer)
IconsAndLayerTextsBrightness = iconsAndLayerTextsBrightness; IconsAndLayerTextsBrightness = iconsAndLayerTextsBrightness;
AlphanumericSegmentsBrightness = alphanumericSegmentsBrightness; AlphanumericSegmentsBrightness = alphanumericSegmentsBrightness;
KeyBacklightBrightness = keyBacklightBrightness; KeyBacklightBrightness = keyBacklightBrightness;
#ifdef LED_DRIVERS_ENABLED
Slaves[SlaveId_LeftLedDriver].isConnected = false; Slaves[SlaveId_LeftLedDriver].isConnected = false;
Slaves[SlaveId_RightLedDriver].isConnected = false; Slaves[SlaveId_RightLedDriver].isConnected = false;
#endif
// Update mouse key speeds // Update mouse key speeds
MouseMoveState.initialSpeed = mouseMoveInitialSpeed; MouseMoveState.initialSpeed = mouseMoveInitialSpeed;

View File

@@ -10,11 +10,12 @@
// Main bus // Main bus
#define I2C_MAIN_BUS_BASEADDR I2C0 #define I2C_MAIN_BUS_BASEADDR I2C0
#define I2C_MAIN_BUS_IRQ_ID I2C0_IRQn #define I2C_MAIN_BUS_IRQ_ID I2C0_IRQn
#define I2C_MAIN_BUS_CLK_SRC I2C0_CLK_SRC #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_MUX kPORT_MuxAlt7 #define I2C_MAIN_BUS_BUSPAL_BAUD_RATE 30000
#define I2C_MAIN_BUS_MUX kPORT_MuxAlt7
#define I2C_MAIN_BUS_SDA_GPIO GPIOD #define I2C_MAIN_BUS_SDA_GPIO GPIOD
#define I2C_MAIN_BUS_SDA_PORT PORTD #define I2C_MAIN_BUS_SDA_PORT PORTD

View 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;
}
}

View 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

View File

@@ -5,7 +5,6 @@
#include "fsl_gpio.h" #include "fsl_gpio.h"
#include "i2c.h" #include "i2c.h"
#include "i2c_watchdog.h" #include "i2c_watchdog.h"
#include "slave_scheduler.h"
#include "init_peripherals.h" #include "init_peripherals.h"
uint32_t I2cWatchdog_WatchCounter; uint32_t I2cWatchdog_WatchCounter;
@@ -19,17 +18,13 @@ static uint32_t prevWatchdogCounter;
void PIT_I2C_WATCHDOG_HANDLER(void) void PIT_I2C_WATCHDOG_HANDLER(void)
{ {
I2cWatchdog_WatchCounter++; I2cWatchdog_WatchCounter++;
if (I2C_Watchdog == prevWatchdogCounter) { // Restart I2C if there haven't been any interrupts recently if (I2C_Watchdog == prevWatchdogCounter) { // Restart I2C if there haven't been any interrupts recently
I2cWatchdog_RecoveryCounter++; I2cWatchdog_RecoveryCounter++;
i2c_master_config_t masterConfig; ReinitI2cMainBus();
I2C_MasterGetDefaultConfig(&masterConfig);
I2C_MasterDeinit(I2C_MAIN_BUS_BASEADDR);
InitI2cMainBus();
InitSlaveScheduler();
} }
prevWatchdogCounter = I2C_Watchdog; prevWatchdogCounter = I2C_Watchdog;
PIT_ClearStatusFlags(PIT, PIT_I2C_WATCHDOG_CHANNEL, PIT_TFLG_TIF_MASK); PIT_ClearStatusFlags(PIT, PIT_I2C_WATCHDOG_CHANNEL, PIT_TFLG_TIF_MASK);
} }

View File

@@ -14,8 +14,22 @@
#include "timer.h" #include "timer.h"
#include "key_debouncer.h" #include "key_debouncer.h"
#include "usb_api.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_I2C_WATCHDOG_IRQ_ID, 1);
NVIC_SetPriority(PIT_TIMER_IRQ_ID, 2); NVIC_SetPriority(PIT_TIMER_IRQ_ID, 2);
@@ -60,7 +74,7 @@ void recoverI2c(void)
delay(); delay();
} }
void InitI2cMainBus(void) void initI2cMainBus(void)
{ {
CLOCK_EnableClock(I2C_MAIN_BUS_SDA_CLOCK); CLOCK_EnableClock(I2C_MAIN_BUS_SDA_CLOCK);
CLOCK_EnableClock(I2C_MAIN_BUS_SCL_CLOCK); CLOCK_EnableClock(I2C_MAIN_BUS_SCL_CLOCK);
@@ -78,9 +92,17 @@ void InitI2cMainBus(void)
i2c_master_config_t masterConfig; i2c_master_config_t masterConfig;
I2C_MasterGetDefaultConfig(&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); uint32_t sourceClock = CLOCK_GetFreq(I2C_MAIN_BUS_CLK_SRC);
I2C_MasterInit(I2C_MAIN_BUS_BASEADDR, &masterConfig, sourceClock); 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) void initI2cEepromBus(void)
@@ -91,7 +113,6 @@ void initI2cEepromBus(void)
.mux = I2C_EEPROM_BUS_MUX, .mux = I2C_EEPROM_BUS_MUX,
}; };
CLOCK_EnableClock(I2C_EEPROM_BUS_SDA_CLOCK); CLOCK_EnableClock(I2C_EEPROM_BUS_SDA_CLOCK);
CLOCK_EnableClock(I2C_EEPROM_BUS_SCL_CLOCK); CLOCK_EnableClock(I2C_EEPROM_BUS_SCL_CLOCK);
@@ -105,21 +126,22 @@ void initI2cEepromBus(void)
I2C_MasterInit(I2C_EEPROM_BUS_BASEADDR, &masterConfig, sourceClock); I2C_MasterInit(I2C_EEPROM_BUS_BASEADDR, &masterConfig, sourceClock);
} }
void InitI2c(void) void initI2c(void)
{ {
InitI2cMainBus(); initI2cMainBus();
initI2cEepromBus(); initI2cEepromBus();
} }
void InitPeripherals(void) void InitPeripherals(void)
{ {
InitInterruptPriorities(); initBusPalState();
initInterruptPriorities();
Timer_Init(); Timer_Init();
InitLedDriver(); InitLedDriver();
InitResetButton(); InitResetButton();
InitMergeSensor(); InitMergeSensor();
ADC_Init(); ADC_Init();
InitI2c(); initI2c();
InitTestLed(); InitTestLed();
LedPwm_Init(); LedPwm_Init();
#ifdef I2C_WATCHDOG #ifdef I2C_WATCHDOG

View File

@@ -5,9 +5,15 @@
#include "fsl_common.h" #include "fsl_common.h"
// Variables:
extern bool IsBusPalOn;
extern uint32_t I2cMainBusRequestedBaudRateBps;
extern uint32_t I2cMainBusActualBaudRateBps;
// Functions: // Functions:
void InitPeripherals(void); void InitPeripherals(void);
void InitI2cMainBus(void); void ReinitI2cMainBus(void);
#endif #endif

View File

@@ -5,7 +5,6 @@
#include "slave_scheduler.h" #include "slave_scheduler.h"
#include "bus_pal_hardware.h" #include "bus_pal_hardware.h"
#include "command.h" #include "command.h"
#include "bootloader/wormhole.h"
#include "eeprom.h" #include "eeprom.h"
#include "key_scanner.h" #include "key_scanner.h"
#include "usb_commands/usb_command_apply_config.h" #include "usb_commands/usb_command_apply_config.h"
@@ -34,8 +33,7 @@ void main(void)
EEPROM_LaunchTransfer(EepromOperation_Read, ConfigBufferId_HardwareConfig, hardwareConfigurationReadFinished); EEPROM_LaunchTransfer(EepromOperation_Read, ConfigBufferId_HardwareConfig, hardwareConfigurationReadFinished);
} }
if (Wormhole.magicNumber == WORMHOLE_MAGIC_NUMBER && Wormhole.enumerationMode == EnumerationMode_BusPal) { if (IsBusPalOn) {
Wormhole.magicNumber = 0;
init_hardware(); init_hardware();
handleUsbBusPalCommand(); handleUsbBusPalCommand();
} else { } else {

View File

@@ -4,7 +4,7 @@
kboot_driver_state_t KbootDriverState; 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 pingCommand[] = {0x5a, 0xa6};
static uint8_t resetCommand[] = {0x5a, 0xa4, 0x04, 0x00, 0x6f, 0x46, 0x0b, 0x00, 0x00, 0x00}; static uint8_t resetCommand[] = {0x5a, 0xa4, 0x04, 0x00, 0x6f, 0x46, 0x0b, 0x00, 0x00, 0x00};
static uint8_t ackMessage[] = {0x5a, 0xa1}; static uint8_t ackMessage[] = {0x5a, 0xa1};
@@ -27,50 +27,52 @@ status_t KbootSlaveDriver_Update(uint8_t kbootInstanceId)
{ {
status_t status = kStatus_Uhk_IdleSlave; status_t status = kStatus_Uhk_IdleSlave;
switch (KbootDriverState.commandType) { switch (KbootDriverState.command) {
case KbootCommand_Idle: case KbootCommand_Idle:
break; break;
case KbootCommand_Ping: case KbootCommand_Ping:
switch (KbootDriverState.phase) { switch (KbootDriverState.phase) {
case 0: case KbootPhase_SendPing:
status = tx(pingCommand, sizeof(pingCommand)); status = tx(pingCommand, sizeof(pingCommand));
KbootDriverState.phase++; KbootDriverState.phase = KbootPhase_CheckPingStatus;
break; break;
case 1: case KbootPhase_CheckPingStatus:
KbootDriverState.status = Slaves[SlaveId_KbootDriver].previousStatus; KbootDriverState.status = Slaves[SlaveId_KbootDriver].previousStatus;
KbootDriverState.phase = KbootDriverState.status == kStatus_Success ? 2 : 0; KbootDriverState.phase = KbootDriverState.status == kStatus_Success
return kStatus_Uhk_NoTransfer; ? KbootPhase_ReceivePingResponse
case 2: : KbootPhase_SendPing;
status = rx(10); return kStatus_Uhk_IdleCycle;
KbootDriverState.phase++; case KbootPhase_ReceivePingResponse:
status = rx(KBOOT_PACKAGE_LENGTH_PING_RESPONSE);
KbootDriverState.phase = KbootPhase_CheckPingResponseStatus;
break; break;
case 3: case KbootPhase_CheckPingResponseStatus:
KbootDriverState.status = Slaves[SlaveId_KbootDriver].previousStatus; KbootDriverState.status = Slaves[SlaveId_KbootDriver].previousStatus;
if (KbootDriverState.status == kStatus_Success) { if (KbootDriverState.status == kStatus_Success) {
KbootDriverState.commandType = KbootCommand_Idle; KbootDriverState.command = KbootCommand_Idle;
} else { } else {
KbootDriverState.phase = 0; KbootDriverState.phase = KbootPhase_SendPing;
return kStatus_Uhk_NoTransfer; return kStatus_Uhk_IdleCycle;
} }
} }
break; break;
case KbootCommand_Reset: case KbootCommand_Reset:
switch (KbootDriverState.phase) { switch (KbootDriverState.phase) {
case 0: case KbootPhase_SendReset:
status = tx(resetCommand, sizeof(resetCommand)); status = tx(resetCommand, sizeof(resetCommand));
KbootDriverState.phase++; KbootDriverState.phase = KbootPhase_ReceiveResetAck;
break; break;
case 1: case KbootPhase_ReceiveResetAck:
status = rx(2); status = rx(KBOOT_PACKAGE_LENGTH_ACK);
KbootDriverState.phase++; KbootDriverState.phase = KbootPhase_ReceiveResetGenericResponse;
break; break;
case 2: case KbootPhase_ReceiveResetGenericResponse:
status = rx(18); status = rx(KBOOT_PACKAGE_LENGTH_GENERIC_RESPONSE);
KbootDriverState.phase++; KbootDriverState.phase = KbootPhase_CheckResetSendAck;
break; break;
case 3: case KbootPhase_CheckResetSendAck:
status = tx(ackMessage, sizeof(ackMessage)); status = tx(ackMessage, sizeof(ackMessage));
KbootDriverState.commandType = KbootCommand_Idle; KbootDriverState.command = KbootCommand_Idle;
break; break;
} }
break; break;

View File

@@ -7,7 +7,10 @@
// Macros: // 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: // Typedefs:
@@ -21,8 +24,22 @@
KbootCommand_Reset, KbootCommand_Reset,
} kboot_command_t; } 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 { typedef struct {
kboot_command_t commandType; kboot_command_t command;
uint8_t i2cAddress; uint8_t i2cAddress;
uint8_t phase; uint8_t phase;
uint32_t status; uint32_t status;

View File

@@ -69,6 +69,13 @@ status_t UhkModuleSlaveDriver_Update(uint8_t uhkModuleDriverId)
switch (*uhkModulePhase) { switch (*uhkModulePhase) {
// Jump to bootloader
case UhkModulePhase_JumpToBootloader:
txMessage.data[0] = SlaveCommand_JumpToBootloader;
txMessage.length = 1;
status = tx(i2cAddress);
break;
// Sync communication // Sync communication
case UhkModulePhase_RequestSync: case UhkModulePhase_RequestSync:
txMessage.data[0] = SlaveCommand_RequestProperty; txMessage.data[0] = SlaveCommand_RequestProperty;
@@ -84,32 +91,54 @@ status_t UhkModuleSlaveDriver_Update(uint8_t uhkModuleDriverId)
case UhkModulePhase_ProcessSync: { case UhkModulePhase_ProcessSync: {
bool isMessageValid = CRC16_IsMessageValid(rxMessage); bool isMessageValid = CRC16_IsMessageValid(rxMessage);
bool isSyncValid = memcmp(rxMessage->data, SlaveSyncString, SLAVE_SYNC_STRING_LENGTH) == 0; bool isSyncValid = memcmp(rxMessage->data, SlaveSyncString, SLAVE_SYNC_STRING_LENGTH) == 0;
status = kStatus_Uhk_NoTransfer; status = kStatus_Uhk_IdleCycle;
*uhkModulePhase = isSyncValid && isMessageValid *uhkModulePhase = isSyncValid && isMessageValid
? UhkModulePhase_RequestProtocolVersion ? UhkModulePhase_RequestModuleProtocolVersion
: UhkModulePhase_RequestSync; : UhkModulePhase_RequestSync;
break; break;
} }
// Get protocol version // Get module protocol version
case UhkModulePhase_RequestProtocolVersion: case UhkModulePhase_RequestModuleProtocolVersion:
txMessage.data[0] = SlaveCommand_RequestProperty; txMessage.data[0] = SlaveCommand_RequestProperty;
txMessage.data[1] = SlaveProperty_ProtocolVersion; txMessage.data[1] = SlaveProperty_ModuleProtocolVersion;
txMessage.length = 2; txMessage.length = 2;
status = tx(i2cAddress); status = tx(i2cAddress);
*uhkModulePhase = UhkModulePhase_ReceiveProtocolVersion; *uhkModulePhase = UhkModulePhase_ReceiveModuleProtocolVersion;
break; break;
case UhkModulePhase_ReceiveProtocolVersion: case UhkModulePhase_ReceiveModuleProtocolVersion:
status = rx(rxMessage, i2cAddress); status = rx(rxMessage, i2cAddress);
*uhkModulePhase = UhkModulePhase_ProcessProtocolVersion; *uhkModulePhase = UhkModulePhase_ProcessModuleProtocolVersion;
break; break;
case UhkModulePhase_ProcessProtocolVersion: { case UhkModulePhase_ProcessModuleProtocolVersion: {
bool isMessageValid = CRC16_IsMessageValid(rxMessage); bool isMessageValid = CRC16_IsMessageValid(rxMessage);
if (isMessageValid) { if (isMessageValid) {
uhkModuleState->protocolVersion = rxMessage->data[0]; memcpy(&uhkModuleState->moduleProtocolVersion, rxMessage->data, sizeof(version_t));
} }
status = kStatus_Uhk_NoTransfer; status = kStatus_Uhk_IdleCycle;
*uhkModulePhase = isMessageValid ? UhkModulePhase_RequestModuleId : UhkModulePhase_RequestProtocolVersion; *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; break;
} }
@@ -130,30 +159,52 @@ status_t UhkModuleSlaveDriver_Update(uint8_t uhkModuleDriverId)
if (isMessageValid) { if (isMessageValid) {
uhkModuleState->moduleId = rxMessage->data[0]; uhkModuleState->moduleId = rxMessage->data[0];
} }
status = kStatus_Uhk_NoTransfer; status = kStatus_Uhk_IdleCycle;
*uhkModulePhase = isMessageValid ? UhkModulePhase_RequestModuleFeatures : UhkModulePhase_RequestModuleId; *uhkModulePhase = isMessageValid ? UhkModulePhase_RequestModuleKeyCount : UhkModulePhase_RequestModuleId;
break; break;
} }
// Get module features // Get module key count
case UhkModulePhase_RequestModuleFeatures: case UhkModulePhase_RequestModuleKeyCount:
txMessage.data[0] = SlaveCommand_RequestProperty; txMessage.data[0] = SlaveCommand_RequestProperty;
txMessage.data[1] = SlaveProperty_Features; txMessage.data[1] = SlaveProperty_KeyCount;
txMessage.length = 2; txMessage.length = 2;
status = tx(i2cAddress); status = tx(i2cAddress);
*uhkModulePhase = UhkModulePhase_ReceiveModuleFeatures; *uhkModulePhase = UhkModulePhase_ReceiveModuleKeyCount;
break; break;
case UhkModulePhase_ReceiveModuleFeatures: case UhkModulePhase_ReceiveModuleKeyCount:
status = rx(rxMessage, i2cAddress); status = rx(rxMessage, i2cAddress);
*uhkModulePhase = UhkModulePhase_ProcessModuleFeatures; *uhkModulePhase = UhkModulePhase_ProcessModuleKeyCount;
break; break;
case UhkModulePhase_ProcessModuleFeatures: { case UhkModulePhase_ProcessModuleKeyCount: {
bool isMessageValid = CRC16_IsMessageValid(rxMessage); bool isMessageValid = CRC16_IsMessageValid(rxMessage);
if (isMessageValid) { if (isMessageValid) {
memcpy(&uhkModuleState->features, rxMessage->data, sizeof(uhk_module_features_t)); uhkModuleState->keyCount = rxMessage->data[0];
} }
status = kStatus_Uhk_NoTransfer; status = kStatus_Uhk_IdleCycle;
*uhkModulePhase = isMessageValid ? UhkModulePhase_RequestKeyStates : UhkModulePhase_RequestModuleFeatures; *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; break;
} }
@@ -171,32 +222,19 @@ status_t UhkModuleSlaveDriver_Update(uint8_t uhkModuleDriverId)
case UhkModulePhase_ProcessKeystates: case UhkModulePhase_ProcessKeystates:
if (CRC16_IsMessageValid(rxMessage)) { if (CRC16_IsMessageValid(rxMessage)) {
uint8_t slotId = uhkModuleDriverId + 1; uint8_t slotId = uhkModuleDriverId + 1;
BoolBitsToBytes(rxMessage->data, keyStatesBuffer, uhkModuleState->features.keyCount); BoolBitsToBytes(rxMessage->data, keyStatesBuffer, uhkModuleState->keyCount);
for (uint8_t keyId=0; keyId<uhkModuleState->features.keyCount; keyId++) { for (uint8_t keyId=0; keyId<uhkModuleState->keyCount; keyId++) {
KeyStates[slotId][keyId].current = keyStatesBuffer[keyId]; KeyStates[slotId][keyId].current = keyStatesBuffer[keyId];
} }
} }
status = kStatus_Uhk_NoTransfer; status = kStatus_Uhk_IdleCycle;
*uhkModulePhase = UhkModulePhase_JumpToBootloader;
break;
// 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; *uhkModulePhase = UhkModulePhase_SetTestLed;
break; break;
// Set test LED // Set test LED
case UhkModulePhase_SetTestLed: case UhkModulePhase_SetTestLed:
if (uhkModuleSourceVars->isTestLedOn == uhkModuleTargetVars->isTestLedOn) { if (uhkModuleSourceVars->isTestLedOn == uhkModuleTargetVars->isTestLedOn) {
status = kStatus_Uhk_NoTransfer; status = kStatus_Uhk_IdleCycle;
} else { } else {
txMessage.data[0] = SlaveCommand_SetTestLed; txMessage.data[0] = SlaveCommand_SetTestLed;
txMessage.data[1] = uhkModuleSourceVars->isTestLedOn; txMessage.data[1] = uhkModuleSourceVars->isTestLedOn;
@@ -210,7 +248,7 @@ status_t UhkModuleSlaveDriver_Update(uint8_t uhkModuleDriverId)
// Set PWM brightness // Set PWM brightness
case UhkModulePhase_SetLedPwmBrightness: case UhkModulePhase_SetLedPwmBrightness:
if (uhkModuleSourceVars->ledPwmBrightness == uhkModuleTargetVars->ledPwmBrightness) { if (uhkModuleSourceVars->ledPwmBrightness == uhkModuleTargetVars->ledPwmBrightness) {
status = kStatus_Uhk_NoTransfer; status = kStatus_Uhk_IdleCycle;
} else { } else {
txMessage.data[0] = SlaveCommand_SetLedPwmBrightness; txMessage.data[0] = SlaveCommand_SetLedPwmBrightness;
txMessage.data[1] = uhkModuleSourceVars->ledPwmBrightness; txMessage.data[1] = uhkModuleSourceVars->ledPwmBrightness;
@@ -227,8 +265,10 @@ status_t UhkModuleSlaveDriver_Update(uint8_t uhkModuleDriverId)
void UhkModuleSlaveDriver_Disconnect(uint8_t uhkModuleDriverId) void UhkModuleSlaveDriver_Disconnect(uint8_t uhkModuleDriverId)
{ {
#ifdef LED_DRIVERS_ENABLED
if (uhkModuleDriverId == SlaveId_LeftKeyboardHalf) { if (uhkModuleDriverId == SlaveId_LeftKeyboardHalf) {
Slaves[SlaveId_LeftLedDriver].isConnected = false; Slaves[SlaveId_LeftLedDriver].isConnected = false;
} }
UhkModuleStates[uhkModuleDriverId].moduleId = 0; UhkModuleStates[uhkModuleDriverId].moduleId = 0;
#endif
} }

View File

@@ -5,6 +5,7 @@
#include "fsl_common.h" #include "fsl_common.h"
#include "crc16.h" #include "crc16.h"
#include "versions.h"
// Macros: // Macros:
@@ -29,19 +30,29 @@
UhkModulePhase_ProcessSync, UhkModulePhase_ProcessSync,
// Get protocol version // Get protocol version
UhkModulePhase_RequestProtocolVersion, UhkModulePhase_RequestModuleProtocolVersion,
UhkModulePhase_ReceiveProtocolVersion, UhkModulePhase_ReceiveModuleProtocolVersion,
UhkModulePhase_ProcessProtocolVersion, UhkModulePhase_ProcessModuleProtocolVersion,
// Get firmware version
UhkModulePhase_RequestFirmwareVersion,
UhkModulePhase_ReceiveFirmwareVersion,
UhkModulePhase_ProcessFirmwareVersion,
// Get module id // Get module id
UhkModulePhase_RequestModuleId, UhkModulePhase_RequestModuleId,
UhkModulePhase_ReceiveModuleId, UhkModulePhase_ReceiveModuleId,
UhkModulePhase_ProcessModuleId, UhkModulePhase_ProcessModuleId,
// Get module features // Get module key count
UhkModulePhase_RequestModuleFeatures, UhkModulePhase_RequestModuleKeyCount,
UhkModulePhase_ReceiveModuleFeatures, UhkModulePhase_ReceiveModuleKeyCount,
UhkModulePhase_ProcessModuleFeatures, UhkModulePhase_ProcessModuleKeyCount,
// Get module key count
UhkModulePhase_RequestModulePointerCount,
UhkModulePhase_ReceiveModulePointerCount,
UhkModulePhase_ProcessModulePointerCount,
// Get key states // Get key states
UhkModulePhase_RequestKeyStates, UhkModulePhase_RequestKeyStates,
@@ -49,9 +60,9 @@
UhkModulePhase_ProcessKeystates, UhkModulePhase_ProcessKeystates,
// Misc phases // Misc phases
UhkModulePhase_JumpToBootloader,
UhkModulePhase_SetTestLed, UhkModulePhase_SetTestLed,
UhkModulePhase_SetLedPwmBrightness, UhkModulePhase_SetLedPwmBrightness,
UhkModulePhase_JumpToBootloader,
} uhk_module_phase_t; } uhk_module_phase_t;
@@ -62,15 +73,16 @@
typedef struct { typedef struct {
uint8_t moduleId; uint8_t moduleId;
uint8_t protocolVersion; version_t moduleProtocolVersion;
version_t firmwareVersion;
uhk_module_phase_t phase; uhk_module_phase_t phase;
uhk_module_vars_t sourceVars; uhk_module_vars_t sourceVars;
uhk_module_vars_t targetVars; uhk_module_vars_t targetVars;
i2c_message_t rxMessage; i2c_message_t rxMessage;
uint8_t firmwareI2cAddress; uint8_t firmwareI2cAddress;
uint8_t bootloaderI2cAddress; uint8_t bootloaderI2cAddress;
uhk_module_features_t features; uint8_t keyCount;
bool jumpToBootloader; uint8_t pointerCount;
} uhk_module_state_t; } uhk_module_state_t;
typedef struct { typedef struct {

View File

@@ -6,6 +6,8 @@
#include "slave_drivers/kboot_driver.h" #include "slave_drivers/kboot_driver.h"
#include "i2c.h" #include "i2c.h"
#include "i2c_addresses.h" #include "i2c_addresses.h"
#include "config.h"
#include "i2c_error_logger.h"
uint32_t I2cSlaveScheduler_Counter; uint32_t I2cSlaveScheduler_Counter;
@@ -29,6 +31,7 @@ uhk_slave_t Slaves[] = {
.update = UhkModuleSlaveDriver_Update, .update = UhkModuleSlaveDriver_Update,
.perDriverId = UhkModuleDriverId_RightAddon, .perDriverId = UhkModuleDriverId_RightAddon,
}, },
#ifdef LED_DRIVERS_ENABLED
{ {
.init = LedSlaveDriver_Init, .init = LedSlaveDriver_Init,
.update = LedSlaveDriver_Update, .update = LedSlaveDriver_Update,
@@ -39,6 +42,7 @@ uhk_slave_t Slaves[] = {
.update = LedSlaveDriver_Update, .update = LedSlaveDriver_Update,
.perDriverId = LedDriverId_Left, .perDriverId = LedDriverId_Left,
}, },
#endif
{ {
.init = KbootSlaveDriver_Init, .init = KbootSlaveDriver_Init,
.update = KbootSlaveDriver_Update, .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) 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; bool isTransferScheduled = false;
I2cSlaveScheduler_Counter++; I2cSlaveScheduler_Counter++;
do { do {
uhk_slave_t *previousSlave = Slaves + previousSlaveId;
uhk_slave_t *currentSlave = Slaves + currentSlaveId; uhk_slave_t *currentSlave = Slaves + currentSlaveId;
previousSlave->previousStatus = previousStatus; 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; bool wasPreviousSlaveConnected = previousSlave->isConnected;
previousSlave->isConnected = previousStatus == kStatus_Success; previousSlave->isConnected = previousStatus == kStatus_Success;
if (wasPreviousSlaveConnected && !previousSlave->isConnected && previousSlave->disconnect) { if (wasPreviousSlaveConnected && !previousSlave->isConnected && previousSlave->disconnect) {
previousSlave->disconnect(previousSlaveId); previousSlave->disconnect(previousSlaveId);
} }
isFirstIteration = false;
isFirstCycle = false;
} }
if (!currentSlave->isConnected) { 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); 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) { if (isTransferScheduled) {
currentSlave->isConnected = true; currentSlave->isConnected = true;
} }
if (currentStatus != kStatus_Uhk_NoTransfer) { if (currentStatus != kStatus_Uhk_IdleCycle) {
previousSlaveId = currentSlaveId++; previousSlaveId = currentSlaveId++;
if (currentSlaveId >= SLAVE_COUNT) {
currentSlaveId = 0;
}
} }
if (currentSlaveId >= (sizeof(Slaves) / sizeof(uhk_slave_t))) {
currentSlaveId = 0;
}
} while (!isTransferScheduled); } while (!isTransferScheduled);
} }
@@ -92,7 +103,7 @@ void InitSlaveScheduler(void)
previousSlaveId = 0; previousSlaveId = 0;
currentSlaveId = 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; uhk_slave_t *currentSlave = Slaves + i;
currentSlave->isConnected = false; currentSlave->isConnected = false;
} }

View File

@@ -4,6 +4,14 @@
// Includes: // Includes:
#include "fsl_common.h" #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: // Typedefs:
@@ -11,8 +19,10 @@
SlaveId_LeftKeyboardHalf, SlaveId_LeftKeyboardHalf,
SlaveId_LeftAddon, SlaveId_LeftAddon,
SlaveId_RightAddon, SlaveId_RightAddon,
#ifdef LED_DRIVERS_ENABLED
SlaveId_RightLedDriver, SlaveId_RightLedDriver,
SlaveId_LeftLedDriver, SlaveId_LeftLedDriver,
#endif
SlaveId_KbootDriver, SlaveId_KbootDriver,
} slave_id_t; } slave_id_t;
@@ -30,12 +40,12 @@
} uhk_slave_t; } uhk_slave_t;
typedef enum { typedef enum {
kStatusGroup_Uhk = -1, kStatusGroup_Uhk = 200,
} uhk_status_group_t; } uhk_status_group_t;
typedef enum { typedef enum {
kStatus_Uhk_IdleSlave = MAKE_STATUS(kStatusGroup_Uhk, 0), // Another slave should be scheduled 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; } uhk_status_t;
// Variables: // Variables:

View File

@@ -13,7 +13,7 @@
// Macros: // Macros:
#define SLOT_COUNT 4 #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: // Typedefs:

View File

@@ -0,0 +1,78 @@
#include "fsl_common.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,
DEVICE_PROTOCOL_MINOR_VERSION,
DEVICE_PROTOCOL_PATCH_VERSION,
};
version_t protocolVersions[] =
{
{
FIRMWARE_MAJOR_VERSION,
FIRMWARE_MINOR_VERSION,
FIRMWARE_PATCH_VERSION,
},
{
DEVICE_PROTOCOL_MAJOR_VERSION,
DEVICE_PROTOCOL_MINOR_VERSION,
DEVICE_PROTOCOL_PATCH_VERSION,
},
{
MODULE_PROTOCOL_MAJOR_VERSION,
MODULE_PROTOCOL_MINOR_VERSION,
MODULE_PROTOCOL_PATCH_VERSION,
},
{
USER_CONFIG_MAJOR_VERSION,
USER_CONFIG_MINOR_VERSION,
USER_CONFIG_PATCH_VERSION,
},
{
HARDWARE_CONFIG_MAJOR_VERSION,
HARDWARE_CONFIG_MINOR_VERSION,
HARDWARE_CONFIG_PATCH_VERSION,
}
};
uint16_t configSizes[] = {HARDWARE_CONFIG_SIZE, USER_CONFIG_SIZE};
void UsbCommand_GetDeviceProperty(void)
{
uint8_t propertyId = GetUsbRxBufferUint8(1);
switch (propertyId) {
case DevicePropertyId_DeviceProtocolVersion:
memcpy(GenericHidOutBuffer+1, (uint8_t*)&deviceProtocolVersion, sizeof(deviceProtocolVersion));
break;
case DevicePropertyId_ProtocolVersions:
memcpy(GenericHidOutBuffer+1, (uint8_t*)&protocolVersions, sizeof(protocolVersions));
break;
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_GetDeviceProperty_InvalidProperty);
break;
}
}

View 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

View File

@@ -1,5 +1,5 @@
#include "fsl_common.h" #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 "usb_protocol_handler.h"
#include "eeprom.h" #include "eeprom.h"
#include "peripherals/merge_sensor.h" #include "peripherals/merge_sensor.h"

View 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;
}
}
}

View 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

View File

@@ -1,33 +0,0 @@
#include "fsl_common.h"
#include "usb_commands/usb_command_get_property.h"
#include "usb_protocol_handler.h"
#include "eeprom.h"
void UsbCommand_GetProperty(void)
{
uint8_t propertyId = GetUsbRxBufferUint8(1);
switch (propertyId) {
case SystemPropertyId_UsbProtocolVersion:
SetUsbTxBufferUint8(1, SYSTEM_PROPERTY_USB_PROTOCOL_VERSION);
break;
case SystemPropertyId_BridgeProtocolVersion:
SetUsbTxBufferUint8(1, SYSTEM_PROPERTY_BRIDGE_PROTOCOL_VERSION);
break;
case SystemPropertyId_DataModelVersion:
SetUsbTxBufferUint8(1, SYSTEM_PROPERTY_DATA_MODEL_VERSION);
break;
case SystemPropertyId_FirmwareVersion:
SetUsbTxBufferUint8(1, SYSTEM_PROPERTY_FIRMWARE_VERSION);
break;
case SystemPropertyId_HardwareConfigSize:
SetUsbTxBufferUint16(1, HARDWARE_CONFIG_SIZE);
break;
case SystemPropertyId_UserConfigSize:
SetUsbTxBufferUint16(1, USER_CONFIG_SIZE);
break;
default:
SetUsbTxBufferUint8(0, UsbStatusCode_GetProperty_InvalidProperty);
break;
}
}

View File

@@ -1,30 +0,0 @@
#ifndef __USB_COMMAND_GET_PROPERTY_H__
#define __USB_COMMAND_GET_PROPERTY_H__
// Macros:
#define SYSTEM_PROPERTY_USB_PROTOCOL_VERSION 1
#define SYSTEM_PROPERTY_BRIDGE_PROTOCOL_VERSION 1
#define SYSTEM_PROPERTY_DATA_MODEL_VERSION 1
#define SYSTEM_PROPERTY_FIRMWARE_VERSION 1
// Typedefs:
typedef enum {
SystemPropertyId_UsbProtocolVersion = 0,
SystemPropertyId_BridgeProtocolVersion = 1,
SystemPropertyId_DataModelVersion = 2,
SystemPropertyId_FirmwareVersion = 3,
SystemPropertyId_HardwareConfigSize = 4,
SystemPropertyId_UserConfigSize = 5,
} system_property_t;
typedef enum {
UsbStatusCode_GetProperty_InvalidProperty = 2,
} usb_status_code_get_property_t;
// Functions:
void UsbCommand_GetProperty(void);
#endif

View 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);
}

View 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

View File

@@ -7,11 +7,11 @@ void UsbCommand_JumpToModuleBootloader(void)
{ {
uint8_t slotId = GetUsbRxBufferUint8(1); uint8_t slotId = GetUsbRxBufferUint8(1);
if (!IS_VALID_SLAVE_SLOT(slotId)) { if (!IS_VALID_MODULE_SLOT(slotId)) {
SetUsbTxBufferUint8(0, UsbStatusCode_JumpToModuleBootloader_InvalidSlaveSlotId); SetUsbTxBufferUint8(0, UsbStatusCode_JumpToModuleBootloader_InvalidSlaveSlotId);
return; return;
} }
uint8_t uhkModuleDriverId = SLOT_ID_TO_UHK_MODULE_DRIVER_ID(slotId); uint8_t uhkModuleDriverId = SLOT_ID_TO_UHK_MODULE_DRIVER_ID(slotId);
UhkModuleStates[uhkModuleDriverId].jumpToBootloader = true; UhkModuleStates[uhkModuleDriverId].phase = UhkModulePhase_JumpToBootloader;
} }

View File

@@ -6,5 +6,5 @@ void UsbCommand_SendKbootCommandToModule(void)
{ {
KbootDriverState.phase = 0; KbootDriverState.phase = 0;
KbootDriverState.i2cAddress = GetUsbRxBufferUint8(2); KbootDriverState.i2cAddress = GetUsbRxBufferUint8(2);
KbootDriverState.commandType = GetUsbRxBufferUint8(1); // Command should be set last. KbootDriverState.command = GetUsbRxBufferUint8(1); // Command should be set last.
} }

View 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();
}

View 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

View File

@@ -1,6 +1,7 @@
#include "usb_protocol_handler.h" #include "usb_protocol_handler.h"
#include "buffer.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_reenumerate.h"
#include "usb_commands/usb_command_set_test_led.h" #include "usb_commands/usb_command_set_test_led.h"
#include "usb_commands/usb_command_write_config.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_get_adc_value.h"
#include "usb_commands/usb_command_launch_eeprom_transfer.h" #include "usb_commands/usb_command_launch_eeprom_transfer.h"
#include "usb_commands/usb_command_read_config.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_get_debug_buffer.h"
#include "usb_commands/usb_command_jump_to_module_bootloader.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_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) void UsbProtocolHandler(void)
{ {
bzero(GenericHidOutBuffer, USB_GENERIC_HID_OUT_BUFFER_LENGTH); bzero(GenericHidOutBuffer, USB_GENERIC_HID_OUT_BUFFER_LENGTH);
uint8_t command = GetUsbRxBufferUint8(0); uint8_t command = GetUsbRxBufferUint8(0);
switch (command) { switch (command) {
case UsbCommandId_GetProperty: case UsbCommandId_GetDeviceProperty:
UsbCommand_GetProperty(); UsbCommand_GetDeviceProperty();
break; break;
case UsbCommandId_Reenumerate: case UsbCommandId_Reenumerate:
UsbCommand_Reenumerate(); UsbCommand_Reenumerate();
@@ -61,6 +64,15 @@ void UsbProtocolHandler(void)
case UsbCommandId_SetLedPwmBrightness: case UsbCommandId_SetLedPwmBrightness:
UsbCommand_SetLedPwmBrightness(); UsbCommand_SetLedPwmBrightness();
break; break;
case UsbCommandId_GetModuleProperty:
UsbCommand_GetModuleProperty();
break;
case UsbCommandId_GetSlaveI2cErrors:
UsbCommand_GetSlaveI2cErrors();
break;
case UsbCommandId_SetI2cBaudRate:
UsbCommand_SetI2cBaudRate();
break;
default: default:
SetUsbTxBufferUint8(0, UsbStatusCode_InvalidCommand); SetUsbTxBufferUint8(0, UsbStatusCode_InvalidCommand);
break; break;

View File

@@ -13,7 +13,7 @@
// Typedefs: // Typedefs:
typedef enum { typedef enum {
UsbCommandId_GetProperty = 0x00, UsbCommandId_GetDeviceProperty = 0x00,
UsbCommandId_Reenumerate = 0x01, UsbCommandId_Reenumerate = 0x01,
UsbCommandId_JumpToModuleBootloader = 0x02, UsbCommandId_JumpToModuleBootloader = 0x02,
@@ -30,6 +30,9 @@
UsbCommandId_GetDebugBuffer = 0x0b, UsbCommandId_GetDebugBuffer = 0x0b,
UsbCommandId_GetAdcValue = 0x0c, UsbCommandId_GetAdcValue = 0x0c,
UsbCommandId_SetLedPwmBrightness = 0x0d, UsbCommandId_SetLedPwmBrightness = 0x0d,
UsbCommandId_GetModuleProperty = 0x0e,
UsbCommandId_GetSlaveI2cErrors = 0x0f,
UsbCommandId_SetI2cBaudRate = 0x10,
} usb_command_id_t; } usb_command_id_t;
typedef enum { typedef enum {

View File

@@ -99,15 +99,21 @@ void processMouseKineticState(mouse_kinetic_state_t *kineticState)
float distance = kineticState->currentSpeed * elapsedTime / 1000; float distance = kineticState->currentSpeed * elapsedTime / 1000;
if (kineticState->isScroll && !kineticState->wasMoveAction) { if (kineticState->isScroll && !kineticState->wasMoveAction) {
kineticState->xSum = 0; kineticState->xSum = 0;
kineticState->ySum = 0; kineticState->ySum = 0;
} }
// Update horizontal state
bool horizontalMovement = true;
if (activeMouseStates[kineticState->leftState]) { if (activeMouseStates[kineticState->leftState]) {
kineticState->xSum -= distance; kineticState->xSum -= distance;
} else if (activeMouseStates[kineticState->rightState]) { } else if (activeMouseStates[kineticState->rightState]) {
kineticState->xSum += distance; kineticState->xSum += distance;
} else {
horizontalMovement = false;
} }
float xSumInt; float xSumInt;
@@ -115,15 +121,20 @@ void processMouseKineticState(mouse_kinetic_state_t *kineticState)
kineticState->xSum = xSumFrac; kineticState->xSum = xSumFrac;
kineticState->xOut = xSumInt; kineticState->xOut = xSumInt;
if (kineticState->isScroll && !kineticState->wasMoveAction && kineticState->xOut == 0) { if (kineticState->isScroll && !kineticState->wasMoveAction && kineticState->xOut == 0 && horizontalMovement) {
kineticState->xOut = kineticState->xSum > 0 ? 1 : -1; kineticState->xOut = kineticState->xSum > 0 ? 1 : -1;
kineticState->xSum = 0; kineticState->xSum = 0;
} }
// Update vertical state
bool verticalMovement = true;
if (activeMouseStates[kineticState->upState]) { if (activeMouseStates[kineticState->upState]) {
kineticState->ySum -= distance; kineticState->ySum -= distance;
} else if (activeMouseStates[kineticState->downState]) { } else if (activeMouseStates[kineticState->downState]) {
kineticState->ySum += distance; kineticState->ySum += distance;
} else {
verticalMovement = false;
} }
float ySumInt; float ySumInt;
@@ -131,7 +142,7 @@ void processMouseKineticState(mouse_kinetic_state_t *kineticState)
kineticState->ySum = ySumFrac; kineticState->ySum = ySumFrac;
kineticState->yOut = ySumInt; kineticState->yOut = ySumInt;
if (kineticState->isScroll && !kineticState->wasMoveAction && kineticState->yOut == 0) { if (kineticState->isScroll && !kineticState->wasMoveAction && kineticState->yOut == 0 && verticalMovement) {
kineticState->yOut = kineticState->ySum > 0 ? 1 : -1; kineticState->yOut = kineticState->ySum > 0 ? 1 : -1;
kineticState->ySum = 0; kineticState->ySum = 0;
} }

41
scripts/generate-versions-h.js Executable file
View File

@@ -0,0 +1,41 @@
#!/usr/bin/env node
const fs = require('fs');
const versionPropertyPrefixes = ['firmware', 'deviceProtocol', 'moduleProtocol', 'userConfig', 'hardwareConfig'];
const patchVersions = ['Major', 'Minor', 'Patch'];
const package = JSON.parse(fs.readFileSync(`${__dirname}/package.json`));
const versionVariables = versionPropertyPrefixes.map(versionPropertyPrefix => {
const versionPropertyName = `${versionPropertyPrefix}Version`
const versionPropertyValues = package[versionPropertyName].split('.');
return patchVersions.map(patchVersion => {
const versionPropertyValue = versionPropertyValues.shift();
const versionPropertyMacroName = `${versionPropertyPrefix}${patchVersion}Version`.split(/(?=[A-Z])/).join('_').toUpperCase()
return ` #define ${versionPropertyMacroName} ${versionPropertyValue}`;
}).join('\n') + '\n';
}).join('\n');
fs.writeFileSync(`${__dirname}/../shared/versions.h`,
`// Please do not edit this file by hand!
// It is to be regenerated by /scripts/generate-versions-h.js
#ifndef __VERSIONS_H__
#define __VERSIONS_H__
// Includes:
#include "fsl_common.h"
// Typedefs:
typedef struct {
uint16_t major;
uint16_t minor;
uint16_t patch;
} version_t;
// Variables:
${versionVariables}
#endif
`);

View File

@@ -5,8 +5,10 @@ require('shelljs/global');
config.fatal = true; config.fatal = true;
config.verbose = true; config.verbose = true;
exec(`${__dirname}/generate-versions-h.js`);
const package = JSON.parse(fs.readFileSync(`${__dirname}/package.json`)); const package = JSON.parse(fs.readFileSync(`${__dirname}/package.json`));
const version = package.version; const version = package.firmwareVersion;
const releaseName = `uhk-firmware-${version}`; const releaseName = `uhk-firmware-${version}`;
const releaseDir = `${__dirname}/${releaseName}`; const releaseDir = `${__dirname}/${releaseName}`;
const modulesDir = `${releaseDir}/modules`; const modulesDir = `${releaseDir}/modules`;
@@ -28,7 +30,7 @@ exec(`/opt/Freescale/KDS_v3/eclipse/kinetis-design-studio \
-cleanBuild uhk-right` -cleanBuild uhk-right`
); );
for (let device of package.devices) { for (const device of package.devices) {
const deviceDir = `${releaseDir}/devices/${device.name}`; const deviceDir = `${releaseDir}/devices/${device.name}`;
const deviceSource = `${__dirname}/../${device.source}`; const deviceSource = `${__dirname}/../${device.source}`;
mkdir('-p', deviceDir); mkdir('-p', deviceDir);
@@ -37,7 +39,7 @@ for (let device of package.devices) {
exec(`${usbDir}/user-config-json-to-bin.ts ${deviceDir}/config.bin`); exec(`${usbDir}/user-config-json-to-bin.ts ${deviceDir}/config.bin`);
} }
for (let module of package.modules) { for (const module of package.modules) {
const moduleDir = `${releaseDir}/modules`; const moduleDir = `${releaseDir}/modules`;
const moduleSource = `${__dirname}/../${module.source}`; const moduleSource = `${__dirname}/../${module.source}`;
mkdir('-p', moduleDir); mkdir('-p', moduleDir);

View File

@@ -15,10 +15,11 @@
"commander": "^2.11.0", "commander": "^2.11.0",
"shelljs": "^0.7.8" "shelljs": "^0.7.8"
}, },
"version": "6.0.0", "firmwareVersion": "8.1.0",
"dataModelVersion": "4.0.0", "deviceProtocolVersion": "4.2.0",
"usbProtocolVersion": "3.0.0", "moduleProtocolVersion": "4.0.0",
"slaveProtocolVersion": "3.0.0", "userConfigVersion": "4.0.0",
"hardwareConfigVersion": "1.0.0",
"devices": [ "devices": [
{ {
"deviceId": 1, "deviceId": 1,

View File

@@ -27,9 +27,11 @@
typedef enum { typedef enum {
SlaveProperty_Sync, SlaveProperty_Sync,
SlaveProperty_ProtocolVersion, SlaveProperty_ModuleProtocolVersion,
SlaveProperty_FirmwareVersion,
SlaveProperty_ModuleId, SlaveProperty_ModuleId,
SlaveProperty_Features, SlaveProperty_KeyCount,
SlaveProperty_PointerCount,
} slave_property_t; } slave_property_t;
typedef enum { typedef enum {
@@ -40,11 +42,6 @@
ModuleId_TouchpadRight = 5, ModuleId_TouchpadRight = 5,
} module_id_t; } module_id_t;
typedef struct {
uint8_t keyCount;
bool hasPointer;
} uhk_module_features_t;
typedef struct { typedef struct {
uint8_t length; uint8_t length;
uint16_t crc; uint16_t crc;

41
shared/versions.h Normal file
View File

@@ -0,0 +1,41 @@
// Please do not edit this file by hand!
// It is to be regenerated by /scripts/generate-versions-h.js
#ifndef __VERSIONS_H__
#define __VERSIONS_H__
// Includes:
#include "fsl_common.h"
// Typedefs:
typedef struct {
uint16_t major;
uint16_t minor;
uint16_t patch;
} version_t;
// Variables:
#define FIRMWARE_MAJOR_VERSION 8
#define FIRMWARE_MINOR_VERSION 1
#define FIRMWARE_PATCH_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 4
#define MODULE_PROTOCOL_MINOR_VERSION 0
#define MODULE_PROTOCOL_PATCH_VERSION 0
#define USER_CONFIG_MAJOR_VERSION 4
#define USER_CONFIG_MINOR_VERSION 0
#define USER_CONFIG_PATCH_VERSION 0
#define HARDWARE_CONFIG_MAJOR_VERSION 1
#define HARDWARE_CONFIG_MINOR_VERSION 0
#define HARDWARE_CONFIG_PATCH_VERSION 0
#endif