Add kStatus_Uhk_IdleSlave and ditch the global IsI2cTransferScheduled. Make slave drivers return status_t and utilize that value instead.

This commit is contained in:
László Monda
2017-08-19 17:47:56 +02:00
parent 430c02f0ed
commit 946d3c1451
8 changed files with 38 additions and 26 deletions

View File

@@ -1,7 +1,6 @@
#include "i2c.h"
i2c_master_handle_t I2cMasterHandle;
bool IsI2cTransferScheduled;
i2c_master_transfer_t masterTransfer;
status_t I2cAsyncWrite(uint8_t i2cAddress, uint8_t *data, size_t dataSize)
@@ -11,7 +10,6 @@ status_t I2cAsyncWrite(uint8_t i2cAddress, uint8_t *data, size_t dataSize)
masterTransfer.data = data;
masterTransfer.dataSize = dataSize;
status_t status = I2C_MasterTransferNonBlocking(I2C_MAIN_BUS_BASEADDR, &I2cMasterHandle, &masterTransfer);
IsI2cTransferScheduled = status == kStatus_Success;
return status;
}
@@ -22,6 +20,5 @@ status_t I2cAsyncRead(uint8_t i2cAddress, uint8_t *data, size_t dataSize)
masterTransfer.data = data;
masterTransfer.dataSize = dataSize;
status_t status = I2C_MasterTransferNonBlocking(I2C_MAIN_BUS_BASEADDR, &I2cMasterHandle, &masterTransfer);
IsI2cTransferScheduled = status == kStatus_Success;
return status;
}

View File

@@ -40,7 +40,6 @@
// Variables:
extern i2c_master_handle_t I2cMasterHandle;
extern bool IsI2cTransferScheduled;
// Functions:

View File

