Refactor the state machine

This commit is contained in:
Eric Tang
2018-08-12 13:11:28 -07:00
parent 26da686e4d
commit 5ae351db6f
2 changed files with 98 additions and 131 deletions

View File

@@ -13,49 +13,6 @@ enum {
uint8_t KeyBacklightBrightness = 0xff; uint8_t KeyBacklightBrightness = 0xff;
uint8_t LedDriverValues[LED_DRIVER_MAX_COUNT][LED_DRIVER_LED_COUNT]; uint8_t LedDriverValues[LED_DRIVER_MAX_COUNT][LED_DRIVER_LED_COUNT];
const static led_driver_phase_sequence_t ledDriverPhaseSequenceInit = {
(led_driver_phase_t []){
LedDriverPhase_SetFunctionFrame,
LedDriverPhase_SetShutdownModeNormal,
LedDriverPhase_InitAutoPlayControlRegister1,
LedDriverPhase_InitAutoPlayControlRegister2,
LedDriverPhase_InitBreathControlRegister1,
LedDriverPhase_InitBreathControlRegister2,
LedDriverPhase_SetFrame2,
LedDriverPhase_InitLedControlRegistersZero,
LedDriverPhase_SetFrame8,
LedDriverPhase_InitLedControlRegistersZero,
LedDriverPhase_SetFrame1,
LedDriverPhase_InitLedControlRegisters,
LedDriverPhase_InitLedValues
},
13
};
const static led_driver_phase_sequence_t ledDriverPhaseSequenceUpdateLeds = {
(led_driver_phase_t []){
LedDriverPhase_SetFrame1,
LedDriverPhase_UpdateChangedLedValues
},
2
};
const static led_driver_phase_sequence_t ledDriverPhaseSequenceDisableLeds = {
(led_driver_phase_t []){
LedDriverPhase_SetFunctionFrame,
LedDriverPhase_SetConfigurationRegisterFadeOut,
},
2
};
const static led_driver_phase_sequence_t ledDriverPhaseSequenceEnableLeds = {
(led_driver_phase_t []){
LedDriverPhase_SetFunctionFrame,
LedDriverPhase_SetConfigurationRegisterFadeIn,
},
2
};
static led_driver_state_t ledDriverStates[LED_DRIVER_MAX_COUNT] = { static led_driver_state_t ledDriverStates[LED_DRIVER_MAX_COUNT] = {
{ {
.i2cAddress = I2C_ADDRESS_IS31FL3731_RIGHT, .i2cAddress = I2C_ADDRESS_IS31FL3731_RIGHT,
@@ -174,56 +131,59 @@ status_t LedSlaveDriver_Update(uint8_t ledDriverId)
uint8_t ledDriverAddress = currentLedDriverState->i2cAddress; uint8_t ledDriverAddress = currentLedDriverState->i2cAddress;
uint8_t *ledIndex = &currentLedDriverState->ledIndex; uint8_t *ledIndex = &currentLedDriverState->ledIndex;
if (!currentLedDriverState->phaseSequence) { switch (currentLedDriverState->phase) {
if (currentLedDriverState->phaseSequenceRequests) { case LedDriverPhase_SetFunctionFrameInit:
if (currentLedDriverState->phaseSequenceRequests & PhaseSequenceRequest_Init) {
currentLedDriverState->phaseSequence = &ledDriverPhaseSequenceInit;
currentLedDriverState->phaseSequenceRequests &= ~PhaseSequenceRequest_Init;
} else if (currentLedDriverState->phaseSequenceRequests & PhaseSequenceRequest_EnableLeds) {
currentLedDriverState->phaseSequence = &ledDriverPhaseSequenceEnableLeds;
currentLedDriverState->phaseSequenceRequests &= ~PhaseSequenceRequest_EnableLeds;
} else if (currentLedDriverState->phaseSequenceRequests & PhaseSequenceRequest_DisableLeds) {
currentLedDriverState->phaseSequence = &ledDriverPhaseSequenceDisableLeds;
currentLedDriverState->phaseSequenceRequests &= ~PhaseSequenceRequest_DisableLeds;
} else if (currentLedDriverState->phaseSequenceRequests & PhaseSequenceRequest_UpdateLeds) {
currentLedDriverState->phaseSequence = &ledDriverPhaseSequenceUpdateLeds;
currentLedDriverState->phaseSequenceRequests &= ~PhaseSequenceRequest_UpdateLeds;
}
currentLedDriverState->phaseSequenceIndex = 0;
} else {
return kStatus_Uhk_IdleSlave;
}
}
switch (currentLedDriverState->phaseSequence->phases[currentLedDriverState->phaseSequenceIndex]) {
case LedDriverPhase_SetFunctionFrame:
// if (ledDriverId == LedDriverId_Left && !Slaves[SlaveId_LeftKeyboardHalf].isConnected) { // if (ledDriverId == LedDriverId_Left && !Slaves[SlaveId_LeftKeyboardHalf].isConnected) {
// break; // break;
// } // }
status = I2cAsyncWrite(ledDriverAddress, setFunctionFrameBuffer, sizeof(setFunctionFrameBuffer)); status = I2cAsyncWrite(ledDriverAddress, setFunctionFrameBuffer, sizeof(setFunctionFrameBuffer));
++currentLedDriverState->phaseSequenceIndex; currentLedDriverState->phase = LedDriverPhase_SetShutdownModeNormalInit;
break; break;
case LedDriverPhase_SetShutdownModeNormal: case LedDriverPhase_SetShutdownModeNormalInit:
status = I2cAsyncWrite(ledDriverAddress, setShutdownModeNormalBuffer, sizeof(setShutdownModeNormalBuffer)); status = I2cAsyncWrite(ledDriverAddress, setShutdownModeNormalBuffer, sizeof(setShutdownModeNormalBuffer));
++currentLedDriverState->phaseSequenceIndex; currentLedDriverState->phase = LedDriverPhase_InitAutoPlayControlRegister1Init;
break; break;
case LedDriverPhase_SetFrame1: case LedDriverPhase_InitAutoPlayControlRegister1Init:
status = I2cAsyncWrite(ledDriverAddress, setFrame1Buffer, sizeof(setFrame1Buffer)); status = I2cAsyncWrite(ledDriverAddress, initAutoPlayControlRegister1Buffer, sizeof(initAutoPlayControlRegister1Buffer));
++currentLedDriverState->phaseSequenceIndex; currentLedDriverState->phase = LedDriverPhase_InitAutoPlayControlRegister2Init;
break; break;
case LedDriverPhase_SetFrame2: case LedDriverPhase_InitAutoPlayControlRegister2Init:
status = I2cAsyncWrite(ledDriverAddress, initAutoPlayControlRegister2Buffer, sizeof(initAutoPlayControlRegister2Buffer));
currentLedDriverState->phase = LedDriverPhase_InitBreathControlRegister1Init;
break;
case LedDriverPhase_InitBreathControlRegister1Init:
status = I2cAsyncWrite(ledDriverAddress, initBreathControlRegister1Buffer, sizeof(initBreathControlRegister1Buffer));
currentLedDriverState->phase = LedDriverPhase_InitBreathControlRegister2Init;
break;
case LedDriverPhase_InitBreathControlRegister2Init:
status = I2cAsyncWrite(ledDriverAddress, initBreathControlRegister2Buffer, sizeof(initBreathControlRegister2Buffer));
currentLedDriverState->phase = LedDriverPhase_SetFrame2Init;
break;
case LedDriverPhase_SetFrame2Init:
status = I2cAsyncWrite(ledDriverAddress, setFrame2Buffer, sizeof(setFrame2Buffer)); status = I2cAsyncWrite(ledDriverAddress, setFrame2Buffer, sizeof(setFrame2Buffer));
++currentLedDriverState->phaseSequenceIndex; currentLedDriverState->phase = LedDriverPhase_InitLedControlRegistersZero1Init;
break; break;
case LedDriverPhase_SetFrame8: case LedDriverPhase_InitLedControlRegistersZero1Init:
status = I2cAsyncWrite(ledDriverAddress, initLedControlRegistersZeroBuffer, sizeof(initLedControlRegistersZeroBuffer));
currentLedDriverState->phase = LedDriverPhase_SetFrame8Init;
break;
case LedDriverPhase_SetFrame8Init:
status = I2cAsyncWrite(ledDriverAddress, setFrame8Buffer, sizeof(setFrame8Buffer)); status = I2cAsyncWrite(ledDriverAddress, setFrame8Buffer, sizeof(setFrame8Buffer));
++currentLedDriverState->phaseSequenceIndex; currentLedDriverState->phase = LedDriverPhase_InitLedControlRegistersZero2Init;
break; break;
case LedDriverPhase_InitLedControlRegisters: case LedDriverPhase_InitLedControlRegistersZero2Init:
status = I2cAsyncWrite(ledDriverAddress, initLedControlRegistersZeroBuffer, sizeof(initLedControlRegistersZeroBuffer));
currentLedDriverState->phase = LedDriverPhase_SetFrame1Init;
break;
case LedDriverPhase_SetFrame1Init:
status = I2cAsyncWrite(ledDriverAddress, setFrame1Buffer, sizeof(setFrame1Buffer));
currentLedDriverState->phase = LedDriverPhase_InitLedControlRegistersInit;
break;
case LedDriverPhase_InitLedControlRegistersInit:
status = I2cAsyncWrite(ledDriverAddress, currentLedDriverState->setupLedControlRegistersCommand, LED_CONTROL_REGISTERS_COMMAND_LENGTH); status = I2cAsyncWrite(ledDriverAddress, currentLedDriverState->setupLedControlRegistersCommand, LED_CONTROL_REGISTERS_COMMAND_LENGTH);
++currentLedDriverState->phaseSequenceIndex; currentLedDriverState->phase = LedDriverPhase_InitLedValuesInit;
break; break;
case LedDriverPhase_InitLedValues: case LedDriverPhase_InitLedValuesInit:
updatePwmRegistersBuffer[0] = FRAME_REGISTER_PWM_FIRST + *ledIndex; updatePwmRegistersBuffer[0] = FRAME_REGISTER_PWM_FIRST + *ledIndex;
uint8_t chunkSize = MIN(LED_DRIVER_LED_COUNT - *ledIndex, PMW_REGISTER_UPDATE_CHUNK_SIZE); uint8_t chunkSize = MIN(LED_DRIVER_LED_COUNT - *ledIndex, PMW_REGISTER_UPDATE_CHUNK_SIZE);
memcpy(updatePwmRegistersBuffer+1, ledValues + *ledIndex, chunkSize); memcpy(updatePwmRegistersBuffer+1, ledValues + *ledIndex, chunkSize);
@@ -232,10 +192,25 @@ status_t LedSlaveDriver_Update(uint8_t ledDriverId)
if (*ledIndex >= LED_DRIVER_LED_COUNT) { if (*ledIndex >= LED_DRIVER_LED_COUNT) {
*ledIndex = 0; *ledIndex = 0;
memcpy(currentLedDriverState->targetLedValues, ledValues, LED_DRIVER_LED_COUNT); memcpy(currentLedDriverState->targetLedValues, ledValues, LED_DRIVER_LED_COUNT);
++currentLedDriverState->phaseSequenceIndex; currentLedDriverState->phase = LedDriverPhase_Idle;
} }
break; break;
case LedDriverPhase_UpdateChangedLedValues: { case LedDriverPhase_Idle:
if (currentLedDriverState->phaseSequenceRequests & PhaseSequenceRequest_Init) {
currentLedDriverState->phase = LedDriverPhase_SetFunctionFrameInit;
currentLedDriverState->phaseSequenceRequests &= ~PhaseSequenceRequest_Init;
} else if (currentLedDriverState->phaseSequenceRequests & PhaseSequenceRequest_EnableLeds) {
currentLedDriverState->phase = LedDriverPhase_SetFunctionFrameEnableLeds;
currentLedDriverState->phaseSequenceRequests &= ~PhaseSequenceRequest_EnableLeds;
} else if (currentLedDriverState->phaseSequenceRequests & PhaseSequenceRequest_DisableLeds) {
currentLedDriverState->phase = LedDriverPhase_SetFunctionFrameDisableLeds;
currentLedDriverState->phaseSequenceRequests &= ~PhaseSequenceRequest_DisableLeds;
} else if (currentLedDriverState->phaseSequenceRequests & PhaseSequenceRequest_UpdateLeds) {
currentLedDriverState->phase = LedDriverPhase_UpdateChangedLedValuesUpdateLeds;
currentLedDriverState->phaseSequenceRequests &= ~PhaseSequenceRequest_UpdateLeds;
}
break;
case LedDriverPhase_UpdateChangedLedValuesUpdateLeds: {
uint8_t *targetLedValues = currentLedDriverState->targetLedValues; uint8_t *targetLedValues = currentLedDriverState->targetLedValues;
uint8_t lastLedChunkStartIndex = LED_DRIVER_LED_COUNT - PMW_REGISTER_UPDATE_CHUNK_SIZE; uint8_t lastLedChunkStartIndex = LED_DRIVER_LED_COUNT - PMW_REGISTER_UPDATE_CHUNK_SIZE;
@@ -255,7 +230,7 @@ status_t LedSlaveDriver_Update(uint8_t ledDriverId)
bool foundStartIndex = count < LED_DRIVER_LED_COUNT; bool foundStartIndex = count < LED_DRIVER_LED_COUNT;
if (!foundStartIndex) { if (!foundStartIndex) {
*ledIndex = 0; *ledIndex = 0;
++currentLedDriverState->phaseSequenceIndex; currentLedDriverState->phase = LedDriverPhase_Idle;
break; break;
} }
@@ -276,43 +251,35 @@ status_t LedSlaveDriver_Update(uint8_t ledDriverId)
*ledIndex += length; *ledIndex += length;
if (*ledIndex >= LED_DRIVER_LED_COUNT) { if (*ledIndex >= LED_DRIVER_LED_COUNT) {
*ledIndex = 0; *ledIndex = 0;
++currentLedDriverState->phaseSequenceIndex; currentLedDriverState->phase = LedDriverPhase_Idle;
} }
break; break;
} }
case LedDriverPhase_InitAutoPlayControlRegister1: case LedDriverPhase_SetFunctionFrameDisableLeds:
status = I2cAsyncWrite(ledDriverAddress, initAutoPlayControlRegister1Buffer, sizeof(initAutoPlayControlRegister1Buffer)); status = I2cAsyncWrite(ledDriverAddress, setFunctionFrameBuffer, sizeof(setFunctionFrameBuffer));
++currentLedDriverState->phaseSequenceIndex; currentLedDriverState->phase = LedDriverPhase_SetConfigurationRegisterDisableLeds;
break; break;
case LedDriverPhase_InitAutoPlayControlRegister2: case LedDriverPhase_SetConfigurationRegisterDisableLeds:
status = I2cAsyncWrite(ledDriverAddress, initAutoPlayControlRegister2Buffer, sizeof(initAutoPlayControlRegister2Buffer));
++currentLedDriverState->phaseSequenceIndex;
break;
case LedDriverPhase_InitBreathControlRegister1:
status = I2cAsyncWrite(ledDriverAddress, initBreathControlRegister1Buffer, sizeof(initBreathControlRegister1Buffer));
++currentLedDriverState->phaseSequenceIndex;
break;
case LedDriverPhase_InitBreathControlRegister2:
status = I2cAsyncWrite(ledDriverAddress, initBreathControlRegister2Buffer, sizeof(initBreathControlRegister2Buffer));
++currentLedDriverState->phaseSequenceIndex;
break;
case LedDriverPhase_SetConfigurationRegisterFadeOut:
status = I2cAsyncWrite(ledDriverAddress, setConfigurationRegisterFadeOutBuffer, sizeof(setConfigurationRegisterFadeOutBuffer)); status = I2cAsyncWrite(ledDriverAddress, setConfigurationRegisterFadeOutBuffer, sizeof(setConfigurationRegisterFadeOutBuffer));
++currentLedDriverState->phaseSequenceIndex; currentLedDriverState->phase = LedDriverPhase_SetFrame1DisableLeds;
break; break;
case LedDriverPhase_SetConfigurationRegisterFadeIn: case LedDriverPhase_SetFrame1DisableLeds:
status = I2cAsyncWrite(ledDriverAddress, setFrame1Buffer, sizeof(setFrame1Buffer));
currentLedDriverState->phase = LedDriverPhase_Idle;
break;
case LedDriverPhase_SetFunctionFrameEnableLeds:
status = I2cAsyncWrite(ledDriverAddress, setFunctionFrameBuffer, sizeof(setFunctionFrameBuffer));
currentLedDriverState->phase = LedDriverPhase_SetConfigurationRegisterEnableLeds;
break;
case LedDriverPhase_SetConfigurationRegisterEnableLeds:
status = I2cAsyncWrite(ledDriverAddress, setConfigurationRegisterFadeInBuffer, sizeof(setConfigurationRegisterFadeInBuffer)); status = I2cAsyncWrite(ledDriverAddress, setConfigurationRegisterFadeInBuffer, sizeof(setConfigurationRegisterFadeInBuffer));
++currentLedDriverState->phaseSequenceIndex; currentLedDriverState->phase = LedDriverPhase_SetFrame1EnableLeds;
break; break;
case LedDriverPhase_InitLedControlRegistersZero: case LedDriverPhase_SetFrame1EnableLeds:
status = I2cAsyncWrite(ledDriverAddress, initLedControlRegistersZeroBuffer, sizeof(initLedControlRegistersZeroBuffer)); status = I2cAsyncWrite(ledDriverAddress, setFrame1Buffer, sizeof(setFrame1Buffer));
++currentLedDriverState->phaseSequenceIndex; currentLedDriverState->phase = LedDriverPhase_Idle;
break; break;
} }
if (currentLedDriverState->phaseSequenceIndex == currentLedDriverState->phaseSequence->phaseCount) {
currentLedDriverState->phaseSequence = NULL;
}
return status; return status;
} }

View File

@@ -27,32 +27,32 @@
} led_driver_id_t; } led_driver_id_t;
typedef enum { typedef enum {
LedDriverPhase_SetFunctionFrame, LedDriverPhase_Idle,
LedDriverPhase_SetShutdownModeNormal, LedDriverPhase_SetFunctionFrameInit,
LedDriverPhase_SetFrame1, LedDriverPhase_SetFunctionFrameDisableLeds,
LedDriverPhase_SetFrame2, LedDriverPhase_SetFunctionFrameEnableLeds,
LedDriverPhase_SetFrame8, LedDriverPhase_SetShutdownModeNormalInit,
LedDriverPhase_InitAutoPlayControlRegister1, LedDriverPhase_SetFrame1Init,
LedDriverPhase_InitAutoPlayControlRegister2, LedDriverPhase_SetFrame1EnableLeds,
LedDriverPhase_InitBreathControlRegister1, LedDriverPhase_SetFrame1DisableLeds,
LedDriverPhase_InitBreathControlRegister2, LedDriverPhase_SetFrame2Init,
LedDriverPhase_InitLedControlRegisters, LedDriverPhase_SetFrame8Init,
LedDriverPhase_InitLedValues, LedDriverPhase_InitAutoPlayControlRegister1Init,
LedDriverPhase_UpdateChangedLedValues, LedDriverPhase_InitAutoPlayControlRegister2Init,
LedDriverPhase_SetConfigurationRegisterFadeOut, LedDriverPhase_InitBreathControlRegister1Init,
LedDriverPhase_SetConfigurationRegisterFadeIn, LedDriverPhase_InitBreathControlRegister2Init,
LedDriverPhase_InitLedControlRegistersZero LedDriverPhase_InitLedControlRegistersZero1Init,
LedDriverPhase_InitLedControlRegistersZero2Init,
LedDriverPhase_InitLedValuesInit,
LedDriverPhase_UpdateChangedLedValuesUpdateLeds,
LedDriverPhase_SetConfigurationRegisterDisableLeds,
LedDriverPhase_SetConfigurationRegisterEnableLeds,
LedDriverPhase_InitLedControlRegistersInit
} led_driver_phase_t; } led_driver_phase_t;
typedef struct { typedef struct {
led_driver_phase_t *phases;
uint8_t phaseCount;
} led_driver_phase_sequence_t;
typedef struct {
const led_driver_phase_sequence_t *volatile phaseSequence;
volatile uint8_t phaseSequenceRequests; volatile uint8_t phaseSequenceRequests;
volatile uint8_t phaseSequenceIndex; volatile led_driver_phase_t phase;
volatile uint8_t targetLedValues[LED_DRIVER_LED_COUNT]; volatile uint8_t targetLedValues[LED_DRIVER_LED_COUNT];
volatile uint8_t ledIndex; volatile uint8_t ledIndex;
uint8_t i2cAddress; uint8_t i2cAddress;