From 26da686e4d85a98bd368884ee36c5680cba716ec Mon Sep 17 00:00:00 2001 From: Eric Tang Date: Sat, 11 Aug 2018 17:04:11 -0700 Subject: [PATCH] Implement the fade out effect --- right/src/config_parser/parse_config.c | 2 - right/src/led_display.c | 3 + right/src/peripherals/led_driver.h | 28 ++- right/src/slave_drivers/is31fl3731_driver.c | 182 +++++++++++++++++--- right/src/slave_drivers/is31fl3731_driver.h | 27 ++- right/src/usb_composite_device.c | 8 +- 6 files changed, 215 insertions(+), 35 deletions(-) diff --git a/right/src/config_parser/parse_config.c b/right/src/config_parser/parse_config.c index 2e1e036..4e84e9a 100644 --- a/right/src/config_parser/parse_config.c +++ b/right/src/config_parser/parse_config.c @@ -146,8 +146,6 @@ parser_error_t ParseConfig(config_buffer_t *buffer) AlphanumericSegmentsBrightness = alphanumericSegmentsBrightness; KeyBacklightBrightness = keyBacklightBrightness; - LedSlaveDriver_UpdateLeds(); - // Update mouse key speeds MouseMoveState.initialSpeed = mouseMoveInitialSpeed; diff --git a/right/src/led_display.c b/right/src/led_display.c index 6979eef..2a3fcf9 100644 --- a/right/src/led_display.c +++ b/right/src/led_display.c @@ -84,6 +84,7 @@ void LedDisplay_SetText(uint8_t length, const char* text) } allSegmentSets >>= 5; } + LedSlaveDriver_UpdateLeds(LedDriverId_Left); } void LedDisplay_SetLayer(layer_id_t layerId) @@ -95,6 +96,7 @@ void LedDisplay_SetLayer(layer_id_t layerId) if (layerId >= LayerId_Mod && layerId <= LayerId_Mouse) { LedDriverValues[LedDriverId_Left][16 * layerId - 3] = IconsAndLayerTextsBrightness; } + LedSlaveDriver_UpdateLeds(LedDriverId_Left); } bool LedDisplay_GetIcon(led_display_icon_t icon) @@ -106,6 +108,7 @@ void LedDisplay_SetIcon(led_display_icon_t icon, bool isEnabled) { ledIconStates[icon] = isEnabled; LedDriverValues[LedDriverId_Left][icon + 8] = isEnabled ? IconsAndLayerTextsBrightness : 0; + LedSlaveDriver_UpdateLeds(LedDriverId_Left); } void LedDisplay_UpdateIcons(void) diff --git a/right/src/peripherals/led_driver.h b/right/src/peripherals/led_driver.h index 1ad835f..c6ddad3 100644 --- a/right/src/peripherals/led_driver.h +++ b/right/src/peripherals/led_driver.h @@ -16,8 +16,13 @@ #define LED_DRIVER_SDB_CLOCK kCLOCK_PortA #define LED_DRIVER_SDB_PIN 2 - #define LED_DRIVER_REGISTER_SHUTDOWN 0x0A - #define LED_DRIVER_REGISTER_FRAME 0xFD + #define LED_DRIVER_REGISTER_SHUTDOWN 0x0A + #define LED_DRIVER_REGISTER_FRAME 0xFD + #define LED_DRIVER_REGISTER_CONFIGURATION 0x00 + #define LED_DRIVER_REGISTER_AUTO_PLAY_CONTROL_1 0x02 + #define LED_DRIVER_REGISTER_AUTO_PLAY_CONTROL_2 0x03 + #define LED_DRIVER_REGISTER_BREATH_CONTROL_1 0x08 + #define LED_DRIVER_REGISTER_BREATH_CONTROL_2 0x09 #define LED_DRIVER_FRAME_1 0 #define LED_DRIVER_FRAME_2 1 @@ -42,6 +47,25 @@ #define SHUTDOWN_MODE_SHUTDOWN 0 #define SHUTDOWN_MODE_NORMAL 1 + #define DISPLAY_MODE_AUTO_FRAME_PLAY 0b01 + #define DISPLAY_MODE_SHIFT 3 + #define FRAME_START_1 0b000 + #define FRAME_START_8 0b111 + + #define PLAY_LOOP_NUMBER_1 0b001 + #define PLAY_LOOP_NUMBER_SHIFT 4 + #define PLAY_FRAME_NUMBER_1 0b001 + + #define FRAME_DELAY_TIME 1 + + #define FADE_OUT_TIME 5 + #define FADE_OUT_TIME_SHIFT 4 + #define FADE_IN_TIME 5 + + #define BREATH_ENABLE 1 + #define BREATH_ENABLE_SHIFT 4 + #define EXTINGUISH_TIME 0 + // Functions: void InitLedDriver(void); diff --git a/right/src/slave_drivers/is31fl3731_driver.c b/right/src/slave_drivers/is31fl3731_driver.c index 1824a44..6f9e736 100644 --- a/right/src/slave_drivers/is31fl3731_driver.c +++ b/right/src/slave_drivers/is31fl3731_driver.c @@ -3,9 +3,59 @@ #include "slave_scheduler.h" #include "led_display.h" +enum { + PhaseSequenceRequest_Init = 1 << 0, + PhaseSequenceRequest_UpdateLeds = 1 << 1, + PhaseSequenceRequest_DisableLeds = 1 << 2, + PhaseSequenceRequest_EnableLeds = 1 << 3 +}; + uint8_t KeyBacklightBrightness = 0xff; 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] = { { .i2cAddress = I2C_ADDRESS_IS31FL3731_RIGHT, @@ -60,22 +110,48 @@ static led_driver_state_t ledDriverStates[LED_DRIVER_MAX_COUNT] = { static uint8_t setFunctionFrameBuffer[] = {LED_DRIVER_REGISTER_FRAME, LED_DRIVER_FRAME_FUNCTION}; static uint8_t setShutdownModeNormalBuffer[] = {LED_DRIVER_REGISTER_SHUTDOWN, SHUTDOWN_MODE_NORMAL}; static uint8_t setFrame1Buffer[] = {LED_DRIVER_REGISTER_FRAME, LED_DRIVER_FRAME_1}; +static uint8_t setFrame2Buffer[] = {LED_DRIVER_REGISTER_FRAME, LED_DRIVER_FRAME_2}; +static uint8_t setFrame8Buffer[] = {LED_DRIVER_REGISTER_FRAME, LED_DRIVER_FRAME_8}; +static uint8_t initLedControlRegistersZeroBuffer[19] = { FRAME_REGISTER_LED_CONTROL_FIRST }; +static uint8_t setConfigurationRegisterFadeInBuffer[] = { + LED_DRIVER_REGISTER_CONFIGURATION, + DISPLAY_MODE_AUTO_FRAME_PLAY << DISPLAY_MODE_SHIFT | FRAME_START_8 +}; +static uint8_t setConfigurationRegisterFadeOutBuffer[] = { + LED_DRIVER_REGISTER_CONFIGURATION, + DISPLAY_MODE_AUTO_FRAME_PLAY << DISPLAY_MODE_SHIFT | FRAME_START_1 +}; +static uint8_t initAutoPlayControlRegister1Buffer[] = { + LED_DRIVER_REGISTER_AUTO_PLAY_CONTROL_1, + PLAY_LOOP_NUMBER_1 << PLAY_LOOP_NUMBER_SHIFT | PLAY_FRAME_NUMBER_1 +}; +static uint8_t initAutoPlayControlRegister2Buffer[] = { + LED_DRIVER_REGISTER_AUTO_PLAY_CONTROL_2, + FRAME_DELAY_TIME +}; +static uint8_t initBreathControlRegister1Buffer[] = { + LED_DRIVER_REGISTER_BREATH_CONTROL_1, + FADE_OUT_TIME << FADE_OUT_TIME_SHIFT | FADE_IN_TIME +}; +static uint8_t initBreathControlRegister2Buffer[] = { + LED_DRIVER_REGISTER_BREATH_CONTROL_2, + BREATH_ENABLE << BREATH_ENABLE_SHIFT | EXTINGUISH_TIME +}; static uint8_t updatePwmRegistersBuffer[PWM_REGISTER_BUFFER_LENGTH]; -void LedSlaveDriver_DisableLeds(void) +void LedSlaveDriver_DisableLeds(uint8_t ledDriverId) { - for (uint8_t ledDriverId=0; ledDriverId<=LedDriverId_Last; ledDriverId++) { - memset(LedDriverValues[ledDriverId], 0, LED_DRIVER_LED_COUNT); - } + ledDriverStates[ledDriverId].phaseSequenceRequests |= PhaseSequenceRequest_DisableLeds; } -void LedSlaveDriver_UpdateLeds(void) +void LedSlaveDriver_EnableLeds(uint8_t ledDriverId) { - for (uint8_t ledDriverId=0; ledDriverId<=LedDriverId_Last; ledDriverId++) { - memset(LedDriverValues[ledDriverId], KeyBacklightBrightness, LED_DRIVER_LED_COUNT); - } + // ledDriverStates[ledDriverId].phaseSequenceRequests |= PhaseSequenceRequest_EnableLeds; +} - LedDisplay_UpdateAll(); +void LedSlaveDriver_UpdateLeds(uint8_t ledDriverId) +{ + ledDriverStates[ledDriverId].phaseSequenceRequests |= PhaseSequenceRequest_UpdateLeds; } void LedSlaveDriver_Init(uint8_t ledDriverId) @@ -85,13 +161,9 @@ void LedSlaveDriver_Init(uint8_t ledDriverId) } led_driver_state_t *currentLedDriverState = ledDriverStates + ledDriverId; - currentLedDriverState->phase = LedDriverPhase_SetFunctionFrame; currentLedDriverState->ledIndex = 0; memset(LedDriverValues[ledDriverId], KeyBacklightBrightness, LED_DRIVER_LED_COUNT); - - if (ledDriverId == LedDriverId_Left) { - LedDisplay_UpdateAll(); - } + ledDriverStates[ledDriverId].phaseSequenceRequests |= PhaseSequenceRequest_Init; } status_t LedSlaveDriver_Update(uint8_t ledDriverId) @@ -99,29 +171,57 @@ status_t LedSlaveDriver_Update(uint8_t ledDriverId) status_t status = kStatus_Uhk_IdleSlave; uint8_t *ledValues = LedDriverValues[ledDriverId]; led_driver_state_t *currentLedDriverState = ledDriverStates + ledDriverId; - uint8_t *ledDriverPhase = ¤tLedDriverState->phase; uint8_t ledDriverAddress = currentLedDriverState->i2cAddress; uint8_t *ledIndex = ¤tLedDriverState->ledIndex; - switch (*ledDriverPhase) { - case LedDriverPhase_SetFunctionFrame: - if (ledDriverId == LedDriverId_Left && !Slaves[SlaveId_LeftKeyboardHalf].isConnected) { - break; + if (!currentLedDriverState->phaseSequence) { + if (currentLedDriverState->phaseSequenceRequests) { + 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) { + // break; + // } status = I2cAsyncWrite(ledDriverAddress, setFunctionFrameBuffer, sizeof(setFunctionFrameBuffer)); - *ledDriverPhase = LedDriverPhase_SetShutdownModeNormal; + ++currentLedDriverState->phaseSequenceIndex; break; case LedDriverPhase_SetShutdownModeNormal: status = I2cAsyncWrite(ledDriverAddress, setShutdownModeNormalBuffer, sizeof(setShutdownModeNormalBuffer)); - *ledDriverPhase = LedDriverPhase_SetFrame1; + ++currentLedDriverState->phaseSequenceIndex; break; case LedDriverPhase_SetFrame1: status = I2cAsyncWrite(ledDriverAddress, setFrame1Buffer, sizeof(setFrame1Buffer)); - *ledDriverPhase = LedDriverPhase_InitLedControlRegisters; + ++currentLedDriverState->phaseSequenceIndex; + break; + case LedDriverPhase_SetFrame2: + status = I2cAsyncWrite(ledDriverAddress, setFrame2Buffer, sizeof(setFrame2Buffer)); + ++currentLedDriverState->phaseSequenceIndex; + break; + case LedDriverPhase_SetFrame8: + status = I2cAsyncWrite(ledDriverAddress, setFrame8Buffer, sizeof(setFrame8Buffer)); + ++currentLedDriverState->phaseSequenceIndex; break; case LedDriverPhase_InitLedControlRegisters: status = I2cAsyncWrite(ledDriverAddress, currentLedDriverState->setupLedControlRegistersCommand, LED_CONTROL_REGISTERS_COMMAND_LENGTH); - *ledDriverPhase = LedDriverPhase_InitLedValues; + ++currentLedDriverState->phaseSequenceIndex; break; case LedDriverPhase_InitLedValues: updatePwmRegistersBuffer[0] = FRAME_REGISTER_PWM_FIRST + *ledIndex; @@ -132,7 +232,7 @@ status_t LedSlaveDriver_Update(uint8_t ledDriverId) if (*ledIndex >= LED_DRIVER_LED_COUNT) { *ledIndex = 0; memcpy(currentLedDriverState->targetLedValues, ledValues, LED_DRIVER_LED_COUNT); - *ledDriverPhase = LedDriverPhase_UpdateChangedLedValues; + ++currentLedDriverState->phaseSequenceIndex; } break; case LedDriverPhase_UpdateChangedLedValues: { @@ -155,6 +255,7 @@ status_t LedSlaveDriver_Update(uint8_t ledDriverId) bool foundStartIndex = count < LED_DRIVER_LED_COUNT; if (!foundStartIndex) { *ledIndex = 0; + ++currentLedDriverState->phaseSequenceIndex; break; } @@ -175,9 +276,42 @@ status_t LedSlaveDriver_Update(uint8_t ledDriverId) *ledIndex += length; if (*ledIndex >= LED_DRIVER_LED_COUNT) { *ledIndex = 0; + ++currentLedDriverState->phaseSequenceIndex; } break; } + case LedDriverPhase_InitAutoPlayControlRegister1: + status = I2cAsyncWrite(ledDriverAddress, initAutoPlayControlRegister1Buffer, sizeof(initAutoPlayControlRegister1Buffer)); + ++currentLedDriverState->phaseSequenceIndex; + break; + case LedDriverPhase_InitAutoPlayControlRegister2: + 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)); + ++currentLedDriverState->phaseSequenceIndex; + break; + case LedDriverPhase_SetConfigurationRegisterFadeIn: + status = I2cAsyncWrite(ledDriverAddress, setConfigurationRegisterFadeInBuffer, sizeof(setConfigurationRegisterFadeInBuffer)); + ++currentLedDriverState->phaseSequenceIndex; + break; + case LedDriverPhase_InitLedControlRegistersZero: + status = I2cAsyncWrite(ledDriverAddress, initLedControlRegistersZeroBuffer, sizeof(initLedControlRegistersZeroBuffer)); + ++currentLedDriverState->phaseSequenceIndex; + break; + } + + if (currentLedDriverState->phaseSequenceIndex == currentLedDriverState->phaseSequence->phaseCount) { + currentLedDriverState->phaseSequence = NULL; } return status; diff --git a/right/src/slave_drivers/is31fl3731_driver.h b/right/src/slave_drivers/is31fl3731_driver.h index 11ab9db..0ef2062 100644 --- a/right/src/slave_drivers/is31fl3731_driver.h +++ b/right/src/slave_drivers/is31fl3731_driver.h @@ -30,15 +30,31 @@ LedDriverPhase_SetFunctionFrame, LedDriverPhase_SetShutdownModeNormal, LedDriverPhase_SetFrame1, + LedDriverPhase_SetFrame2, + LedDriverPhase_SetFrame8, + LedDriverPhase_InitAutoPlayControlRegister1, + LedDriverPhase_InitAutoPlayControlRegister2, + LedDriverPhase_InitBreathControlRegister1, + LedDriverPhase_InitBreathControlRegister2, LedDriverPhase_InitLedControlRegisters, LedDriverPhase_InitLedValues, LedDriverPhase_UpdateChangedLedValues, + LedDriverPhase_SetConfigurationRegisterFadeOut, + LedDriverPhase_SetConfigurationRegisterFadeIn, + LedDriverPhase_InitLedControlRegistersZero } led_driver_phase_t; typedef struct { - led_driver_phase_t phase; - uint8_t targetLedValues[LED_DRIVER_LED_COUNT]; - uint8_t ledIndex; + 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 phaseSequenceIndex; + volatile uint8_t targetLedValues[LED_DRIVER_LED_COUNT]; + volatile uint8_t ledIndex; uint8_t i2cAddress; uint8_t setupLedControlRegistersCommand[LED_CONTROL_REGISTERS_COMMAND_LENGTH]; } led_driver_state_t; @@ -50,8 +66,9 @@ // Functions: - void LedSlaveDriver_DisableLeds(void); - void LedSlaveDriver_UpdateLeds(void); + void LedSlaveDriver_DisableLeds(uint8_t ledDriverId); + void LedSlaveDriver_EnableLeds(uint8_t ledDriverId); + void LedSlaveDriver_UpdateLeds(uint8_t ledDriverId); void LedSlaveDriver_Init(uint8_t ledDriverId); status_t LedSlaveDriver_Update(uint8_t ledDriverId); diff --git a/right/src/usb_composite_device.c b/right/src/usb_composite_device.c index acaa2de..d271702 100644 --- a/right/src/usb_composite_device.c +++ b/right/src/usb_composite_device.c @@ -168,12 +168,16 @@ static volatile bool wakeUpHostAllowed; static void suspendUhk(void) { SleepModeActive = true; - LedSlaveDriver_DisableLeds(); + for (uint8_t i = 0; i <= LedDriverId_Last; i++) { + LedSlaveDriver_DisableLeds(i); + } } static void wakeUpUhk(void) { SleepModeActive = false; - LedSlaveDriver_UpdateLeds(); + for (uint8_t i = 0; i <= LedDriverId_Last; i++) { + LedSlaveDriver_EnableLeds(i); + } } void WakeUpHost(void) {