/********************************** (C) COPYRIGHT *******************************
* File Name          : IIC.c
* Author             : WCH
* Version            : V1.0
* Date               : 2018/12/12
* Description        : I2C 读写
*******************************************************************************/


/*********************************************************************
 * INCLUDES
 */
#include "include.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)

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 CheckTouchChipType();
static void CheckTouchINT(void);

#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

  static BOOL StylusFlag;
#endif

static BOOL SysInitFinish = FALSE;

//BOOL GT_Check_I2C_Address()
//{
//    BOOL bRet;
//
//    IIC_Start();
//
//    bRet = IIC_Send_Byte(GT_CMD_WR);     //发送写命令
//
//    IIC_Stop();
//
//    return bRet;
//}


static void ShutdownHIDI2C()
{
    IICWriteBytes( 0x8000, ShareBuf + 1, 1);
    ShareBuf[0]=0xAA;
    ShareBuf[1]=0;
    ShareBuf[2]=0x56;

    IICWriteBytes( 0x8041, ShareBuf + 1, 2);
    IICWriteBytes( 0x8040, ShareBuf, 1);//关闭HID-I2C功能

    IICWriteBytes( 0x824E, ShareBuf + 1, 1);
}

/*******************************************************************************
* Function Name  : GT_Init
* Description    : 触摸板初始化，获取ID，确认是否工作
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void GT_Init(void)
{
    //TouchProc = CheckTouchINT;

    //CheckPos = MAX_POINT;
    CheckTouchChipType();

    if(ChipType == CHIP_TYPE_73XX)//新版7387必须要先关掉hid才能读取版本号
    {
      delay_ms(500);
      ShutdownHIDI2C();
      delay_ms(40);
      ShutdownHIDI2C();
      delay_ms(40);
      ShutdownHIDI2C();
    }


    if(ChipType == CHIP_TYPE_9XXX || ChipType == CHIP_TYPE_9PXX)
    {
        gpio_reset_bits(GPIOA_REG, INT_PIN);
        gpio_set_out(GPIOA_REG, INT_PIN);

        delay_ms(60);//RST

        gpio_set_input(GPIOA_REG, INT_PIN);
    }


    if (IICTouchTaskId == INVALID_TASK_ID)
    {
      IICTouchTaskId = TMOS_ProcessEventRegister(IICTouch_ProcessEvent);
      tmos_set_event(IICTouchTaskId, HID_DEBUG_EVT);
    }
//
    //PRINT("enable esd check\n");
    tmos_start_task(IICTouchTaskId, CHECK_ESD_EVT, PERIO_2s );
    tmos_start_task(IICTouchTaskId, SYS_INIT_FINISH_EVT, PERIO_40s );
}


void GT_Check_ESD()
{
    UINT8 tmp;


    if(!enable_ESD_check) return;

    if (!IICReadBytes(0x8044, &tmp, 1) || tmp == 0x03)
    {
      PRINT("GT Check ESD Error!\n");
      ResetTouchChip();

      return;
    }
    else if(!IICReadBytes(0x8040,&tmp,1) || tmp == 0xAA)
    {
      PRINT("GT Check ESD Error!\n");
      ResetTouchChip(); //Rstart touch ic

      return;
    }
    else
    {
      tmp = 0xAA;
      IICWriteOneByte(0x8040,tmp);
    }

}


static void CheckTouchChipType()
{
    UINT8 i;
    UINT8 pid[8];

    for(i=0; i<10; i++)
    {
        if(IICReadBytes(0x8240, pid, 4))
        {
            if((pid[0] ==  '7'&& pid[1] ==  '3'&& pid[2] ==  '8' && pid[3] ==  '8')
            || (pid[0] ==  '7'&& pid[1] ==  '3'&& pid[2] ==  '8' && pid[3] ==  '7')
            )
            {
                ChipType = CHIP_TYPE_73XX;
                break;
            }
        }
        if(IICReadBytes(0x8140, pid, 4))
        {
           if((pid[0] ==  '9'&& pid[1] ==  '1'&& pid[2] ==  '1'))
           {
               ChipType = CHIP_TYPE_9XXX;
               break;
           }
           else if((pid[0] ==  '7'&& pid[1] ==  '2'&& pid[2] ==  '8' && pid[3] ==  '8')
                   || (pid[0] ==  '9'&& pid[1] ==  '2'&& pid[2] ==  '8' && pid[3] ==  '6')
                   )
           {
               ChipType = CHIP_TYPE_9XXX;
               break;
           }
        }
    }
    if(i==10)
    {
        PRINT("Chip type unknow\n");

        if(IsBerlinChipType(ChipType))
        {
            ChipType = CHIP_TYPE_9XXX;
        }
    }
}



static void ClearTouchFlag()
{
  UINT16 addr;

  if(ChipType == CHIP_TYPE_73XX)
  {
    addr = 0x824e;
  }
  else
  {
    addr = 0x814e;
  }
#ifdef CHIP_TYPE_GT738X
  if(!IsDebugMode)
#else
  if(!IsDebugMode)
#endif
  {
      UINT8 temp = 0;
      IICWriteBytes(addr,&temp,1);             //清标志

  }

}
void GT_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");
      GT_Check_ESD();
      events ^= CHECK_ESD_EVT;
      //PRINT("enable esd check\n");
      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(void)
{
    UINT8 point_num;

    UINT16 addr;

    if(ChipType == CHIP_TYPE_73XX)
    {
      addr = 0x824e;
    }
    else
    {
      addr = 0x814e;
    }

    IICReadBytes(addr,&point_num,1);                //读取触摸点的状态
#ifdef CHIP_TYPE_GT738X
    if((( point_num & BIT7 ) == 0 || (point_num & 0x0F)> MAX_POINT) && !ReleaseFlag)                                      /* 正常不会执行这个的,表示GT芯片是否准备好 */
