Files
firmware/right/src/usb_protocol_handler.c

221 lines
5.6 KiB
C

#include "usb_protocol_handler.h"
#include "system_properties.h"
#include "test_led.h"
#include "i2c_addresses.h"
#include "led_driver.h"
#include "merge_sensor.h"
#include "deserialize.h"
#include "config_buffer.h"
#include "led_pwm.h"
void setError(uint8_t error);
void setGenericError();
void usbProtocolHandler();
void getSystemProperty();
void jumpToBootloader();
void getSetTestLed();
void writeLedDriver();
void readLedDriver();
void writeEeprom();
void readEeprom();
void readMergeSensor();
void uploadConfig();
void applyConfig();
void setLedPwm();
// Functions for setting error statuses
void setError(uint8_t error) {
GenericHidOutBuffer[0] = error;
}
void setGenericError()
{
setError(PROTOCOL_RESPONSE_GENERIC_ERROR);
}
// Set a single byte as the response.
void SetResponseByte(uint8_t response)
{
GenericHidOutBuffer[1] = response;
}
// The main protocol handler function
void usbProtocolHandler()
{
bzero(GenericHidOutBuffer, USB_GENERIC_HID_OUT_BUFFER_LENGTH);
uint8_t command = GenericHidInBuffer[0];
switch (command) {
case USB_COMMAND_GET_SYSTEM_PROPERTY:
getSystemProperty();
break;
case USB_COMMAND_JUMP_TO_BOOTLOADER:
jumpToBootloader();
break;
case USB_COMMAND_TEST_LED:
getSetTestLed();
break;
case USB_COMMAND_WRITE_LED_DRIVER:
writeLedDriver();
break;
case USB_COMMAND_READ_LED_DRIVER:
readLedDriver();
break;
case USB_COMMAND_WRITE_EEPROM:
writeEeprom();
break;
case USB_COMMAND_READ_EEPROM:
readEeprom();
break;
case USB_COMMAND_READ_MERGE_SENSOR:
readMergeSensor();
break;
case USB_COMMAND_UPLOAD_CONFIG:
uploadConfig();
break;
case USB_COMMAND_APPLY_CONFIG:
applyConfig();
break;
case USB_COMMAND_SET_LED_PWM:
setLedPwm();
break;
default:
break;
}
}
// Per command protocol command handlers
void getSystemProperty() {
uint8_t propertyId = GenericHidInBuffer[1];
switch (propertyId) {
case SYSTEM_PROPERTY_USB_PROTOCOL_VERSION_ID:
SetResponseByte(SYSTEM_PROPERTY_USB_PROTOCOL_VERSION);
break;
case SYSTEM_PROPERTY_BRIDGE_PROTOCOL_VERSION_ID:
SetResponseByte(SYSTEM_PROPERTY_BRIDGE_PROTOCOL_VERSION);
break;
case SYSTEM_PROPERTY_DATA_MODEL_VERSION_ID:
SetResponseByte(SYSTEM_PROPERTY_DATA_MODEL_VERSION);
break;
case SYSTEM_PROPERTY_FIRMWARE_VERSION_ID:
SetResponseByte(SYSTEM_PROPERTY_FIRMWARE_VERSION);
break;
default:
setGenericError();
break;
}
}
void jumpToBootloader() {
// We should reset the device here
SCB->AIRCR = (0x5FA<<SCB_AIRCR_VECTKEY_Pos)|SCB_AIRCR_SYSRESETREQ_Msk;
//SCB->AIRCR = 0x05fA0002; // If the masked version doesn't work, this should also reset the core.
for(;;);
}
void getSetTestLed()
{
uint8_t ledState = GenericHidInBuffer[1];
uint8_t data[] = {1, ledState};
I2cWrite(I2C_MAIN_BUS_BASEADDR, I2C_ADDRESS_LEFT_KEYBOARD_HALF, data, sizeof(data));
switch (ledState) {
case 0:
TEST_LED_ON();
break;
case 1:
TEST_LED_OFF();
break;
}
}
void writeLedDriver()
{
uint8_t i2cAddress = GenericHidInBuffer[1];
uint8_t i2cPayloadSize = GenericHidInBuffer[2];
if (!IS_I2C_LED_DRIVER_ADDRESS(i2cAddress)) {
setError(WRITE_LED_DRIVER_RESPONSE_INVALID_ADDRESS);
return;
}
if (i2cPayloadSize > USB_GENERIC_HID_OUT_BUFFER_LENGTH-3) {
setError(WRITE_LED_DRIVER_RESPONSE_INVALID_PAYLOAD_SIZE);
return;
}
I2cWrite(I2C_MAIN_BUS_BASEADDR, i2cAddress, GenericHidInBuffer+3, i2cPayloadSize);
}
void readLedDriver()
{
}
void writeEeprom()
{
uint8_t i2cPayloadSize = GenericHidInBuffer[1];
if (i2cPayloadSize > USB_GENERIC_HID_OUT_BUFFER_LENGTH-2) {
setError(WRITE_EEPROM_RESPONSE_INVALID_PAYLOAD_SIZE);
return;
}
I2cWrite(I2C_EEPROM_BUS_BASEADDR, I2C_ADDRESS_EEPROM, GenericHidInBuffer+2, i2cPayloadSize);
}
void readEeprom()
{
uint8_t i2cPayloadSize = GenericHidInBuffer[1];
if (i2cPayloadSize > USB_GENERIC_HID_OUT_BUFFER_LENGTH-1) {
setError(WRITE_EEPROM_RESPONSE_INVALID_PAYLOAD_SIZE);
return;
}
I2cWrite(I2C_EEPROM_BUS_BASEADDR, I2C_ADDRESS_EEPROM, GenericHidInBuffer+2, 2);
I2cRead(I2C_EEPROM_BUS_BASEADDR, I2C_ADDRESS_EEPROM, GenericHidOutBuffer+1, i2cPayloadSize);
GenericHidOutBuffer[0] = PROTOCOL_RESPONSE_SUCCESS;
}
void readMergeSensor()
{
SetResponseByte(MERGE_SENSOR_IS_MERGED);
}
void uploadConfig()
{
uint8_t byteCount = GenericHidInBuffer[1];
uint16_t memoryOffset = *((uint16_t*)(GenericHidInBuffer+2));
if (byteCount > USB_GENERIC_HID_OUT_BUFFER_LENGTH-4) {
setError(UPLOAD_CONFIG_INVALID_PAYLOAD_SIZE);
return;
}
memcpy(ConfigBuffer+memoryOffset, GenericHidInBuffer+4, byteCount);
}
void applyConfig()
{
deserialize_Layer(ConfigBuffer, 0);
}
void setLedPwm()
{
#if UHK_PCB_MAJOR_VERSION == 7
uint8_t isRightKeyboardHalf = GenericHidInBuffer[1];
uint8_t brightnessPercent = GenericHidInBuffer[2];
if (isRightKeyboardHalf) {
LedPwm_SetBrightness(brightnessPercent);
} else {
uint8_t data[] = {2, brightnessPercent};
I2cWrite(I2C_MAIN_BUS_BASEADDR, I2C_ADDRESS_LEFT_KEYBOARD_HALF, data, sizeof(data));
}
#endif
}