DWM22测试板
This commit is contained in:
@@ -102,7 +102,12 @@ static uint8_t pair_command_replay;
|
||||
#define PAIRING_WINDOW_TICKS 50000UL
|
||||
#define RF433_RELEASE_TIMEOUT_TICKS 1500U
|
||||
#define RF433_MS_TO_SAMPLE_TICKS(ms) ((uint16_t)((ms) * (1000U / RF433_DECODER_SAMPLE_US)))
|
||||
#define RF433_MODE_REPEAT_TICKS ((uint32_t)RF433_MS_TO_SAMPLE_TICKS(500U))
|
||||
uint8_t long_flag_s=0;
|
||||
static volatile uint32_t rf433_sample_ticks;
|
||||
static uint32_t rf433_mode_last_action_tick;
|
||||
static uint8_t rf433_mode_last_key;
|
||||
static uint8_t rf433_mode_action_valid;
|
||||
|
||||
void _433_fun(void);
|
||||
|
||||
@@ -422,8 +427,38 @@ static void set_click(){
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t rf433_is_mode_step_command(uint8_t command)
|
||||
{
|
||||
return command == Mode_add || command == Mode_dow;
|
||||
}
|
||||
|
||||
/*
|
||||
* Act immediately on the first valid mode frame. Repeated frames carrying
|
||||
* the same key are accepted at most once every 500 ms. Keep this independent
|
||||
* from the generic 150 ms release detector so an occasional missing RF frame
|
||||
* cannot turn one physical hold into several rapid short presses.
|
||||
*/
|
||||
static uint8_t rf433_mode_step_ready(uint8_t command)
|
||||
{
|
||||
uint32_t now = rf433_sample_ticks;
|
||||
|
||||
if(!rf433_mode_action_valid ||
|
||||
rf433_mode_last_key != command ||
|
||||
(uint32_t)(now - rf433_mode_last_action_tick) >=
|
||||
RF433_MODE_REPEAT_TICKS)
|
||||
{
|
||||
rf433_mode_last_key = command;
|
||||
rf433_mode_last_action_tick = now;
|
||||
rf433_mode_action_valid = 1U;
|
||||
return 1U;
|
||||
}
|
||||
|
||||
return 0U;
|
||||
}
|
||||
|
||||
void rf433_receive(void)//RF433 sample, called every 100 us
|
||||
{
|
||||
rf433_sample_ticks++;
|
||||
rf433_decoder_sample((RF_DATA == HIGH_LEVEL) ? 1U : 0U);
|
||||
|
||||
if(long_time > 0U)
|
||||
@@ -473,8 +508,15 @@ void _433_fun(){
|
||||
pair_deferred_receive_data = receive_data;
|
||||
return;
|
||||
}
|
||||
if(Key_TypeDef.KEY_STATE_Click==1||KEY_STATE_re==1) return;
|
||||
set_click();
|
||||
if(rf433_is_mode_step_command(res_data))
|
||||
{
|
||||
if(!rf433_mode_step_ready(res_data)) return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(Key_TypeDef.KEY_STATE_Click==1||KEY_STATE_re==1) return;
|
||||
set_click();
|
||||
}
|
||||
switch(res_data){
|
||||
//椭圆
|
||||
case ON://单击
|
||||
|
||||
@@ -390,7 +390,6 @@ int main(void)
|
||||
#endif
|
||||
|
||||
|
||||
wdt_init();
|
||||
/* Set the broadcast address of the device. */
|
||||
board_init();
|
||||
xc_fmc_spi_init_oprt( );
|
||||
@@ -398,6 +397,8 @@ int main(void)
|
||||
|
||||
fmc_spi_read();
|
||||
power_restore_apply_on_boot();
|
||||
/* Start the watchdog after the optional boot-time Flash update. */
|
||||
wdt_init();
|
||||
timer0_2_init();
|
||||
bluetooth_init();
|
||||
|
||||
|
||||
@@ -522,13 +522,18 @@ __RAM_CODE void Bridge_Service_1ms(void)
|
||||
(BRIDGE_MIX_SCALE / 2U)) / BRIDGE_MIX_SCALE);
|
||||
/*
|
||||
* A mixed H-bridge frame has 450 us of active time after deadtime.
|
||||
* Use the same 450/500 energy at both single-color endpoints of the
|
||||
* continuous gradient so its total brightness does not jump there.
|
||||
* Continuous CCT always uses the same 450/500 endpoint energy.
|
||||
* A static color transition also reaches its single-color endpoint
|
||||
* at 90%, then light_transition.c restores it to 100% over 900 ms.
|
||||
*/
|
||||
if (Mode == mode3 && choose_mode_falsg == 7U) {
|
||||
pwm_duty = (uint16_t)(
|
||||
((uint32_t)pwm_duty * BRIDGE_DUAL_ACTIVE_US +
|
||||
(BRIDGE_FRAME_US / 2U)) / BRIDGE_FRAME_US);
|
||||
} else if (Mode == mode0 && choose_mode_falsg <= 2U) {
|
||||
pwm_duty = (uint16_t)(
|
||||
((uint32_t)pwm_duty *
|
||||
Light_Transition_StaticEndpointScale_Q12 + 2048U) >> 12);
|
||||
}
|
||||
|
||||
if (output_mode == BRIDGE_MODE_SINGLE &&
|
||||
|
||||
@@ -289,14 +289,9 @@ void power_restore_apply_on_boot(void)
|
||||
power_cycle_next_mode = (uint8_t)((mode_index + 1U) % 3U);
|
||||
|
||||
/*
|
||||
* Save the next startup mode before timers, BLE and the H-bridge start.
|
||||
* A deferred flash erase/write masks interrupts long enough to stretch
|
||||
* one Timer3-controlled dual-color pulse and causes a visible flash.
|
||||
* Cycle-static is also a remembered state. Start PWM, BLE and the
|
||||
* H-bridge through the same path as full-memory restore, then persist
|
||||
* the next static mode through the normal deferred Flash state machine.
|
||||
*/
|
||||
wright_user_data();
|
||||
GLOBAL_INT_DISABLE();
|
||||
xc_fmc_spi_flash_erase_page(USER_DATA_FLASH_ADDR);
|
||||
xc_fmc_spi_flash_write_page(USER_DATA_FLASH_ADDR,
|
||||
app_data, FLASH_PAGE_SIZE);
|
||||
GLOBAL_INT_RESTORE();
|
||||
set_TaskComps_timer(2U, POWER_POLICY_SAVE_DELAY_MS);
|
||||
}
|
||||
|
||||
@@ -6,10 +6,19 @@ volatile uint8_t Light_Transition_FadeActive;
|
||||
volatile uint8_t Light_Transition_ModeActive;
|
||||
volatile uint32_t Light_Transition_W_Output_Q12;
|
||||
volatile uint32_t Light_Transition_C_Output_Q12;
|
||||
volatile uint16_t Light_Transition_StaticEndpointScale_Q12 = 4096U;
|
||||
|
||||
#define BRIGHTNESS_SMOOTH_SHIFT 4U
|
||||
#define OUTPUT_SMOOTH_SHIFT 4U
|
||||
#define MODE_TRANSITION_TICKS 40U
|
||||
#define MODE_TRANSITION_TICKS 100U
|
||||
#define CCT_RING_TRANSITION_TICKS 40U
|
||||
#define STATIC_ENDPOINT_SCALE_START_Q12 3686U
|
||||
#define STATIC_ENDPOINT_SCALE_MAX_Q12 4096U
|
||||
#define STATIC_PRE_TRANSITION_TICKS 50U
|
||||
#define STATIC_ENDPOINT_RECOVERY_TICKS 180U
|
||||
#define TRANSITION_CURVE_LINEAR 0U
|
||||
#define TRANSITION_CURVE_GAMMA_S 1U
|
||||
#define TRANSITION_CURVE_GAMMA_OUT 2U
|
||||
#define LIGHT_OUTPUT_SCALE 1000U
|
||||
#define BREATH_MIN_OUTPUT (LIGHT_OUTPUT_SCALE / 100U)
|
||||
#define DUAL_MIN_STABLE_CHANNEL_OUTPUT 102U
|
||||
@@ -78,6 +87,29 @@ static const uint16_t power_fade_gamma_q12[101] = {
|
||||
4096U
|
||||
};
|
||||
|
||||
/*
|
||||
* Symmetric Gamma 1.8 transition curve:
|
||||
* q = p^1.8 / (p^1.8 + (1-p)^1.8)
|
||||
*
|
||||
* Unlike applying Gamma independently to W and C, q and (1-q) remain
|
||||
* complementary. The transition therefore eases in and out without causing
|
||||
* a brightness dip in the middle. A table keeps the 5 ms task free of
|
||||
* floating-point and power calculations.
|
||||
*/
|
||||
static const uint16_t transition_gamma_s_q12[101] = {
|
||||
0U, 1U, 4U, 8U, 13U, 20U, 29U, 39U, 50U, 63U,
|
||||
77U, 93U, 110U, 130U, 150U, 173U, 197U, 223U, 251U, 281U,
|
||||
312U, 345U, 381U, 418U, 457U, 498U, 541U, 586U, 633U, 681U,
|
||||
732U, 784U, 839U, 895U, 953U, 1012U, 1073U, 1136U, 1200U, 1265U,
|
||||
1332U, 1400U, 1469U, 1539U, 1610U, 1682U, 1754U, 1827U, 1901U, 1974U,
|
||||
2048U, 2122U, 2195U, 2269U, 2342U, 2414U, 2486U, 2557U, 2627U, 2696U,
|
||||
2764U, 2831U, 2896U, 2960U, 3023U, 3084U, 3143U, 3201U, 3257U, 3312U,
|
||||
3364U, 3415U, 3463U, 3510U, 3555U, 3598U, 3639U, 3678U, 3715U, 3751U,
|
||||
3784U, 3815U, 3845U, 3873U, 3899U, 3923U, 3946U, 3966U, 3986U, 4003U,
|
||||
4019U, 4033U, 4046U, 4057U, 4067U, 4076U, 4083U, 4088U, 4092U, 4095U,
|
||||
4096U
|
||||
};
|
||||
|
||||
static uint16_t current_brightness_q12;
|
||||
static uint16_t power_fade_progress_q12;
|
||||
static uint16_t power_fade_remainder;
|
||||
@@ -86,6 +118,13 @@ static uint8_t transition_sync_pending;
|
||||
static uint16_t mode_transition_start_w;
|
||||
static uint16_t mode_transition_start_c;
|
||||
static uint8_t mode_transition_tick;
|
||||
static uint8_t mode_transition_total_ticks;
|
||||
static uint8_t mode_transition_gamma_curve;
|
||||
static uint8_t static_pre_transition_active;
|
||||
static uint8_t static_pre_transition_tick;
|
||||
static uint16_t static_pre_transition_start_scale_q12;
|
||||
static uint8_t static_endpoint_recovery_active;
|
||||
static uint8_t static_endpoint_recovery_tick;
|
||||
static volatile uint8_t feedback_active;
|
||||
static volatile uint8_t feedback_on;
|
||||
|
||||
@@ -153,24 +192,54 @@ static uint16_t approach_target(uint16_t current, uint16_t target)
|
||||
return current - step;
|
||||
}
|
||||
|
||||
static uint16_t transition_gamma_s_scale(uint8_t tick, uint8_t total_ticks)
|
||||
{
|
||||
uint16_t index;
|
||||
|
||||
if(total_ticks == 0U || tick >= total_ticks) return 4096U;
|
||||
index = (uint16_t)(((uint16_t)tick * 100U +
|
||||
(total_ticks / 2U)) / total_ticks);
|
||||
if(index > 100U) index = 100U;
|
||||
return transition_gamma_s_q12[index];
|
||||
}
|
||||
|
||||
static uint16_t transition_gamma_out_scale(uint8_t tick, uint8_t total_ticks)
|
||||
{
|
||||
uint16_t index;
|
||||
|
||||
if(total_ticks == 0U || tick >= total_ticks) return 4096U;
|
||||
index = (uint16_t)(((uint16_t)tick * 100U +
|
||||
(total_ticks / 2U)) / total_ticks);
|
||||
if(index > 100U) index = 100U;
|
||||
return (uint16_t)(4096U - power_fade_gamma_q12[100U - index]);
|
||||
}
|
||||
|
||||
static uint16_t interpolate_mode_output(uint16_t start, uint16_t target,
|
||||
uint8_t tick)
|
||||
{
|
||||
uint32_t delta;
|
||||
uint16_t progress_q12;
|
||||
uint8_t total_ticks = mode_transition_total_ticks;
|
||||
|
||||
if(total_ticks == 0U || tick >= total_ticks) return target;
|
||||
if(mode_transition_gamma_curve == TRANSITION_CURVE_GAMMA_S)
|
||||
progress_q12 = transition_gamma_s_scale(tick, total_ticks);
|
||||
else if(mode_transition_gamma_curve == TRANSITION_CURVE_GAMMA_OUT)
|
||||
progress_q12 = transition_gamma_out_scale(tick, total_ticks);
|
||||
else
|
||||
progress_q12 = (uint16_t)(
|
||||
((uint32_t)tick * 4096U + (total_ticks / 2U)) / total_ticks);
|
||||
|
||||
if(tick >= MODE_TRANSITION_TICKS) return target;
|
||||
if(target >= start)
|
||||
{
|
||||
delta = (uint32_t)(target - start) * tick;
|
||||
delta = (uint32_t)(target - start) * progress_q12;
|
||||
return (uint16_t)(start +
|
||||
((delta + (MODE_TRANSITION_TICKS / 2U)) /
|
||||
MODE_TRANSITION_TICKS));
|
||||
((delta + 2048U) >> 12));
|
||||
}
|
||||
|
||||
delta = (uint32_t)(start - target) * tick;
|
||||
delta = (uint32_t)(start - target) * progress_q12;
|
||||
return (uint16_t)(start -
|
||||
((delta + (MODE_TRANSITION_TICKS / 2U)) /
|
||||
MODE_TRANSITION_TICKS));
|
||||
((delta + 2048U) >> 12));
|
||||
}
|
||||
|
||||
static uint16_t effect_gamma_output(uint16_t level)
|
||||
@@ -265,6 +334,53 @@ void Light_Transition_BeginModeChange(void)
|
||||
mode_transition_start_w = W_PWM_duty;
|
||||
mode_transition_start_c = C_PWM_duty;
|
||||
mode_transition_tick = 0U;
|
||||
mode_transition_total_ticks =
|
||||
(choose_mode_falsg == CUSTOM_TEMPERATURE_MODE)
|
||||
? CCT_RING_TRANSITION_TICKS : MODE_TRANSITION_TICKS;
|
||||
if(Mode == mode0 && choose_mode_falsg <= 2U)
|
||||
mode_transition_gamma_curve = TRANSITION_CURVE_GAMMA_S;
|
||||
else if(Mode == mode0 &&
|
||||
choose_mode_falsg == CUSTOM_TEMPERATURE_MODE)
|
||||
mode_transition_gamma_curve = TRANSITION_CURVE_GAMMA_OUT;
|
||||
else
|
||||
mode_transition_gamma_curve = TRANSITION_CURVE_LINEAR;
|
||||
if(Mode == mode0 && choose_mode_falsg <= 2U)
|
||||
{
|
||||
/*
|
||||
* A dual-color bridge frame has only 450 us of active time, while a
|
||||
* single-color hardware-PWM frame has the full 500 us. If the current
|
||||
* output is single color, first fade its frame energy from 100% to
|
||||
* 90% without changing color. The following mixed-light transition
|
||||
* can then start at the same 450 us energy without an abrupt drop.
|
||||
*/
|
||||
static_pre_transition_active = 0U;
|
||||
static_pre_transition_tick = 0U;
|
||||
static_pre_transition_start_scale_q12 =
|
||||
Light_Transition_StaticEndpointScale_Q12;
|
||||
if(((mode_transition_start_w == 0U) ^
|
||||
(mode_transition_start_c == 0U)) &&
|
||||
Light_Transition_StaticEndpointScale_Q12 >
|
||||
STATIC_ENDPOINT_SCALE_START_Q12)
|
||||
{
|
||||
static_pre_transition_active = 1U;
|
||||
}
|
||||
else
|
||||
{
|
||||
Light_Transition_StaticEndpointScale_Q12 =
|
||||
STATIC_ENDPOINT_SCALE_START_Q12;
|
||||
}
|
||||
static_endpoint_recovery_active = 0U;
|
||||
static_endpoint_recovery_tick = 0U;
|
||||
}
|
||||
else
|
||||
{
|
||||
Light_Transition_StaticEndpointScale_Q12 =
|
||||
STATIC_ENDPOINT_SCALE_MAX_Q12;
|
||||
static_pre_transition_active = 0U;
|
||||
static_pre_transition_tick = 0U;
|
||||
static_endpoint_recovery_active = 0U;
|
||||
static_endpoint_recovery_tick = 0U;
|
||||
}
|
||||
Light_Transition_ModeActive = 1U;
|
||||
}
|
||||
|
||||
@@ -304,6 +420,8 @@ void Light_Transition_Task(void)
|
||||
uint16_t floor_w;
|
||||
uint32_t scaled_w_q12;
|
||||
uint32_t scaled_c_q12;
|
||||
uint32_t scale_delta;
|
||||
uint16_t endpoint_curve_q12;
|
||||
uint8_t power_transitioning;
|
||||
|
||||
/*
|
||||
@@ -322,7 +440,36 @@ void Light_Transition_Task(void)
|
||||
}
|
||||
|
||||
if(!powered_on)
|
||||
{
|
||||
Light_Transition_ModeActive = 0U;
|
||||
Light_Transition_StaticEndpointScale_Q12 =
|
||||
STATIC_ENDPOINT_SCALE_MAX_Q12;
|
||||
static_pre_transition_active = 0U;
|
||||
static_pre_transition_tick = 0U;
|
||||
static_endpoint_recovery_active = 0U;
|
||||
static_endpoint_recovery_tick = 0U;
|
||||
}
|
||||
|
||||
if(static_endpoint_recovery_active)
|
||||
{
|
||||
scale_delta =
|
||||
STATIC_ENDPOINT_SCALE_MAX_Q12 -
|
||||
STATIC_ENDPOINT_SCALE_START_Q12;
|
||||
|
||||
static_endpoint_recovery_tick++;
|
||||
endpoint_curve_q12 = transition_gamma_s_scale(
|
||||
static_endpoint_recovery_tick,
|
||||
STATIC_ENDPOINT_RECOVERY_TICKS);
|
||||
Light_Transition_StaticEndpointScale_Q12 = (uint16_t)(
|
||||
STATIC_ENDPOINT_SCALE_START_Q12 +
|
||||
((scale_delta * endpoint_curve_q12 + 2048U) >> 12));
|
||||
if(static_endpoint_recovery_tick >= STATIC_ENDPOINT_RECOVERY_TICKS)
|
||||
{
|
||||
Light_Transition_StaticEndpointScale_Q12 =
|
||||
STATIC_ENDPOINT_SCALE_MAX_Q12;
|
||||
static_endpoint_recovery_active = 0U;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Keep APP brightness tracking while off. Power fading is a separate
|
||||
@@ -428,15 +575,67 @@ void Light_Transition_Task(void)
|
||||
|
||||
if(Light_Transition_ModeActive && powered_on && !power_transitioning)
|
||||
{
|
||||
mode_transition_tick++;
|
||||
W_PWM_duty =
|
||||
interpolate_mode_output(mode_transition_start_w, target_w,
|
||||
mode_transition_tick);
|
||||
C_PWM_duty =
|
||||
interpolate_mode_output(mode_transition_start_c, target_c,
|
||||
mode_transition_tick);
|
||||
if(mode_transition_tick >= MODE_TRANSITION_TICKS)
|
||||
if(static_pre_transition_active)
|
||||
{
|
||||
uint16_t pre_curve_q12;
|
||||
uint32_t pre_scale_delta;
|
||||
|
||||
static_pre_transition_tick++;
|
||||
pre_curve_q12 = transition_gamma_s_scale(
|
||||
static_pre_transition_tick,
|
||||
STATIC_PRE_TRANSITION_TICKS);
|
||||
pre_scale_delta =
|
||||
static_pre_transition_start_scale_q12 -
|
||||
STATIC_ENDPOINT_SCALE_START_Q12;
|
||||
Light_Transition_StaticEndpointScale_Q12 = (uint16_t)(
|
||||
static_pre_transition_start_scale_q12 -
|
||||
((pre_scale_delta * pre_curve_q12 + 2048U) >> 12));
|
||||
W_PWM_duty = mode_transition_start_w;
|
||||
C_PWM_duty = mode_transition_start_c;
|
||||
if(static_pre_transition_tick >= STATIC_PRE_TRANSITION_TICKS)
|
||||
{
|
||||
Light_Transition_StaticEndpointScale_Q12 =
|
||||
STATIC_ENDPOINT_SCALE_START_Q12;
|
||||
static_pre_transition_active = 0U;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mode_transition_tick++;
|
||||
W_PWM_duty =
|
||||
interpolate_mode_output(mode_transition_start_w, target_w,
|
||||
mode_transition_tick);
|
||||
C_PWM_duty =
|
||||
interpolate_mode_output(mode_transition_start_c, target_c,
|
||||
mode_transition_tick);
|
||||
}
|
||||
/*
|
||||
* At low brightness, integer PWM resolution can reach the requested
|
||||
* single-color endpoint before the nominal transition tick ends.
|
||||
* Begin the 90%->100% envelope at that physical endpoint instead of
|
||||
* waiting and creating a visible pause followed by a final lift.
|
||||
*/
|
||||
if(!static_pre_transition_active &&
|
||||
!static_endpoint_recovery_active &&
|
||||
Mode == mode0 && choose_mode_falsg <= 2U &&
|
||||
((target_w == 0U && W_PWM_duty == 0U) ||
|
||||
(target_c == 0U && C_PWM_duty == 0U)))
|
||||
{
|
||||
static_endpoint_recovery_tick = 0U;
|
||||
static_endpoint_recovery_active = 1U;
|
||||
}
|
||||
if(!static_pre_transition_active &&
|
||||
mode_transition_tick >= mode_transition_total_ticks)
|
||||
{
|
||||
Light_Transition_ModeActive = 0U;
|
||||
if(!static_endpoint_recovery_active &&
|
||||
Mode == mode0 && choose_mode_falsg <= 2U &&
|
||||
(target_w == 0U || target_c == 0U))
|
||||
{
|
||||
static_endpoint_recovery_tick = 0U;
|
||||
static_endpoint_recovery_active = 1U;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(((Mode == mode2 || Mode == mode3) && powered_on) ||
|
||||
power_transitioning ||
|
||||
|
||||
@@ -7,6 +7,7 @@ extern volatile uint8_t Light_Transition_FadeActive;
|
||||
extern volatile uint8_t Light_Transition_ModeActive;
|
||||
extern volatile uint32_t Light_Transition_W_Output_Q12;
|
||||
extern volatile uint32_t Light_Transition_C_Output_Q12;
|
||||
extern volatile uint16_t Light_Transition_StaticEndpointScale_Q12;
|
||||
|
||||
#define Light_Transition_RequestOn() (Light_Transition_FadeActive = 0U)
|
||||
#define Light_Transition_RequestOff() (Light_Transition_FadeActive = 1U)
|
||||
|
||||
Reference in New Issue
Block a user