From ef6a50597b6f52b8fdeeb7f065c6a2d97bf361f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=90=B4=E7=90=AA?= Date: Sun, 26 Jul 2026 23:44:12 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0Gamma=E6=9F=A5=E8=A1=A8?= =?UTF-8?q?=E8=B0=83=E5=85=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../example/ble/ble_peripheral/app/src/PWM.h | 2 +- .../ble/ble_peripheral/app/src/bridge_pwm.c | 2 +- .../ble_peripheral/app/src/light_transition.c | 69 +++++++++++++++---- 3 files changed, 58 insertions(+), 15 deletions(-) diff --git a/project/example/ble/ble_peripheral/app/src/PWM.h b/project/example/ble/ble_peripheral/app/src/PWM.h index 9b44f43..15a6405 100644 --- a/project/example/ble/ble_peripheral/app/src/PWM.h +++ b/project/example/ble/ble_peripheral/app/src/PWM.h @@ -65,7 +65,7 @@ extern uint8_t driveMode; extern uint8_t PWMMAX; extern uint8_t Brightness; -#define BRIGHTNESS_MIN_PERCENT 10U +#define BRIGHTNESS_MIN_PERCENT 1U #define BRIGHTNESS_MAX_PERCENT 100U #define BRIGHTNESS_RF_STEP_PERCENT 10U 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 002133a..3c09ec4 100644 --- a/project/example/ble/ble_peripheral/app/src/bridge_pwm.c +++ b/project/example/ble/ble_peripheral/app/src/bridge_pwm.c @@ -21,7 +21,7 @@ */ #define BRIDGE_PWM_SCALE 1000U #define BRIDGE_PWM_PERIOD 7U -#define BRIDGE_MIX_SCALE 100U +#define BRIDGE_MIX_SCALE 1000U #define BRIDGE_FRAME_US 1000U #define BRIDGE_DEADTIME_US 50U #define BRIDGE_DUAL_ACTIVE_US 900U 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 6a056ce..2a6636a 100644 --- a/project/example/ble/ble_peripheral/app/src/light_transition.c +++ b/project/example/ble/ble_peripheral/app/src/light_transition.c @@ -4,29 +4,72 @@ volatile uint8_t Light_Transition_FadeActive; -static uint8_t approach_target(uint8_t current, uint8_t target) +#define LIGHT_OUTPUT_SCALE 10U +#define LIGHT_FADE_STEP 10U + +/* + * Gamma 1.8, mapping APP levels 1..100 to a stable physical range of + * 10%..100%. Values are Q12 scale factors, so the runtime path is only: + * table lookup + multiply + shift. + */ +static const uint16_t brightness_gamma_q12[100] = { + 410U, 411U, 413U, 416U, 421U, 427U, 433U, 441U, 449U, 459U, + 469U, 480U, 492U, 505U, 519U, 533U, 548U, 564U, 581U, 598U, + 617U, 636U, 656U, 676U, 697U, 719U, 742U, 765U, 789U, 814U, + 839U, 866U, 892U, 920U, 948U, 977U, 1006U, 1037U, 1067U, 1099U, + 1131U, 1164U, 1197U, 1231U, 1266U, 1301U, 1337U, 1374U, 1411U, 1449U, + 1488U, 1527U, 1566U, 1607U, 1648U, 1689U, 1731U, 1774U, 1818U, 1862U, + 1906U, 1951U, 1997U, 2044U, 2091U, 2138U, 2186U, 2235U, 2284U, 2334U, + 2385U, 2436U, 2488U, 2540U, 2593U, 2646U, 2700U, 2755U, 2810U, 2865U, + 2922U, 2978U, 3036U, 3094U, 3152U, 3211U, 3271U, 3331U, 3392U, 3453U, + 3515U, 3577U, 3640U, 3704U, 3768U, 3832U, 3897U, 3963U, 4029U, 4096U +}; + +static uint16_t approach_target(uint16_t current, uint16_t target) { - if(current < target) return current + 1U; - if(current > target) return current - 1U; + if(current < target) + { + uint16_t delta = target - current; + return current + ((delta > LIGHT_FADE_STEP) ? LIGHT_FADE_STEP : delta); + } + if(current > target) + { + uint16_t delta = current - target; + return current - ((delta > LIGHT_FADE_STEP) ? LIGHT_FADE_STEP : delta); + } return current; } void Light_Transition_Task(void) { uint8_t target_brightness = 0U; - uint8_t target_w; - uint8_t target_c; + uint16_t target_w; + uint16_t target_c; uint16_t brightness_scale; if(deviceStatus != POWEROFF) target_brightness = Brightness; - /* 41 / 4096 is approximately 1 / 100, avoiding division in this task. */ - brightness_scale = (uint16_t)target_brightness * 41U; - target_w = - (uint8_t)(((uint32_t)W_PWM * brightness_scale + 2048U) >> 12); - target_c = - (uint8_t)(((uint32_t)C_PWM * brightness_scale + 2048U) >> 12); - W_PWM_duty = approach_target((uint8_t)W_PWM_duty, target_w); - C_PWM_duty = approach_target((uint8_t)C_PWM_duty, target_c); + if(target_brightness > BRIGHTNESS_MAX_PERCENT) + target_brightness = BRIGHTNESS_MAX_PERCENT; + + if(target_brightness == 0U) + { + brightness_scale = 0U; + } + else + { + if(target_brightness < BRIGHTNESS_MIN_PERCENT) + target_brightness = BRIGHTNESS_MIN_PERCENT; + brightness_scale = brightness_gamma_q12[target_brightness - 1U]; + } + + target_w = (uint16_t) + (((uint32_t)W_PWM * brightness_scale * LIGHT_OUTPUT_SCALE + 2048U) >> + 12); + target_c = (uint16_t) + (((uint32_t)C_PWM * brightness_scale * LIGHT_OUTPUT_SCALE + 2048U) >> + 12); + W_PWM_duty = approach_target(W_PWM_duty, target_w); + C_PWM_duty = approach_target(C_PWM_duty, target_c); Light_Transition_FadeActive = deviceStatus == POWEROFF && (W_PWM_duty != 0U || C_PWM_duty != 0U);