Start to implement the fully asynchronous bridge protocol scheduler and use it to transfer key and LED state.

This commit is contained in:
László Monda
2017-02-03 01:37:25 +01:00
parent d8761a95ba
commit fc0fc4a3f4
8 changed files with 118 additions and 12 deletions

View File

@@ -84,7 +84,7 @@ static bool handleKey(key_action_t key, int scancodeIdx, usb_keyboard_report_t *
if (hasKeyReleased(prevKeyStates, currKeyStates, keyId)) {
ActiveLayer = LAYER_ID_BASE;
}
LedDisplay_SetLayerLed(ActiveLayer);
//LedDisplay_SetLayerLed(ActiveLayer);
return false;
break;
default:

View File

@@ -0,0 +1,73 @@
#include "fsl_i2c.h"
#include "led_driver.h"
#include "bridge_protocol_scheduler.h"
#include "slot.h"
#include "main.h"
#define BUFFER_SIZE (LED_DRIVER_LED_COUNT + 1)
i2c_master_handle_t masterHandle;
i2c_master_config_t masterConfig;
uint8_t ledsBuffer[BUFFER_SIZE] = {FRAME_REGISTER_PWM_FIRST};
i2c_master_transfer_t masterXfer;
uint8_t currentBridgeSlaveId = 0;
bridge_slave_t bridgeSlaves[] = {
{ .i2cAddress = I2C_ADDRESS_LEFT_KEYBOARD_HALF, .type = BridgeSlaveType_UhkModule },
{ .i2cAddress = I2C_ADDRESS_LED_DRIVER_LEFT, .type = BridgeSlaveType_LedDriver },
// { .i2cAddress = I2C_ADDRESS_LED_DRIVER_RIGHT, .type = BridgeSlaveType_LedDriver }
};
// Possible I2C statuses to log:
// kStatus_Success
// kStatus_I2C_Timeout
// kStatus_I2C_ArbitrationLost
// kStatus_I2C_Nak
// kStatus_I2C_Busy
// kStatus_I2C_Idle
void i2cAsyncWrite(uint8_t i2cAddress, uint8_t *volatile data, volatile size_t dataSize)
{
masterXfer.slaveAddress = i2cAddress;
masterXfer.direction = kI2C_Write;
masterXfer.data = data;
masterXfer.dataSize = dataSize;
I2C_MasterTransferNonBlocking(I2C_MAIN_BUS_BASEADDR, &masterHandle, &masterXfer);
}
void i2cAsyncRead(uint8_t i2cAddress, uint8_t *volatile data, volatile size_t dataSize)
{
masterXfer.slaveAddress = i2cAddress;
masterXfer.direction = kI2C_Read;
masterXfer.data = data;
masterXfer.dataSize = dataSize;
I2C_MasterTransferNonBlocking(I2C_MAIN_BUS_BASEADDR, &masterHandle, &masterXfer);
}
static void bridgeProtocolCallback(I2C_Type *base, i2c_master_handle_t *handle, status_t status, void *userData)
{
bridge_slave_t *bridgeSlave = bridgeSlaves + currentBridgeSlaveId;
if (bridgeSlave->type == BridgeSlaveType_UhkModule) {
i2cAsyncRead(I2C_ADDRESS_LEFT_KEYBOARD_HALF, CurrentKeyStates[SLOT_ID_LEFT_KEYBOARD_HALF], LEFT_KEYBOARD_HALF_KEY_COUNT);
// i2cAsyncRead(bridgeSlave->i2cAddress, ledsBuffer, BUFFER_SIZE);
// i2cAsyncWrite(I2C_ADDRESS_LED_DRIVER_LEFT, txBuff, BUFFER_SIZE);
} else if (bridgeSlave->type == BridgeSlaveType_LedDriver) {
i2cAsyncWrite(I2C_ADDRESS_LED_DRIVER_LEFT, ledsBuffer, BUFFER_SIZE);
}
if (++currentBridgeSlaveId >= (sizeof(bridgeSlaves) / sizeof(bridge_slave_t))) {
currentBridgeSlaveId = 0;
}
}
void InitBridgeProtocolScheduler()
{
I2C_MasterTransferCreateHandle(I2C_MAIN_BUS_BASEADDR, &masterHandle, bridgeProtocolCallback, NULL);
i2cAsyncWrite(I2C_ADDRESS_LED_DRIVER_LEFT, ledsBuffer, BUFFER_SIZE);
}
void SetLeds(uint8_t ledBrightness)
{
memset(ledsBuffer+1, ledBrightness, LED_DRIVER_LED_COUNT);
}

View File

@@ -0,0 +1,27 @@
#ifndef __BRIDGE_PROTOCOL_SCHEDULER_H__
#define __BRIDGE_PROTOCOL_SCHEDULER_H__
// Includes:
#include "fsl_common.h"
// Typedefs:
typedef enum {
BridgeSlaveType_LedDriver,
BridgeSlaveType_UhkModule,
BridgeSlaveType_Touchpad
} bridge_slave_type_t;
typedef struct {
uint8_t i2cAddress;
bridge_slave_type_t type;
bool isConnected;
} bridge_slave_t;
// Functions:
void InitBridgeProtocolScheduler();
void SetLeds(uint8_t ledBrightness);
#endif

View File

@@ -53,6 +53,6 @@ void InitPeripherials(void)
LedPwm_Init();
#endif
InitTestLed(); // This function must not be called before LedPwm_Init() or else the UHK won't
// enumerate over USB unless disconnecting it, waiting for at least 4 seconds
// reenumerate over USB unless disconnecting it, waiting for at least 4 seconds
// and reconnecting it. This is the strangest thing ever!
}

