/********************************** (C) COPYRIGHT ******************************* * File Name : IIC.c * Author : WCH * Version : V1.0 * Date : 2018/12/12 * Description : I2C 读写 *******************************************************************************/ /********************************************************************* * INCLUDES */ #include "typedef.h" #include "TouchInclude.h" #define READ_TOUCH_POS_EVT 0x0001 #define READ_RESET_TOUCH_IC_EVT 0x0002 #define SYS_INIT_FINISH_EVT 0x0004 #define RELEASE_TOUCH_EVT 0x0008 #define READ_ONE_POINT_EVT 0x0010 #define START_REPORT_POS_EVT 0x0020 #define CHECK_TOUCH_INT_EVT 0x0040 #define REPORT_AGAIN_EVT 0x0080 #define CHECK_ESD_EVT 0x0100 #define HID_DEBUG_EVT 0x0200 #define CHECK_USB_STATUS_EVT 0x0400 #define PERIO_1s 1600 #define PERIO_2s (PERIO_1s*2) #define PERIO_5s (PERIO_1s*5) #define PERIO_40s (PERIO_1s*40) #pragma pack(1) typedef struct { UINT8 Reserved0:3; UINT8 FPEvent:1; UINT8 HotknotEvent:1; UINT8 GestureEvent:1; UINT8 RequestEvent:1; UINT8 TouchEvent:1; UINT8 INTCounter; UINT8 TouchNum:4; UINT8 LargeTouch:1; UINT8 HoverApproachFlag:1; UINT8 EdgeFlag:1; UINT8 ReseINT:1; UINT8 CustomCoorInfoFlag:1; UINT8 StylusKey:3; UINT8 Reserved1:4; UINT8 StylusPower; UINT8 Reserved3; UINT16 CheckSum; }ST_EVENT_HEAD; #pragma pack(1) typedef struct{ UINT8 rom_pid[6]; /* rom PID */ UINT8 rom_vid[3]; /* Mask VID */ UINT8 rom_vid_reserved; UINT8 patch_pid[8]; /* Patch PID */ UINT8 patch_vid[4]; /* Patch VID */ UINT8 patch_vid_reserved; UINT8 sensor_id; UINT8 reserved[2]; UINT16 checksum; }ST_FW_VERSION; static UINT8 IICTouchTaskId = INVALID_TASK_ID; static UINT8 PointNum = 0; static UINT8 ReadPointCnt = 0; static BOOL ReportPosSuccess = TRUE; static void ReadOnePoint(void); static void CheckTouchINT(void); static void StartReportPos(void); static void ReportPos(void); static UINT16 IICTouch_ProcessEvent( UINT8 task_id, UINT16 events ); static void BT_Check_ESD(); #ifdef MOUSE_REPORT #ifndef GESTURE extern UINT8 mouse_right_click_time; #endif #ifndef GESTURE extern void ReportMousePos(POINTER * pTP); #else void ReportMousePos(POINTER * pTP, UINT8 interface); #endif BOOL StylusFlag; #endif static BOOL SysInitFinish = FALSE; extern BOOL SleepEn; /******************************************************************************* * Function Name : BT_WR_Reg * Description : 向GT911写入一次数据 * Input : reg:起始寄存器地址 buf:数据缓缓存区 len:写数据长度 * Output : None * Return : 0,成功;1,失败. *******************************************************************************/ __attribute__((section(".highcode"))) UINT8 BT_WR_Reg(UINT32 reg,UINT8 *buf,UINT8 len) { return IICWriteBytes(reg,buf,len); } ///******************************************************************************* //* Function Name : BT_RD_Reg //* Description : 从GT911读出一次数据 //* Input : reg:起始寄存器地址 // buf:数据缓缓存区 // len:读数据长度 //* Output : None //* Return : None //*******************************************************************************/ //__attribute__((section(".highcode"))) UINT8 BT_RD_Reg(UINT32 reg, UINT8 *buf,UINT8 len) { return IICReadBytes(reg, buf, len); } static void ShutdownHIDI2C() { UINT8 nTryTimes = 50; if(IICWriteOneByte(0x3030AABB, 0xCC)) { delay_ms(80); while(nTryTimes--) { if(SearchAddress(100)) break; delay_ms(10); } } } BOOL EntryUpdateMode() { UINT8 tryTimes = 3,i; UINT8 cmd[6] = {0x00,0x00,0x00,0x02,0x01,0x00}; UINT32 state1,state2; gpio_reset_bits(GPIOA_REG, RST_PIN); delay_ms(20);//RST gpio_set_bits(GPIOA_REG, RST_PIN); delay_ms(15);//RST GioInterruptFlag = 0; if(!SearchAddress(100)) { return FALSE; } while(tryTimes--) { IICWriteBytes(0x00000002, cmd + 4, 2); cmd[2] = 0x20; cmd[3] = 0x00; IICReadBytes(0x00002000, (UINT8*)&state1, 4); for(i=0; i<3; i++) { IICReadBytes(0x00002000, (UINT8*)&state2, 4); if(state1 != state2) { break; } } if(i==3) return TRUE; } return FALSE; } static void CheckTouchChipType(void) { UINT8 i; ST_FW_VERSION fw; for(i=0; i<100; i++) { if(IICReadBytes(0x1000C, (UINT8*)&fw, sizeof(fw))) { if(GetCheckSum8((UINT8*)&fw, sizeof(fw)-2)==fw.checksum) { PRINT("pid1=%s\n", fw.patch_pid); if(fw.patch_pid[0] == '9' && fw.patch_pid[1] == '8' && fw.patch_pid[2] == '9' && fw.patch_pid[3] == '7' ) { ChipType = CHIP_TYPE_BERLINA; break; } } } if(IICReadBytes(0x10014, (UINT8*)&fw, sizeof(fw))) { if(GetCheckSum8((UINT8*)&fw, sizeof(fw)-2)==fw.checksum) { PRINT("pid2=%s\n", fw.patch_pid); if((fw.patch_pid[0]=='2' && fw.patch_pid[1] == '9' && fw.patch_pid[2] == '3' && (fw.patch_pid[3] == '3' || fw.patch_pid[3] == '6')) ||(fw.patch_pid[0]=='6' && fw.patch_pid[1] == '8' && fw.patch_pid[2] == '7' ) ) { ChipType = CHIP_TYPE_BERLINB; break; } else if(fw.patch_pid[0]=='2' && fw.patch_pid[1] == '9' && fw.patch_pid[2] == '3' && fw.patch_pid[3] == '1' ) { ChipType = CHIP_TYPE_BERLIND; break; } } } } if(i==10) { PRINT("Chip type unknown\n"); if(!IsBerlinChipType(ChipType)) { ChipType = CHIP_TYPE_BERLIND; } } } /******************************************************************************* * Function Name : BT_Init * Description : 触摸板初始化,获取ID,确认是否工作 * Input : None * Output : None * Return : None *******************************************************************************/ void BT_Init(void) { TouchProc = CheckTouchINT; CheckPos = MAX_POINT; CheckTouchChipType(); if(ChipType==CHIP_TYPE_BERLINB || ChipType==CHIP_TYPE_BERLIND) { ShutdownHIDI2C(); } if (IICTouchTaskId == INVALID_TASK_ID) { IICTouchTaskId = TMOS_ProcessEventRegister(IICTouch_ProcessEvent); tmos_set_event(IICTouchTaskId, HID_DEBUG_EVT); } tmos_start_task(IICTouchTaskId, CHECK_ESD_EVT, PERIO_2s ); tmos_start_task(IICTouchTaskId, SYS_INIT_FINISH_EVT, PERIO_40s ); PRINT("sys init\n"); } static void BT_Check_ESD() { UINT32 reg_addr = 0x10170; if(ChipType==CHIP_TYPE_BERLINA) { reg_addr = 0x10168; } if(!enable_ESD_check) return; if(IICReadOneByte(reg_addr) == 0xAA) { PRINT("BT Check ESD Error!\n"); ResetTouchChip(); //Rstart touch ic } else { IICWriteOneByte(reg_addr, 0xAA); } } static void ClearTouchFlag() { UINT32 reg_addr = 0x10274; if(ChipType == CHIP_TYPE_BERLINA) { reg_addr = 0x10338; } else if(ChipType == CHIP_TYPE_BERLIND) { reg_addr = 0x10308; } if(!IsDebugMode && !ReleaseFlag) { IICWriteOneByte(reg_addr, 0); //清标志 } } void BT_SetTouchEvent() { tmos_set_event(IICTouchTaskId, CHECK_TOUCH_INT_EVT); } static UINT16 IICTouch_ProcessEvent( UINT8 task_id, UINT16 events ) { //BOOL bSuccess = TRUE;; if(events & REPORT_AGAIN_EVT) { ReportPos(); events ^= REPORT_AGAIN_EVT; goto OUT_FUMC; } if(events & START_REPORT_POS_EVT) { //PRINT("SR"); StartReportPos(); events ^= START_REPORT_POS_EVT; goto OUT_FUMC; } if(events & READ_ONE_POINT_EVT) { ReadOnePoint(); events ^= READ_ONE_POINT_EVT; //有中断,取消USB检测 events &= ~CHECK_USB_STATUS_EVT; tmos_stop_task(IICTouchTaskId, CHECK_USB_STATUS_EVT); goto OUT_FUMC; } if(events & CHECK_TOUCH_INT_EVT) { //PRINT("TI"); CheckTouchINT(); events ^= CHECK_TOUCH_INT_EVT; if(PointNum == 0 && SysInitFinish) //松键 { tmos_start_task(IICTouchTaskId, CHECK_USB_STATUS_EVT, PERIO_1s ); //1s后开启USB检测 } goto OUT_FUMC; } if(events & CHECK_ESD_EVT) { //PRINT("esd check\n"); BT_Check_ESD(); events ^= CHECK_ESD_EVT; tmos_start_task(IICTouchTaskId, CHECK_ESD_EVT, PERIO_2s ); goto OUT_FUMC; } if(events & SYS_INIT_FINISH_EVT) { SysInitFinish = TRUE; events ^= SYS_INIT_FINISH_EVT; tmos_start_task(IICTouchTaskId, CHECK_USB_STATUS_EVT, PERIO_1s); goto OUT_FUMC; } if(events & CHECK_USB_STATUS_EVT) { events ^= CHECK_USB_STATUS_EVT; if(CheckUsbStatus()) { tmos_start_task(IICTouchTaskId, CHECK_USB_STATUS_EVT, PERIO_5s );//避免系统重连慢造成反复复位重连 } else { tmos_start_task(IICTouchTaskId, CHECK_USB_STATUS_EVT, PERIO_1s ); } goto OUT_FUMC; } if(events & HID_DEBUG_EVT) { CommandHandle(); events ^= HID_DEBUG_EVT; tmos_set_event(task_id, HID_DEBUG_EVT); goto OUT_FUMC; } return 0; OUT_FUMC: return events; } static void CheckTouchINT() { //UINT8 PointNum; ST_EVENT_HEAD event_head; UINT32 reg_addr = 0x10274; if(ChipType == CHIP_TYPE_BERLINA) { reg_addr = 0x10338; } else if(ChipType == CHIP_TYPE_BERLIND) { reg_addr = 0x10308; } StylusFlag = FALSE; IICReadBytes(reg_addr, (UINT8*)&event_head, sizeof(ST_EVENT_HEAD)); if(event_head.TouchEvent==0 && !ReleaseFlag) { IICWriteOneByte(reg_addr, 0); //清标志,如果延迟较长可以去掉 return ; } PointNum = event_head.TouchNum; TouchNum = 0; if(PointNum > MAX_POINT) PointNum = MAX_POINT; #ifdef MOUSE_REPORT StylusFlag = FALSE; #endif NoTouchTimer = 0; ReadPointCnt = 0; OutRangeFlag = 0xFFFF; Press_Flag = 0; if(PointNum==0) { tmos_set_event(IICTouchTaskId, START_REPORT_POS_EVT); } else { tmos_set_event(IICTouchTaskId, READ_ONE_POINT_EVT); } } //__attribute__((section(".highcode"))) static void ReadOnePoint() { UINT8 buf[13]; UINT8 index; UINT16 tmp; UINT32 reg_addr = 0x10274; if(ChipType == CHIP_TYPE_BERLINA) { reg_addr = 0x10338; } else if(ChipType == CHIP_TYPE_BERLIND) { reg_addr = 0x10308; } reg_addr += (ReadPointCnt<<3) + sizeof(ST_EVENT_HEAD); IICReadBytes(reg_addr, buf, 8); #ifdef STYLUS_REPORT if(buf[0]&0x80) { BT_RD_Reg(BT_GSTID_REG + (PointNum << 3) ,buf+7,6); //stylus keY StylusPress = ((UINT16)buf[6]<<8)+buf[5] ; //stylus pressure StylusFlag = TRUE; if((DeviceMode!=DEVICE_MODE_MOUSE) && (BleDeviceMode!=DEVICE_MODE_MOUSE) && (!UartReportPosEn)) { Press_Flag = (((UINT16)buf[12] & 0xFC) << 8) | 0x8000; buf[0] =9;//&= 0x7F; index = 9; } else { if(StylusPress==0) goto OUT_FUNC; ShareBuf[0] =0; index = 0; } } else #endif {//查找和上次相同Press_Flag的索引位置 for(index=0; index<10; index++) { if(((Press_Flag_Bak0 & (1L<>4)) { break; // } } if(index>=10)//没有找到配对位置,找一个空位 { for(index=0; index<10; index++) { if(((Press_Flag_Bak0 | Press_Flag ) & (1L<=10) goto OUT_FUNC; //没有空位 if((Press_Flag & 0x8000) && buf[0] == 9) //stylus Press_Flag { #ifdef STYLUS_TILT StylusTiltX = ((UINT16)buf[8]<<8)+buf[7] ; StylusTiltY = ((UINT16)buf[10]<<8)+buf[9] ; #endif } else { tmp = ((UINT16)buf[7]<<8)+buf[6]; if(tmp==0) { goto OUT_FUNC; } } #ifdef AUTO_ADJUST_SOLUTION if(bSolutionValid) { TP[index].X_pos = (UINT32)(((UINT16)buf[2]<<8)+buf[1] ) * (RESOLUTION_X-1) / wMaxX; TP[index].Y_pos = (UINT32)(((UINT16)buf[4]<<8)+buf[3] ) * (RESOLUTION_Y-1) / wMaxY; } else #else { TP[index].X_pos = ( ((UINT16)buf[3]<<8)+buf[2] ); TP[index].Y_pos = ( ((UINT16)buf[5]<<8)+buf[4] ); } #endif TP[index].X_pos_back = TP[index].X_pos; TP[index].Y_pos_back = TP[index].Y_pos; #ifdef NEW_REVOLVE_PROTOCAL if (PosConvert(TP, index) == FALSE) //超出黑边的坐标返回FALSE,裁剪掉 goto OUT_FUNC; #endif TP[ index ].Tip_Switch = 1; Press_Flag |= ((UINT16)1<>4; OUT_FUNC: ReadPointCnt++; if(ReadPointCnt >= PointNum) { tmos_set_event(IICTouchTaskId, START_REPORT_POS_EVT); } else { tmos_set_event(IICTouchTaskId, READ_ONE_POINT_EVT); } } //__attribute__((section(".highcode"))) void StartReportPos() { TouchNum = 0; for(UINT8 i=0; i