/********************************** (C) COPYRIGHT *******************************
* File Name          : JD9366.c
* Author             : Wngcool
* Version            : V1.0
* Date               : 2025/11/24
* Description        : 对JD9366(incell)的操作
*******************************************************************************/


/*********************************************************************
 * 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 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 UINT8 ReadPointIndexCnt = 0;
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
#endif

static UINT32 lJDRegAddr;
static BOOL SysInitFinish = FALSE;
extern BOOL SleepEn;
/*******************************************************************************
* Function Name  : JD_WR_Reg
* Description    : 向GT911写入一次数据
* Input          : reg:起始寄存器地址
                   buf:数据缓缓存区
                   len:写数据长度
* Output         : None
* Return         : 0,成功;1,失败.
*******************************************************************************/
__attribute__((section(".highcode")))
UINT8 JD_WR_Reg(UINT32 reg,UINT8 *buf,UINT8 len)
{
    return IICWriteBytes(reg,buf,len);
}

///*******************************************************************************
//* Function Name  : JD_RD_Reg
//* Description    : 从GT911读出一次数据
//* Input          : reg:起始寄存器地址
//                   buf:数据缓缓存区
//                   len:读数据长度
//* Output         : None
//* Return         : None
//*******************************************************************************/
//__attribute__((section(".highcode")))
UINT8 JD_RD_Reg(UINT32 reg, UINT8 *buf,UINT8 len)
{
    return IICReadBytes(reg, buf, len);
}

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

    CheckPos = MAX_POINT;

    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;
  }

}
*/
void JD_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) //松键
      {
        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;

      CheckUsbStatus();

      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()
{
  lJDRegAddr = 0x20021120;

  PointNum = IICReadOneByte(lJDRegAddr);  //read point number

  TouchNum = 0;

  if(PointNum > MAX_POINT)   PointNum = MAX_POINT;

    NoTouchTimer = 0;

    ReadPointCnt = 0;
    ReadPointIndexCnt = 0;

    OutRangeFlag = 0xFFFF;

    Press_Flag = 0;

    if(PointNum==0)
    {
      tmos_set_event(IICTouchTaskId, START_REPORT_POS_EVT);
    }
    else
    {
      lJDRegAddr += 3;
      tmos_set_event(IICTouchTaskId, READ_ONE_POINT_EVT);
    }
}

//__attribute__((section(".highcode")))
static void ReadOnePoint()
{
    UINT8 buf[5];
    UINT8 Contact_Identifier;
    UINT8 index = 0;
    UINT16 tmp;

    IICReadBytes(lJDRegAddr, buf, 5);

    lJDRegAddr += 5;

    ReadPointIndexCnt++;

    if (buf[4])  //coor weight
    {
        Contact_Identifier = ReadPointIndexCnt;
    }
    else
    {
        if(ReadPointCnt < PointNum)
          tmos_set_event(IICTouchTaskId, READ_ONE_POINT_EVT);
        else
          tmos_set_event(IICTouchTaskId, START_REPORT_POS_EVT);

        return;
    }


    //查找和上次相同Press_Flag的索引位置
    for (index = 0; index < 10; index++)
    {
        if(((Press_Flag_Bak0 & (1L<<index))!= 0) && TP[ index ].Contact_Identifier == Contact_Identifier)
        {
          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; //没有空位

    tmp = buf[4];
    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[0]<<8)+buf[1] );
      TP[index].Y_pos = ( ((UINT16)buf[2]<<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 = Contact_Identifier;


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 < 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(0, 0);
  }
  else
  {
    DoubleClickTimer = 100;
  }
#endif

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

#ifdef GESTURE
  if ( DeviceMode == DEVICE_MODE_MOUSE || BleDeviceMode == DEVICE_MODE_MOUSE)
  {
    WheelMove();

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

  Press_Flag &= OutRangeFlag;

  for(UINT8 i = 0; i < MAX_POINT; i++)
  {
    if((Press_Flag & (((UINT16)1)<<i)) == 0)
    {
      TP[i].Tip_Switch = 0;
    }
  }

  Press_Flag_Bak0 = Press_Flag;
  Press_Flag |= Press_Flag_Bak1|Press_Flag_Bak2;//|Press_Flag_Bak3;

  ReportPos();
}


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

  if(UsbReportPosEn || BleReportPosEn)
  {
    if(((DeviceMode == DEVICE_MODE_MULTITOUCH) && (config.report_type != EN_MOUSE_ONLY)) || (config.report_type == EN_MULTITOUCH_ONLY))
    {
      Absolute_Up_Pack(TP);
    }
    else if(config.report_type != EN_MULTITOUCH_ONLY)
    {
      ReportMousePos(TP);
    }
  }
#ifdef UART_ENABLE
  else if(UartReportPosEn)
  {
    UartUpdatePos( &TP[0]);
  }
#endif

    //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 );

}

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