View File

@@ -29,6 +29,8 @@
#define LED_DRIVER_FRAME_8 7
#define LED_DRIVER_FRAME_FUNCTION 0x0B
#define LED_DRIVER_LED_COUNT (2*8*9)
#define FRAME_REGISTER_LED_CONTROL_FIRST 0x00
#define FRAME_REGISTER_LED_CONTROL_LAST 0x11
#define FRAME_REGISTER_BLINK_CONTROL_FIRST 0x12

View File

@@ -5,6 +5,8 @@
#include "led_driver.h"
#include "deserialize.h"
#include "action.h"
#include "bridge_protocol_scheduler.h"
#include "test_led.h"
key_matrix_t KeyMatrix = {
.colNum = KEYBOARD_MATRIX_COLS_NUM,
@@ -66,11 +68,11 @@ void UpdateUsbReports()
KeyMatrix_Scan(&KeyMatrix);
memcpy(CurrentKeyStates[SLOT_ID_RIGHT_KEYBOARD_HALF], KeyMatrix.keyStates, MAX_KEY_COUNT_PER_MODULE);
uint8_t txData[] = {0};
bzero(CurrentKeyStates[SLOT_ID_LEFT_KEYBOARD_HALF], MAX_KEY_COUNT_PER_MODULE);
if (I2cWrite(I2C_MAIN_BUS_BASEADDR, I2C_ADDRESS_LEFT_KEYBOARD_HALF, txData, sizeof(txData)) == kStatus_Success) {
I2cRead(I2C_MAIN_BUS_BASEADDR, I2C_ADDRESS_LEFT_KEYBOARD_HALF, CurrentKeyStates[SLOT_ID_LEFT_KEYBOARD_HALF], LEFT_KEYBOARD_HALF_KEY_COUNT);
}
// uint8_t txData[] = {0};
// bzero(CurrentKeyStates[SLOT_ID_LEFT_KEYBOARD_HALF], MAX_KEY_COUNT_PER_MODULE);
// if (I2cWrite(I2C_MAIN_BUS_BASEADDR, I2C_ADDRESS_LEFT_KEYBOARD_HALF, txData, sizeof(txData)) == kStatus_Success) {
// I2cRead(I2C_MAIN_BUS_BASEADDR, I2C_ADDRESS_LEFT_KEYBOARD_HALF, CurrentKeyStates[SLOT_ID_LEFT_KEYBOARD_HALF], LEFT_KEYBOARD_HALF_KEY_COUNT);
// }
HandleKeyboardEvents(ActiveUsbKeyboardReport, &UsbMouseReport);
@@ -81,6 +83,7 @@ void main() {
InitPeripherials();
InitClock();
LedDriver_InitAllLeds(1);
InitBridgeProtocolScheduler();
KeyMatrix_Init(&KeyMatrix);
//UpdateUsbReports();
InitUsb();

View File

@@ -13,7 +13,6 @@
#define KEYBOARD_MATRIX_ROWS_NUM 5
#define LEFT_KEYBOARD_HALF_KEY_COUNT (5*7)
// Variables:
extern key_matrix_t KeyMatrix;

View File

@@ -7,6 +7,7 @@
#include "deserialize.h"
#include "config_buffer.h"
#include "led_pwm.h"
#include "bridge_protocol_scheduler.h"
void setError(uint8_t error);
void setGenericError();
@@ -57,10 +58,10 @@ void usbProtocolHandler()
getSetTestLed();
break;
case USB_COMMAND_WRITE_LED_DRIVER:
writeLedDriver();
//writeLedDriver();
break;
case USB_COMMAND_READ_LED_DRIVER:
readLedDriver();
//readLedDriver();
break;
case USB_COMMAND_WRITE_EEPROM:
writeEeprom();
@@ -119,8 +120,8 @@ void jumpToBootloader() {
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));
// uint8_t data[] = {1, ledState};
// I2cWrite(I2C_MAIN_BUS_BASEADDR, I2C_ADDRESS_LEFT_KEYBOARD_HALF, data, sizeof(data));
switch (ledState) {
case 0:
@@ -130,6 +131,7 @@ void getSetTestLed()
TEST_LED_OFF();
break;
}
SetLeds(ledState ? 0xff : 0);
}
void writeLedDriver()