/********************************** (C) COPYRIGHT ****************************** * File Name :usb_driver.h * Author : DL * Version : V1.1 * Date : 2020/06/02 * Description : A demo for USB compound device created by CH552, support touch panel , and HID-compliant device. ********************************************************************************/ #include "TouchInclude.h" UINT16 wTwoPointsCoorYBak[2]; //备份Y坐标,用来判断角落是否有两指滑动 BOOL bTwoFingersMoveDown = 0; //双指下滑 UINT8 byTwoTouch = 0; //双指按下计算用 extern UINT8 TouchNum; #ifdef GESTURE UINT8 byTouchNumberChange = 0; //双指点击时记录手指数变化 UINT8 byTouchTime1 = 0; //单指点击时计时 UINT8 byTouchTime2 = 0; //双指点击时计时 UINT16 wCoorXBak[5]; //备份X坐标,用来判断是否有滑动 UINT16 wCoorYBak[5]; //备份Y坐标,用来判断是否有滑动 UINT8 byFirstTouch = 0; //用于双指第一次按下去抖 BOOL bMoveFlag = 0; //双指滑动标志 BOOL bclickFlag = 0; //双指点击标志 UINT8 byWheelUpDown = 0; //双指滑动后滚轮上下滚动标志 #define LEFT_RIGHT_MOVE_DIS 600 #define UP_DOWN_MOVE_DIS 600 #define FIVE_MOVE_DIS 400 UINT8 byFourTouch = 0; UINT8 byFiveTouch = 0; UINT8 FourfingersGesture(void); UINT8 byLeftRightMoveFlag = 0; //左右滑动的标志 UINT8 byUpDownMoveFlag = 0; //上下滑动的标志 BOOL bUpDowntMoveCtrl = 0; //上下滑动,上报键值之后要上报ctrl键 UINT16 wDisCoorX[4]; UINT16 wDisCoorY[4]; UINT16 wDisCoorXbak[4]; UINT16 wDisCoorYbak[4]; BOOL bFiveFingersMoveInFlag = 0; BOOL bFiveFingersMoveOutFlag = 0; extern UINT8 TouchNumBak; extern BOOL bTwoFingerCoorBak; extern UINT8 TouchCount; //手指按下帧数记录,要延迟3帧才上报鼠标 /******************************************************************************* * Function Name : WheelMove * Description : 检测双指滑动 * Input : None * Output : None * Return : None *******************************************************************************/ void WheelMove() { byWheelUpDown = 0; //每次清0重新判断 if (TouchNum == 0) { byFirstTouch = 0; } else if (TouchNum == 2) { if (byFirstTouch == 0) { byFirstTouch++; //要去抖一次,否则坐标不对 } else if(byFirstTouch == 1) { byFirstTouch = 3; wCoorXBak[0] = TP[0].X_pos; //备份坐标,用来做距离判断滑动 wCoorXBak[1] = TP[1].X_pos; wCoorYBak[0] = TP[0].Y_pos; wCoorYBak[1] = TP[1].Y_pos; } else if (byFirstTouch > 1) { //左右滑动也要判断,以免识别成点击 if (TP[0].X_pos + 100 < wCoorXBak[0] && TP[1].X_pos + 100 < wCoorXBak[1]) { bMoveFlag = 1; //置滑动标志,有滑动就不会识别成点击 } else if (TP[0].X_pos > wCoorXBak[0] + 100 && TP[1].X_pos > wCoorXBak[1] + 100) { bMoveFlag = 1; } else if (TP[0].Y_pos + 20 < wCoorYBak[0] && TP[1].Y_pos + 20 < wCoorYBak[1]) //Up { bMoveFlag = 1; byWheelUpDown = 1; } else if (TP[0].Y_pos > wCoorYBak[0] + 20 && TP[1].Y_pos > wCoorYBak[1] + 20) //Down { bMoveFlag = 1; byWheelUpDown = 2; } if (bMoveFlag) //有滑动了,重新备份坐标来判断距离 { wCoorXBak[0] = TP[0].X_pos; wCoorXBak[1] = TP[1].X_pos; wCoorYBak[0] = TP[0].Y_pos; wCoorYBak[1] = TP[1].Y_pos; } } } } /******************************************************************************* * Function Name : TwoPointsClick * Description : 检测双指点击,有下面4种情况: 1、双指同时点击,同时松开 2、双指同时点击,松开时一指先离开,另一指再离开 3、单指先触摸到,紧接着双指触摸,双指同时松开 4、单指先触摸到,紧接着双指触摸,松开时一指先离开,另一指再离开 * Input : None * Output : None * Return : 1:双指双击 other:无效 *******************************************************************************/ UINT8 TwoPointsClick() { UINT8 flag = 0xff; if (bMoveFlag == 1) //双指有滑动,直接退出检测 { byTouchNumberChange = 0; return(flag); } if (TouchNum == 0) //没有手指,已松键 { //双指同时按下同时松开,并且触摸时间在400ms内 if ((byTouchNumberChange == 2) && (byTouchTime2 < 10)) { //CH552UART0SendByte(0xbb); flag = 1; } //两指同时按下,松开过程先变一指再松开,触摸时间在400ms内 else if ((byTouchNumberChange == 3) && (byTouchTime1 < 10)) { //CH552UART0SendByte(0xbb); flag = 1; } //按下时先单指接触再变两指接触,松开过程不管,触摸时间在400ms内 else if ((byTouchNumberChange == 4) && (byTouchTime1 < 20) && (byTouchTime2 < 10)) { //CH552UART0SendByte(0xbb); flag = 1; } byTouchNumberChange = 0; byTouchTime1 = 0; byTouchTime2 = 0; } else if ((TouchNum == 1) && (byTouchNumberChange != 0xFF)) //检测到单指触摸 { if (byTouchNumberChange == 0) //如果之前没有触摸,说明在按下的过程先是一指触摸 { byTouchNumberChange = 1; byTouchTime1 = 0; } else if (byTouchNumberChange == 2) //如果之前是两指触摸,说明在松开的过程先是一指离开 { byTouchNumberChange = 3; } flag = 2; } else if ((TouchNum == 2) && (byTouchNumberChange != 0xFF)) //检测到两指触摸 { if (byTouchNumberChange == 0) //如果之前没有触摸,说明在按下的过程是两指同时触摸 { byTouchNumberChange = 2; byTouchTime1 = 0; byTouchTime2 = 0; } else if (byTouchNumberChange == 1) //如果之前先识别到一指触摸,说明在按下的过程是一指变两指 { byTouchNumberChange = 4; byTouchTime2 = 0; } flag = 2; } else //其他手指数则非法 { byTouchNumberChange = 0xFF; byTouchTime1 = 0; byTouchTime2 = 0; flag = 0; } return(flag); } void BackUpXPos() { UINT8 i; for (i = 0; i < 5; i++) { wCoorXBak[i] = TP[i].X_pos; } } void BackUpYPos() { UINT8 i; for (i = 0; i < 5; i++) { wCoorYBak[i] = TP[i].Y_pos; } } UINT16 GetAbs(UINT16 a, UINT16 b) { return a > b ? a - b : b - a; } void ReportKey() { #if (DEBUG!=Debug_USB) if (!IsBLEConnected() || BleReportPosEn == DISABLE) #else if (((!BleReportFirst) && EnumOK) || !IsBLEConnected() || BleReportPosEn == DISABLE) #endif { R8_UEP3_T_LEN = 9; R8_UEP3_CTRL = (R8_UEP3_CTRL & (~ MASK_UEP_T_RES)) | UEP_T_RES_ACK; } else { HidDev_Report(HID_RPT_ID_KEY_IN, HID_REPORT_TYPE_INPUT, 8, &pEP3_RAM_Addr[1]); } } UINT8 FourfingersGesture() { UINT8 i; UINT8 xmoveincount = 0; UINT8 ymoveincount = 0; UINT8 xmoveoutcount = 0; UINT8 ymoveoutcount = 0; memset(pEP3_RAM_Addr, 0, 9); pEP3_RAM_Addr[0] = HID_RPT_ID_KEY_IN; //CH552UART0SendByte(TouchNum); //PRINT("Touch=%d\n", TouchNum); if (TouchNum == 0) { byLeftRightMoveFlag = 0; //clean move flag byUpDownMoveFlag = 0; bFiveFingersMoveInFlag = 0; bFiveFingersMoveOutFlag = 0; if (byFourTouch || byFiveTouch) { if (byFourTouch == 3 || byFiveTouch == 3) //松键第一帧 { pEP3_RAM_Addr[1] = 1; //上报Ctrl } else { pEP3_RAM_Addr[1] = 0; //防止鼠标判断有误,需要清除以下标志 TouchNumBak = 0; TouchCount = 0; bTwoFingerCoorBak = 0; } ReportKey(); if (byFourTouch) byFourTouch--; if (byFiveTouch) byFiveTouch--; return 1; } } else if (TouchNum == 4) { if (byFourTouch == 0 ) { byFourTouch++; } else if (byFourTouch == 1) { byFiveTouch = 0; BackUpXPos(); BackUpYPos(); byFourTouch = 3; pEP3_RAM_Addr[1] = 1; //Ctrl ReportKey(); } else if (byFourTouch > 1) { //上报了键值,要紧接着上报一帧Ctrl键,否则系统会识别长按键,键值功能失效 if (bUpDowntMoveCtrl) { bUpDowntMoveCtrl = 0; //byFourTouch = 2; //这里上报了Ctrl,松键的时候就不上报Ctrl了 pEP3_RAM_Addr[1] = 1; //上报Ctrl ReportKey(); } if (TP[0].X_pos + LEFT_RIGHT_MOVE_DIS < wCoorXBak[0] && TP[1].X_pos + LEFT_RIGHT_MOVE_DIS < wCoorXBak[1] && TP[2].X_pos + LEFT_RIGHT_MOVE_DIS < wCoorXBak[2] /*&& TP[3].X_pos + LEFT_RIGHT_MOVE_DIS < wCoorXBak[3]*/) //left { //CH552UART0SendByte(0xF5); if (byLeftRightMoveFlag == 0 || byLeftRightMoveFlag == 2) { byLeftRightMoveFlag = 1; pEP3_RAM_Addr[1] = 0x01; //Ctrl pEP3_RAM_Addr[3] = 0x4f;//0x50; //<- ReportKey(); } BackUpXPos(); } else if (TP[0].X_pos > wCoorXBak[0] + LEFT_RIGHT_MOVE_DIS && TP[1].X_pos > wCoorXBak[1] + LEFT_RIGHT_MOVE_DIS && TP[2].X_pos > wCoorXBak[2] + LEFT_RIGHT_MOVE_DIS/* && TP[3].X_pos > wCoorXBak[3] + LEFT_RIGHT_MOVE_DIS*/) //right { //CH552UART0SendByte(0xF6); if (byLeftRightMoveFlag == 0 || byLeftRightMoveFlag == 1) { byLeftRightMoveFlag = 2; pEP3_RAM_Addr[1] = 0x01; //Ctrl pEP3_RAM_Addr[3] = 0x50;//0x4f; //-> ReportKey(); } BackUpXPos(); } else if (TP[0].Y_pos + UP_DOWN_MOVE_DIS < wCoorYBak[0] && TP[1].Y_pos + UP_DOWN_MOVE_DIS < wCoorYBak[1] && TP[2].Y_pos + UP_DOWN_MOVE_DIS < wCoorYBak[2] /*&& TP[3].Y_pos + UP_DOWN_MOVE_DIS < wCoorYBak[3]*/) //Up { if (byUpDownMoveFlag == 0 || byUpDownMoveFlag == 2) { byUpDownMoveFlag = 1; bUpDowntMoveCtrl = 1; pEP3_RAM_Addr[1] = 0x01; //Ctrl pEP3_RAM_Addr[3] = 0x52; //up ReportKey(); } BackUpYPos(); } else if (TP[0].Y_pos > wCoorYBak[0] + UP_DOWN_MOVE_DIS && TP[1].Y_pos > wCoorYBak[1] + UP_DOWN_MOVE_DIS && TP[2].Y_pos > wCoorYBak[2] + UP_DOWN_MOVE_DIS /*&& TP[3].Y_pos > wCoorYBak[3] + UP_DOWN_MOVE_DIS*/) //Down { if (byUpDownMoveFlag == 0 || byUpDownMoveFlag == 1) { byUpDownMoveFlag = 2; bUpDowntMoveCtrl = 1; pEP3_RAM_Addr[1] = 0x01; //Ctrl pEP3_RAM_Addr[3] = 0x51; //down ReportKey(); } BackUpYPos(); } } return 1; } else if (TouchNum == 5) //五指手势识别 { if (byFiveTouch == 0 ) { byFiveTouch++; } else if (byFiveTouch == 1) { byFourTouch = 0; BackUpXPos(); BackUpYPos(); byFiveTouch = 3; pEP3_RAM_Addr[1] = 1; //Ctrl ReportKey(); } else if (byFiveTouch > 1) { for (i = 0; i < 3; i++) { wDisCoorX[i] = GetAbs(TP[i].X_pos, TP[i + 2].X_pos); wDisCoorY[i] = GetAbs(TP[i].Y_pos, TP[i + 2].Y_pos); wDisCoorXbak[i] = GetAbs(wCoorXBak[i], wCoorXBak[i + 2]); wDisCoorYbak[i] = GetAbs(wCoorYBak[i], wCoorYBak[i + 2]); } wDisCoorX[3] = GetAbs(TP[0].X_pos, TP[4].X_pos); wDisCoorY[3] = GetAbs(TP[0].Y_pos, TP[4].Y_pos); wDisCoorXbak[3] = GetAbs(wCoorXBak[0], wCoorXBak[4]); wDisCoorYbak[3] = GetAbs(wCoorYBak[0], wCoorYBak[4]); //=======================Close========================// for (i = 0; i < 4; i++) { if (wDisCoorX[i] + FIVE_MOVE_DIS < wDisCoorXbak[i]) { xmoveincount++; } if (wDisCoorY[i] + FIVE_MOVE_DIS < wDisCoorYbak[i]) { ymoveincount++; } } if ((xmoveincount + ymoveincount >= 3)) { if (bFiveFingersMoveInFlag == 0) { bFiveFingersMoveInFlag = 1; pEP3_RAM_Addr[1] = 1; //Ctrl pEP3_RAM_Addr[3] = 0x05; //B ReportKey(); } BackUpXPos(); BackUpYPos(); } //=======================Open========================// for (i = 0; i < 4; i++) { if (wDisCoorX[i] > wDisCoorXbak[i] + FIVE_MOVE_DIS) { xmoveoutcount++; } if (wDisCoorY[i] > wDisCoorYbak[i] + FIVE_MOVE_DIS) { ymoveoutcount++; } } if (xmoveoutcount + ymoveoutcount >= 3) { //CH552UART0SendByte(0xF3); if (bFiveFingersMoveOutFlag == 0) { bFiveFingersMoveOutFlag = 1; pEP3_RAM_Addr[1] = 1; //Ctrl pEP3_RAM_Addr[3] = 0x05; //B ReportKey(); } BackUpXPos(); BackUpYPos(); } } return 1; } else if (byFourTouch || byFiveTouch) { return 1; } return 0; } #endif #ifdef DOUBLECLIK_FILETER extern UINT16 Press_Flag; extern UINT16 Press_Flag_Bak1; extern UINT16 Press_Flag_Bak2; extern UINT16 StylusPress; UINT8 DoubleClickTimer = 0; void DoubleClickFilter(BOOL flag, UINT8 id) { static UINT16 PrePointX = 0xFFFF, PrePointY = 0xFFFF; //static UINT16 PreStylusPressure = 0; UINT16 Range = 240; //static UINT8 ID; #if USBCONFIG if(config.mouse_double_click_en ==0) return; #endif if(flag) { Range = 150; } if(DoubleClickTimer < 5)// || DoubleClickFlag) //400ms以内连续单指Touch { if(TP[id].X_pos < PrePointX + Range && TP[id].X_pos + Range > PrePointX && TP[id].Y_pos < PrePointY + Range && TP[id].Y_pos + Range > PrePointY) { //ID = id; TP[id].X_pos = PrePointX; TP[id].Y_pos = PrePointY; } else { DoubleClickTimer = 100; } } else { PrePointX = TP[id].X_pos; PrePointY = TP[id].Y_pos; } if((Press_Flag&Press_Flag_Bak1&Press_Flag_Bak2)==0 && !flag) { DoubleClickTimer = 0; } } #endif #ifdef CALL_OSD_MENU //双指在右下角下滑,串口上报命令调用OSD菜单 #define X_RANGE 10916 #define Y_RANGE 6400 UINT8 CallOsdMenuCmd[10] = {0x55, 0x56, 0xd1, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x27}; void CallOSDMenu() { UINT16 x_range = X_RANGE; if (TouchNum == 0) { byTwoTouch = 0; if (bTwoFingersMoveDown) { bTwoFingersMoveDown = 0; USART2_SendData(CallOsdMenuCmd, 10); } } else if (TouchNum == 2) { if(TpOption.uart_cmd == UART_COMMAND_A_90 ||TpOption.uart_cmd == UART_COMMAND_B_90 ||TpOption.uart_cmd == UART_COMMAND_A_270 ||TpOption.uart_cmd == UART_COMMAND_B_270 ) { x_range = RESOLUTION_X/2; } if (TP[0].X_pos_back > x_range && TP[0].Y_pos_back > Y_RANGE && TP[1].X_pos_back > x_range && TP[1].Y_pos_back > Y_RANGE) { if (byTwoTouch == 0) { byTwoTouch++; } else if (byTwoTouch == 1) { wTwoPointsCoorYBak[0] = TP[0].Y_pos_back; wTwoPointsCoorYBak[1] = TP[1].Y_pos_back; byTwoTouch++; } else if (byTwoTouch > 1) { if (TP[0].Y_pos_back > wTwoPointsCoorYBak[0] + 320 && TP[1].Y_pos_back > wTwoPointsCoorYBak[1] + 320) { //CH552UART0SendByte(0x66); bTwoFingersMoveDown = 1; } } } } } #endif