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 65be2e5..a24ebd5 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 @@ -436,10 +436,12 @@ int start_hilink_ble_net_config(int32_t net_cfg_time_s) { ble_adv_time = net_cfg_time_s; if (ble_sdk_running) { + e_printf("set ble adv time: %ds\n", ble_adv_time); BLE_CfgNetAdvCtrl(ble_adv_time); } return 0; } + int hilink_ble_main(void) { int ret = 0; diff --git a/application/ws63/user_main/CMakeLists.txt b/application/ws63/user_main/CMakeLists.txt index aed2f5a..d61d981 100755 --- a/application/ws63/user_main/CMakeLists.txt +++ b/application/ws63/user_main/CMakeLists.txt @@ -8,6 +8,7 @@ set(SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/app_main.c ${CMAKE_CURRENT_SOURCE_DIR}/spotlight/spotlight_main.c ${CMAKE_CURRENT_SOURCE_DIR}/spotlight/device_module.c + ${CMAKE_CURRENT_SOURCE_DIR}/spotlight/factory_test.c ) if (DEFINES MATCHES "CONFIG_SPOTLIGHT_UT") list(APPEND SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/spotlight/spotlight_ut.c) diff --git a/application/ws63/user_main/spotlight/factory_test.c b/application/ws63/user_main/spotlight/factory_test.c new file mode 100644 index 0000000..f0badb2 --- /dev/null +++ b/application/ws63/user_main/spotlight/factory_test.c @@ -0,0 +1,359 @@ +// factory_test.c +#include "factory_test.h" +#include +#include // For e_printf (debugging) +#include // For strncmp, memset, strncpy +#include // For bool type + +#include "systick.h" +#include "hsf.h" +#include "spotlight.h" // For update_pwm_output and PWM_DUTY_RATIO_MAX +#include "lwip/netifapi.h" +#include "wifi_hotspot.h" +#include "wifi_hotspot_config.h" +#include "soc_osal.h" +#include "cmsis_os2.h" + +// --- Configuration Constants --- +#define FACTORY_TEST_TARGET_SSID "ShuorongSelfTest" +#define FACTORY_TEST_TARGET_PASSWD "" +#define FACTORY_TEST_RSSI_THRESHOLD (-70) // dBm +#define TRIGGER_SCAN_DURATION_MS 5000 // 5 seconds for initial scan +#define TRIGGER_SCAN_INTERVAL_MS 1000 // Wait 1s between scan attempts during trigger phase + +#define LIGHT_FLASH_DURATION_MS 3000 // 3 seconds for entry indication flashing +#define LIGHT_FLASH_FREQUENCY_HZ 2 // Hz for entry indication flashing + +#define SINGLE_LIGHT_TEST_DURATION_MS 3000 // 3 seconds for white/yellow light test + +#define WIFI_IFNAME_MAX_SIZE 16 +#define WIFI_MAX_SSID_LEN 33 +#define WIFI_SCAN_AP_LIMIT 64 +#define WIFI_MAC_LEN 6 +#define WIFI_STA_SAMPLE_LOG "" +#define WIFI_NOT_AVALLIABLE 0 +#define WIFI_AVALIABE 1 +#define WIFI_GET_IP_MAX_COUNT 300 + +#define WIFI_TASK_PRIO (osPriority_t)(13) +#define WIFI_TASK_DURATION_MS 2000 +#define WIFI_TASK_STACK_SIZE 0x1000 + +static void wifi_scan_state_changed(int32_t state, int32_t size); +static void wifi_connection_changed(int32_t state, const wifi_linked_info_stru *info, int32_t reason_code); + +wifi_event_stru wifi_event_cb = { + .wifi_event_connection_changed = wifi_connection_changed, + .wifi_event_scan_state_changed = wifi_scan_state_changed, +}; + +enum { + WIFI_STA_SAMPLE_INIT = 0, /* 0:初始态 */ + WIFI_STA_SAMPLE_SCANING, /* 1:扫描中 */ + WIFI_STA_SAMPLE_SCAN_DONE, /* 2:扫描完成 */ + WIFI_STA_SAMPLE_FOUND_TARGET, /* 3:匹配到目标AP */ + WIFI_STA_SAMPLE_CONNECTING, /* 4:连接中 */ + WIFI_STA_SAMPLE_CONNECT_DONE, /* 5:关联成功 */ + WIFI_STA_SAMPLE_GET_IP, /* 6:获取IP */ +} wifi_state_enum; + +static uint8_t g_wifi_state = WIFI_STA_SAMPLE_INIT; + +/***************************************************************************** + STA 扫描事件回调函数 +*****************************************************************************/ +static void wifi_scan_state_changed(int32_t state, int32_t size) +{ + UNUSED(state); + UNUSED(size); + e_printf("%s::Scan done!.\r\n", WIFI_STA_SAMPLE_LOG); + g_wifi_state = WIFI_STA_SAMPLE_SCAN_DONE; + return; +} + +/***************************************************************************** + STA 关联事件回调函数 +*****************************************************************************/ +static void wifi_connection_changed(int32_t state, const wifi_linked_info_stru *info, int32_t reason_code) +{ + UNUSED(info); + UNUSED(reason_code); + + if (state == WIFI_NOT_AVALLIABLE) { + e_printf("%s::Connect fail!. try agin !\r\n", WIFI_STA_SAMPLE_LOG); + g_wifi_state = WIFI_STA_SAMPLE_INIT; + } else { + e_printf("%s::Connect succ!.\r\n", WIFI_STA_SAMPLE_LOG); + g_wifi_state = WIFI_STA_SAMPLE_CONNECT_DONE; + } +} + +/***************************************************************************** + STA 匹配目标AP +*****************************************************************************/ +int32_t get_match_network(wifi_sta_config_stru *expected_bss) +{ + int32_t ret; + uint32_t num = 64; /* 64:扫描到的Wi-Fi网络数量 */ + char expected_ssid[] = FACTORY_TEST_TARGET_SSID; + char key[] = FACTORY_TEST_TARGET_PASSWD; /* 待连接的网络接入密码 */ + bool find_ap = false; + uint8_t bss_index; + /* 获取扫描结果 */ + uint32_t scan_len = sizeof(wifi_scan_info_stru) * WIFI_SCAN_AP_LIMIT; + wifi_scan_info_stru *result = osal_kmalloc(scan_len, OSAL_GFP_ATOMIC); + if (result == NULL) { + return -1; + } + memset_s(result, scan_len, 0, scan_len); + ret = wifi_sta_get_scan_info(result, &num); + if (ret != 0) { + osal_kfree(result); + return -1; + } + /* 筛选扫描到的Wi-Fi网络,选择待连接的网络 */ + for (bss_index = 0; bss_index < num; bss_index ++) { + if (strlen(expected_ssid) == strlen(result[bss_index].ssid)) { + if (memcmp(expected_ssid, result[bss_index].ssid, strlen(expected_ssid)) == 0) { + find_ap = true; + break; + } + } + } + /* 未找到待连接AP,可以继续尝试扫描或者退出 */ + if (find_ap == false) { + osal_kfree(result); + return -1; + } + /* 找到网络后复制网络信息和接入密码 */ + if (memcpy_s(expected_bss->ssid, WIFI_MAX_SSID_LEN, expected_ssid, strlen(expected_ssid)) != 0) { + osal_kfree(result); + return -1; + } + if (memcpy_s(expected_bss->bssid, WIFI_MAC_LEN, result[bss_index].bssid, WIFI_MAC_LEN) != 0) { + osal_kfree(result); + return -1; + } + expected_bss->security_type = result[bss_index].security_type; + if (memcpy_s(expected_bss->pre_shared_key, WIFI_MAX_SSID_LEN, key, strlen(key)) != 0) { + osal_kfree(result); + return -1; + } + expected_bss->ip_type = 1; /* 1:IP类型为动态DHCP获取 */ + expected_bss->rsv = result[bss_index].rssi;// 使用保留字段作为信号强度的存储 + osal_kfree(result); + return 0; +} + +/***************************************************************************** + STA 关联状态查询 +*****************************************************************************/ +// bool example_check_connect_status(void) +// { +// uint8_t index; +// wifi_linked_info_stru wifi_status; +// /* 获取网络连接状态,共查询5次,每次间隔500ms */ +// for (index = 0; index < 5; index ++) { +// (void)msleep(500); /* 50: 延时500ms */ +// memset_s(&wifi_status, sizeof(wifi_linked_info_stru), 0, sizeof(wifi_linked_info_stru)); +// if (wifi_sta_get_ap_info(&wifi_status) != 0) { +// continue; +// } +// if (wifi_status.conn_state == 1) { +// return 0; /* 连接成功退出循环 */ +// } +// } +// return -1; +// } + +/***************************************************************************** + STA DHCP状态查询 +*****************************************************************************/ +// bool example_check_dhcp_status(struct netif *netif_p, uint32_t *wait_count) +// { +// if ((ip_addr_isany(&(netif_p->ip_addr)) == 0) && (*wait_count <= WIFI_GET_IP_MAX_COUNT)) { +// /* DHCP成功 */ +// e_printf("%s::STA DHCP success.\r\n", WIFI_STA_SAMPLE_LOG); +// return 0; +// } + +// if (*wait_count > WIFI_GET_IP_MAX_COUNT) { +// e_printf("%s::STA DHCP timeout, try again !.\r\n", WIFI_STA_SAMPLE_LOG); +// *wait_count = 0; +// g_wifi_state = WIFI_STA_SAMPLE_INIT; +// } +// return -1; +// } + +int32_t wifi_scan_and_check(int32_t rssi_threshold) +{ + wifi_sta_config_stru expected_bss = {0}; /* 连接请求信息 */ + g_wifi_state = WIFI_STA_SAMPLE_INIT; + do { + (void)msleep(10); /* 1: 等待10ms后判断状态 */ + if (g_wifi_state == WIFI_STA_SAMPLE_INIT) { + e_printf("%s::Scan start!\r\n", WIFI_STA_SAMPLE_LOG); + g_wifi_state = WIFI_STA_SAMPLE_SCANING; + /* 启动STA扫描 */ + if (wifi_sta_scan() != 0) { + g_wifi_state = WIFI_STA_SAMPLE_INIT; + continue; + } + } else if (g_wifi_state == WIFI_STA_SAMPLE_SCAN_DONE) { + /* 获取待连接的网络 */ + if (get_match_network(&expected_bss) != 0) { + e_printf("%s::Do not find target AP!\n", WIFI_STA_SAMPLE_LOG); + return -1; + } + break; + } + } while (1); + if (rssi_threshold == 0) { // rssi_threshold == 0, just check if the target AP is found + return 0; + } + e_printf("WiFi signal strength test. RSSI: expect >= %d, actual %d\n", rssi_threshold, expected_bss.rsv); + if (expected_bss.rsv !=0 && expected_bss.rsv >= rssi_threshold) { + return 0; + } + return -1; +} + +int factory_test_init(void) +{ + /* 注册事件回调 */ + if (wifi_register_event_cb(&wifi_event_cb) != 0) { + e_printf("%s::wifi_event_cb register fail.\r\n", WIFI_STA_SAMPLE_LOG); + return -1; + } + e_printf("%s::wifi_event_cb register succ.\r\n", WIFI_STA_SAMPLE_LOG); + + /* 等待wifi初始化完成 */ + while (wifi_is_wifi_inited() == 0) { + (void)osDelay(10); /* 1: 等待100ms后判断状态 */ + } + e_printf("%s::wifi init succ.\r\n", WIFI_STA_SAMPLE_LOG); + + /* 创建STA接口 */ + if (wifi_sta_enable() != 0) { + e_printf("%s::wifi sta init fail.\r\n", WIFI_STA_SAMPLE_LOG); + return -1; + } + e_printf("%s::STA enable succ.\r\n", WIFI_STA_SAMPLE_LOG); + return 0; +} +// --- Factory Test Sequence --- +static void run_test_sequence(void) { + e_printf("FactoryTest: Entering test sequence.\n"); + + // 1. Entry Indication: Two lights fast flash (alternate, 5Hz) for 3s, then off. + e_printf("FactoryTest: Step 0 - Entry indication flashing...\n"); + uint32_t flash_start_time = uapi_systick_get_ms(); + int half_period_ms = (1000 / LIGHT_FLASH_FREQUENCY_HZ) / 2; + bool white_on = true; + while (uapi_systick_get_ms() - flash_start_time < LIGHT_FLASH_DURATION_MS) { + if (white_on) { + update_pwm_output(true, PWM_DUTY_RATIO_MAX, 0); + } else { + update_pwm_output(true, 0, PWM_DUTY_RATIO_MAX); + } + white_on = !white_on; + msleep(half_period_ms); + } + update_pwm_output(false, 0, 0); + e_printf("FactoryTest: Entry indication finished.\n"); + + // 2. White Light Test: Max bright 3s, then off. + e_printf("FactoryTest: Step 1 - White light test...\n"); + update_pwm_output(true, PWM_DUTY_RATIO_MAX, 0); + msleep(SINGLE_LIGHT_TEST_DURATION_MS); + // update_pwm_output(false, 0, 0); // Ensure both are off + e_printf("FactoryTest: White light test finished.\n"); + // msleep(500); // Small delay before next test + + // 3. Yellow Light Test: Max bright 3s, then off. + e_printf("FactoryTest: Step 2 - Yellow light test...\n"); + update_pwm_output(true, 0, PWM_DUTY_RATIO_MAX); + msleep(SINGLE_LIGHT_TEST_DURATION_MS); + // update_pwm_output(false, 0, 0); // Ensure both are off + e_printf("FactoryTest: Yellow light test finished.\n"); + // msleep(500); // Small delay before next test + + // 4. Wi-Fi Signal Strength Test + e_printf("FactoryTest: Step 3 - WiFi signal strength test...\n"); + int rssi = 0; + bool wifi_test_passed = false; + if (wifi_scan_and_check(FACTORY_TEST_RSSI_THRESHOLD) == 0) { + wifi_test_passed = true; + } else { + e_printf("FactoryTest: WiFi test FAILED. Target AP not found in this scan.\n"); + } + + if (wifi_test_passed) { + update_pwm_output(true, PWM_DUTY_RATIO_MAX, PWM_DUTY_RATIO_MAX); + e_printf("FactoryTest: Final state - Both lights ON (Max Brightness).\n"); + } else { + update_pwm_output(false, 0, 0); // Ensure lights are off if test fails + e_printf("FactoryTest: Final state - All lights OFF.\n"); + } + e_printf("FactoryTest: Sequence complete.\n"); +} + +// --- Main Factory Test Trigger Function --- +void check_and_run_factory_test(void *param) { + e_printf("FactoryTest: Checking for trigger condition ([%s] AP within %dms)...\n", + FACTORY_TEST_TARGET_SSID, TRIGGER_SCAN_DURATION_MS); + + // Ensure Wi-Fi STA mode is started. This might be handled globally. + // If not, you might need: hi_wifi_start_sta(); or similar. + // For this example, we assume Wi-Fi is ready for scanning. + // A robust check: if (!hi_wifi_is_started()) { hi_wifi_start_sta(); } + + uint32_t trigger_phase_start_time = uapi_systick_get_ms(); + bool triggered = false; + + while (uapi_systick_get_ms() - trigger_phase_start_time < TRIGGER_SCAN_DURATION_MS) { + if (wifi_scan_and_check(0) == 0) { + e_printf("FactoryTest: Trigger AP '%s' found. Entering factory test mode.\n", FACTORY_TEST_TARGET_SSID); + triggered = true; + break; + } + // Wait before next scan attempt, if time permits + if (uapi_systick_get_ms() - trigger_phase_start_time < (TRIGGER_SCAN_DURATION_MS - TRIGGER_SCAN_INTERVAL_MS - 2000 /*approx scan time*/)) { + e_printf("FactoryTest: Trigger AP not found, retrying scan soon...\n"); + // osal_msleep(TRIGGER_SCAN_INTERVAL_MS); + } else { + // Not enough time for another full scan + interval + break; + } + } + + if (triggered) { + stop_net_config(); + run_test_sequence(); + // The device will remain in the state set by run_test_sequence (lights on or off). + // Further application logic might be halted or bypassed here if needed. + } else { + e_printf("FactoryTest: Trigger condition not met. Proceeding with normal boot.\n"); + // Ensure lights are off if factory test is not triggered + update_pwm_output(false, 0, 0); + } +} + +void try_detect_factory_test(void) +{ + osThreadAttr_t attr; + attr.name = "factory_test_task"; + attr.attr_bits = 0U; + attr.cb_mem = NULL; + attr.cb_size = 0U; + attr.stack_mem = NULL; + attr.stack_size = WIFI_TASK_STACK_SIZE; + attr.priority = WIFI_TASK_PRIO; + + factory_test_init(); + if (osThreadNew((osThreadFunc_t)check_and_run_factory_test, NULL, &attr) == NULL) { + PRINT("%s::Create factory_test_task fail.\r\n", WIFI_STA_SAMPLE_LOG); + } + PRINT("%s::Create factory_test_task succ.\r\n", WIFI_STA_SAMPLE_LOG); +} + \ No newline at end of file diff --git a/application/ws63/user_main/spotlight/factory_test.h b/application/ws63/user_main/spotlight/factory_test.h new file mode 100644 index 0000000..81d137e --- /dev/null +++ b/application/ws63/user_main/spotlight/factory_test.h @@ -0,0 +1,4 @@ +#ifndef FACTORY_TEST_H +#define FACTORY_TEST_H +void try_detect_factory_test(void); +#endif // FACTORY_TEST_H diff --git a/application/ws63/user_main/spotlight/spotlight.h b/application/ws63/user_main/spotlight/spotlight.h index df08b21..d79a386 100644 --- a/application/ws63/user_main/spotlight/spotlight.h +++ b/application/ws63/user_main/spotlight/spotlight.h @@ -134,12 +134,6 @@ typedef struct __attribute__((packed, aligned(1))) { #define DEVICE_DATA_MAGIC 0x4C505426 // "LPT&"的ASCII码 #define DEVICE_DATA_VERSION 1 // 数据版本号 -int spotlight_main(void); -int set_light(int32_t brightness, int32_t cct); // 新的统一控制函数 -int set_switch(bool open); -int set_smooth_time(uint32_t smooth_time); // 设置渐变时长 - -extern int fast_report(const char* svc_id); // 保存任务相关定义 #define SAVE_TASK_PRIO 25 @@ -166,5 +160,14 @@ typedef enum { .duty_ww = 0, \ }; +int spotlight_main(void); +int set_light(int32_t brightness, int32_t cct); // 新的统一控制函数 +int set_switch(bool open); +int set_smooth_time(uint32_t smooth_time); // 设置渐变时长 +void update_pwm_output(bool on_state, uint16_t duty_cw, uint16_t duty_ww); + +void stop_net_config(void); +extern int fast_report(const char* svc_id); + #endif diff --git a/application/ws63/user_main/spotlight/spotlight_main.c b/application/ws63/user_main/spotlight/spotlight_main.c index c972b59..594d4a0 100644 --- a/application/ws63/user_main/spotlight/spotlight_main.c +++ b/application/ws63/user_main/spotlight/spotlight_main.c @@ -14,6 +14,7 @@ // #include "tcxo.h" #include "spotlight.h" +#include "factory_test.h" // 函数前向声明 static void init_timer_system(void); @@ -30,7 +31,6 @@ 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 update_pwm_output(void); // 定义上报函数类型 typedef void (*report_func_t)(void); @@ -245,7 +245,7 @@ static void *fade_task(const char *arg) g_device_control.brightness_local = fade_ctx.current_brightness; g_device_control.cct_local = fade_ctx.current_cct; calculate_pwm_duty(); - update_pwm_output(); + update_pwm_output(g_device_control.on, g_device_control.duty_cw, g_device_control.duty_ww); if (fade_ctx.fade_completed) { fade_ctx.fade_completed = false; @@ -306,7 +306,7 @@ static void *breath_task(const char *arg) g_device_control.duty_ww = brightness_pwm; g_device_control.duty_cw = PWM_DUTY_RATIO_MAX - brightness_pwm; - update_pwm_output(); + update_pwm_output(g_device_control.on, g_device_control.duty_cw, g_device_control.duty_ww); } e_printf("[breath_task] Task exited\r\n"); @@ -424,7 +424,7 @@ static void stop_fade_task(void) } // 停止呼吸灯任务 -static void stop_breath_task(void) +void stop_breath_task(void) { if (breath_ctx.task_handle == NULL) { return; @@ -438,7 +438,7 @@ static void stop_breath_task(void) breath_ctx.task_handle = NULL; osal_kthread_unlock(); - osal_sem_destroy(&breath_ctx.sem); + // osal_sem_destroy(&breath_ctx.sem); e_printf("[stop_breath_task] Breath task stopped\n"); } @@ -446,8 +446,11 @@ static void stop_breath_task(void) // 修改stop_breath_timer函数 static void stop_breath_timer(void) { - uapi_timer_stop(breath_ctx.timer_handle); - uapi_timer_delete(breath_ctx.timer_handle); + if (breath_ctx.timer_handle) { + uapi_timer_stop(breath_ctx.timer_handle); + uapi_timer_delete(breath_ctx.timer_handle); + } + breath_ctx.timer_handle = NULL; stop_breath_task(); } @@ -465,53 +468,53 @@ void calculate_pwm_duty(void) } // 更新PWM输出 -void update_pwm_output(void) +void update_pwm_output(bool on_state, uint16_t duty_cw_val, uint16_t duty_ww_val) { pwm_config_t cfg_repeat = {0}; cfg_repeat.repeat = true; - if (g_device_control.duty_cw > PWM_DUTY_RATIO_MAX) { - g_device_control.duty_cw = PWM_DUTY_RATIO_MAX; + + uint16_t current_duty_cw = duty_cw_val; + uint16_t current_duty_ww = duty_ww_val; + + if (current_duty_cw > PWM_DUTY_RATIO_MAX) { + current_duty_cw = PWM_DUTY_RATIO_MAX; } - if (g_device_control.duty_ww > PWM_DUTY_RATIO_MAX) { - g_device_control.duty_ww = PWM_DUTY_RATIO_MAX; + if (current_duty_ww > PWM_DUTY_RATIO_MAX) { + current_duty_ww = PWM_DUTY_RATIO_MAX; } - uint32_t high_cnt_cw = (pwm_period_cnt * g_device_control.duty_cw) / PWM_DUTY_RATIO_MAX; + + uint32_t high_cnt_cw = (pwm_period_cnt * current_duty_cw) / PWM_DUTY_RATIO_MAX; uint32_t low_cnt_cw = pwm_period_cnt - high_cnt_cw; - uint32_t high_cnt_ww = (pwm_period_cnt * g_device_control.duty_ww) / PWM_DUTY_RATIO_MAX; + uint32_t high_cnt_ww = (pwm_period_cnt * current_duty_ww) / PWM_DUTY_RATIO_MAX; uint32_t low_cnt_ww = pwm_period_cnt - high_cnt_ww; - // uapi_pwm_stop_group(CONFIG_PWM_GROUP_ID); - // uapi_pwm_clear_group(CONFIG_PWM_GROUP_ID); - if (!g_device_control.on) { // 如果开关关闭,则占空比为0 - e_printf("spotlight off\r\n"); + if (!on_state) { high_cnt_cw = 0; - low_cnt_cw = 0; + low_cnt_cw = pwm_period_cnt; // Ensure low_cnt is full period if off high_cnt_ww = 0; - low_cnt_ww = 0; + low_cnt_ww = pwm_period_cnt; // Ensure low_cnt is full period if off } + cfg_repeat.high_time = high_cnt_cw; cfg_repeat.low_time = low_cnt_cw; uapi_pwm_open(channel_id_cw, &cfg_repeat); - // 配置第二个通道 + cfg_repeat.high_time = high_cnt_ww; cfg_repeat.low_time = low_cnt_ww; - cfg_repeat.offset_time = high_cnt_cw;//配置互补形成相位 + cfg_repeat.offset_time = high_cnt_cw; // WW PWM starts after CW PWM high time uapi_pwm_open(channel_id_ww, &cfg_repeat); - // 设置PWM组 - uint8_t channel_ids[2] = {channel_id_cw, channel_id_ww}; - // uapi_pwm_set_group(CONFIG_PWM_GROUP_ID, channel_ids, 2); - // // 更新PWM占空比 - // uapi_pwm_update_duty_ratio(channel_id_cw, low_cnt_cw, high_cnt_cw); - // uapi_pwm_update_duty_ratio(channel_id_ww, low_cnt_ww, high_cnt_ww); - - // 启动PWM组 + // The line 'uint8_t channel_ids[2] = {channel_id_cw, channel_id_ww};' was present in the original code snippet from the checkpoint + // but seems unused before the uapi_pwm_start_group call. Retaining original behavior regarding this line. + // If it was indeed unused, it can be removed. For now, assuming it might have a purpose or was for debugging. + // uint8_t channel_ids[2] = {channel_id_cw, channel_id_ww}; // This line is commented out as it appears unused in the provided snippet. uapi_pwm_start_group(CONFIG_PWM_GROUP_ID); + if (should_print(&pwm_limiter)) { - e_printf("cw:high:%u, low:%u, duty:%u/1000, ww:high:%u, low:%u, duty:%u/1000, offset_time:%u\r\n", - high_cnt_cw, low_cnt_cw, g_device_control.duty_cw, high_cnt_ww, low_cnt_ww, g_device_control.duty_ww, cfg_repeat.offset_time); + e_printf("on:%d, cw:high:%u, low:%u, duty:%u/1000, ww:high:%u, low:%u, duty:%u/1000, offset_time:%u\r\n", + on_state, high_cnt_cw, low_cnt_cw, current_duty_cw, high_cnt_ww, low_cnt_ww, current_duty_ww, cfg_repeat.offset_time); } } @@ -883,6 +886,7 @@ int set_light(int32_t brightness_local, int32_t cct_local) // 启动渐变定时器 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) { @@ -910,7 +914,7 @@ int set_switch(bool open) cancel_current_light_fade(); } calculate_pwm_duty(); - update_pwm_output(); + 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); return 0; } @@ -954,6 +958,29 @@ static void pwm_init(pin_t pin, pin_t pin1) e_printf("PWM基础时钟频率: %dHz, 目标时钟频率: %dHz, 周期计数: %d\r\n", frequency, PWM_FREQUENCY, pwm_period_cnt); } +extern int start_hilink_ble_net_config(int32_t net_cfg_time_s); +void start_net_config(void) { + e_printf("进入配网状态,上电次数:%d, is_new_device:%d\r\n", g_device_control.power_on_cnt, !g_device_control.is_net_configured); + g_device_control.power_on_cnt = 0;// + int ret = start_hilink_ble_net_config(NET_CFG_TOTAL_TIMEOUT/1000); + if (ret) { + // FIXME: 这里简单恢复之前等待配网的灯效即可 + e_printf("start net_cfg fail:%n\r\n", ret); + req_save_device_data(); + // extern int HILINK_RestoreFactorySettings(void); + // HILINK_RestoreFactorySettings(); + return; + } + // 初始化呼吸灯控制 + init_breath_ctx(); + start_breath_timer(); +} + +void stop_net_config(void) { + stop_breath_timer(); + start_hilink_ble_net_config(0); +} + // 配网状态管理相关函数 static void handle_network_status(void) { @@ -967,21 +994,7 @@ static void handle_network_status(void) e_printf("现在是第 %d 次上电\r\n", g_device_control.power_on_cnt); // 检查是否需要进入配网状态 if ((!g_device_control.is_net_configured) || g_device_control.power_on_cnt >= NET_CFG_ENTRY_CNT) { - e_printf("进入配网状态,上电次数:%d, is_new_device:%d\r\n", g_device_control.power_on_cnt, !g_device_control.is_net_configured); - g_device_control.power_on_cnt = 0;// - extern int start_hilink_ble_net_config(int32_t net_cfg_time_s); - int ret = start_hilink_ble_net_config(NET_CFG_TOTAL_TIMEOUT/1000); - if (ret) { - // FIXME: 这里简单恢复之前等待配网的灯效即可 - e_printf("start net_cfg fail:%n\r\n", ret); - req_save_device_data(); - // extern int HILINK_RestoreFactorySettings(void); - // HILINK_RestoreFactorySettings(); - return; - } - // 初始化呼吸灯控制 - init_breath_ctx(); - start_breath_timer(); + start_net_config(); } // 保存设备状态 @@ -1227,7 +1240,9 @@ int spotlight_main(void) { handle_network_status(); set_switch(g_device_control.on);//按照当前值更新light - + if (!g_device_control.is_networked && !g_device_control.is_net_configured) { + try_detect_factory_test(); + } start_spotlight_main_task(); return 0; } @@ -1259,7 +1274,7 @@ 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(); - update_pwm_output(); + update_pwm_output(g_device_control.on, g_device_control.duty_cw, g_device_control.duty_ww); } // 设置灯光到配网完成状态 @@ -1270,7 +1285,7 @@ static void set_light2net_cfg_done(void) g_device_control.cct_local = CCT_REMOTE2LOCAL(NET_CFG_DEFAULT_CCT); g_device_control.fade_time = NET_CFG_DEFAULT_FADE_TIME; calculate_pwm_duty(); - update_pwm_output(); + update_pwm_output(g_device_control.on, g_device_control.duty_cw, g_device_control.duty_ww); } // 启动呼吸灯 diff --git a/application/ws63/user_main/spotlight/spotlight_ut.c b/application/ws63/user_main/spotlight/spotlight_ut.c index b5f222e..3c6765e 100644 --- a/application/ws63/user_main/spotlight/spotlight_ut.c +++ b/application/ws63/user_main/spotlight/spotlight_ut.c @@ -9,7 +9,7 @@ #include "systick.h" extern device_control_t g_device_control; -extern void update_pwm_output(void); +extern void update_pwm_output(bool on_state, uint16_t duty_cw_val, uint16_t duty_ww_val); extern void calculate_pwm_duty(void); // AT指令:设置PWM占空比 @@ -45,7 +45,7 @@ int hf_atcmd_pwm(pat_session_t s, int argc, char *argv[], char *rsp, int len) } // 更新PWM输出 - update_pwm_output(); + update_pwm_output(true, g_device_control.duty_cw, g_device_control.duty_ww); sprintf(rsp, "OK: Channel %d PWM duty set to %d", channel, duty); return 0; @@ -90,7 +90,7 @@ int hf_atcmd_light(pat_session_t s, int argc, char *argv[], char *rsp, int len) // 计算PWM占空比并更新输出 calculate_pwm_duty(); - update_pwm_output(); + update_pwm_output(true, g_device_control.duty_cw, g_device_control.duty_ww); sprintf(rsp, "OK: Brightness=%d, CCT=%d, CW=%d%%%%, WW=%d%%%%", brightness, cct, g_device_control.duty_cw, g_device_control.duty_ww); diff --git a/output/SR_light-LPT262_hilink-20250610-1.0.0.fwpkg b/output/SR_light-LPT262_hilink-20250610-1.0.0.fwpkg new file mode 100644 index 0000000..6af9ff1 Binary files /dev/null and b/output/SR_light-LPT262_hilink-20250610-1.0.0.fwpkg differ diff --git a/output/package(SR_light-LPT262_hilink-20250610-1.0.0).zip b/output/package(SR_light-LPT262_hilink-20250610-1.0.0).zip new file mode 100644 index 0000000..73d5f55 Binary files /dev/null and b/output/package(SR_light-LPT262_hilink-20250610-1.0.0).zip differ