diff --git a/project/example/ble/ble_peripheral/app/src/bridge_pwm.c b/project/example/ble/ble_peripheral/app/src/bridge_pwm.c index aa7d929..cd0cf73 100644 --- a/project/example/ble/ble_peripheral/app/src/bridge_pwm.c +++ b/project/example/ble/ble_peripheral/app/src/bridge_pwm.c @@ -18,6 +18,7 @@ * The available OFF time is distributed around both direction changes and * each W/C transition retains at least 25 us protection. * Normal dual-color output produces one pulse per color per frame (2 kHz). + * Only the low-output neutral section of three-color breathing uses PDM. */ #define BRIDGE_PWM_SCALE 1000U #define BRIDGE_PWM_PERIOD 6U @@ -26,8 +27,11 @@ #define BRIDGE_DEADTIME_US 25U #define BRIDGE_DUAL_ACTIVE_US 450U #define BRIDGE_MIN_DUAL_PULSE_US 1U +#define BRIDGE_NEUTRAL_PDM_PULSE_US 50U #define BRIDGE_TIMER_TICKS_PER_US 16U #define BRIDGE_PDM_THRESHOLD (BRIDGE_MIX_SCALE * 4096UL) +#define BRIDGE_NEUTRAL_PDM_THRESHOLD \ + (BRIDGE_NEUTRAL_PDM_PULSE_US * BRIDGE_PDM_THRESHOLD) #define BRIDGE_GPIO_PORT 0U #define BRIDGE_GPIO_MASK ((1UL << IO_PWM_W) | (1UL << IO_PWM_C)) @@ -383,6 +387,40 @@ __RAM_CODE void Bridge_Service_1ms(void) goto dual_output_ready; } + /* + * In the neutral part of three-color breathing, keep each W/C pulse at + * a reliable 50 us and reduce only its frame density below that level. + * Single-color breathing never enters this branch and stays on hardware + * PWM all the way down to zero. + */ + if (deviceStatus != POWEROFF && + Mode == mode1 && choose_mode_falsg == 5U && + w_mix != 0U && c_mix != 0U) { + pdm_w_step = + BRIDGE_DUAL_ACTIVE_US * ((uint32_t)w_mix << 12); + pdm_c_step = + BRIDGE_DUAL_ACTIVE_US * ((uint32_t)c_mix << 12); + + if (pdm_w_step < BRIDGE_NEUTRAL_PDM_THRESHOLD && + pdm_c_step < BRIDGE_NEUTRAL_PDM_THRESHOLD) { + next_w_us = BRIDGE_NEUTRAL_PDM_PULSE_US; + next_c_us = BRIDGE_NEUTRAL_PDM_PULSE_US; + total_off_us = + BRIDGE_FRAME_US - + (2U * BRIDGE_NEUTRAL_PDM_PULSE_US); + next_wc_off_us = (uint16_t)(total_off_us / 2U); + next_cw_off_us = + (uint16_t)(total_off_us - next_wc_off_us); + next_pdm_w_step = pdm_w_step; + next_pdm_c_step = pdm_c_step; + next_pdm_threshold = BRIDGE_NEUTRAL_PDM_THRESHOLD; + next_pdm_enabled = 1U; + cached_w_mix = (uint16_t)w_mix; + cached_c_mix = (uint16_t)c_mix; + goto dual_output_ready; + } + } + if (next_pdm_enabled) { cached_w_mix = 0xFFFFU; cached_c_mix = 0xFFFFU;