diff --git a/project/example/ble/ble_peripheral/app/src/light_transition.c b/project/example/ble/ble_peripheral/app/src/light_transition.c index 34079ed..fda6d8e 100644 --- a/project/example/ble/ble_peripheral/app/src/light_transition.c +++ b/project/example/ble/ble_peripheral/app/src/light_transition.c @@ -8,6 +8,7 @@ volatile uint8_t Light_Transition_FadeActive; #define OUTPUT_SMOOTH_SHIFT 4U #define LIGHT_OUTPUT_SCALE 1000U #define BREATH_MIN_OUTPUT (LIGHT_OUTPUT_SCALE / 100U) +#define DUAL_CHANNEL_MIN_OUTPUT (LIGHT_OUTPUT_SCALE / 10U) #define POWER_FADE_Q12_MAX 4096U #define POWER_FADE_ON_TICKS 140U #define POWER_FADE_OFF_TICKS 160U @@ -206,8 +207,7 @@ void Light_Transition_Task(void) target_brightness_scale); update_power_fade(powered_on); fade_scale = power_fade_scale(power_fade_progress_q12); - brightness_scale = (uint16_t)( - ((uint32_t)current_brightness_q12 * fade_scale + 2048U) >> 12); + brightness_scale = current_brightness_q12; power_transitioning = powered_on ? (power_fade_progress_q12 < POWER_FADE_Q12_MAX) : (power_fade_progress_q12 != 0U); @@ -219,6 +219,39 @@ void Light_Transition_Task(void) (uint16_t)(((uint32_t)C_PWM * brightness_scale * (LIGHT_OUTPUT_SCALE / 100U) + 2048U) >> 12); + /* + * In mixed light, each active direction has a 10% floor. Scale both + * directions together from the weaker side so the requested W:C ratio is + * preserved whenever the stronger side remains within 100%. Single-color + * output keeps the 1% Gamma minimum. + */ + if(W_PWM != 0U && C_PWM != 0U && + (target_w < DUAL_CHANNEL_MIN_OUTPUT || + target_c < DUAL_CHANNEL_MIN_OUTPUT)) + { + if(W_PWM <= C_PWM) + { + target_w = DUAL_CHANNEL_MIN_OUTPUT; + target_c = (uint16_t)( + ((uint32_t)DUAL_CHANNEL_MIN_OUTPUT * C_PWM + + (W_PWM / 2U)) / W_PWM); + if(target_c > LIGHT_OUTPUT_SCALE) + target_c = LIGHT_OUTPUT_SCALE; + } + else + { + target_c = DUAL_CHANNEL_MIN_OUTPUT; + target_w = (uint16_t)( + ((uint32_t)DUAL_CHANNEL_MIN_OUTPUT * W_PWM + + (C_PWM / 2U)) / C_PWM); + if(target_w > LIGHT_OUTPUT_SCALE) + target_w = LIGHT_OUTPUT_SCALE; + } + } + + target_w = (uint16_t)(((uint32_t)target_w * fade_scale + 2048U) >> 12); + target_c = (uint16_t)(((uint32_t)target_c * fade_scale + 2048U) >> 12); + if(Mode == mode1 && powered_on && !power_transitioning) { if(W_PWM != 0U && target_w < BREATH_MIN_OUTPUT)