1. 更改模式时进行渐变
2. 开灯渐变
3. 提高亮灯的速度,从flashboot中开始亮灯
4. spotlight_main 调整到app_main中来
This commit is contained in:
Ekko.bao 2025-06-25 23:14:48 +08:00
parent c2ac3319f2
commit a4b68ffadb
12 changed files with 398 additions and 211 deletions

1
.gitignore vendored
View File

@ -17,3 +17,4 @@ interim_binary
middleware
include
drivers
*.pyc

View File

@ -445,7 +445,6 @@ int start_hilink_ble_net_config(int32_t net_cfg_time_s)
int hilink_ble_main(void)
{
int ret = 0;
hfdbg_set_level(1);
hfset_hilink_mode(SMTLK_BLE_FAST_CONNECT);
int hilink_entry_mode=hfget_hilink_mode();
printf("hilink_entry_mode:%d\r\n",hilink_entry_mode);
@ -544,8 +543,6 @@ int hilink_ble_main(void)
e_printf("HILINK_Main start success\r\n");
hf_set_hilink_main_runing();
// HILINK_RestoreFactorySettings();
extern int spotlight_main(void);
spotlight_main();
return 0;
}

View File

@ -27,10 +27,10 @@ extern "C" {
#define brandEn "SORONTEK"
#define deviceName "SORONTEK智能双色温灯"
#define productSeries ""
#define DEVICE_HIVERSION "1.0.0"
/* 设备固件版本号 */
#define FIRMWARE_VER "1.0.1"
#define FIRMWARE_VER "1.0.3"
/* 设备硬件版本号 */
#define HARDWARE_VER "1.0.0"
/* 设备软件版本号 */

View File

@ -514,7 +514,7 @@ void HILINK_NotifyDevStatus(int status)
/* 设备与云端连接断开,请在此处添加实现 */
#if defined(SUPPORT_MINIMALIST_NETCFG) || defined(SUPPORT_BLE_ANCILLAY_NETCFG)
BLE_CfgNetAdvUpdate(NULL);
BLE_CfgNetAdvCtrl(0);
// BLE_CfgNetAdvCtrl(0);
(void)BLE_CfgNetAdvCtrl(0xFFFFFFFF);
#endif
handle_device_offline();
@ -524,7 +524,7 @@ void HILINK_NotifyDevStatus(int status)
#if defined(SUPPORT_MINIMALIST_NETCFG) || defined(SUPPORT_BLE_ANCILLAY_NETCFG)
BLE_CfgNetAdvUpdate(NULL);
BLE_CfgNetAdvCtrl(0);
(void)BLE_CfgNetAdvCtrl(0xFFFFFFFF);
// (void)BLE_CfgNetAdvCtrl(0xFFFFFFFF);
#endif
/* 设备连接云端成功,请在此处添加实现 */
handle_device_online(); // 处理设备上线

View File

@ -227,11 +227,13 @@ const hfat_cmd_t user_define_at_cmds_table[]=
int USER_FUNC user_app_main(void)
{
hfdbg_set_level(1);
//AT+UART uart0
if(hfnet_start_uart(HFTHREAD_PRIORITIES_LOW,(hfnet_callback_t)uart_recv_callback)!=HF_SUCCESS)
{
HF_Debug(DEBUG_WARN,"start uart fail!\r\n");
}
spotlight_main();
#ifdef HF_MCU_OTA
if(hf_mcu_init() != HF_SUCCESS)
HF_Debug(DEBUG_WARN,"init mcu ota fail!\r\n");

View File

@ -47,7 +47,7 @@ int myhandle_put_brightness(const char* svc_id, const char* payload, unsigned in
// g_device_control.brightness_local = brightness;
g_device_control.elightMode = LIGHT_MODE_CUSTOMER;
ret = set_light(BRIGHTNESS_REMOTE2LOCAL(brightness), -1); // 只更新亮度,色温保持不变
ret = set_light(APP_CHANGE_LIGHT_BRIGHTNESS_CCT, BRIGHTNESS_REMOTE2LOCAL(brightness), -1); // 只更新亮度,色温保持不变
cJSON_Delete(json);
return ret; //异步上报
@ -74,7 +74,7 @@ int myhandle_put_cct(const char* svc_id, const char* payload, unsigned int len)
// g_device_control.cct_local = cct;
g_device_control.elightMode = LIGHT_MODE_CUSTOMER;
ret = set_light(-1, CCT_REMOTE2LOCAL(cct)); // 只更新色温,亮度保持不变
ret = set_light(APP_CHANGE_LIGHT_BRIGHTNESS_CCT, -1, CCT_REMOTE2LOCAL(cct)); // 只更新色温,亮度保持不变
cJSON_Delete(json);
return ret ;//异步上报
@ -100,7 +100,7 @@ int myhandle_put_lightMode(const char* svc_id, const char* payload, unsigned int
g_device_control.elightMode = mode;
// 同时更新亮度和色温
ret = set_light(BRIGHTNESS_REMOTE2LOCAL(scene_presets[mode].brightness), CCT_REMOTE2LOCAL(scene_presets[mode].cct));
ret = set_light(APP_CHANGE_LIGHT_MODE, BRIGHTNESS_REMOTE2LOCAL(scene_presets[mode].brightness), CCT_REMOTE2LOCAL(scene_presets[mode].cct));
}
cJSON_Delete(json);
@ -123,8 +123,11 @@ int myhandle_put_switch(const char* svc_id, const char* payload, unsigned int le
}
bool on = (item->valueint != 0);
ret = set_switch(on);
if (on) {
ret = set_light(APP_OPEN_LIGHT, -1, -1);
} else {
ret = set_light(APP_CLOSE_LIGHT, -1, -1);
}
cJSON_Delete(json);
return ret;
}

View File

@ -27,7 +27,6 @@ typedef enum {
#define SVC_ID_CCT "cct" // 色温控制
#define SVC_ID_LIGHT_MODE "lightMode" // 场景模式控制
#define SVC_ID_FADE_TIME "progressSwitch" // 渐变时长的控制
#define SVC_ID_NET_INFO "netInfo" // 配网信息
// JSON字段名定义
#define JSON_FIELD_ON "on" // 开关状态字段
@ -36,14 +35,21 @@ typedef enum {
#define JSON_FIELD_MODE "mode" // 场景模式字段
#define JSON_FIELD_FADE_TIME "fadeTime" // 渐变时长字段
typedef enum {
REPORT_SWITCH = 1 << 0,
REPORT_BRIGHTNESS = 1 << 1,
REPORT_CCT = 1 << 2,
REPORT_LIGHT_MODE = 1 << 3,
REPORT_FADE_TIME = 1 << 4,
REPORT_ALL = REPORT_SWITCH | REPORT_BRIGHTNESS | REPORT_CCT | REPORT_LIGHT_MODE | REPORT_FADE_TIME,
} report_mask_e;
// 当前亮度和色温状态
typedef struct __attribute__((packed, aligned(1))) {
// 物模型同步需要 持久化维持
uint8_t on; // 开关状态
lightMode_e elightMode;
uint16_t brightness_local; // 当前亮度 (0-1000)
uint16_t fade_time; // s
uint16_t fade_time; // 渐变时长(s)
uint16_t cct_local; // 当前色温 (2700-6500)
// 持久化维持
int32_t power_on_cnt; // 上电次数计数
@ -102,8 +108,8 @@ typedef struct __attribute__((packed, aligned(1))) {
#define NET_CFG_TIMEOUT_BRIGHTNESS 50 // 呼吸灯超时后的亮度
#define NET_CFG_TIMEOUT_CCT 4000 // 呼吸灯超时后的色温
#define FADE_INTERVAL_MIN (1*1000) //us
#define FADE_INTERVAL_MIN (10*1000) //us
#define NORMAL_FADE_TIME 3 //s
#define PWM_DUTY_RATIO_MAX 1000
//呼吸灯定义
@ -112,6 +118,9 @@ typedef struct __attribute__((packed, aligned(1))) {
#define BREARTH_STEP ((PWM_DUTY_RATIO_MAX) * 2) / (BREARTH_PERIOD / BREARTH_INTERVAL) //每次变化的幅度
// PWM频率和周期定义
#define PWM_FREQUENCY 3000 // PWM频率 2KHz
//渐变范围
#define SMOOTH_TIME_MAX 30
#define SMOOTH_TIME_MIN 0
@ -147,6 +156,15 @@ typedef enum {
SAVE_STATE_WAITING // 等待保存
} save_state_e;
typedef enum {
APP_CHANGE_LIGHT_MODE = 0,
APP_CHANGE_LIGHT_BRIGHTNESS_CCT,
APP_CLOSE_LIGHT,
APP_OPEN_LIGHT,
DEV_POWER_ON,
} light_ctrl_source_e;
#define DEFAULT_DEVICE_DATA { \
.read_done = false, \
.on = true, \
@ -161,8 +179,8 @@ typedef enum {
};
int spotlight_main(void);
int set_light(int32_t brightness, int32_t cct); // 新的统一控制函数
int set_switch(bool open);
int set_light(light_ctrl_source_e source,
int32_t brightness_local_target, int32_t cct_local_target);
int set_smooth_time(uint32_t smooth_time); // 设置渐变时长
void update_pwm_output(bool on_state, uint16_t duty_cw, uint16_t duty_ww);

View File

@ -30,11 +30,11 @@ static void set_light2breathtimeout(void);
static void set_light2net_cfg_done(void);
static void start_breath_timer(void);
static void report_switch_status(void);
void calculate_pwm_duty(void);
void calculate_pwm_duty(device_control_t* pdevice_control);
void close_light(void);
// 定义上报函数类型
typedef void (*report_func_t)(void);
static void start_report_task(report_func_t report_func);
static void start_report_task(uint32_t report_mask);
static void report_fade_complete_status(void);
static uint8_t calculate_checksum(const device_data_t* data);
static bool write_device_data_to_addr(uint32_t addr, const device_data_t* data);;
@ -56,6 +56,10 @@ static void report_device_online_status(void);
static osal_task *report_task_handle = NULL;
static bool report_task_running = false; // 添加任务运行状态标志
// 新增:全局上报掩码变量和条件变量
static uint32_t g_report_mask = 0;
static osal_semaphore report_sem; // 条件变量用于唤醒report task
// 灯渐变任务相关定义
#define FADE_TASK_PRIO 80
#define FADE_TASK_STACK_SIZE 0x1000
@ -64,9 +68,6 @@ static bool report_task_running = false; // 添加任务运行状态标志
#define BREATH_TASK_PRIO 80
#define BREATH_TASK_STACK_SIZE 0x1000
// PWM频率和周期定义
#define PWM_FREQUENCY 2000 // PWM频率 2KHz
static uint32_t pwm_period_cnt = 0; // PWM周期 40us
static uint8_t channel_id_cw = 0; // 冷白LED通道ID
static uint8_t channel_id_ww = 0; // 暖白LED通道ID
@ -101,28 +102,31 @@ typedef struct {
const char *prefix; // 打印前缀
} print_limiter_t;
#define FADE_CTRL_DATA_SIZE(fade_ctx) ((fade_ctx).member_barrier - (uint8_t*)&(fade_ctx))
// 渐变控制相关变量
static struct fade_ctx_t {
// 渐变控制参数
int32_t target_brightness;
int32_t target_cct;
int32_t current_brightness;
int32_t current_cct;
int32_t step_brightness;
int32_t step_cct;
bool is_fading;
bool fade_completed;
uint32_t smooth_time_us; // 渐变总时长(us)
uint32_t update_interval; // 更新间隔(us)
struct{
// 渐变控制参数
int32_t target_brightness;
int32_t target_cct;
int32_t current_brightness;
int32_t current_cct;
int32_t step_brightness;
int32_t step_cct;
bool is_fading;
bool fade_completed;
uint16_t fade_time; //s
uint32_t smooth_time_us; // 渐变总时长(us)
uint32_t update_interval; // 更新间隔(us)
// 打印限制器
print_limiter_t print_limiter;
};
uint8_t member_barrier[0]; // 用于计算前面成员变量大小
// 任务相关
osal_task *task_handle;
bool task_running;
osal_semaphore sem;
timer_handle_t timer_handle;
// 打印限制器
print_limiter_t print_limiter;
} fade_ctx = {0};
// 呼吸灯控制相关变量
@ -191,7 +195,7 @@ static void *fade_task(const char *arg)
{
unused(arg);
e_printf("[fade_task] Task started\r\n");
device_control_t device_control = {};
while (fade_ctx.task_running) {
// 等待渐变信号
if (osal_sem_down_timeout(&fade_ctx.sem, 100*1000) != OSAL_SUCCESS) {
@ -242,18 +246,22 @@ static void *fade_task(const char *arg)
BRIGHTNESS_LITME_RANGE(fade_ctx.current_brightness);
CCT_LITME_RANGE(fade_ctx.current_cct);
// 更新PWM输出
g_device_control.brightness_local = fade_ctx.current_brightness;
g_device_control.cct_local = fade_ctx.current_cct;
calculate_pwm_duty();
update_pwm_output(g_device_control.on, g_device_control.duty_cw, g_device_control.duty_ww);
device_control.brightness_local = fade_ctx.current_brightness;
device_control.cct_local = fade_ctx.current_cct;
calculate_pwm_duty(&device_control);
update_pwm_output(g_device_control.on, device_control.duty_cw, device_control.duty_ww);
if (fade_ctx.fade_completed) {
fade_ctx.fade_completed = false;
g_device_control.duty_ww = device_control.duty_ww;
g_device_control.duty_cw = device_control.duty_cw;
g_device_control.brightness_local = fade_ctx.current_brightness;
g_device_control.cct_local = fade_ctx.current_cct;
e_printf("[fade_task] Status report: local brightness=%d, CCT=%d\r\n",
g_device_control.brightness_local,
g_device_control.cct_local);
// 启动状态上报任务,使用渐变完成状态上报函数
start_report_task(report_device_online_status);
start_report_task(REPORT_BRIGHTNESS | REPORT_CCT);
req_save_device_data();
}
}
@ -316,7 +324,7 @@ static void *breath_task(const char *arg)
// 渐变定时器回调函数
static void fade_timer_callback(uintptr_t data)
{
osal_sem_up(&fade_ctx.sem);
osal_sem_up(&fade_ctx.sem); // 唤醒渐变任务 fade_task
uapi_timer_start(fade_ctx.timer_handle, fade_ctx.update_interval, fade_timer_callback, 0);
}
@ -361,6 +369,8 @@ static void init_fade_ctx(void)
// 设置默认更新间隔
fade_ctx.update_interval = FADE_INTERVAL_MIN;
fade_ctx.current_brightness = g_device_control.brightness_local;
fade_ctx.current_cct = g_device_control.cct_local;
}
// 初始化呼吸灯控制
@ -455,16 +465,16 @@ static void stop_breath_timer(void)
}
// 计算PWM占空比
void calculate_pwm_duty(void)
void calculate_pwm_duty(device_control_t* pdevice_control)
{ // 如果开关关闭则占空比为0
uint32_t total_brightness_pwm = g_device_control.brightness_local;
uint32_t total_brightness_pwm = pdevice_control->brightness_local;
// 计算色温比例 (0-10000)
uint16_t cct_ratio = ((g_device_control.cct_local - CCT_LOCAL_MIN) * 10000) / CCT_RANGE;
uint16_t cct_ratio = ((pdevice_control->cct_local - CCT_LOCAL_MIN) * 10000) / CCT_RANGE;
// 根据色温比例计算CW和WW的占空比
// 总亮度保持不变只调整CW和WW的比例
g_device_control.duty_cw = (total_brightness_pwm * cct_ratio) / 10000;
g_device_control.duty_ww = total_brightness_pwm - g_device_control.duty_cw;
pdevice_control->duty_cw = (total_brightness_pwm * cct_ratio) / 10000;
pdevice_control->duty_ww = total_brightness_pwm - pdevice_control->duty_cw;
}
// 更新PWM输出
@ -496,15 +506,18 @@ void update_pwm_output(bool on_state, uint16_t duty_cw_val, uint16_t duty_ww_val
low_cnt_ww = pwm_period_cnt; // Ensure low_cnt is full period if off
}
// uapi_pwm_stop_group(CONFIG_PWM_GROUP_ID);
cfg_repeat.high_time = high_cnt_cw;
cfg_repeat.low_time = low_cnt_cw;
uapi_pwm_open(channel_id_cw, &cfg_repeat);
// uapi_pwm_update_duty_ratio(channel_id_cw, cfg_repeat.low_time, cfg_repeat.high_time);
cfg_repeat.high_time = high_cnt_ww;
cfg_repeat.low_time = low_cnt_ww;
cfg_repeat.offset_time = high_cnt_cw; // WW PWM starts after CW PWM high time
uapi_pwm_open(channel_id_ww, &cfg_repeat);
// uapi_pwm_update_duty_ratio(channel_id_ww, cfg_repeat.low_time, cfg_repeat.high_time);
uapi_pwm_start_group(CONFIG_PWM_GROUP_ID);
@ -517,74 +530,78 @@ void update_pwm_output(bool on_state, uint16_t duty_cw_val, uint16_t duty_ww_val
#define ABS(x) ((x) < 0 ? -(x) : (x))
// 计算渐变步长
static void calculate_fade_steps(void)
static void calculate_fade_steps(struct fade_ctx_t *pfade_ctx)
{
// 从g_device_control获取渐变时间
fade_ctx.smooth_time_us = g_device_control.fade_time * 1000 * 1000;//s->us
e_printf("fade brightness: curr:%d, target:%d, cct: curr:%d, target:%d\r\n",
fade_ctx.current_brightness, fade_ctx.target_brightness, fade_ctx.current_cct, fade_ctx.target_cct);
pfade_ctx->smooth_time_us = pfade_ctx->fade_time * 1000 * 1000;//s->us
e_printf("fade brightness:%d->%d, cct:%d->%d, time:%ds\r\n",
pfade_ctx->current_brightness, pfade_ctx->target_brightness, pfade_ctx->current_cct, pfade_ctx->target_cct, pfade_ctx->fade_time);
// 计算亮度渐变步长
int32_t brightness_diff = fade_ctx.target_brightness - fade_ctx.current_brightness;
int32_t cct_diff = fade_ctx.target_cct - fade_ctx.current_cct;
int32_t brightness_diff = pfade_ctx->target_brightness - pfade_ctx->current_brightness;
int32_t cct_diff = pfade_ctx->target_cct - pfade_ctx->current_cct;
// 计算需要的总步数(取亮度和色温中变化较大的那个)
uint32_t max_diff = (ABS(brightness_diff) > ABS(cct_diff)) ? ABS(brightness_diff) : ABS(cct_diff);
uint32_t min_steps = 0;
uint32_t available_interval = 0;
// 如果变化太小,直接设置目标值 EKKO:这里需要确认是直接设置目标值还是强制等待渐变时长
if (max_diff == 0) {
fade_ctx.step_brightness = 0;
fade_ctx.step_cct = 0;
fade_ctx.update_interval = fade_ctx.smooth_time_us;
// 如果变化太小或者不需要渐变,直接设置目标值
if (max_diff == 0 || pfade_ctx->smooth_time_us == 0) {
pfade_ctx->current_brightness = pfade_ctx->target_brightness;
pfade_ctx->current_cct = pfade_ctx->target_cct;
pfade_ctx->step_brightness = 0;
pfade_ctx->step_cct = 0;
pfade_ctx->update_interval = FADE_INTERVAL_MIN;
goto lab_exit;
}
min_steps = max_diff;
// 计算实际可用的时间间隔
available_interval = fade_ctx.smooth_time_us / min_steps;
available_interval = pfade_ctx->smooth_time_us / min_steps;
// 如果时间间隔太小(小于允许的最小更新间隔),则增加步长
if (available_interval < FADE_INTERVAL_MIN) {
// 重新计算步长,确保在指定时间内完成
fade_ctx.update_interval = FADE_INTERVAL_MIN;
int32_t actual_steps = fade_ctx.smooth_time_us / fade_ctx.update_interval;
pfade_ctx->update_interval = FADE_INTERVAL_MIN;
int32_t actual_steps = pfade_ctx->smooth_time_us / pfade_ctx->update_interval;
// 计算新的步长
fade_ctx.step_brightness = brightness_diff / actual_steps;
fade_ctx.step_cct = cct_diff / actual_steps;
pfade_ctx->step_brightness = brightness_diff / actual_steps;
pfade_ctx->step_cct = cct_diff / actual_steps;
// 确保至少有一个最小步长
if (fade_ctx.step_brightness == 0 && brightness_diff != 0) {
fade_ctx.step_brightness = (brightness_diff > 0) ? 1 : -1;
if (pfade_ctx->step_brightness == 0 && brightness_diff != 0) {
pfade_ctx->step_brightness = (brightness_diff > 0) ? 1 : -1;
}
if (fade_ctx.step_cct == 0 && cct_diff != 0) {
fade_ctx.step_cct = (cct_diff > 0) ? 1 : -1;
if (pfade_ctx->step_cct == 0 && cct_diff != 0) {
pfade_ctx->step_cct = (cct_diff > 0) ? 1 : -1;
}
} else {
// 使用计算出的时间间隔
fade_ctx.update_interval = available_interval;
fade_ctx.step_brightness = (brightness_diff > 0) ? 1 : -1;
fade_ctx.step_cct = (cct_diff > 0) ? 1 : -1;
pfade_ctx->update_interval = available_interval;
pfade_ctx->step_brightness = (brightness_diff > 0) ? 1 : -1;
pfade_ctx->step_cct = (cct_diff > 0) ? 1 : -1;
}
// 如果亮度或色温没有变化则步长为0
if (brightness_diff == 0) {
fade_ctx.step_brightness = 0;
pfade_ctx->step_brightness = 0;
}
if (cct_diff == 0) {
fade_ctx.step_cct = 0;
pfade_ctx->step_cct = 0;
}
lab_exit:
if (should_print(&fade_ctx.print_limiter)) {
e_printf("max_diff:%d, fade time:%uus, Brightness: diff:%d, step:%d, CCT: diff:%d, step:%d, update_interval:%uus\r\n",
max_diff, fade_ctx.smooth_time_us, brightness_diff, fade_ctx.step_brightness, cct_diff, fade_ctx.step_cct, fade_ctx.update_interval);
}
e_printf("fade max_diff:%d, fade time:%uus, Brightness: diff:%d, step:%d, CCT: diff:%d, step:%d, update_interval:%uus\r\n",
max_diff, pfade_ctx->smooth_time_us, brightness_diff, pfade_ctx->step_brightness, cct_diff, pfade_ctx->step_cct, pfade_ctx->update_interval);
}
static void cancel_current_light_fade(void)
{
uapi_timer_stop(fade_ctx.timer_handle);
// 如果我打断了渐变,则将当前值更新到目标值不然下次计算会异常
// g_device_control.cct_local = fade_ctx.current_cct;
// g_device_control.brightness_local = fade_ctx.current_brightness;
// memset(&fade_ctx, 0, FADE_CTRL_DATA_SIZE(fade_ctx));
}
// 计算校验和
@ -834,88 +851,113 @@ static void stop_save_task(void)
}
// 设置灯光状态(统一控制函数)
int set_light(int32_t brightness_local, int32_t cct_local)
// 参数:
// source: 控制源,用于区分不同的控制场景
// current_brightness_local: 当前亮度值
// current_cct_local: 当前色温值
// brightness_local_target: 亮度目标值
// cct_local_target: 色温目标值
// 返回值:
// 0: 成功
// -111: 异步上报
// -1: 失败
int set_light(light_ctrl_source_e source,
int32_t brightness_local_target, int32_t cct_local_target)
{
struct fade_ctx_t tmp_fade_ctx = fade_ctx;
// 如果任一参数大于等于0则更新对应值
e_printf("ligMode:%d, local brightness: curr:%d, target:%d, local cct: curr:%d, target:%d\r\n",
g_device_control.elightMode, g_device_control.brightness_local, brightness_local, g_device_control.cct_local, cct_local);
tmp_fade_ctx.current_brightness = g_device_control.brightness_local;
tmp_fade_ctx.current_cct = g_device_control.cct_local;
tmp_fade_ctx.target_brightness = tmp_fade_ctx.current_brightness ;
tmp_fade_ctx.target_cct = tmp_fade_ctx.current_cct;
if (brightness_local >= 0) {
BRIGHTNESS_LITME_RANGE(brightness_local);
if (g_device_control.elightMode == LIGHT_MODE_CUSTOMER) {
tmp_fade_ctx.target_brightness = brightness_local;
} else {
g_device_control.brightness_local = brightness_local;
}
}
if (cct_local >= 0) {
CCT_LITME_RANGE(cct_local);
if (g_device_control.elightMode == LIGHT_MODE_CUSTOMER) {
tmp_fade_ctx.target_cct = cct_local;
} else {
g_device_control.cct_local = cct_local;
}
}
switch (g_device_control.elightMode)
{
case LIGHT_MODE_CUSTOMER:
if (g_device_control.fade_time) {
tmp_fade_ctx.is_fading = true;
tmp_fade_ctx.fade_completed = false;
// if(fade_ctx.is_fading) {
// e_printf("fade is running, skip set_light\r\n");
// return -111;
// }
fade_ctx = tmp_fade_ctx;
// 计算渐变步长
calculate_fade_steps();
e_printf("start fade\r\n");
// 启动渐变定时器
set_switch(true);
uapi_timer_start(fade_ctx.timer_handle, fade_ctx.update_interval, fade_timer_callback, 0);
fast_report(SVC_ID_LIGHT_MODE);
#if 0
while (!fade_ctx.fade_completed) {
msleep(10);
}
return 0; // 同步上报
#else
return -111; // 异步上报
#endif
}
g_device_control.cct_local = tmp_fade_ctx.target_cct;
g_device_control.brightness_local = tmp_fade_ctx.target_brightness;
// no break; // 如果渐变时间是0则直接一步完成
default: //情景模式直接切换到对应的色温和亮度
set_switch(true);
}
start_report_task(report_device_online_status);//直接全量上报
return -111; // 异步上报
}
// 设置开关状态
int set_switch(bool open)
{
g_device_control.on = open;
if (fade_ctx.is_fading) //打断当前的渐变计划
{
struct fade_ctx_t tmp_fade_ctx = {0};
if (fade_ctx.is_fading) {
cancel_current_light_fade();
}
calculate_pwm_duty();
update_pwm_output(g_device_control.on, g_device_control.duty_cw, g_device_control.duty_ww);
uapi_gpio_set_val(SWITCH_PIN, open ? OPEN_LIGHT : CLOSE_LIGHT);
// 如果打开灯,则需要手动将前置状态设置为关闭的样子,这样子后面计算渐变才能正常计算
if (APP_OPEN_LIGHT == source) {
g_device_control.on = true;
fade_ctx.current_brightness = 0;
fade_ctx.current_cct = g_device_control.cct_local;
brightness_local_target = g_device_control.brightness_local;
cct_local_target = g_device_control.cct_local;
}
memcpy(&tmp_fade_ctx, &fade_ctx, FADE_CTRL_DATA_SIZE(fade_ctx));
tmp_fade_ctx.target_brightness = tmp_fade_ctx.current_brightness;
if (brightness_local_target >= 0) {
BRIGHTNESS_LITME_RANGE(brightness_local_target);
tmp_fade_ctx.target_brightness = brightness_local_target;
}
tmp_fade_ctx.target_cct = tmp_fade_ctx.current_cct;
if (cct_local_target >= 0) {
CCT_LITME_RANGE(cct_local_target);
tmp_fade_ctx.target_cct = cct_local_target;
}
e_printf("source:%d, lightMode:%d, local brightness: base:%d, target:%d, local cct: base:%d, target:%d\r\n",
source, g_device_control.elightMode, tmp_fade_ctx.current_brightness,
tmp_fade_ctx.target_brightness, tmp_fade_ctx.current_cct, tmp_fade_ctx.target_cct);
tmp_fade_ctx.fade_time = g_device_control.fade_time;
switch (source) {
case APP_CLOSE_LIGHT:
close_light();
return 0;
break;
case DEV_POWER_ON:
case APP_OPEN_LIGHT:
tmp_fade_ctx.fade_time = NORMAL_FADE_TIME; // 上电时,直接设置为默认渐变时长
case APP_CHANGE_LIGHT_MODE:
// 直接将信息更新到目标值
g_device_control.cct_local = tmp_fade_ctx.target_cct;
g_device_control.brightness_local = tmp_fade_ctx.target_brightness;
//情景模式或者上电时直接切换到对应的色温和亮度
tmp_fade_ctx.is_fading = true;
tmp_fade_ctx.fade_completed = false;
if (tmp_fade_ctx.is_fading) {
cancel_current_light_fade();
}
calculate_fade_steps(&tmp_fade_ctx);
memcpy(&fade_ctx, &tmp_fade_ctx, FADE_CTRL_DATA_SIZE(tmp_fade_ctx));
e_printf("start fade\r\n");
uapi_timer_start(fade_ctx.timer_handle, fade_ctx.update_interval, fade_timer_callback, 0);
start_report_task(REPORT_SWITCH | REPORT_BRIGHTNESS | REPORT_CCT);
req_save_device_data();
return 0; // 异步上报
break;
case APP_CHANGE_LIGHT_BRIGHTNESS_CCT:
// 直接将信息更新到目标值
g_device_control.cct_local = tmp_fade_ctx.target_cct;
g_device_control.brightness_local = tmp_fade_ctx.target_brightness;
tmp_fade_ctx.is_fading = true;
tmp_fade_ctx.fade_completed = false;
if (tmp_fade_ctx.is_fading) {
cancel_current_light_fade();
}
calculate_fade_steps(&tmp_fade_ctx);
memcpy(&fade_ctx, &tmp_fade_ctx, FADE_CTRL_DATA_SIZE(tmp_fade_ctx));
e_printf("start fade\r\n");
uapi_timer_start(fade_ctx.timer_handle, fade_ctx.update_interval, fade_timer_callback, 0);
start_report_task(REPORT_BRIGHTNESS | REPORT_CCT | REPORT_LIGHT_MODE);
req_save_device_data();
#if 0
while (!fade_ctx.fade_completed) {
msleep(10);
}
return 0; // 同步上报
#else
return -111; // 异步上报
#endif
break;
}
e_printf("set_light error, source:%d, current_brightness_local:%d, current_cct_local:%d, brightness_local_target:%d, cct_local_target:%d\r\n",
source, tmp_fade_ctx.current_brightness, tmp_fade_ctx.current_cct, brightness_local_target, cct_local_target);
return -1;
}
void close_light(void)
{
g_device_control.on = false;
if (fade_ctx.is_fading) {
cancel_current_light_fade();
}
fade_ctx.current_brightness = 0;
fade_ctx.current_cct = 0;
update_pwm_output(false, 0, 0);
req_save_device_data();
return 0;
}
static void gpio_init(pin_t pin)
@ -950,10 +992,10 @@ static void pwm_init(pin_t pin, pin_t pin1)
channel_id_cw = pin%8;
channel_id_ww = pin1%8;
uint8_t channel_ids[2] = {channel_id_cw, channel_id_ww};
uapi_pwm_open(channel_id_cw, &cfg_repeat);
uapi_pwm_open(channel_id_ww, &cfg_repeat);
// uapi_pwm_open(channel_id_cw, &cfg_repeat);
// uapi_pwm_open(channel_id_ww, &cfg_repeat);
uapi_pwm_set_group(CONFIG_PWM_GROUP_ID, channel_ids, sizeof(channel_ids));
uapi_pwm_start_group(CONFIG_PWM_GROUP_ID);
// uapi_pwm_start_group(CONFIG_PWM_GROUP_ID);
e_printf("PWM基础时钟频率: %dHz, 目标时钟频率: %dHz, 周期计数: %d\r\n", frequency, PWM_FREQUENCY, pwm_period_cnt);
}
@ -981,11 +1023,12 @@ void stop_net_config(void) {
}
// 配网状态管理相关函数
static void handle_network_status(void)
static int handle_network_status(void)
{
uint8_t start_net_cfg = 0;
// 如果已经配网,直接返回
if (g_device_control.is_networked) {
return;
return start_net_cfg;
}
// 增加上电计数
@ -994,10 +1037,12 @@ static void handle_network_status(void)
// 检查是否需要进入配网状态
if ((!g_device_control.is_net_configured) || g_device_control.power_on_cnt >= NET_CFG_ENTRY_CNT) {
start_net_config();
start_net_cfg = 1;
}
// 保存设备状态
req_save_device_data();
return start_net_cfg;
}
@ -1031,46 +1076,93 @@ static void report_switch_status(void)
fast_report(SVC_ID_SWITCH);
}
static const struct {
const char* svc_id;
} report_mask_map[] = {
[REPORT_SWITCH] = {SVC_ID_SWITCH},
[REPORT_BRIGHTNESS] = {SVC_ID_BRIGHTNESS},
[REPORT_CCT] = {SVC_ID_CCT},
[REPORT_LIGHT_MODE] = {SVC_ID_LIGHT_MODE},
[REPORT_FADE_TIME] = {SVC_ID_FADE_TIME},
};
// 状态上报任务函数
static void *report_task(const char *arg)
{
report_func_t report_func = (report_func_t)arg;
e_printf("report_task running...\r\n");
unused(arg);
e_printf("[report_task] Task started\r\n");
// 等待hilink和数据ready
while (!(g_device_control.read_done && hf_hilink_main_is_runing())) {
// 数据已经正确load并且hilink已经运行才开始上报
e_printf("read_done%d, hilink:%d\r\n", g_device_control.read_done, hf_hilink_main_is_runing());
osal_msleep(50);
}
if (report_func)
{
report_func();
while (report_task_running) {
// 等待信号量唤醒
if (g_report_mask == 0 && osal_sem_down_timeout(&report_sem, 100*1000) != OSAL_SUCCESS) {
continue;
}
e_printf("[report_task] Reported mask: 0x%x\r\n", g_report_mask);
// 根据掩码进行上报
if (g_report_mask & REPORT_SWITCH) {
g_report_mask &= ~REPORT_SWITCH;
fast_report(SVC_ID_SWITCH);
}
if (g_report_mask & REPORT_BRIGHTNESS) {
g_report_mask &= ~REPORT_BRIGHTNESS;
fast_report(SVC_ID_BRIGHTNESS);
}
if (g_report_mask & REPORT_CCT) {
g_report_mask &= ~REPORT_CCT;
fast_report(SVC_ID_CCT);
}
if (g_report_mask & REPORT_LIGHT_MODE) {
g_report_mask &= ~REPORT_LIGHT_MODE;
fast_report(SVC_ID_LIGHT_MODE);
}
if (g_report_mask & REPORT_FADE_TIME) {
g_report_mask &= ~REPORT_FADE_TIME;
fast_report(SVC_ID_FADE_TIME);
}
}
report_task_running = false;
e_printf("[report_task] exited\r\n");
e_printf("[report_task] Task exited\r\n");
return NULL;
}
// 启动状态上报任务
static void start_report_task(report_func_t report_func)
static void start_report_task(uint32_t report_mask)
{
if (report_task_running) {
e_printf("[report_task] Previous task is still running, skip this report\r\n");
return;
// 设置全局掩码
g_report_mask |= report_mask;
osal_sem_up(&report_sem);
// 只在第一次创建任务
if (!report_task_running) {
osal_kthread_lock();
if (report_task_running) {
osal_kthread_unlock();
return;
}
report_task_running = true;
e_printf("[start_report_task] Creating report task\r\n");
report_task_handle = osal_kthread_create((osal_kthread_handler)report_task, NULL, "ReportStaTask",
REPORT_TASK_STACK_SIZE);
if (report_task_handle != NULL) {
osal_kthread_set_priority(report_task_handle, REPORT_TASK_PRIO);
e_printf("[start_report_task] Report task created successfully\r\n");
} else {
e_printf("[start_report_task] Failed to create report task\r\n");
report_task_running = false;
}
osal_kthread_unlock();
} else {
e_printf("[start_report_task] Report task already running, mask: 0x%x\r\n", report_mask);
}
report_task_running = true; // 设置任务运行标志
if (report_task_handle) {
osal_kthread_destroy(report_task_handle, 0);
report_task_handle = NULL;
}
e_printf("start report_task\r\n");
osal_kthread_lock();
report_task_handle = osal_kthread_create((osal_kthread_handler)report_task, (void*)report_func, "ReportStaTask",
REPORT_TASK_STACK_SIZE);
if (report_task_handle != NULL) {
osal_kthread_set_priority(report_task_handle, REPORT_TASK_PRIO);
}
osal_kthread_unlock();
}
static int device_online = 0;
@ -1094,8 +1186,8 @@ void handle_device_online(void)
// 重置配网状态
g_net_breath_state = NET_CFG_IDLE;
g_net_cfg_start_time = 0;
// 启动状态上报任务,使用设备上线状态上报函数
start_report_task(report_device_online_status);
// 启动状态上报任务,上报所有服务状态
start_report_task(REPORT_ALL);
device_online = 1;
}
@ -1200,6 +1292,22 @@ static void stop_spotlight_main_task(void)
spotlight_main_task_handle = NULL;
osal_kthread_unlock();
// 停止report task
if (report_task_running) {
report_task_running = false;
osal_sem_up(&report_sem); // 唤醒任务以使其退出
osal_kthread_lock();
if (report_task_handle) {
osal_kthread_destroy(report_task_handle, 0);
report_task_handle = NULL;
}
osal_kthread_unlock();
osal_sem_destroy(&report_sem);
e_printf("[stop_spotlight_main_task] Report task stopped\r\n");
}
e_printf("[stop_spotlight_main_task] Task stopped\r\n");
}
@ -1220,9 +1328,8 @@ static void check_net_cfg_timeout(void)
// 修改spotlight_main函数
int spotlight_main(void) {
uapi_systick_init();
e_printf("uapi_timer_get_max_us:%uus, start_time:%uus\r\n", uapi_timer_get_max_us(), uapi_systick_get_ms());
read_device_data();
e_printf("uapi_timer_get_max_us:%uus\r\n", uapi_timer_get_max_us());
// 初始化GPIO并将灯关闭
gpio_init(SWITCH_PIN);
// 初始化PWM系统
@ -1235,10 +1342,19 @@ int spotlight_main(void) {
// 初始化保存任务
init_save_task();
// 初始化report task信号量
if (osal_sem_init(&report_sem, 0) != OSAL_SUCCESS) {
e_printf("[spotlight_main] Failed to init report semaphore\r\n");
return -1;
}
// 检查配网状态,确定是否需要进入配网状态
handle_network_status();
//上电亮灯也是需要缓慢亮起来, 如果是在配网的话就不用了。交给配网的代码进行控制
if (g_net_breath_state == NET_CFG_IDLE && g_device_control.on == true){
set_light(DEV_POWER_ON, g_device_control.brightness_local, g_device_control.cct_local);
}
set_switch(g_device_control.on);//按照当前值更新light
if (!g_device_control.is_networked && !g_device_control.is_net_configured) {
try_detect_factory_test();
}
@ -1272,7 +1388,9 @@ static void set_light2breathtimeout(void)
// 恢复到自定义模式
g_device_control.brightness_local = BRIGHTNESS_REMOTE2LOCAL(NET_CFG_TIMEOUT_BRIGHTNESS);
g_device_control.cct_local = CCT_REMOTE2LOCAL(NET_CFG_TIMEOUT_CCT);
calculate_pwm_duty();
fade_ctx.current_brightness = g_device_control.brightness_local;
fade_ctx.current_cct = g_device_control.cct_local;
calculate_pwm_duty(&g_device_control);
update_pwm_output(g_device_control.on, g_device_control.duty_cw, g_device_control.duty_ww);
}
@ -1283,7 +1401,9 @@ static void set_light2net_cfg_done(void)
g_device_control.brightness_local = BRIGHTNESS_REMOTE2LOCAL(NET_CFG_DEFAULT_BRIGHTNESS);
g_device_control.cct_local = CCT_REMOTE2LOCAL(NET_CFG_DEFAULT_CCT);
g_device_control.fade_time = NET_CFG_DEFAULT_FADE_TIME;
calculate_pwm_duty();
fade_ctx.current_brightness = g_device_control.brightness_local;
fade_ctx.current_cct = g_device_control.cct_local;
calculate_pwm_duty(&g_device_control);
update_pwm_output(g_device_control.on, g_device_control.duty_cw, g_device_control.duty_ww);
}
@ -1292,7 +1412,6 @@ static void start_breath_timer(void)
{
g_net_breath_state = NET_CFG_BREATHING;
g_net_cfg_start_time = uapi_systick_get_ms();
breath_ctx.is_initial_breath = true;
uapi_timer_start(breath_ctx.timer_handle, breath_ctx.update_interval, breath_timer_callback, 0);
}

View File

@ -131,6 +131,7 @@ target = {
'-:hal_systick', 'partition', 'partition_ws63','pmp_cfg_ws63', 'nonos_malloc', 'nonos_malloc_port',
'update_common', 'update_local', 'update_local_ws63', 'lzma_22.00', 'update_storage', 'update_common_ws63', 'update_ab_ws63', 'factory_ws63',
'efuse', 'hal_efuse_v151', 'efuse_port', 'soc_port',
'pwm', 'hal_pwm', 'pwm_port', # ADD
],
'ram_component_set': ['uart', "time_set", "cpu", "pinctrl", "watchdog", "security_unified",'pmp_set'],
'os': 'non-os',

View File

@ -214,7 +214,22 @@ CONFIG_GPIO1_WIDTH=32
# CONFIG_DRIVER_SUPPORT_PINCTRL is not set
# CONFIG_DRIVER_SUPPORT_PM is not set
# CONFIG_DRIVER_SUPPORT_PMP is not set
# CONFIG_DRIVER_SUPPORT_PWM is not set
CONFIG_DRIVER_SUPPORT_PWM=y
#
# PWM Configuration
#
#
# Config PWM
#
CONFIG_PWM_USING_V151=y
# CONFIG_PWM_USING_V150 is not set
CONFIG_PWM_GROUP_NUM=6
CONFIG_PWM_CHANNEL_NUM=6
# CONFIG_PWM_PRELOAD is not set
# end of PWM Configuration
# CONFIG_DRIVER_SUPPORT_RTC is not set
# CONFIG_DRIVER_SUPPORT_SDIO is not set
# CONFIG_DRIVER_SUPPORT_SEC is not set
@ -270,15 +285,6 @@ CONFIG_DRIVER_SUPPORT_SFC=y
#
# Config SFC
#
# CONFIG_SFC_SUPPORT_DMA is not set
# CONFIG_SFC_ALLOW_ERASE_WRITEBACK is not set
# CONFIG_SFC_ALREADY_INIT is not set
# CONFIG_SFC_SUPPORT_LPM is not set
# CONFIG_SFC_SUPPORT_SFC_LOCK is not set
# CONFIG_SFC_SUPPORT_DATA_CACHE is not set
# CONFIG_SFC_SUPPORT_RWE_INDEPENDENT is not set
# CONFIG_SFC_SUPPORT_WRITE_PROTECT is not set
# CONFIG_SFC_USE_CUSTOMIZED_DEVICE_INFO is not set
# CONFIG_SFC_DEBUG is not set
# end of SFC Configuration
@ -459,13 +465,54 @@ CONFIG_MIDDLEWARE_SUPPORT_EXCEPT_REBOOT=y
#
#
# bt
# bt_host
#
#
# Config bluetooth.
#
# end of bt
CONFIG_AT_BLE=y
#
# AT_BLE
#
#
# Config bluetooth host AT BLE.
#
# end of AT_BLE
CONFIG_AT_GLE=y
#
# AT_GLE
#
#
# Config bluetooth host AT GLE.
#
# end of AT_GLE
#
# FEATURE_GLE
#
#
# Config bluetooth host GLE feature.
#
# CONFIG_FEATURE_GLE_LOW_LATENCY is not set
# CONFIG_FEATURE_GLE_HADM is not set
# end of FEATURE_GLE
# end of bt_host
#
# bt_controller
#
#
# Config bluetooth.
#
# end of bt_controller
#
# nfc
@ -495,5 +542,4 @@ CONFIG_MIDDLEWARE_SUPPORT_EXCEPT_REBOOT=y
#
# Config the test.
#
# CONFIG_TEST_SUPPORT_TESTSUITE is not set
# end of Test