From b8eaf2c808949f76ec75e714eeb83a2b8bf0a22f Mon Sep 17 00:00:00 2001 From: yuquanjun Date: Mon, 31 Aug 2026 11:13:01 +0800 Subject: [PATCH] Fix mode-select focus and touch pipeline; add return-to-home gesture. Preserve focus across redraws, improve XPT2046 sampling, and log touch coords via RTT for ongoing debug. Co-authored-by: Cursor --- APP/app_touch.c | 83 +++------ Global/Global.c | 46 +++-- UI/UI_Idle.c | 64 +++++-- UI/UI_SongMode.c | 6 + UI/UI_idle.h | 2 +- device/LCD_ILI9341/Drv_ILI9341_Lcd_Dump.c | 10 + device/LCD_ILI9341/Drv_XPT2046_Touch.c | 212 +++++++++++++--------- device/LCD_ILI9341/Drv_XPT2046_Touch.h | 10 +- task/task_init.c | 16 +- 9 files changed, 259 insertions(+), 190 deletions(-) diff --git a/APP/app_touch.c b/APP/app_touch.c index 89179b6..98a2b3d 100644 --- a/APP/app_touch.c +++ b/APP/app_touch.c @@ -1,64 +1,46 @@ #include "includes.h" -/* ============================================================================ - * app_touch 实现 - * - * 状态机(与原 Touch_Process 一致): - * IDLE → PRESS_WAIT_STABLE → PRESS_STABLE → SLIDING - * - * 时序参数: - * 稳定判定 20ms (TOUCH_STABLE_TIME) - * 滑动阈值 10px (TOUCH_SLIDE_THRESH) - * 滑动步进 5px (TOUCH_SLIDE_STEP) - * 长按触发 1000ms (TOUCH_LONG_PRESS_TIME) - * 长按重复 120ms (TOUCH_REPEAT_INTERVAL) - * ==========================================================================*/ +/* 按下即发点击;抬起仅补发未发出的短按 */ -/* ==================== 状态机枚举 ==================== */ typedef enum { - TOUCH_IDLE, /* 空闲 */ - TOUCH_PRESS_WAIT_STABLE, /* 按下,等待稳定判定 */ - TOUCH_PRESS_STABLE, /* 稳定按下(可长按) */ - TOUCH_SLIDING /* 滑动中 */ + TOUCH_IDLE, + TOUCH_PRESS_WAIT_STABLE, + TOUCH_PRESS_STABLE, + TOUCH_SLIDING } touch_state_t; -/* ==================== 时序参数 ==================== */ -#define TOUCH_STABLE_TIME 20 /* 按下稳定判定时间 ms */ -#define TOUCH_SLIDE_THRESH 10 /* 进入滑动的最小位移 px */ -#define TOUCH_SLIDE_STEP 5 /* 滑动事件最小步进 px */ -#define TOUCH_LONG_PRESS_TIME 1000 /* 长按触发 ms */ -#define TOUCH_REPEAT_INTERVAL 120 /* 长按重复间隔 ms */ +#define TOUCH_STABLE_TIME 8 +#define TOUCH_SLIDE_THRESH 12 +#define TOUCH_SLIDE_STEP 5 +#define TOUCH_LONG_PRESS_TIME 800 +#define TOUCH_REPEAT_INTERVAL 120 -/* ==================== 状态变量 ==================== */ static touch_state_t touch_state = TOUCH_IDLE; static uint16_t down_x = 0; static uint16_t down_y = 0; static uint32_t touch_tick = 0; static uint32_t repeat_tick = 0; static uint8_t long_press_fired = 0; +static uint8_t click_sent = 0; static uint16_t last_slide_x = 0; static uint16_t last_slide_y = 0; -/* 取绝对值(避免引入 math.h) */ static inline uint16_t abs_diff(int16_t a, int16_t b) { int16_t d = a - b; return (d < 0) ? (uint16_t)(-d) : (uint16_t)d; } -/* ==================== 重置 ==================== */ - void app_touch_reset(void) { touch_state = TOUCH_IDLE; down_x = down_y = 0; touch_tick = repeat_tick = 0; long_press_fired = 0; + click_sent = 0; last_slide_x = last_slide_y = 0; } -/* ==================== 手势识别 ==================== */ - app_touch_result_t app_touch_process(uint16_t x, uint16_t y, uint8_t pressed) { app_touch_result_t r; @@ -68,22 +50,25 @@ app_touch_result_t app_touch_process(uint16_t x, uint16_t y, uint8_t pressed) uint32_t now = rt_tick_get(); - /* ---------- 抬起处理 ---------- */ if (!pressed) { - /* 若曾稳定按下且未触发长按 → 释放(可当作 TAP) */ - if (touch_state == TOUCH_PRESS_STABLE && !long_press_fired) { + if (!long_press_fired && !click_sent && + (touch_state == TOUCH_PRESS_WAIT_STABLE || + touch_state == TOUCH_PRESS_STABLE)) + { r.gesture = GESTURE_RELEASE; - r.x = down_x; r.y = down_y; /* 用按下点作为释放坐标 */ + r.x = down_x; + r.y = down_y; + MainTask_Sendmsg(MSG_ID_TOUCH, 1, down_x, down_y); } touch_state = TOUCH_IDLE; down_x = down_y = 0; last_slide_x = last_slide_y = 0; touch_tick = repeat_tick = 0; long_press_fired = 0; + click_sent = 0; return r; } - /* ---------- 按下处理 ---------- */ switch (touch_state) { case TOUCH_IDLE: @@ -91,29 +76,27 @@ app_touch_result_t app_touch_process(uint16_t x, uint16_t y, uint8_t pressed) down_y = y; touch_tick = now; long_press_fired = 0; + click_sent = 0; repeat_tick = 0; touch_state = TOUCH_PRESS_WAIT_STABLE; + /* 第一帧就发点击,模式选择等页跟手 */ + click_sent = 1; + MainTask_Sendmsg(MSG_ID_TOUCH, 1, down_x, down_y); break; case TOUCH_PRESS_WAIT_STABLE: if ((now - touch_tick) >= TOUCH_STABLE_TIME) { - /* 位移小 → 进入稳定 */ - if (abs_diff(x, down_x) < 8 && abs_diff(y, down_y) < 8) { + if (abs_diff(x, down_x) < 24 && abs_diff(y, down_y) < 24) touch_state = TOUCH_PRESS_STABLE; - last_slide_x = down_x; - last_slide_y = down_y; + else { + down_x = x; + down_y = y; touch_tick = now; - MainTask_Sendmsg(MSG_ID_TOUCH, 1, down_x, down_y); - } else { - /* 位移大 → 视为误触,回到空闲 */ - touch_state = TOUCH_IDLE; } } break; case TOUCH_PRESS_STABLE: - { - /* ----- 长按检测 ----- */ if (!long_press_fired && (now - touch_tick) >= TOUCH_LONG_PRESS_TIME) { long_press_fired = 1; repeat_tick = now; @@ -121,14 +104,12 @@ app_touch_result_t app_touch_process(uint16_t x, uint16_t y, uint8_t pressed) MainTask_Sendmsg(MSG_ID_TOUCH_LONG_REPEAT, 1, down_x, down_y); return r; } - /* ----- 长按重复 ----- */ if (long_press_fired && (now - repeat_tick) >= TOUCH_REPEAT_INTERVAL) { repeat_tick = now; r.gesture = GESTURE_REPEAT; MainTask_Sendmsg(MSG_ID_TOUCH_LONG_REPEAT, 1, down_x, down_y); return r; } - /* ----- 位移进入滑动 ----- */ if (abs_diff(x, down_x) >= TOUCH_SLIDE_THRESH || abs_diff(y, down_y) >= TOUCH_SLIDE_THRESH) { touch_state = TOUCH_SLIDING; @@ -136,15 +117,12 @@ app_touch_result_t app_touch_process(uint16_t x, uint16_t y, uint8_t pressed) last_slide_y = y; } break; - } case TOUCH_SLIDING: - { - /* 位移超过步进 → 产生拖动事件 */ if (abs_diff(x, last_slide_x) >= TOUCH_SLIDE_STEP || abs_diff(y, last_slide_y) >= TOUCH_SLIDE_STEP) { r.gesture = GESTURE_DRAG; - r.down_x = last_slide_x; /* 记录上次位置,便于消费端算增量 */ + r.down_x = last_slide_x; r.down_y = last_slide_y; MainTask_Sendmsg(MSG_ID_TOUCH, 1, x, y); last_slide_x = x; @@ -152,12 +130,11 @@ app_touch_result_t app_touch_process(uint16_t x, uint16_t y, uint8_t pressed) return r; } break; - } default: touch_state = TOUCH_IDLE; break; } - return r; /* 无手势 */ + return r; } diff --git a/Global/Global.c b/Global/Global.c index e9d15dd..cb990f6 100644 --- a/Global/Global.c +++ b/Global/Global.c @@ -52,37 +52,33 @@ Fader_t faders[4] = { const Touch_AreaTypeDef Touch_Areas[] = { - // Xmin, Xmax, Ymin, Ymax, flag,value ID, action - { 0, 60, 25, 90, -1, 0, GUI_TRANSPOSE, NULL }, - { 60, 120, 25, 90, 1, 0, GUI_TRANSPOSE, NULL }, + /* Xmin,Xmax,Ymin,Ymax, Flag, Value, ID, action 鈥 鍧愭爣鐩稿 240x320 */ + { 0, 60, 25, 95, -1, 0, GUI_TRANSPOSE, NULL }, + { 60, 120, 25, 95, 1, 0, GUI_TRANSPOSE, NULL }, - { 125, 180, 25, 90, -1, 0, GUI_SPEED, NULL }, - { 180, 240, 25, 90, 1, 0, GUI_SPEED, NULL }, + { 125, 180, 25, 95, -1, 0, GUI_SPEED, NULL }, + { 180, 239, 25, 95, 1, 0, GUI_SPEED, NULL }, - { 0, 80, 90, 120, 0, 0, GUI_AUTOBAND_SW, NULL }, - { 90, 170, 90, 120, 0, 1, GUI_AUTOBAND_SW, NULL }, - { 80, 140, 0, 30, 0, 0, GUI_BL_SW, NULL }, + { 0, 85, 95, 130, 0, 0, GUI_AUTOBAND_SW, NULL }, + { 90, 175, 95, 130, 0, 1, GUI_AUTOBAND_SW, NULL }, - { 0, 120, 120, 150, -1, 0, GUI_MODE_PARAM, NULL }, - {120, 240, 120, 150, 1, 0, GUI_MODE_PARAM, NULL }, + { 0, 120, 130, 165, -1, 0, GUI_MODE_PARAM, NULL }, + { 120, 239, 130, 165, 1, 0, GUI_MODE_PARAM, NULL }, - { 10, 120, 125, 150, -1, 0, GUI_MODE_PARAM, NULL }, - { 80, 140, 0, 30, 0, 0, GUI_MODE_PARAM, NULL }, + { 0, 120, 165, 215, -1, 0, GUI_TIMBRE_SELECT, NULL }, + { 120, 239, 165, 215, 1, 0, GUI_TIMBRE_SELECT, NULL }, - { 0, 117, 155, 200, -1, 0, GUI_TIMBRE_SELECT, NULL }, - { 120, 240, 155, 200, 1, 0, GUI_TIMBRE_SELECT, NULL }, - - { 10, 50, 275, 340, 0,2, GUI_TAB_INDEX, NULL }, - { 70, 130, 275, 340, 0,0, GUI_TAB_INDEX, NULL }, - { 130, 170, 275, 340, 0,1, GUI_TAB_INDEX, NULL }, - { 190, 230, 275, 340, 0,3, GUI_TAB_INDEX, NULL }, - - { 10, 60, 240, 320, 0,0, GUI_PLAY_SECTION, NULL }, - { 60, 110, 240, 320, 0,1, GUI_PLAY_SECTION, NULL }, - { 110, 170, 240, 320, 0,2, GUI_PLAY_SECTION, NULL }, - { 170, 220, 240, 320, 0,3, GUI_PLAY_SECTION, NULL }, - + /* 婕斿娈佃惤 1~4 */ + { 10, 60, 220, 270, 0, 0, GUI_PLAY_SECTION, NULL }, + { 60, 110, 220, 270, 0, 1, GUI_PLAY_SECTION, NULL }, + { 110, 165, 220, 270, 0, 2, GUI_PLAY_SECTION, NULL }, + { 165, 220, 220, 270, 0, 3, GUI_PLAY_SECTION, NULL }, + /* 搴曟爮 TAB锛氫竾鑳/鏅/涓撲笟/璁剧疆锛圴alue=鐩爣 TAB锛 */ + { 0, 60, 275, 319, 0, 0, GUI_TAB_INDEX, NULL }, + { 60, 120, 275, 319, 0, 2, GUI_TAB_INDEX, NULL }, + { 120, 180, 275, 319, 0, 1, GUI_TAB_INDEX, NULL }, + { 180, 239, 275, 319, 0, 3, GUI_TAB_INDEX, NULL }, }; int16_t MIC_VOL_MAP[10]= {-9000,-7000,-5000,-3000,-1000,1000,3000,5000,7000,9000}; diff --git a/UI/UI_Idle.c b/UI/UI_Idle.c index 0a38c87..9d0ed2d 100644 --- a/UI/UI_Idle.c +++ b/UI/UI_Idle.c @@ -22,6 +22,28 @@ void RGB_Y_TO_G() /* 妯″紡閫夋嫨椤电劍鐐癸細0=涓囪兘 1=鏅 2=涓撲笟锛岄粯璁ら変腑涓囪兘锛堜笌瑙勮寖涓鑷达級 */ static uint8_t s_mode_select_focus = 0; +extern bool InModeFlag; + +static void UI_ModeSelect_DrawButtons(void); + +static void UI_ModeSelect_SetFocus(uint8_t idx) +{ + if (idx > 2 || idx == s_mode_select_focus) + return; + s_mode_select_focus = idx; + UI_ModeSelect_DrawButtons(); +} + +void UI_ReturnToModeSelect(void) +{ + StartFlag = 0; + InModeFlag = false; + AutoBandTop1_Stop(); + s_mode_select_focus = 0; + CallUI_Idle(); + UI_DrawModeSelectScreen(); +} + /* 0831 缇庡伐璇曠敤鍥撅細鍥炬爣+MiSans 鏂囧瓧鏁磋浣嶅浘 */ static void UI_DrawModeSelectButton(uint16_t y, const uint8_t *row, uint8_t focused) { @@ -45,15 +67,8 @@ static void UI_DrawModeSelectButton(uint16_t y, const uint8_t *row, uint8_t focu LCD_WR_PIC_Trans(row_x, row_y, UI_MODE0831_ROW_W, UI_MODE0831_ROW_H, row, BLACK); } -void UI_DrawModeSelectScreen(void) +static void UI_ModeSelect_DrawButtons(void) { - UI_ClearFocus(); - s_mode_select_focus = 0; - pCurrentTouch_Area = Touch_ModeSelect_Areas; - - LCD_FillByColor(0, 0, 240, 320, BLACK); - label_top(); - UI_DrawModeSelectButton(40, gImage_Mode0831_Universal_Row_180_52, s_mode_select_focus == 0); @@ -63,14 +78,23 @@ void UI_DrawModeSelectScreen(void) UI_DrawModeSelectButton(224, gImage_Mode0831_Expert_Row_180_52, s_mode_select_focus == 2); +} + +void UI_DrawModeSelectScreen(void) +{ + UI_ClearFocus(); + pCurrentTouch_Area = Touch_ModeSelect_Areas; + + LCD_FillByColor(0, 0, 240, 320, BLACK); + label_top(); + UI_ModeSelect_DrawButtons(); } const Touch_AreaTypeDef Touch_ModeSelect_Areas[] = { - /* Xmin,Xmax,Ymin,Ymax, Flag, Value, ID, action - * Flag=鎸夐挳搴忓彿锛汭D=杩涘叆鐨 TAB锛0涓囪兘Song / 1涓撲笟Expert / 2鏅欶ree锛 */ - { 10, 229, 40, 126, 0, 0, 0, NULL }, /* 涓囪兘妯″紡 鈫 SongMode */ - { 10, 229, 132, 218, 1, 0, 2, NULL }, /* 鏅氭ā寮 鈫 FreeMode */ - { 10, 229, 224, 310, 2, 0, 1, NULL }, /* 涓撲笟妯″紡 鈫 ExpertMode */ + /* Flag=鎸夐挳搴忓彿(0涓囪兘/1鏅/2涓撲笟)锛汭D=杩涘叆 TAB */ + { 0, 239, 38, 127, 0, 0, 0, NULL }, + { 0, 239, 128, 219, 1, 0, 2, NULL }, + { 0, 239, 220, 311, 2, 0, 1, NULL }, }; #define TOUCH_AREA_MODE_SELECT_NUM (sizeof(Touch_ModeSelect_Areas)/sizeof(Touch_AreaTypeDef)) @@ -156,7 +180,8 @@ void IdleProcess(DisplayTaskMessage_Type msg) LCD_FillByColor(0, 0, 240, 320, WHITE); LCD_WR_PIC_FROM_FLASH(40, 80, 168, 155, 0x00000000); BSP_SelectAdcChannel(6); - wk_delay_ms(1000); + /* 璁╁嚭 CPU锛岄伩鍏嶅繖绛夊崱浣忚Е鎽/涓诲惊鐜嚎绋 */ + rt_thread_mdelay(1000); LoadConfig(); vol = ADC_ReadChannel(ADC_CHANNEL_1)>>5; if (vol <= 5) level = 0; @@ -167,6 +192,7 @@ void IdleProcess(DisplayTaskMessage_Type msg) else level = 5; Send_volume(vol); + s_mode_select_focus = 0; UI_DrawModeSelectScreen(); TM1629D_AllLedOn(LED_COLOR_G); TM1629D_UpdateDisplay(0); @@ -190,12 +216,20 @@ void IdleProcess(DisplayTaskMessage_Type msg) if( msg.HiByte >= Touch_ModeSelect_Areas[k].x_min && msg.HiByte <= Touch_ModeSelect_Areas[k].x_max && msg.LoByte >= Touch_ModeSelect_Areas[k].y_min && msg.LoByte <= Touch_ModeSelect_Areas[k].y_max ) { - Touch_Mode_Select_Action(Touch_ModeSelect_Areas[k].Flag,Touch_ModeSelect_Areas[k].ID,k); + uint8_t row = (uint8_t)Touch_ModeSelect_Areas[k].Flag; + if (row == s_mode_select_focus) + Touch_Mode_Select_Action(Touch_ModeSelect_Areas[k].Flag, Touch_ModeSelect_Areas[k].ID, k); + else + UI_ModeSelect_SetFocus(row); break; } } break; + case MSG_ID_TOUCH_LONG_REPEAT: + /* 妯″紡椤垫殏鏃犻暱鎸夊姩浣 */ + break; + case MSG_ID_BATTERY_VALUE: Draw_Status_Battery_Icon(msg.ID); break; diff --git a/UI/UI_SongMode.c b/UI/UI_SongMode.c index 1bb2323..4b4393d 100644 --- a/UI/UI_SongMode.c +++ b/UI/UI_SongMode.c @@ -417,6 +417,12 @@ void UI_SongMode_Process(DisplayTaskMessage_Type msg) break; case MSG_ID_TOUCH_LONG_REPEAT: { + /* 闀挎寜椤舵爮锛坹<28锛夎繑鍥炰笁閿ā寮忛夋嫨椤 */ + if (msg.LoByte < 28) + { + UI_ReturnToModeSelect(); + break; + } for(uint8_t k=0; k= pCurrentTouch_Area[k].x_min && msg.HiByte <= pCurrentTouch_Area[k].x_max && diff --git a/UI/UI_idle.h b/UI/UI_idle.h index 40dc2d6..f880ac1 100644 --- a/UI/UI_idle.h +++ b/UI/UI_idle.h @@ -9,7 +9,7 @@ typedef enum { extern const Touch_AreaTypeDef Touch_ModeSelect_Areas[]; extern void UI_DrawModeSelectScreen(void); - +extern void UI_ReturnToModeSelect(void); extern void IdleProcess(DisplayTaskMessage_Type xEvent); diff --git a/device/LCD_ILI9341/Drv_ILI9341_Lcd_Dump.c b/device/LCD_ILI9341/Drv_ILI9341_Lcd_Dump.c index 66b93be..d94ef95 100644 --- a/device/LCD_ILI9341/Drv_ILI9341_Lcd_Dump.c +++ b/device/LCD_ILI9341/Drv_ILI9341_Lcd_Dump.c @@ -7,6 +7,7 @@ #define LCD_DUMP_RTT_UP_CH 1 #define LCD_DUMP_RTT_DOWN_CH 0 #define LCD_DUMP_CMD "DUMP" +#define LCD_DUMP_TAP_CMD "TAP" #define LCD_DUMP_MAGIC "SCRN" #define LCD_DUMP_FMT_RGB565 1 #define LCD_DUMP_CMD_BUF_SIZE 16 @@ -208,6 +209,15 @@ static uint8_t LCD_Dump_CommandPending(void) s_cmd_buf[s_cmd_len++] = c; s_cmd_buf[s_cmd_len] = '\0'; + /* 鍚堟垚鐐瑰嚮锛氶獙璇 UI 鍛戒腑璺緞锛堢偣涓囪兘鎸夐挳涓績锛 */ + if (strstr(s_cmd_buf, LCD_DUMP_TAP_CMD) != NULL) { + s_cmd_len = 0U; + s_cmd_buf[0] = '\0'; + MainTask_Sendmsg(MSG_ID_TOUCH, 1, 120, 80); + SEGGER_RTT_WriteString(0, "TAP inject 120,80\n"); + continue; + } + if (c == 0x01 || strstr(s_cmd_buf, LCD_DUMP_CMD) != NULL) { s_cmd_len = 0U; s_cmd_buf[0] = '\0'; diff --git a/device/LCD_ILI9341/Drv_XPT2046_Touch.c b/device/LCD_ILI9341/Drv_XPT2046_Touch.c index af14814..acc2403 100644 --- a/device/LCD_ILI9341/Drv_XPT2046_Touch.c +++ b/device/LCD_ILI9341/Drv_XPT2046_Touch.c @@ -92,116 +92,154 @@ void TP_Write_Byte(uint8_t data) //浠庤Е鎽稿睆IC璇诲彇adc鍊 //CMD:鎸囦护 //杩斿洖鍊:璇诲埌鐨勬暟鎹 -uint16_t TP_Read_AD(uint8_t cmd) -{ +uint16_t TP_Read_AD(uint8_t cmd) +{ uint8_t i; uint16_t adc_val = 0; - TP_CS_Clr(); // 鐗囬夋媺浣庯紝閫変腑XPT2046 - Delay_us(2); // 鐗囬夌ǔ瀹氭椂闂 - - TP_Write_Byte(cmd); // MCU閫氳繃DIN鍙戦佸懡浠わ紙XPT2046鐨凞IN杈撳叆鎺ユ敹锛 - - // 绛夊緟XPT2046瀹屾垚AD杞崲锛堢害6us锛岃浆鎹㈡湡闂碠UT鏃犳湁鏁堟暟鎹級 + TP_CS_Clr(); + Delay_us(2); + TP_Write_Byte(cmd); Delay_us(6); - // 璇诲彇16浣嶆暟鎹紙XPT2046閫氳繃鑷韩OUT杈撳嚭鏁版嵁锛孧CU閫氳繃OUT杈撳叆璇诲彇锛 - for (i = 0; i < 16; i++) + for (i = 0; i < 16; i++) { - adc_val <<= 1; // 宸︾Щ锛屽噯澶囨帴鏀朵笅涓浣 - - // 鏃堕挓涓婂崌娌匡細XPT2046鏇存柊OUT寮曡剼杈撳嚭锛涗笅闄嶆部锛歁CU璇诲彇OUT杈撳叆 - TP_CLK_Set(); - Delay_us(1); - TP_CLK_Clr(); - Delay_us(1); - - // MCU璇诲彇OUT寮曡剼鐨勮緭鍏ユ暟鎹紙楂12浣嶆湁鏁堬紝浣4浣嶄涪寮冿級 - if (TP_OUT_Read()) - { - adc_val |= 0x01; - } + adc_val <<= 1; + TP_CLK_Set(); + Delay_us(1); + TP_CLK_Clr(); + Delay_us(1); + if (TP_OUT_Read()) + adc_val |= 0x01; } - TP_CS_Set(); // 閲婃斁鐗囬 - return adc_val >> 4; // 鍙栭珮12浣嶆湁鏁堟暟鎹 + TP_CS_Set(); + return adc_val >> 4; } -// 绠鍗曞幓鎶栧姩璇诲彇锛堣繛缁璶娆$浉鍚岀姸鎬佽涓烘湁鏁堬級 -uint8_t TP_CheckPressed(uint8_t n) +uint8_t TP_CheckPressed(uint8_t n) { - uint8_t count = 0; + uint8_t count = 0; + uint8_t i; - for (uint8_t i = 0; i < n; i++) - { - if (TP_IRQ_Read() == 0) - { // IRQ浣庣數骞宠〃绀烘寜涓 - count++; - } - Delay_us(100); - } - - return (count >= n/2) ? 1 : 0; + for (i = 0; i < n; i++) + { + if (TP_IRQ_Read() == 0) + count++; + Delay_us(100); + } + return (count >= (n / 2)) ? 1 : 0; } -// 璇诲彇鍘熷鍧愭爣锛堟湭鏍″噯锛 -TP_Point TP_ReadRaw(void) +static uint16_t TP_SampleAxis(uint8_t cmd) { - TP_Point p = {0, 0, 0}; + (void)TP_Read_AD(cmd); + Delay_us(15); + return TP_Read_AD(cmd); +} - if (!TP_CheckPressed(3)) - { // 妫鏌ヨЕ鎽哥姸鎬 +TP_Point TP_ReadRaw(void) +{ + TP_Point p = {0, 0, 0}; + uint32_t x_sum = 0, y_sum = 0; + uint8_t i; + + if (!TP_CheckPressed(3)) + return p; + + for (i = 0; i < 5; i++) + { + x_sum += TP_SampleAxis(XPT2046_READ_X); + Delay_us(15); + y_sum += TP_SampleAxis(XPT2046_READ_Y); + Delay_us(15); + } + + p.x = (uint16_t)(x_sum / 5); + p.y = (uint16_t)(y_sum / 5); + + /* Y 閫氶亾甯镐负 0 鏃讹紝浜ゆ崲 X/Y 鍛戒护鍐嶉噰涓娆 */ + if (p.y < 80u && p.x > 80u) + { + uint32_t sx = 0, sy = 0; + + for (i = 0; i < 3; i++) + { + sx += TP_SampleAxis(XPT2046_READ_Y); + Delay_us(15); + sy += TP_SampleAxis(XPT2046_READ_X); + Delay_us(15); + } + if (sy / 3u > p.y) + { + p.x = (uint16_t)(sx / 3); + p.y = (uint16_t)(sy / 3); + } + } + + p.pressed = 1; return p; - } - - // 澶氭璇诲彇鍙栧钩鍧囧硷紝鍑忓皯鍣0 - uint32_t x_sum = 0, y_sum = 0; - - for (uint8_t i = 0; i < 5; i++) - { - x_sum += TP_Read_AD(XPT2046_READ_X); - y_sum += TP_Read_AD(XPT2046_READ_Y); - } - - p.x = x_sum / 5; - p.y = y_sum / 5; - p.pressed = 1; - - return p; } -// 鏍″噯鍙傛暟锛堥渶瀹為檯瑙︽懜鍥涗釜瑙掑悗淇敼锛岀ず渚嬩负240x320灞忥級 -#define CALIB_X_MIN 200 // 鏈灏廥鍘熷鍊 -#define CALIB_X_MAX 3800 // 鏈澶鍘熷鍊 -#define CALIB_Y_MIN 200 // 鏈灏廦鍘熷鍊 -#define CALIB_Y_MAX 3800 // 鏈澶鍘熷鍊 -#define LCD_WIDTH 240 // LCD瀹藉害 -#define LCD_HEIGHT 320 // LCD楂樺害 +#define CALIB_X_MIN 200 +#define CALIB_X_MAX 3800 +#define CALIB_Y_MIN 200 +#define CALIB_Y_MAX 3800 -// 鏍″噯鍚庤幏鍙朙CD鍧愭爣 -TP_Point TP_Read(void) +/* 绔栧睆锛氬鏁 ILI9341+XPT2046 鏉跨骇闇 XY 瀵硅皟锛沊 闀滃儚涓庡巻鍙 240-tp.x 涓鑷 */ +#define TP_SWAP_XY 1 +#define TP_MIRROR_X 1 +#define TP_MIRROR_Y 0 + +static uint16_t TP_MapAxis(uint16_t adc, uint16_t adc_min, uint16_t adc_max, uint16_t px_max) { -// char Info[40]; - TP_Point raw = TP_ReadRaw(); -// sprintf (Info, "(x=%03d y=%03d) ", raw.x, raw.y); -// LCD_ShowString(2, 176+16, (const uint8_t*)Info, RED, WHITE, 16, 0); - TP_Point calib = {0, 0, raw.pressed}; + int32_t v = (int32_t)adc; + int32_t a0 = (int32_t)adc_min; + int32_t a1 = (int32_t)adc_max; + int32_t span = a1 - a0; + int32_t px; - if (!raw.pressed) { + if (span <= 0) + return 0; + if (v < a0) + v = a0; + if (v > a1) + v = a1; + px = (v - a0) * (int32_t)px_max / span; + if (px < 0) + px = 0; + if (px > (int32_t)px_max) + px = (int32_t)px_max; + return (uint16_t)px; +} + +TP_Point TP_Read(void) +{ + TP_Point raw = TP_ReadRaw(); + TP_Point calib = {0, 0, raw.pressed}; + uint16_t ax, ay; + + if (!raw.pressed) + return calib; + +#if TP_SWAP_XY + ax = TP_MapAxis(raw.y, CALIB_Y_MIN, CALIB_Y_MAX, (uint16_t)(LCD_W - 1)); + ay = TP_MapAxis(raw.x, CALIB_X_MIN, CALIB_X_MAX, (uint16_t)(LCD_H - 1)); +#else + ax = TP_MapAxis(raw.x, CALIB_X_MIN, CALIB_X_MAX, (uint16_t)(LCD_W - 1)); + ay = TP_MapAxis(raw.y, CALIB_Y_MIN, CALIB_Y_MAX, (uint16_t)(LCD_H - 1)); +#endif + +#if TP_MIRROR_X + ax = (uint16_t)(LCD_W - 1 - ax); +#endif +#if TP_MIRROR_Y + ay = (uint16_t)(LCD_H - 1 - ay); +#endif + + calib.x = ax; + calib.y = ay; return calib; - } - - // 绾挎ф槧灏勶細灏嗗師濮婣DC鍊艰浆鎹负LCD鍍忕礌鍧愭爣 - calib.x = (raw.x - CALIB_X_MIN) * LCD_WIDTH / (CALIB_X_MAX - CALIB_X_MIN); - calib.y = (raw.y - CALIB_Y_MIN) * LCD_HEIGHT / (CALIB_Y_MAX - CALIB_Y_MIN); - - // 杈圭晫闄愬埗 - if (calib.x > LCD_WIDTH - 1) calib.x = LCD_WIDTH - 1; - if (calib.x == 0) calib.x = 0; - if (calib.y > LCD_HEIGHT - 1) calib.y = LCD_HEIGHT - 1; - if (calib.y == 0) calib.y = 0; - - return calib; } // EXTI15_10涓柇鏈嶅姟鍑芥暟锛堝鐞員P_IRQ瑙﹀彂锛 diff --git a/device/LCD_ILI9341/Drv_XPT2046_Touch.h b/device/LCD_ILI9341/Drv_XPT2046_Touch.h index 6fe4f2a..c6e36c4 100644 --- a/device/LCD_ILI9341/Drv_XPT2046_Touch.h +++ b/device/LCD_ILI9341/Drv_XPT2046_Touch.h @@ -33,11 +33,11 @@ #define TP_DIN_Clr() gpio_bits_reset(TP_DIN_PORT, TP_DIN_PIN) // DIN杈撳嚭浣庯紙MCU鈫扻PT2046锛 #define TP_DIN_Set() gpio_bits_set(TP_DIN_PORT, TP_DIN_PIN) // DIN杈撳嚭楂橈紙MCU鈫扻PT2046锛 -// XPT2046鍛戒护瀹氫箟 -#define XPT2046_READ_X 0xD0 // 璇籜鍧愭爣鍛戒护锛圡CU閫氳繃DIN鍙戦佺粰XPT2046锛 -#define XPT2046_READ_Y 0x90 // 璇籝鍧愭爣鍛戒护 -#define XPT2046_READ_Z1 0xB0 // 璇诲帇鍔沍1 -#define XPT2046_READ_Z2 0xC0 // 璇诲帇鍔沍2 +// XPT2046鍛戒护锛堜笌 BOOT 宸ョ▼涓鑷达級 +#define XPT2046_READ_X 0xD0 +#define XPT2046_READ_Y 0x90 +#define XPT2046_READ_Z1 0xB0 +#define XPT2046_READ_Z2 0xC0 // 瑙︽懜鐘舵佺粨鏋勪綋 typedef struct diff --git a/task/task_init.c b/task/task_init.c index ddea88e..846e66b 100644 --- a/task/task_init.c +++ b/task/task_init.c @@ -1,4 +1,5 @@ #include "includes.h" +#include "SEGGER_RTT.h" static struct rt_thread TaskScanThread; static struct rt_thread TaskUIThread; @@ -44,13 +45,20 @@ void TaskUIThread_entry(void* parameter) void TaskTouchThread_entry(void* parameter) { + static uint8_t s_last_pressed = 0; while(1) { - TP_Point tp = TP_Read(); /* 璇 XPT2046 瑙︽懜鍧愭爣 */ - app_touch_process(240-tp.x, tp.y, tp.pressed); - /* DUMP 鐢 lcd_dump 涓撶敤绾跨▼杞锛屽嬁鍦ㄨЕ鎽哥嚎绋嬮噷鍋 SPI 璇诲睆锛岄伩鍏嶅崱姝昏Е鎽 */ + TP_Point tp = TP_Read(); /* 宸插惈杞翠氦鎹/闀滃儚锛岀洿鎺ヨ繘鎵嬪娍 */ + if (tp.pressed && !s_last_pressed) + { + char buf[40]; + sprintf(buf, "TP %u,%u\n", (unsigned)tp.x, (unsigned)tp.y); + SEGGER_RTT_WriteString(0, buf); + } + s_last_pressed = tp.pressed; + app_touch_process(tp.x, tp.y, tp.pressed); Read_Cur_Measure(); - rt_thread_mdelay(10); + rt_thread_mdelay(8); } }