fix 3.5 touch freeze: async WiFi scan and GT911 reset.
Scan no longer blocks LVGL; always hw-reset GT911; larger buttons and click areas. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
name: CYD wifitest (cyd_35r)
|
||||
git: ba09f4f
|
||||
git: 9cbbb29
|
||||
date: 2026-10-25
|
||||
board: ESP32-3248S035 (ST7796)
|
||||
flash_size: 4MB
|
||||
@@ -11,5 +11,5 @@ offsets:
|
||||
sha256:
|
||||
bootloader.bin 3D234A7471F67B013686DABD4DEE7C1FA915C9928463616A94BC9297ACF1ABF8
|
||||
boot_app0.bin F94C5D786A7A8FAB06AC5D10E33BF37711A6697636DC037559EA19CC410A17F0
|
||||
firmware.bin 8632B39F60FF68A0ABD39C49071FF91889F5446D0EC93F7ADF59CDA48AB6D438
|
||||
firmware.bin DDB6B8EB5091F9C201A1696CEC05BA68E93A512EE7388C66EC7207850B74FC85
|
||||
partitions.bin 148B959CBFF1C38AA8E1D5C0BA9D612C54997B945E56A63F41223EEF650653A1
|
||||
|
||||
Binary file not shown.
@@ -67,9 +67,14 @@ void wifi_prov_connect_saved();
|
||||
/** 连接指定网络并在成功后写入 NVS */
|
||||
void wifi_prov_connect_to(const char *ssid, const char *password);
|
||||
|
||||
/** 同步扫描,结果写入 out[],返回条数(≤ WIFI_PROV_MAX_SCAN) */
|
||||
/** 同步扫描(会阻塞数秒;门户 HTML 可用)。屏上 UI 请用异步接口。 */
|
||||
int wifi_prov_scan(WifiScanItem *out, int max_items);
|
||||
|
||||
/** 异步扫描:start 后每 loop 调 poll;完成时写入 out 并返回条数,进行中返回 -1。 */
|
||||
bool wifi_prov_scan_start();
|
||||
bool wifi_prov_scan_busy();
|
||||
int wifi_prov_scan_poll(WifiScanItem *out, int max_items);
|
||||
|
||||
/**
|
||||
* SoftAP + 简易 Captive Portal(手机连 CYD-Setup → http://192.168.4.1)
|
||||
* 与屏上配网可并行;配网成功后会自动 stop。
|
||||
|
||||
@@ -42,9 +42,9 @@ void setup() {
|
||||
}
|
||||
|
||||
void loop() {
|
||||
wifi_prov_loop();
|
||||
wifi_ui_tick();
|
||||
lv_timer_handler();
|
||||
lv_tick_inc(5);
|
||||
wifi_prov_loop();
|
||||
wifi_ui_tick();
|
||||
delay(5);
|
||||
}
|
||||
|
||||
@@ -101,15 +101,15 @@ void touch_init() {
|
||||
Wire.setTimeOut(50);
|
||||
#endif
|
||||
|
||||
/* Always hw-reset: probe-only leaves some boards with stuck buffer / bad INT. */
|
||||
Serial.println("GT911 hw reset 0x5D");
|
||||
gt_hw_reset(false);
|
||||
if (!gt_find_addr()) {
|
||||
Serial.println("GT911 not found — hw reset 0x5D");
|
||||
gt_hw_reset(false);
|
||||
if (!gt_find_addr()) {
|
||||
Serial.println("GT911 not found — hw reset 0x14");
|
||||
gt_hw_reset(true);
|
||||
gt_find_addr();
|
||||
}
|
||||
Serial.println("GT911 not found — hw reset 0x14");
|
||||
gt_hw_reset(true);
|
||||
gt_find_addr();
|
||||
}
|
||||
gt_write8(GT_POINT_INFO, 0);
|
||||
|
||||
Serial.printf("GT911 probe 0x5D=%s 0x14=%s using=0x%02X\n",
|
||||
gt_probe(0x5D) ? "OK" : "no", gt_probe(0x14) ? "OK" : "no",
|
||||
|
||||
@@ -26,6 +26,7 @@ static DNSServer *g_dns = nullptr;
|
||||
static WebServer *g_http = nullptr;
|
||||
static bool g_portal = false;
|
||||
static char g_ap_ssid[33] = WIFI_PROV_AP_SSID;
|
||||
static bool g_scan_async = false;
|
||||
|
||||
static void set_state(WifiProvState s) {
|
||||
if (g_state == s) {
|
||||
@@ -269,27 +270,11 @@ void wifi_prov_connect_to(const char *ssid, const char *password) {
|
||||
begin_sta_connect(g_ssid, g_pass);
|
||||
}
|
||||
|
||||
int wifi_prov_scan(WifiScanItem *out, int max_items) {
|
||||
if (!out || max_items <= 0) {
|
||||
return 0;
|
||||
}
|
||||
if (max_items > WIFI_PROV_MAX_SCAN) {
|
||||
max_items = WIFI_PROV_MAX_SCAN;
|
||||
}
|
||||
|
||||
// SoftAP 时用 APSTA,否则扫描会关掉 AP
|
||||
if (g_portal) {
|
||||
WiFi.mode(WIFI_AP_STA);
|
||||
} else {
|
||||
WiFi.mode(WIFI_STA);
|
||||
}
|
||||
|
||||
const int found = WiFi.scanNetworks(/*async=*/false, /*hidden=*/true);
|
||||
static int fill_scan_results(WifiScanItem *out, int max_items, int found) {
|
||||
if (found <= 0) {
|
||||
WiFi.scanDelete();
|
||||
return 0;
|
||||
}
|
||||
|
||||
const int n = found < max_items ? found : max_items;
|
||||
for (int i = 0; i < n; ++i) {
|
||||
String s = WiFi.SSID(i);
|
||||
@@ -302,6 +287,76 @@ int wifi_prov_scan(WifiScanItem *out, int max_items) {
|
||||
return n;
|
||||
}
|
||||
|
||||
int wifi_prov_scan(WifiScanItem *out, int max_items) {
|
||||
if (!out || max_items <= 0) {
|
||||
return 0;
|
||||
}
|
||||
if (max_items > WIFI_PROV_MAX_SCAN) {
|
||||
max_items = WIFI_PROV_MAX_SCAN;
|
||||
}
|
||||
if (g_scan_async) {
|
||||
WiFi.scanDelete();
|
||||
g_scan_async = false;
|
||||
}
|
||||
|
||||
if (g_portal) {
|
||||
WiFi.mode(WIFI_AP_STA);
|
||||
} else {
|
||||
WiFi.mode(WIFI_STA);
|
||||
}
|
||||
|
||||
const int found = WiFi.scanNetworks(/*async=*/false, /*hidden=*/true);
|
||||
return fill_scan_results(out, max_items, found);
|
||||
}
|
||||
|
||||
bool wifi_prov_scan_start() {
|
||||
if (g_scan_async) {
|
||||
return true;
|
||||
}
|
||||
if (g_portal) {
|
||||
WiFi.mode(WIFI_AP_STA);
|
||||
} else {
|
||||
WiFi.mode(WIFI_STA);
|
||||
}
|
||||
/* async — does not block LVGL loop */
|
||||
const int16_t rc = WiFi.scanNetworks(/*async=*/true, /*hidden=*/true);
|
||||
if (rc == WIFI_SCAN_FAILED) {
|
||||
Serial.println("[wifi] scan start failed");
|
||||
return false;
|
||||
}
|
||||
g_scan_async = true;
|
||||
Serial.println("[wifi] scan async started");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool wifi_prov_scan_busy() { return g_scan_async; }
|
||||
|
||||
int wifi_prov_scan_poll(WifiScanItem *out, int max_items) {
|
||||
if (!g_scan_async) {
|
||||
return 0;
|
||||
}
|
||||
if (!out || max_items <= 0) {
|
||||
return 0;
|
||||
}
|
||||
if (max_items > WIFI_PROV_MAX_SCAN) {
|
||||
max_items = WIFI_PROV_MAX_SCAN;
|
||||
}
|
||||
|
||||
const int16_t found = WiFi.scanComplete();
|
||||
if (found == WIFI_SCAN_RUNNING) {
|
||||
return -1;
|
||||
}
|
||||
g_scan_async = false;
|
||||
if (found == WIFI_SCAN_FAILED) {
|
||||
WiFi.scanDelete();
|
||||
Serial.println("[wifi] scan failed");
|
||||
return 0;
|
||||
}
|
||||
const int n = fill_scan_results(out, max_items, found);
|
||||
Serial.printf("[wifi] scan done n=%d\n", n);
|
||||
return n;
|
||||
}
|
||||
|
||||
void wifi_prov_portal_start(const char *ap_ssid) {
|
||||
if (g_portal) {
|
||||
return;
|
||||
|
||||
@@ -41,7 +41,9 @@ static int g_item_n = 0;
|
||||
static char g_pick_ssid[WIFI_PROV_SSID_MAX + 1] = {};
|
||||
static bool g_on_setup = false;
|
||||
static bool g_pass_visible = false;
|
||||
static bool g_scan_pending = false;
|
||||
static WifiProvState g_last_shown = WIFI_PROV_IDLE;
|
||||
static uint32_t g_last_status_ms = 0;
|
||||
|
||||
static void style_btn(lv_obj_t *btn, uint32_t bg) {
|
||||
lv_obj_set_style_radius(btn, 8, 0);
|
||||
@@ -50,6 +52,8 @@ static void style_btn(lv_obj_t *btn, uint32_t bg) {
|
||||
lv_obj_set_style_shadow_width(btn, 0, 0);
|
||||
lv_obj_set_style_border_width(btn, 0, 0);
|
||||
lv_obj_set_style_pad_all(btn, 0, 0);
|
||||
lv_obj_add_flag(btn, LV_OBJ_FLAG_CLICKABLE);
|
||||
lv_obj_set_ext_click_area(btn, 12);
|
||||
}
|
||||
|
||||
static lv_obj_t *make_btn(lv_obj_t *parent, const char *text, uint32_t bg,
|
||||
@@ -62,6 +66,8 @@ static lv_obj_t *make_btn(lv_obj_t *parent, const char *text, uint32_t bg,
|
||||
lv_obj_set_style_text_color(lab, lv_color_hex(COL_INK), 0);
|
||||
lv_obj_set_style_text_font(lab, &lv_font_montserrat_14, 0);
|
||||
lv_obj_center(lab);
|
||||
/* Label must not steal clicks from the button. */
|
||||
lv_obj_clear_flag(lab, LV_OBJ_FLAG_CLICKABLE);
|
||||
if (cb) {
|
||||
lv_obj_add_event_cb(btn, cb, LV_EVENT_CLICKED, nullptr);
|
||||
}
|
||||
@@ -210,6 +216,7 @@ static void rebuild_list() {
|
||||
lv_obj_set_style_text_color(jl, lv_color_hex(COL_INK), 0);
|
||||
lv_obj_set_style_text_font(jl, &lv_font_montserrat_14, 0);
|
||||
lv_obj_center(jl);
|
||||
lv_obj_clear_flag(jl, LV_OBJ_FLAG_CLICKABLE);
|
||||
}
|
||||
lv_obj_add_event_cb(join, on_row_join, LV_EVENT_CLICKED,
|
||||
(void *)(intptr_t)i);
|
||||
@@ -217,22 +224,27 @@ static void rebuild_list() {
|
||||
}
|
||||
|
||||
static void do_scan() {
|
||||
if (g_scan_pending || wifi_prov_scan_busy()) {
|
||||
set_setup_status("Scanning...");
|
||||
return;
|
||||
}
|
||||
set_setup_status("Scanning...");
|
||||
lv_timer_handler();
|
||||
g_item_n = wifi_prov_scan(g_items, WIFI_PROV_MAX_SCAN);
|
||||
rebuild_list();
|
||||
char buf[40];
|
||||
snprintf(buf, sizeof(buf), "Found %d", g_item_n);
|
||||
set_setup_status(buf);
|
||||
if (!wifi_prov_scan_start()) {
|
||||
set_setup_status("Scan failed");
|
||||
return;
|
||||
}
|
||||
g_scan_pending = true;
|
||||
}
|
||||
|
||||
static void on_scan(lv_event_t *e) {
|
||||
LV_UNUSED(e);
|
||||
Serial.println("[ui] Scan clicked");
|
||||
do_scan();
|
||||
}
|
||||
|
||||
static void on_portal(lv_event_t *e) {
|
||||
LV_UNUSED(e);
|
||||
Serial.println("[ui] Phone AP clicked");
|
||||
wifi_prov_portal_start();
|
||||
set_setup_status("Phone: join CYD-Setup");
|
||||
}
|
||||
@@ -382,7 +394,7 @@ static void build_setup() {
|
||||
lv_obj_align(lbl_setup_status, LV_ALIGN_TOP_RIGHT, UX(-10), UY(10));
|
||||
|
||||
lv_obj_t *bar = lv_obj_create(scr_setup);
|
||||
lv_obj_set_size(bar, UI_HOR_RES - UW(16), UH(36));
|
||||
lv_obj_set_size(bar, UI_HOR_RES - UW(16), UH(48));
|
||||
lv_obj_align(bar, LV_ALIGN_TOP_MID, UX(0), UY(34));
|
||||
lv_obj_set_style_bg_opa(bar, LV_OPA_TRANSP, 0);
|
||||
lv_obj_set_style_border_width(bar, 0, 0);
|
||||
@@ -392,17 +404,18 @@ static void build_setup() {
|
||||
LV_FLEX_ALIGN_CENTER);
|
||||
lv_obj_set_style_pad_column(bar, UW(8), 0);
|
||||
lv_obj_clear_flag(bar, LV_OBJ_FLAG_SCROLLABLE);
|
||||
lv_obj_add_flag(bar, LV_OBJ_FLAG_CLICKABLE);
|
||||
|
||||
make_btn(bar, "Scan", COL_BTN_ACC, on_scan, UW(72), UH(32));
|
||||
make_btn(bar, "Phone AP", COL_BTN, on_portal, UW(96), UH(32));
|
||||
make_btn(bar, "Scan", COL_BTN_ACC, on_scan, UW(90), UH(42));
|
||||
make_btn(bar, "Phone AP", COL_BTN, on_portal, UW(110), UH(42));
|
||||
make_btn(bar, "Status", COL_BTN, [](lv_event_t *e) {
|
||||
LV_UNUSED(e);
|
||||
wifi_ui_show_status();
|
||||
}, UW(72), UH(32));
|
||||
}, UW(90), UH(42));
|
||||
|
||||
list_wifi = lv_obj_create(scr_setup);
|
||||
lv_obj_set_size(list_wifi, UI_HOR_RES - UW(16), UI_VER_RES - UH(80));
|
||||
lv_obj_align(list_wifi, LV_ALIGN_TOP_MID, UX(0), UY(74));
|
||||
lv_obj_set_size(list_wifi, UI_HOR_RES - UW(16), UI_VER_RES - UH(92));
|
||||
lv_obj_align(list_wifi, LV_ALIGN_TOP_MID, UX(0), UY(86));
|
||||
lv_obj_set_style_bg_color(list_wifi, lv_color_hex(COL_LINE), 0);
|
||||
lv_obj_set_style_border_width(list_wifi, 0, 0);
|
||||
lv_obj_set_style_radius(list_wifi, 8, 0);
|
||||
@@ -515,6 +528,18 @@ void wifi_ui_show_status() {
|
||||
bool wifi_ui_is_setup() { return g_on_setup; }
|
||||
|
||||
void wifi_ui_tick() {
|
||||
if (g_scan_pending) {
|
||||
const int n = wifi_prov_scan_poll(g_items, WIFI_PROV_MAX_SCAN);
|
||||
if (n >= 0) {
|
||||
g_scan_pending = false;
|
||||
g_item_n = n;
|
||||
rebuild_list();
|
||||
char buf[40];
|
||||
snprintf(buf, sizeof(buf), "Found %d", g_item_n);
|
||||
set_setup_status(buf);
|
||||
}
|
||||
}
|
||||
|
||||
const WifiProvState st = wifi_prov_state();
|
||||
|
||||
if (st != g_last_shown) {
|
||||
@@ -530,7 +555,9 @@ void wifi_ui_tick() {
|
||||
}
|
||||
}
|
||||
|
||||
if (!g_on_setup) {
|
||||
/* Throttle status refresh — every 5ms was wasteful and could feel sticky. */
|
||||
if (!g_on_setup && (millis() - g_last_status_ms >= 500)) {
|
||||
g_last_status_ms = millis();
|
||||
refresh_status_labels();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user