8 Commits

17 changed files with 180 additions and 58 deletions

View File

@@ -5,6 +5,14 @@ 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.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

View File

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

View File

@@ -10,10 +10,23 @@
#include "bool_array_converter.h"
#include "bootloader.h"
#include "module.h"
#include "versions.h"
i2c_message_t RxMessage;
i2c_message_t TxMessage;
static version_t moduleProtocolVersion = {
MODULE_PROTOCOL_MAJOR_VERSION,
MODULE_PROTOCOL_MINOR_VERSION,
MODULE_PROTOCOL_PATCH_VERSION,
};
static version_t firmwareVersion = {
FIRMWARE_MAJOR_VERSION,
FIRMWARE_MINOR_VERSION,
FIRMWARE_PATCH_VERSION,
};
void SlaveRxHandler(void)
{
if (!CRC16_IsMessageValid(&RxMessage)) {
@@ -51,21 +64,29 @@ void SlaveTxHandler(void)
TxMessage.length = SLAVE_SYNC_STRING_LENGTH;
break;
}
case SlaveProperty_ModuleProtocolVersion: {
memcpy(TxMessage.data, &moduleProtocolVersion, sizeof(version_t));
TxMessage.length = sizeof(version_t);
break;
}
case SlaveProperty_FirmwareVersion: {
memcpy(TxMessage.data, &firmwareVersion, sizeof(version_t));
TxMessage.length = sizeof(version_t);
break;
}
case SlaveProperty_ModuleId: {
TxMessage.data[0] = MODULE_ID;
TxMessage.length = 1;
break;
}
case SlaveProperty_ProtocolVersion: {
TxMessage.data[0] = MODULE_PROTOCOL_VERSION;
case SlaveProperty_KeyCount: {
TxMessage.data[0] = MODULE_KEY_COUNT;
TxMessage.length = 1;
break;
}
case SlaveProperty_Features: {
uhk_module_features_t *moduleFeatures = (uhk_module_features_t*)&TxMessage.data;
moduleFeatures->keyCount = MODULE_KEY_COUNT;
moduleFeatures->hasPointer = MODULE_HAS_POINTER;
TxMessage.length = sizeof(uhk_module_features_t);
case SlaveProperty_PointerCount: {
TxMessage.data[0] = MODULE_POINTER_COUNT;
TxMessage.length = 1;
break;
}
}

View File

@@ -93,30 +93,52 @@ status_t UhkModuleSlaveDriver_Update(uint8_t uhkModuleDriverId)
bool isSyncValid = memcmp(rxMessage->data, SlaveSyncString, SLAVE_SYNC_STRING_LENGTH) == 0;
status = kStatus_Uhk_NoTransfer;
*uhkModulePhase = isSyncValid && isMessageValid
? UhkModulePhase_RequestProtocolVersion
? UhkModulePhase_RequestModuleProtocolVersion
: UhkModulePhase_RequestSync;
break;
}
// Get protocol version
case UhkModulePhase_RequestProtocolVersion:
// Get module protocol version
case UhkModulePhase_RequestModuleProtocolVersion:
txMessage.data[0] = SlaveCommand_RequestProperty;
txMessage.data[1] = SlaveProperty_ProtocolVersion;
txMessage.data[1] = SlaveProperty_ModuleProtocolVersion;
txMessage.length = 2;
status = tx(i2cAddress);
*uhkModulePhase = UhkModulePhase_ReceiveProtocolVersion;
*uhkModulePhase = UhkModulePhase_ReceiveModuleProtocolVersion;
break;
case UhkModulePhase_ReceiveProtocolVersion:
case UhkModulePhase_ReceiveModuleProtocolVersion:
status = rx(rxMessage, i2cAddress);
*uhkModulePhase = UhkModulePhase_ProcessProtocolVersion;
*uhkModulePhase = UhkModulePhase_ProcessModuleProtocolVersion;
break;
case UhkModulePhase_ProcessProtocolVersion: {
case UhkModulePhase_ProcessModuleProtocolVersion: {
bool isMessageValid = CRC16_IsMessageValid(rxMessage);
if (isMessageValid) {
uhkModuleState->protocolVersion = rxMessage->data[0];
memcpy(&uhkModuleState->moduleProtocolVersion, rxMessage->data, sizeof(version_t));
}
status = kStatus_Uhk_NoTransfer;
*uhkModulePhase = isMessageValid ? UhkModulePhase_RequestModuleId : UhkModulePhase_RequestProtocolVersion;
*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_NoTransfer;
*uhkModulePhase = isMessageValid ? UhkModulePhase_RequestModuleId : UhkModulePhase_RequestFirmwareVersion;
break;
}
@@ -138,29 +160,51 @@ status_t UhkModuleSlaveDriver_Update(uint8_t uhkModuleDriverId)
uhkModuleState->moduleId = rxMessage->data[0];
}
status = kStatus_Uhk_NoTransfer;
*uhkModulePhase = isMessageValid ? UhkModulePhase_RequestModuleFeatures : UhkModulePhase_RequestModuleId;
*uhkModulePhase = isMessageValid ? UhkModulePhase_RequestModuleKeyCount : UhkModulePhase_RequestModuleId;
break;
}
// Get module features
case UhkModulePhase_RequestModuleFeatures:
// Get module key count
case UhkModulePhase_RequestModuleKeyCount:
txMessage.data[0] = SlaveCommand_RequestProperty;
txMessage.data[1] = SlaveProperty_Features;
txMessage.data[1] = SlaveProperty_KeyCount;
txMessage.length = 2;
status = tx(i2cAddress);
*uhkModulePhase = UhkModulePhase_ReceiveModuleFeatures;
*uhkModulePhase = UhkModulePhase_ReceiveModuleKeyCount;
break;
case UhkModulePhase_ReceiveModuleFeatures:
case UhkModulePhase_ReceiveModuleKeyCount:
status = rx(rxMessage, i2cAddress);
*uhkModulePhase = UhkModulePhase_ProcessModuleFeatures;
*uhkModulePhase = UhkModulePhase_ProcessModuleKeyCount;
break;
case UhkModulePhase_ProcessModuleFeatures: {
case UhkModulePhase_ProcessModuleKeyCount: {
bool isMessageValid = CRC16_IsMessageValid(rxMessage);
if (isMessageValid) {
memcpy(&uhkModuleState->features, rxMessage->data, sizeof(uhk_module_features_t));
uhkModuleState->keyCount = rxMessage->data[0];
}
status = kStatus_Uhk_NoTransfer;
*uhkModulePhase = isMessageValid ? UhkModulePhase_RequestKeyStates : UhkModulePhase_RequestModuleFeatures;
*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_NoTransfer;
*uhkModulePhase = isMessageValid ? UhkModulePhase_RequestKeyStates : UhkModulePhase_RequestModulePointerCount;
break;
}
@@ -178,8 +222,8 @@ status_t UhkModuleSlaveDriver_Update(uint8_t uhkModuleDriverId)
case UhkModulePhase_ProcessKeystates:
if (CRC16_IsMessageValid(rxMessage)) {
uint8_t slotId = uhkModuleDriverId + 1;
BoolBitsToBytes(rxMessage->data, keyStatesBuffer, uhkModuleState->features.keyCount);
for (uint8_t keyId=0; keyId<uhkModuleState->features.keyCount; keyId++) {
BoolBitsToBytes(rxMessage->data, keyStatesBuffer, uhkModuleState->keyCount);
for (uint8_t keyId=0; keyId<uhkModuleState->keyCount; keyId++) {
KeyStates[slotId][keyId].current = keyStatesBuffer[keyId];
}
}

View File

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

View File

@@ -13,7 +13,7 @@
// Macros:
#define SLOT_COUNT 4
#define IS_VALID_SLAVE_SLOT(slotId) (SlotId_LeftKeyboardHalf <= (slotId) && (slotId) <= SlotId_RightModule)
#define IS_VALID_MODULE_SLOT(slotId) (SlotId_LeftKeyboardHalf <= (slotId) && (slotId) <= SlotId_RightModule)
// Typedefs:

View File

@@ -1,5 +1,5 @@
#include "fsl_common.h"
#include "usb_commands/usb_command_get_keyboard_state.h"
#include "usb_commands/usb_command_get_device_state.h"
#include "usb_protocol_handler.h"
#include "eeprom.h"
#include "peripherals/merge_sensor.h"

View File

@@ -0,0 +1,21 @@
#include "fsl_common.h"
#include "usb_commands/usb_command_get_module_properties.h"
#include "usb_protocol_handler.h"
#include "slot.h"
#include "slave_drivers/uhk_module_driver.h"
void UsbCommand_GetModuleProperties()
{
slot_t slotId = GetUsbRxBufferUint8(1);
if (!IS_VALID_MODULE_SLOT(slotId)) {
SetUsbTxBufferUint8(0, UsbStatusCode_ReadConfig_InvalidModuleSlotId);
}
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 + 2 + sizeof(version_t), &moduleState->firmwareVersion, sizeof(version_t));
}

View File

@@ -0,0 +1,14 @@
#ifndef __USB_COMMAND_GET_MODULE_PROPERTIES_H__
#define __USB_COMMAND_GET_MODULE_PROPERTIES_H__
// Functions:
void UsbCommand_GetModuleProperties();
// Typedefs:
typedef enum {
UsbStatusCode_ReadConfig_InvalidModuleSlotId = 2,
} usb_status_code_get_module_properties_t;
#endif

View File

@@ -7,7 +7,7 @@ void UsbCommand_JumpToModuleBootloader(void)
{
uint8_t slotId = GetUsbRxBufferUint8(1);
if (!IS_VALID_SLAVE_SLOT(slotId)) {
if (!IS_VALID_MODULE_SLOT(slotId)) {
SetUsbTxBufferUint8(0, UsbStatusCode_JumpToModuleBootloader_InvalidSlaveSlotId);
return;
}

View File

@@ -9,7 +9,7 @@
#include "usb_commands/usb_command_get_adc_value.h"
#include "usb_commands/usb_command_launch_eeprom_transfer.h"
#include "usb_commands/usb_command_read_config.h"
#include "usb_commands/usb_command_get_keyboard_state.h"
#include "usb_commands/usb_command_get_device_state.h"
#include "usb_commands/usb_command_get_debug_buffer.h"
#include "usb_commands/usb_command_jump_to_module_bootloader.h"
#include "usb_commands/usb_command_send_kboot_command_to_module.h"
@@ -61,6 +61,9 @@ void UsbProtocolHandler(void)
case UsbCommandId_SetLedPwmBrightness:
UsbCommand_SetLedPwmBrightness();
break;
case UsbCommandId_GetModuleProperties:
UsbCommand_GetModuleProperties();
break;
default:
SetUsbTxBufferUint8(0, UsbStatusCode_InvalidCommand);
break;

View File

@@ -30,6 +30,7 @@
UsbCommandId_GetDebugBuffer = 0x0b,
UsbCommandId_GetAdcValue = 0x0c,
UsbCommandId_SetLedPwmBrightness = 0x0d,
UsbCommandId_GetModuleProperties = 0x0e,
} usb_command_id_t;
typedef enum {

View File

@@ -15,9 +15,9 @@
"commander": "^2.11.0",
"shelljs": "^0.7.8"
},
"firmwareVersion": "7.0.0",
"deviceProtocolVersion": "4.0.0",
"moduleProtocolVersion": "3.0.0",
"firmwareVersion": "8.0.0",
"deviceProtocolVersion": "4.1.0",
"moduleProtocolVersion": "4.0.0",
"userConfigVersion": "4.0.0",
"hardwareConfigVersion": "1.0.0",
"devices": [

View File

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

View File

@@ -18,15 +18,15 @@
// Variables:
#define FIRMWARE_MAJOR_VERSION 6
#define FIRMWARE_MAJOR_VERSION 8
#define FIRMWARE_MINOR_VERSION 0
#define FIRMWARE_PATCH_VERSION 0
#define DEVICE_PROTOCOL_MAJOR_VERSION 3
#define DEVICE_PROTOCOL_MINOR_VERSION 0
#define DEVICE_PROTOCOL_MAJOR_VERSION 4
#define DEVICE_PROTOCOL_MINOR_VERSION 1
#define DEVICE_PROTOCOL_PATCH_VERSION 0
#define MODULE_PROTOCOL_MAJOR_VERSION 3
#define MODULE_PROTOCOL_MAJOR_VERSION 4
#define MODULE_PROTOCOL_MINOR_VERSION 0
#define MODULE_PROTOCOL_PATCH_VERSION 0