Compare commits
25 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f1ed699fa2 | ||
|
|
43646beca8 | ||
|
|
195f40949f | ||
|
|
1742437f8b | ||
|
|
5093a0c0a6 | ||
|
|
7e524d97b1 | ||
|
|
2e53331a0f | ||
|
|
c6d60780f4 | ||
|
|
8666a495d8 | ||
|
|
33bbf44199 | ||
|
|
cc49118868 | ||
|
|
f8fd99f588 | ||
|
|
fa8c9dc907 | ||
|
|
0911e67bf6 | ||
|
|
57a7cee62a | ||
|
|
1af28a79db | ||
|
|
6881f8e340 | ||
|
|
00cd1f65e8 | ||
|
|
2c9a6c0bd2 | ||
|
|
0c94cbb256 | ||
|
|
275bfee860 | ||
|
|
8a655e3cfd | ||
|
|
8521619783 | ||
|
|
62184240df | ||
|
|
0b210ac68e |
37
CHANGELOG.md
37
CHANGELOG.md
@@ -5,6 +5,41 @@ 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.5] - 2018-04-04
|
||||
|
||||
Device Protocol: 4.2.0 | Module Protocol: 4.0.0 | User Config: 4.0.0 | Hardware Config: 1.0.0
|
||||
|
||||
- Set key debounce timeout from 30ms to 60ms. This should eliminate key chattering.
|
||||
- Use the correct scancode for the menu key of the factory keymap.
|
||||
|
||||
## [8.1.4] - 2018-03-05
|
||||
|
||||
Device Protocol: 4.2.0 | Module Protocol: 4.0.0 | User Config: 4.0.0 | Hardware Config: 1.0.0
|
||||
|
||||
- Set key debounce timeout from 20ms to 30ms. This should eliminate key chattering.
|
||||
- Set double tap lock layer timeout from 250ms to 150ms. This should minimize the chance of locking layers accidentally by double tapping their keys.
|
||||
|
||||
## [8.1.3] - 2018-02-18
|
||||
|
||||
Device Protocol: 4.2.0 | Module Protocol: 4.0.0 | User Config: 4.0.0 | Hardware Config: 1.0.0
|
||||
|
||||
- Fix system keyboard descriptor, so it is byte-aligned.
|
||||
- Set key debounce timeout from 15ms to 20ms. This should at least reduce and hopefully eliminate key chattering.
|
||||
|
||||
## [8.1.2] - 2018-02-13
|
||||
|
||||
Device Protocol: 4.2.0 | Module Protocol: 4.0.0 | User Config: 4.0.0 | Hardware Config: 1.0.0
|
||||
|
||||
- Detect Caps Lock USB state and light up the Caps Lock icon of the LED display accordingly.
|
||||
- Set key debounce timeout from 10ms to 15ms. This should at least reduce and hopefully eliminate key chattering.
|
||||
|
||||
## [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
|
||||
@@ -68,7 +103,7 @@ Device Protocol: 2.0.0 | Module Protocol: 3.0.0 | User Config: **3.0.0** | Hardw
|
||||
|
||||
- Implement mouse movement and scrolling deceleration and acceleration.
|
||||
- Toggle layers upon double tapping their keys. Make the double tap timeout configurable.
|
||||
- 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`
|
||||
- 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
|
||||
|
||||
|
||||
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
|
||||
|
||||
|
||||
1
left/build/.gitignore
vendored
1
left/build/.gitignore
vendored
@@ -1,3 +1,4 @@
|
||||
/.settings/
|
||||
/uhk60-left_debug/
|
||||
/uhk60-left_release/
|
||||
/uhk60-left_release/
|
||||
|
||||
Submodule lib/agent updated: dd973c80ea...9beadb4aac
@@ -56,6 +56,7 @@ parser_error_t ParseConfig(config_buffer_t *buffer)
|
||||
(void)dataModelMinorVersion;
|
||||
(void)dataModelPatchVersion;
|
||||
(void)deviceName;
|
||||
(void)doubleTapSwitchLayerTimeout;
|
||||
|
||||
// LED brightness
|
||||
|
||||
@@ -136,7 +137,7 @@ parser_error_t ParseConfig(config_buffer_t *buffer)
|
||||
// If parsing succeeded then apply the parsed values.
|
||||
|
||||
if (!ParserRunDry) {
|
||||
DoubleTapSwitchLayerTimeout = doubleTapSwitchLayerTimeout;
|
||||
// DoubleTapSwitchLayerTimeout = doubleTapSwitchLayerTimeout;
|
||||
|
||||
// Update LED brightnesses and reinitialize LED drivers
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
// Macros:
|
||||
|
||||
#define KEY_DEBOUNCER_INTERVAL_MSEC 1
|
||||
#define KEY_DEBOUNCER_TIMEOUT_MSEC 10
|
||||
#define KEY_DEBOUNCER_TIMEOUT_MSEC 60
|
||||
|
||||
// Functions:
|
||||
|
||||
|
||||
@@ -157,7 +157,7 @@ key_action_t CurrentKeymap[LAYER_COUNT][SLOT_COUNT][MAX_KEY_COUNT_PER_MODULE] =
|
||||
{ .type = KeyActionType_None },
|
||||
{ .type = KeyActionType_None },
|
||||
{ .type = KeyActionType_None },
|
||||
{ .type = HID_KEYBOARD_SC_MENU },
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_APPLICATION }},
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_RIGHT_SHIFT }},
|
||||
{ .type = KeyActionType_None },
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ uint8_t UsbBasicKeyboardReportDescriptor[USB_BASIC_KEYBOARD_REPORT_DESCRIPTOR_LE
|
||||
|
||||
// Scancodes
|
||||
HID_RI_LOGICAL_MINIMUM(8, 0x00),
|
||||
HID_RI_LOGICAL_MAXIMUM(8, 0xFF),
|
||||
HID_RI_LOGICAL_MAXIMUM(16, 0xFF),
|
||||
HID_RI_USAGE_PAGE(8, HID_RI_USAGE_PAGE_KEY_CODES),
|
||||
HID_RI_USAGE_MINIMUM(8, 0x00),
|
||||
HID_RI_USAGE_MAXIMUM(8, 0xFF),
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
// Macros:
|
||||
|
||||
#define USB_BASIC_KEYBOARD_REPORT_DESCRIPTOR_LENGTH 63
|
||||
#define USB_BASIC_KEYBOARD_REPORT_DESCRIPTOR_LENGTH 64
|
||||
#define USB_BASIC_KEYBOARD_MAX_KEYS 6
|
||||
|
||||
// Variables:
|
||||
|
||||
@@ -10,7 +10,7 @@ uint8_t UsbGenericHidReportDescriptor[USB_GENERIC_HID_REPORT_DESCRIPTOR_LENGTH]
|
||||
// Input flowing from device to host
|
||||
HID_RI_USAGE(8, USB_GENERIC_HID_REPORT_DESCRIPTOR_VENDOR_USAGE_DATA_IN),
|
||||
HID_RI_LOGICAL_MINIMUM(8, 0x00),
|
||||
HID_RI_LOGICAL_MAXIMUM(8, 0xFF),
|
||||
HID_RI_LOGICAL_MAXIMUM(16, 0xFF),
|
||||
HID_RI_REPORT_SIZE(8, 0x08),
|
||||
HID_RI_REPORT_COUNT(8, USB_GENERIC_HID_INTERRUPT_IN_PACKET_SIZE),
|
||||
HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
|
||||
@@ -18,7 +18,7 @@ uint8_t UsbGenericHidReportDescriptor[USB_GENERIC_HID_REPORT_DESCRIPTOR_LENGTH]
|
||||
// Output flowing from host to device
|
||||
HID_RI_USAGE(8, USB_GENERIC_HID_REPORT_DESCRIPTOR_VENDOR_USAGE_DATA_OUT),
|
||||
HID_RI_LOGICAL_MINIMUM(8, 0x00),
|
||||
HID_RI_LOGICAL_MAXIMUM(8, 0xFF),
|
||||
HID_RI_LOGICAL_MAXIMUM(16, 0xFF),
|
||||
HID_RI_REPORT_SIZE(8, 0x08),
|
||||
HID_RI_REPORT_COUNT(8, USB_GENERIC_HID_INTERRUPT_OUT_PACKET_SIZE),
|
||||
HID_RI_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE),
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
// Macros:
|
||||
|
||||
#define USB_GENERIC_HID_REPORT_DESCRIPTOR_LENGTH 31
|
||||
#define USB_GENERIC_HID_REPORT_DESCRIPTOR_LENGTH 33
|
||||
|
||||
#define USB_GENERIC_HID_REPORT_DESCRIPTOR_VENDOR_USAGE_PAGE_INDEX 0x80
|
||||
#define USB_GENERIC_HID_REPORT_DESCRIPTOR_VENDOR_USAGE_COLLECTION 0x81
|
||||
|
||||
@@ -5,14 +5,16 @@ uint8_t UsbSystemKeyboardReportDescriptor[USB_SYSTEM_KEYBOARD_REPORT_DESCRIPTOR_
|
||||
HID_RI_USAGE_PAGE(8, HID_RI_USAGE_PAGE_GENERIC_DESKTOP),
|
||||
HID_RI_USAGE(8, HID_RI_USAGE_GENERIC_DESKTOP_SYSTEM_CONTROL),
|
||||
HID_RI_COLLECTION(8, HID_RI_COLLECTION_APPLICATION),
|
||||
// System key
|
||||
HID_RI_REPORT_SIZE(8, 2),
|
||||
HID_RI_REPORT_COUNT(8, USB_SYSTEM_KEYBOARD_MAX_KEYS),
|
||||
HID_RI_LOGICAL_MINIMUM(8, 1),
|
||||
HID_RI_LOGICAL_MAXIMUM(8, 3),
|
||||
HID_RI_USAGE(8, 0x82),
|
||||
HID_RI_USAGE(8, 0x81),
|
||||
HID_RI_USAGE(8, 0x83),
|
||||
HID_RI_INPUT(8, HID_IOF_NO_PREFERRED_STATE | HID_IOF_NULLSTATE),
|
||||
// System keys
|
||||
HID_RI_USAGE_MINIMUM(8, 0x81), // SYSTEM_POWER_DOWN, SYSTEM_SLEEP and SYSTEM_WAKE_UP
|
||||
HID_RI_USAGE_MAXIMUM(8, 0x83),
|
||||
HID_RI_REPORT_SIZE(8, 1),
|
||||
HID_RI_REPORT_COUNT(8, 3),
|
||||
HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
|
||||
|
||||
// Padding
|
||||
HID_RI_REPORT_SIZE(8, 1),
|
||||
HID_RI_REPORT_COUNT(8, 5),
|
||||
HID_RI_INPUT(8, HID_IOF_CONSTANT | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
|
||||
HID_RI_END_COLLECTION(0),
|
||||
};
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
#include "led_display.h"
|
||||
#include "usb_composite_device.h"
|
||||
|
||||
static usb_basic_keyboard_report_t usbBasicKeyboardReports[2];
|
||||
uint32_t UsbBasicKeyboardActionCounter;
|
||||
usb_basic_keyboard_report_t* ActiveUsbBasicKeyboardReport = usbBasicKeyboardReports;
|
||||
bool IsUsbBasicKeyboardReportSent = false;
|
||||
static uint8_t usbBasicKeyboardInBuffer[USB_BASIC_KEYBOARD_REPORT_LENGTH];
|
||||
|
||||
usb_basic_keyboard_report_t* getInactiveUsbBasicKeyboardReport(void)
|
||||
{
|
||||
@@ -41,10 +43,28 @@ usb_status_t UsbBasicKeyboardCallback(class_handle_t handle, uint32_t event, voi
|
||||
}
|
||||
break;
|
||||
case kUSB_DeviceHidEventGetReport:
|
||||
case kUSB_DeviceHidEventSetReport:
|
||||
case kUSB_DeviceHidEventRequestReportBuffer:
|
||||
error = kStatus_USB_InvalidRequest;
|
||||
break;
|
||||
case kUSB_DeviceHidEventSetReport: {
|
||||
usb_device_hid_report_struct_t *report = (usb_device_hid_report_struct_t*)param;
|
||||
if (report->reportType == USB_DEVICE_HID_REQUEST_GET_REPORT_TYPE_OUPUT && report->reportId == 0 && report->reportLength == 1) {
|
||||
LedDisplay_SetIcon(LedDisplayIcon_CapsLock, report->reportBuffer[0] & HID_KEYBOARD_LED_CAPSLOCK);
|
||||
error = kStatus_USB_Success;
|
||||
} else {
|
||||
error = kStatus_USB_InvalidRequest;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case kUSB_DeviceHidEventRequestReportBuffer: {
|
||||
usb_device_hid_report_struct_t *report = (usb_device_hid_report_struct_t*)param;
|
||||
if (report->reportLength <= USB_BASIC_KEYBOARD_REPORT_LENGTH) {
|
||||
report->reportBuffer = usbBasicKeyboardInBuffer;
|
||||
error = kStatus_USB_Success;
|
||||
} else {
|
||||
error = kStatus_USB_InvalidRequest;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case kUSB_DeviceHidEventGetIdle:
|
||||
case kUSB_DeviceHidEventGetProtocol:
|
||||
case kUSB_DeviceHidEventSetIdle:
|
||||
|
||||
@@ -20,7 +20,8 @@
|
||||
uint32_t UsbReportUpdateTime = 0;
|
||||
static uint32_t elapsedTime;
|
||||
|
||||
uint16_t DoubleTapSwitchLayerTimeout = 250;
|
||||
uint16_t DoubleTapSwitchLayerTimeout = 150;
|
||||
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 && doubleTapSwitchLayerKey == keyState &&
|
||||
Timer_GetElapsedTime(&doubleTapSwitchLayerTriggerTime) > DoubleTapSwitchLayerReleaseTimeout)
|
||||
{
|
||||
ToggledLayer = LayerId_Base;
|
||||
}
|
||||
|
||||
if (!keyState->previous && previousLayer == LayerId_Base && action->switchLayer.mode == SwitchLayerMode_HoldAndDoubleTapToggle) {
|
||||
if (doubleTapSwitchLayerKey) {
|
||||
if (Timer_GetElapsedTimeAndSetCurrent(&doubleTapSwitchLayerStartTime) < DoubleTapSwitchLayerTimeout) {
|
||||
ToggledLayer = action->switchLayer.layer;
|
||||
}
|
||||
doubleTapSwitchLayerKey = NULL;
|
||||
if (doubleTapSwitchLayerKey && Timer_GetElapsedTimeAndSetCurrent(&doubleTapSwitchLayerStartTime) < DoubleTapSwitchLayerTimeout) {
|
||||
ToggledLayer = action->switchLayer.layer;
|
||||
doubleTapSwitchLayerTriggerTime = CurrentTime;
|
||||
} else {
|
||||
doubleTapSwitchLayerKey = keyState;
|
||||
doubleTapSwitchLayerStartTime = CurrentTime;
|
||||
}
|
||||
doubleTapSwitchLayerStartTime = CurrentTime;
|
||||
}
|
||||
break;
|
||||
case KeyActionType_SwitchKeymap:
|
||||
@@ -258,10 +265,8 @@ static uint8_t secondaryRoleSlotId;
|
||||
static uint8_t secondaryRoleKeyId;
|
||||
static secondary_role_t secondaryRole;
|
||||
|
||||
#define pos 35
|
||||
void updateActiveUsbReports(void)
|
||||
{
|
||||
SetDebugBufferUint32(pos, 1);
|
||||
memset(activeMouseStates, 0, ACTIVE_MOUSE_STATES_COUNT);
|
||||
|
||||
static uint8_t previousModifiers = 0;
|
||||
@@ -293,7 +298,6 @@ void updateActiveUsbReports(void)
|
||||
memcpy(&ActiveUsbSystemKeyboardReport, &MacroSystemKeyboardReport, sizeof MacroSystemKeyboardReport);
|
||||
return;
|
||||
}
|
||||
SetDebugBufferUint32(pos, 2);
|
||||
|
||||
for (uint8_t slotId=0; slotId<SLOT_COUNT; slotId++) {
|
||||
for (uint8_t keyId=0; keyId<MAX_KEY_COUNT_PER_MODULE; keyId++) {
|
||||
@@ -347,10 +351,8 @@ void updateActiveUsbReports(void)
|
||||
keyState->previous = keyState->current;
|
||||
}
|
||||
}
|
||||
SetDebugBufferUint32(pos, 4);
|
||||
|
||||
processMouseActions();
|
||||
SetDebugBufferUint32(pos, 5);
|
||||
|
||||
// When a layer switcher key gets pressed along with another key that produces some modifiers
|
||||
// and the accomanying key gets released then keep the related modifiers active a long as the
|
||||
@@ -365,7 +367,6 @@ void updateActiveUsbReports(void)
|
||||
|
||||
previousModifiers = ActiveUsbBasicKeyboardReport->modifiers;
|
||||
previousLayer = activeLayer;
|
||||
SetDebugBufferUint32(pos, 7);
|
||||
}
|
||||
|
||||
bool UsbBasicKeyboardReportEverSent = false;
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
"commander": "^2.11.0",
|
||||
"shelljs": "^0.7.8"
|
||||
},
|
||||
"firmwareVersion": "8.1.0",
|
||||
"firmwareVersion": "8.1.5",
|
||||
"deviceProtocolVersion": "4.2.0",
|
||||
"moduleProtocolVersion": "4.0.0",
|
||||
"userConfigVersion": "4.0.0",
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
#define FIRMWARE_MAJOR_VERSION 8
|
||||
#define FIRMWARE_MINOR_VERSION 1
|
||||
#define FIRMWARE_PATCH_VERSION 0
|
||||
#define FIRMWARE_PATCH_VERSION 5
|
||||
|
||||
#define DEVICE_PROTOCOL_MAJOR_VERSION 4
|
||||
#define DEVICE_PROTOCOL_MINOR_VERSION 2
|
||||
|
||||
Reference in New Issue
Block a user