diff --git a/.gitignore b/.gitignore index 1fbbfdc..1726afd 100644 --- a/.gitignore +++ b/.gitignore @@ -17,3 +17,4 @@ interim_binary middleware include drivers +*.pyc diff --git a/application/samples/wifi/ohos_connect/hilink_adapt/entry/hilink_ble_main.c b/application/samples/wifi/ohos_connect/hilink_adapt/entry/hilink_ble_main.c index a24ebd5..37486b3 100755 --- a/application/samples/wifi/ohos_connect/hilink_adapt/entry/hilink_ble_main.c +++ b/application/samples/wifi/ohos_connect/hilink_adapt/entry/hilink_ble_main.c @@ -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; } diff --git a/application/samples/wifi/ohos_connect/hilink_adapt/product/device_profile.h b/application/samples/wifi/ohos_connect/hilink_adapt/product/device_profile.h index 4be48f6..1ad289d 100755 --- a/application/samples/wifi/ohos_connect/hilink_adapt/product/device_profile.h +++ b/application/samples/wifi/ohos_connect/hilink_adapt/product/device_profile.h @@ -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" /* 设备软件版本号 */ diff --git a/application/samples/wifi/ohos_connect/hilink_adapt/product/hilink_device.c b/application/samples/wifi/ohos_connect/hilink_adapt/product/hilink_device.c index 8e18040..e2b34ad 100755 --- a/application/samples/wifi/ohos_connect/hilink_adapt/product/hilink_device.c +++ b/application/samples/wifi/ohos_connect/hilink_adapt/product/hilink_device.c @@ -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(); // 处理设备上线 diff --git a/application/ws63/user_main/app_main.c b/application/ws63/user_main/app_main.c index f789636..6ce2e83 100755 --- a/application/ws63/user_main/app_main.c +++ b/application/ws63/user_main/app_main.c @@ -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"); diff --git a/application/ws63/user_main/spotlight/device_module.c b/application/ws63/user_main/spotlight/device_module.c index 258e1fc..a0541ed 100644 --- a/application/ws63/user_main/spotlight/device_module.c +++ b/application/ws63/user_main/spotlight/device_module.c @@ -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; } diff --git a/application/ws63/user_main/spotlight/spotlight.h b/application/ws63/user_main/spotlight/spotlight.h index d79a386..dd24756 100644 --- a/application/ws63/user_main/spotlight/spotlight.h +++ b/application/ws63/user_main/spotlight/spotlight.h @@ -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); diff --git a/application/ws63/user_main/spotlight/spotlight_main.c b/application/ws63/user_main/spotlight/spotlight_main.c index c34af37..9b9307b 100644 --- a/application/ws63/user_main/spotlight/spotlight_main.c +++ b/application/ws63/user_main/spotlight/spotlight_main.c @@ -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); } diff --git a/build/config/target_config/ws63/__pycache__/config.cpython-39.pyc b/build/config/target_config/ws63/__pycache__/config.cpython-39.pyc deleted file mode 100644 index 224c416..0000000 Binary files a/build/config/target_config/ws63/__pycache__/config.cpython-39.pyc and /dev/null differ diff --git a/build/config/target_config/ws63/__pycache__/target_config.cpython-39.pyc b/build/config/target_config/ws63/__pycache__/target_config.cpython-39.pyc deleted file mode 100644 index 387009b..0000000 Binary files a/build/config/target_config/ws63/__pycache__/target_config.cpython-39.pyc and /dev/null differ diff --git a/build/config/target_config/ws63/config.py b/build/config/target_config/ws63/config.py index 121d239..1fc2142 100755 --- a/build/config/target_config/ws63/config.py +++ b/build/config/target_config/ws63/config.py @@ -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', diff --git a/build/config/target_config/ws63/menuconfig/acore/ws63_flashboot.config b/build/config/target_config/ws63/menuconfig/acore/ws63_flashboot.config old mode 100755 new mode 100644 index 442d221..fc2f195 --- a/build/config/target_config/ws63/menuconfig/acore/ws63_flashboot.config +++ b/build/config/target_config/ws63/menuconfig/acore/ws63_flashboot.config @@ -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