#else
    if((( point_num & BIT7 ) == 0 || (point_num & 0x0F)> MAX_POINT))                                      /* 正常不会执行这个的,表示GT芯片是否准备好 */
#endif
    {
      point_num = 0;
      IICWriteBytes(addr,&point_num,1);              //清标志,如果延迟较长可以去掉
      return;
    }
#ifdef MOUSE_REPORT
    StylusFlag = FALSE;
#endif
    NoTouchTimer = 0;

    PointNum = point_num & 0x0F;

    ReadPointCnt = 0;

    OutRangeFlag = 0xFFFF;

    Press_Flag = 0;


//    if(PointNum==0)
//    {
//      StartReportPos();
//    }
//    else
//    {
//      ReadOnePoint();
//    }
    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;
    //UINT8 tmp8;
  UINT16 reg_addr = GT_POINT_BASE_ADDR + ReadPointCnt * 8;

  if(ChipType == CHIP_TYPE_73XX)
  {
    reg_addr = 0x824F + ReadPointCnt * 8;
  }
  else
  {
    reg_addr = 0x814F + ReadPointCnt * 8;
  }


  IICReadBytes( reg_addr, buf, 7 );

#ifdef STYLUS_REPORT
    if(buf[0]&0x80)
    {
      GT_RD_Reg(GT_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) && (!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<<index))!= 0) && TP[ index ].Contact_Identifier == buf[0])
        {
          break; //
        }
      }

      if(index>=10)//没有找到配对位置，找一个空位
      {
        for(index=0; index<10; index++)
        {
          if(((Press_Flag_Bak0 | Press_Flag ) & (1L<<index)) == 0)
          {
            break; //
          }
        }
      }
    }

    if(index>=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[6]<<8)+buf[5];
      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[2]<<8)+buf[1] );
      TP[index].Y_pos = ( ((UINT16)buf[4]<<8)+buf[3] );
    }
  #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<<index);

    TP[ index ].Contact_Identifier = buf[0];


OUT_FUNC:
    ReadPointCnt++;

    if(ReadPointCnt >= PointNum)
    {
      tmos_set_event(IICTouchTaskId, START_REPORT_POS_EVT);
        //StartReportPos();

    }
    else
    {
        //ReadOnePoint();
      tmos_set_event(IICTouchTaskId, READ_ONE_POINT_EVT);
    }
}
__attribute__((section(".highcode")))
void StartReportPos()
{
  TouchNum = 0;
  for(UINT8 i=0; i<MAX_POINT; i++)
  {
    if((Press_Flag & (((UINT16)1)<<i)) == 0)
    {
      TP[i].Tip_Switch = 0;
    }
    else
    {
      TouchNum++;
    }
  }

#ifdef DOUBLECLIK_FILETER
  if(TouchNum <= 1)  //&& (DeviceMode == DEVICE_MODE_MOUSE))
  {
    DoubleClickFilter(StylusFlag, 0);
  }
  else
  {
    DoubleClickTimer = 100;
  }
#endif
  Press_Flag &= OutRangeFlag;
  Press_Flag_Bak0 = Press_Flag;
  Press_Flag |= Press_Flag_Bak1|Press_Flag_Bak2;//|Press_Flag_Bak3;

#ifdef CALL_OSD_MENU
  CallOSDMenu();    //双指在右下角下滑，串口上报命令调用OSD菜单
#endif
#ifdef GESTURE
  if ( DeviceMode == DEVICE_MODE_MOUSE )
  {
    WheelMove();

    if (TwoPointsClick() == 1)
    {
      bclickFlag = 1;
    }
  }
#endif

  ReportPos();
}


//__attribute__((section(".highcode")))
static void ReportPos()
{
  //static UINT8 nUSBFailedTimes = 0;
  ReportPosSuccess = TRUE;

  if (UsbReportPosEn || bTransmitEn)
  {
    if (bTransmitEn && !UsbReportPosEn)
    {
    #ifdef UART_ENABLE
      UartUpdatePos( &TP[0]);
    #endif

      Absolute_Up_Pack(TP);
    }
    else if(((DeviceMode == DEVICE_MODE_MULTITOUCH) && (config.report_type != EN_MOUSE_ONLY)) || (config.report_type == EN_MULTITOUCH_ONLY))
    {
      Absolute_Up_Pack(TP);
    }
  #ifdef MOUSE_REPORT
    else if(config.report_type != EN_MULTITOUCH_ONLY)
    {
      ReportMousePos(TP);
    }
  #endif

  }
#ifdef UART_ENABLE
  //else if(UartReportPosEn)
  //{
  //  UartUpdatePos( &TP[0]);
  //}
#endif

  if(ReportPosSuccess)// || (EnumOK==FALSE && IsBLEConnected()==FALSE))
  {
    ClearTouchFlag();

    Press_Flag_Bak3 = Press_Flag_Bak2;
    Press_Flag_Bak2 = Press_Flag_Bak1;
    Press_Flag_Bak1 = Press_Flag_Bak0;

    //tmos_stop_task( IICTouchTaskId, REPORT_AGAIN_EVT );

    tmos_start_task(IICTouchTaskId, CHECK_USB_STATUS_EVT, PERIO_1s ); //1s后开启USB检测
  }
  else
  {
    //tmos_set_event(IICTouchTaskId, REPORT_AGAIN_EVT);
    //tmos_start_task(IICTouchTaskId, REPORT_AGAIN_EVT,3);
    //GPIOA_InverseBits(GPIO_Pin_2);
  }
}

/*********************************************************************
*********************************************************************/
