diff --git a/right/src/init_peripherals.c b/right/src/init_peripherals.c index 19cd3a4..ac45b64 100644 --- a/right/src/init_peripherals.c +++ b/right/src/init_peripherals.c @@ -60,6 +60,8 @@ void InitPeripherals(void) InitI2c(); InitTestLed(); LedPwm_Init(); +#ifndef LED_DRIVER_STRESS_TEST InitI2cWatchdog(); +#endif EEPROM_Init(); } diff --git a/right/src/led_display.c b/right/src/led_display.c index 79095d7..05571c3 100644 --- a/right/src/led_display.c +++ b/right/src/led_display.c @@ -65,12 +65,12 @@ void LedDisplay_SetText(uint8_t length, const char* text) { case 1: allSegmentSets |= characterToSegmentSet(text[0]); } - LedDriverStates[LedDriverId_Left].ledValues[11] = allSegmentSets & 0b00000001 ? 255 : 0; - LedDriverStates[LedDriverId_Left].ledValues[12] = allSegmentSets & 0b00000010 ? 255 : 0; + LedDriverStates[LedDriverId_Left].sourceLedValues[11] = allSegmentSets & 0b00000001 ? 255 : 0; + LedDriverStates[LedDriverId_Left].sourceLedValues[12] = allSegmentSets & 0b00000010 ? 255 : 0; allSegmentSets >>= 2; for (uint8_t i = 24; i <= 136; i += 16) { for (uint8_t j = 0; j < 5; j++) { - LedDriverStates[LedDriverId_Left].ledValues[i + j] = allSegmentSets & 1 << j ? 255 : 0; + LedDriverStates[LedDriverId_Left].sourceLedValues[i + j] = allSegmentSets & 1 << j ? 255 : 0; } allSegmentSets >>= 5; } @@ -79,13 +79,13 @@ void LedDisplay_SetText(uint8_t length, const char* text) { void LedDisplay_SetLayer(uint8_t layerId) { for (uint8_t i = 13; i <= 45; i += 16) { - LedDriverStates[LedDriverId_Left].ledValues[i] = 0; + LedDriverStates[LedDriverId_Left].sourceLedValues[i] = 0; } if (layerId >= LAYER_ID_MOD && layerId <= LAYER_ID_MOUSE) { - LedDriverStates[LedDriverId_Left].ledValues[16 * layerId - 3] = 255; + LedDriverStates[LedDriverId_Left].sourceLedValues[16 * layerId - 3] = 255; } } void LedDisplay_SetIcon(led_display_icon_t icon, bool isEnabled) { - LedDriverStates[LedDriverId_Left].ledValues[8 + icon] = isEnabled ? 255 : 0; + LedDriverStates[LedDriverId_Left].sourceLedValues[8 + icon] = isEnabled ? 255 : 0; } diff --git a/right/src/slave_drivers/slave_driver_led_driver.c b/right/src/slave_drivers/slave_driver_led_driver.c index 1b567c6..902f37e 100644 --- a/right/src/slave_drivers/slave_driver_led_driver.c +++ b/right/src/slave_drivers/slave_driver_led_driver.c @@ -63,6 +63,7 @@ void LedSlaveDriver_Init(uint8_t ledDriverId) { currentLedDriverState->phase = LedDriverPhase_SetFunctionFrame; currentLedDriverState->ledIndex = 0; LedDriverStates[LedDriverId_Left].setupLedControlRegistersCommand[7] |= 0b00000010; // Enable the LED of the ISO key. + memset(currentLedDriverState->targetLedValues, 0xff, LED_DRIVER_LED_COUNT); SetLeds(0xff); LedDisplay_SetText(3, "ABC"); } @@ -94,20 +95,66 @@ void LedSlaveDriver_Update(uint8_t ledDriverId) { *ledDriverPhase = LedDriverPhase_Initialized; break; case LedDriverPhase_Initialized: + { +#ifdef LED_DRIVER_STRESS_TEST updatePwmRegistersBuffer[0] = FRAME_REGISTER_PWM_FIRST + *ledIndex; - memcpy(updatePwmRegistersBuffer+1, currentLedDriverState->ledValues + *ledIndex, PMW_REGISTER_UPDATE_CHUNK_SIZE); + memcpy(updatePwmRegistersBuffer+1, currentLedDriverState->sourceLedValues + *ledIndex, PMW_REGISTER_UPDATE_CHUNK_SIZE); I2cAsyncWrite(ledDriverAddress, updatePwmRegistersBuffer, PWM_REGISTER_BUFFER_LENGTH); *ledIndex += PMW_REGISTER_UPDATE_CHUNK_SIZE; if (*ledIndex >= LED_DRIVER_LED_COUNT) { *ledIndex = 0; } +#else + uint8_t *sourceLedValues = currentLedDriverState->sourceLedValues; + uint8_t *targetLedValues = currentLedDriverState->targetLedValues; + + uint8_t lastLedChunkStartIndex = LED_DRIVER_LED_COUNT - PMW_REGISTER_UPDATE_CHUNK_SIZE; + uint8_t startLedIndex = *ledIndex > lastLedChunkStartIndex ? lastLedChunkStartIndex : *ledIndex; + + uint8_t count; + for (count=0; count= LED_DRIVER_LED_COUNT) { + startLedIndex = 0; + } + } + + bool foundStartIndex = count < LED_DRIVER_LED_COUNT; + if (!foundStartIndex) { + *ledIndex = 0; + return; + } + + uint8_t maxChunkSize = MIN(LED_DRIVER_LED_COUNT - startLedIndex, PMW_REGISTER_UPDATE_CHUNK_SIZE); + uint8_t maxEndLedIndex = startLedIndex + maxChunkSize - 1; + uint8_t endLedIndex = startLedIndex; + for (uint8_t index=startLedIndex; index<=maxEndLedIndex; index++) { + if (sourceLedValues[index] != targetLedValues[index]) { + endLedIndex = index; + } + } + + updatePwmRegistersBuffer[0] = FRAME_REGISTER_PWM_FIRST + startLedIndex; + 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); + *ledIndex += length; + if (*ledIndex >= LED_DRIVER_LED_COUNT) { + *ledIndex = 0; + } +#endif break; + } } } void SetLeds(uint8_t ledBrightness) { for (uint8_t i=0; i