@@ -68,7 +68,8 @@ void LedSlaveDriver_Init(uint8_t ledDriverId) {
LedDisplay_SetText(3, "ABC");
}
void LedSlaveDriver_Update(uint8_t ledDriverId) {
status_t LedSlaveDriver_Update(uint8_t ledDriverId) {
status_t status = kStatus_Uhk_IdleSlave;
led_driver_state_t *currentLedDriverState = LedDriverStates + ledDriverId;
uint8_t *ledDriverPhase = &currentLedDriverState->phase;
uint8_t ledDriverAddress = currentLedDriverState->i2cAddress;
@@ -79,26 +80,26 @@ void LedSlaveDriver_Update(uint8_t ledDriverId) {
if (ledDriverId == LedDriverId_Left && !Slaves[SlaveId_LeftKeyboardHalf].isConnected) {
break;
}
I2cAsyncWrite(ledDriverAddress, setFunctionFrameBuffer, sizeof(setFunctionFrameBuffer));
status = I2cAsyncWrite(ledDriverAddress, setFunctionFrameBuffer, sizeof(setFunctionFrameBuffer));
*ledDriverPhase = LedDriverPhase_SetShutdownModeNormal;
break;
case LedDriverPhase_SetShutdownModeNormal:
I2cAsyncWrite(ledDriverAddress, setShutdownModeNormalBuffer, sizeof(setShutdownModeNormalBuffer));
status = I2cAsyncWrite(ledDriverAddress, setShutdownModeNormalBuffer, sizeof(setShutdownModeNormalBuffer));
*ledDriverPhase = LedDriverPhase_SetFrame1;
break;
case LedDriverPhase_SetFrame1:
I2cAsyncWrite(ledDriverAddress, setFrame1Buffer, sizeof(setFrame1Buffer));
status = I2cAsyncWrite(ledDriverAddress, setFrame1Buffer, sizeof(setFrame1Buffer));
*ledDriverPhase = LedDriverPhase_InitLedControlRegisters;
break;
case LedDriverPhase_InitLedControlRegisters:
I2cAsyncWrite(ledDriverAddress, currentLedDriverState->setupLedControlRegistersCommand, LED_CONTROL_REGISTERS_COMMAND_LENGTH);
status = I2cAsyncWrite(ledDriverAddress, currentLedDriverState->setupLedControlRegistersCommand, LED_CONTROL_REGISTERS_COMMAND_LENGTH);
*ledDriverPhase = LedDriverPhase_InitLedValues;
break;
case LedDriverPhase_InitLedValues:
updatePwmRegistersBuffer[0] = FRAME_REGISTER_PWM_FIRST + *ledIndex;
uint8_t chunkSize = MIN(LED_DRIVER_LED_COUNT - *ledIndex, PMW_REGISTER_UPDATE_CHUNK_SIZE);
memcpy(updatePwmRegistersBuffer+1, currentLedDriverState->sourceLedValues + *ledIndex, chunkSize);
I2cAsyncWrite(ledDriverAddress, updatePwmRegistersBuffer, chunkSize + 1);
status = I2cAsyncWrite(ledDriverAddress, updatePwmRegistersBuffer, chunkSize + 1);
*ledIndex += chunkSize;
if (*ledIndex >= LED_DRIVER_LED_COUNT) {
*ledIndex = 0;
@@ -129,7 +130,7 @@ void LedSlaveDriver_Update(uint8_t ledDriverId) {
bool foundStartIndex = count < LED_DRIVER_LED_COUNT;
if (!foundStartIndex) {
*ledIndex = 0;
return;
break;
}
uint8_t maxChunkSize = MIN(LED_DRIVER_LED_COUNT - startLedIndex, PMW_REGISTER_UPDATE_CHUNK_SIZE);
@@ -145,7 +146,7 @@ void LedSlaveDriver_Update(uint8_t ledDriverId) {
uint8_t length = endLedIndex - startLedIndex + 1;
memcpy(updatePwmRegistersBuffer+1, currentLedDriverState->sourceLedValues + startLedIndex, length);
memcpy(currentLedDriverState->targetLedValues + startLedIndex, currentLedDriverState->sourceLedValues + startLedIndex, length);
I2cAsyncWrite(ledDriverAddress, updatePwmRegistersBuffer, length+1);
status = I2cAsyncWrite(ledDriverAddress, updatePwmRegistersBuffer, length+1);
*ledIndex += length;
if (*ledIndex >= LED_DRIVER_LED_COUNT) {
*ledIndex = 0;
@@ -153,6 +154,8 @@ void LedSlaveDriver_Update(uint8_t ledDriverId) {
break;
}
}
return status;
}
void SetLeds(uint8_t ledBrightness)

View File

@@ -46,7 +46,7 @@
// Functions:
extern void LedSlaveDriver_Init(uint8_t ledDriverId);
extern void LedSlaveDriver_Update(uint8_t ledDriverId);
extern status_t LedSlaveDriver_Update(uint8_t ledDriverId);
extern void SetLeds(uint8_t ledBrightness);
#endif

View File

@@ -1,5 +1,6 @@
#include "i2c_addresses.h"
#include "i2c.h"
#include "slave_scheduler.h"
#include "slave_drivers/uhk_module_driver.h"
#include "slave_protocol.h"
#include "main.h"
@@ -19,18 +20,19 @@ void UhkModuleSlaveDriver_Init(uint8_t uhkModuleId)
uhkModuleState->ledPwmBrightness = 0x64;
}
void UhkModuleSlaveDriver_Update(uint8_t uhkModuleId)
status_t UhkModuleSlaveDriver_Update(uint8_t uhkModuleId)
{
status_t status = kStatus_Uhk_IdleSlave;
uhk_module_state_t *uhkModuleInternalState = UhkModuleStates + uhkModuleId;
switch (uhkModulePhase) {
case UhkModulePhase_SendKeystatesRequestCommand:
txBuffer[0] = SlaveCommand_GetKeyStates;
I2cAsyncWrite(I2C_ADDRESS_LEFT_KEYBOARD_HALF, txBuffer, 1);
status = I2cAsyncWrite(I2C_ADDRESS_LEFT_KEYBOARD_HALF, txBuffer, 1);
uhkModulePhase = UhkModulePhase_ReceiveKeystates;
break;
case UhkModulePhase_ReceiveKeystates:
I2cAsyncRead(I2C_ADDRESS_LEFT_KEYBOARD_HALF, rxBuffer, KEY_STATE_BUFFER_SIZE);
status = I2cAsyncRead(I2C_ADDRESS_LEFT_KEYBOARD_HALF, rxBuffer, KEY_STATE_BUFFER_SIZE);
uhkModulePhase = UhkModulePhase_SendPwmBrightnessCommand;
break;
case UhkModulePhase_SendPwmBrightnessCommand:
@@ -39,14 +41,16 @@ void UhkModuleSlaveDriver_Update(uint8_t uhkModuleId)
}
txBuffer[0] = SlaveCommand_SetLedPwmBrightness;
txBuffer[1] = uhkModuleInternalState->ledPwmBrightness;
I2cAsyncWrite(I2C_ADDRESS_LEFT_KEYBOARD_HALF, txBuffer, 2);
status = I2cAsyncWrite(I2C_ADDRESS_LEFT_KEYBOARD_HALF, txBuffer, 2);
uhkModulePhase = UhkModulePhase_SendTestLedCommand;
break;
case UhkModulePhase_SendTestLedCommand:
txBuffer[0] = SlaveCommand_SetTestLed;
txBuffer[1] = uhkModuleInternalState->isTestLedOn;
I2cAsyncWrite(I2C_ADDRESS_LEFT_KEYBOARD_HALF, txBuffer, 2);
status = I2cAsyncWrite(I2C_ADDRESS_LEFT_KEYBOARD_HALF, txBuffer, 2);
uhkModulePhase = UhkModulePhase_SendKeystatesRequestCommand;
break;
}
return status;
}

View File

@@ -39,6 +39,6 @@
// Functions:
extern void UhkModuleSlaveDriver_Init(uint8_t uhkModuleId);
extern void UhkModuleSlaveDriver_Update(uint8_t uhkModuleId);
extern status_t UhkModuleSlaveDriver_Update(uint8_t uhkModuleId);
#endif

View File

@@ -17,9 +17,9 @@ uhk_slave_t Slaves[] = {
{ .init = LedSlaveDriver_Init, .update = LedSlaveDriver_Update, .perDriverId = LedDriverId_Left },
};
static void bridgeProtocolCallback(I2C_Type *base, i2c_master_handle_t *handle, status_t status, void *userData)
static void bridgeProtocolCallback(I2C_Type *base, i2c_master_handle_t *handle, status_t previousStatus, void *userData)
{
IsI2cTransferScheduled = false;
bool isTransferScheduled = false;
do {
BridgeCounter++;
@@ -27,14 +27,15 @@ static void bridgeProtocolCallback(I2C_Type *base, i2c_master_handle_t *handle,
uhk_slave_t *previousSlave = Slaves + previousSlaveId;
uhk_slave_t *currentSlave = Slaves + currentSlaveId;
previousSlave->isConnected = status == kStatus_Success;
previousSlave->isConnected = previousStatus == kStatus_Success;
if (!currentSlave->isConnected) {
currentSlave->init(currentSlave->perDriverId);
}
currentSlave->update(currentSlave->perDriverId);
if (IsI2cTransferScheduled) {
status_t currentStatus = currentSlave->update(currentSlave->perDriverId);
isTransferScheduled = currentStatus == kStatus_Success;
if (isTransferScheduled) {
currentSlave->isConnected = true;
}
@@ -44,7 +45,7 @@ static void bridgeProtocolCallback(I2C_Type *base, i2c_master_handle_t *handle,
if (currentSlaveId >= (sizeof(Slaves) / sizeof(uhk_slave_t))) {
currentSlaveId = 0;
}
} while (!IsI2cTransferScheduled);
} while (!isTransferScheduled);
}
static void initSlaveDrivers()

View File

@@ -14,7 +14,7 @@
} slave_id_t;
typedef void (slave_init_t)(uint8_t);
typedef void (slave_update_t)(uint8_t);
typedef status_t (slave_update_t)(uint8_t);
typedef struct {
uint8_t perDriverId; // Identifies the slave instance on a per-driver basis
@@ -23,6 +23,14 @@
bool isConnected;
} uhk_slave_t;
typedef enum {
kStatusGroup_Uhk = -1,
} uhk_status_group_t;
typedef enum {
kStatus_Uhk_IdleSlave = MAKE_STATUS(kStatusGroup_Uhk, 0),
} uhk_status_t;
// Variables:
extern uhk_slave_t Slaves[];