/*
 * TouchCommon.c
 *
 *  Created on: Nov 10, 2021
 *      Author: Administrator
 */
 #include "include.h"
#include "TouchCommon.h"
#include "TouchConfig.h"
#include "pipe.h"
#include "iic.h"
#include "Gesture.h"
#include "GoodixTouch.h"
#include "BerlinTouch.h"
#include "JDTouch.h"
#include "HidReport.h"
#include "tmos.h"
#include "driver_gpio.h"

#define CHECK_TOUCH_INT_EVT                   0x0001
#define USB_HID_DEBUG_EVT                     0x0002
#define RESET_TOUCH_CHIP_EVT                  0x0004
#define CHECK_USB_CONNECT_EVT                 0x0008
#define ENABLE_UART_EVT                       0x0010
#define ENABLE_USB_EVT                        0x0020
#define TIMER_40MS_EVT                        0x0040

static UINT16 Touch_ProcessEvent( UINT8 task_id, UINT16 events );
static UINT8 TaskID = INVALID_TASK_ID;


UINT8 GT_CMD_WR;
UINT8 GT_CMD_RD;
POINTER TP[ 10 ];                          /* �������֧�ֵĶ��� */
UINT8 TouchNumber;
UINT16 StylusPress;
CHIP_TYPE ChipType;
BOOL isBerlinSeries = FALSE;
BOOL bIsJDSeries = TRUE;
BOOL enable_INT_irq;
BOOL enable_ESD_check;
UINT8 HearBeatCheckTimer;
UINT16 OutRangeFlag;
BOOL GioInterruptFlag;
UINT8 ShareBuf[10];
UINT8 NoTouchTimer = 0;
UINT8 DeviceMode  = DEVICE_MODE_MOUSE;
UINT8 BleDeviceMode  = DEVICE_MODE_MULTITOUCH;
UINT16 Press_Flag,Press_Flag_Bak0, Press_Flag_Bak1, Press_Flag_Bak2,Press_Flag_Bak3;
UINT8 Uart1IdleTime = 0;
BOOL BleReportFirst = FALSE;
BOOL ReleaseFlag = 0;

void (*TouchProc)(void);

BOOL UsbReportPosEn = FALSE;
BOOL UartReportPosEn = TRUE;
BOOL BleReportPosEn = FALSE;

#ifdef UART_ENABLE
UINT8 TxBuff[16];
UINT8 RxBuff[10];
#ifdef NEW_REVOLVE_PROTOCAL
BOOL UartRevolveEnable = TRUE;
#endif
#endif

#ifdef NEW_REVOLVE_PROTOCAL
  static UART_STATE uart_state = UART_STATE_IDLE;
  UINT8 UartCmdBuf[sizeof(UART_LONG_CMD)]__attribute__((aligned(4))) = {0} ;
  UART_CMD_BUF TpOption __attribute__((aligned(4))) = {UART_COMMAND_A_0};
#endif

#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


#ifdef STYLUS_TILT
UINT16 StylusTiltX, StylusTiltY;
#endif

BOOL IsBerlinSeries(void)
{
//    UINT8 i,cnt=0;

//    gpio_init_typedef gpio_init_structure;
//
//    gpio_init_structure.gpio_dir = GPIO_DIR_INPUT;
//    gpio_init_structure.gpio_fen = GPIO_FEN_GPIO;
//    gpio_init_structure.gpio_fdir = GPIO_FDIR_SELF;
//    gpio_init_structure.gpio_mode = GPIO_MODE_DIGITAL;
//    gpio_init_structure.gpio_pupd = GPIO_PUPD_PU10K;
//    gpio_init_structure.gpio_drv = GPIO_DRV_6MA;
//
//    gpio_init_structure.gpio_pin = RST_PIN;
//    gpio_init(GPIOA_REG, &gpio_init_structure);
//    gpio_reset_bits(GPIOA_REG, RST_PIN);


//    delay_ms(2);
//
//    for(i=0; i<20; i++)
//    {
//        if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_4))
//        {
//            cnt++;
//        }
//        Delay_Us(100);
//    }
//
//    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
//    GPIO_Init( GPIOB, &GPIO_InitStructure );
//
//    if(cnt > 10)
//    {
//        return FALSE;
//    }
//    else
//    {
//        return TRUE;
//    }
    return  FALSE;
}


void IICTouchInit()
{
  if (bTransmitEn == FALSE)
    return;

  TaskID = TMOS_ProcessEventRegister(Touch_ProcessEvent);

  GioInterruptFlag = FALSE;

  ResetTouchChip();

  if(ChipType!=GetChipTypeFromFlash())
  {
      SaveChipTypeToFlash(ChipType);
      SoftResetChip();
      PRINT("RESET CHIP\n");
  }
#ifdef NEW_REVOLVE_PROTOCAL
    TpOption.uart_long_cmd.ax = 0;
    TpOption.uart_long_cmd.ay = 0;

    TpOption.uart_long_cmd.dx = RESOLUTION_X;
    TpOption.uart_long_cmd.dy = RESOLUTION_Y;
#endif
    //tmos_set_event(TaskID, USB_HID_DEBUG_EVT);
    tmos_start_task(TaskID, TIMER_40MS_EVT, 40);
}

static UINT16 Touch_ProcessEvent( UINT8 task_id, UINT16 events )
{
    if(events & CHECK_TOUCH_INT_EVT)
    {
      CheckTouchInt();
      events ^= CHECK_TOUCH_INT_EVT;
      tmos_start_task(task_id, CHECK_TOUCH_INT_EVT, 1);
      goto OUT_FUMC;
    }
    if(events & ENABLE_USB_EVT)
    {
       events ^= ENABLE_USB_EVT;
       if(Press_Flag_Bak2==0)
       {
           UartReportPosEn = DISABLE;
           UsbReportPosEn = ENABLE;
           tmos_stop_task(task_id, ENABLE_USB_EVT);

           goto OUT_FUMC;
       }
       else
       {
           tmos_start_task(task_id, ENABLE_USB_EVT, 10 );

           goto OUT_FUMC;
       }
    }
    if(events & ENABLE_UART_EVT)
    {
        events ^= ENABLE_UART_EVT;
        if(Press_Flag_Bak2==0)
        {
            UartReportPosEn = ENABLE;
            UsbReportPosEn = DISABLE;
            tmos_stop_task(task_id, ENABLE_UART_EVT);
            goto OUT_FUMC;
        }
        else
        {
            tmos_start_task(task_id, ENABLE_UART_EVT, 10 );

            goto OUT_FUMC;
        }

    }
    if(events & USB_HID_DEBUG_EVT)
    {
      CommandHandle();
      events ^= USB_HID_DEBUG_EVT;
      tmos_set_event(task_id, USB_HID_DEBUG_EVT);
      goto OUT_FUMC;
    }
    if(events & RESET_TOUCH_CHIP_EVT)
    {
      ResetTouchChip();
      events ^= RESET_TOUCH_CHIP_EVT;
      //tmos_set_event(task_id, RESET_TOUCH_CHIP_EVT);
      goto OUT_FUMC;
    }
    if(events & TIMER_40MS_EVT)
    {
      #ifdef DOUBLECLIK_FILETER
        DoubleClickTimer++;
        if(DoubleClickTimer > 100) DoubleClickTimer = 100; //4s
      #endif

      #ifdef MOUSE_REPORT
        #ifndef GESTURE
          if(++mouse_right_click_time > 20) mouse_right_click_time = 20;
        #endif
      #endif
       tmos_start_task(TaskID, TIMER_40MS_EVT, 40);
      events ^= TIMER_40MS_EVT;
      goto OUT_FUMC;
    }

    return 0;

OUT_FUMC:

    return  events;
}
char info[] = "io_isr\n";
AT(.com_text.gpio_isr)
void gpio_isr_callback(void)
{
    gpio_edge_pending_clear();
    GioInterruptFlag = TRUE;
    printf(info);
}

void io_interrupt_init(void)
{
    gpio_edge_cap_typedef config;

    config.edge = GPIO_EDGE_FALLING;
    config.gpiox = GPIOA_REG;
    config.gpio_pin = INT_PIN;

    gpio_edge_capture_config(&config);

    gpio_edge_pic_config(gpio_isr_callback, 0);
}


void ResetTouchChip()
{
    gpio_init_typedef gpio_init_structure;

    gpio_init_structure.gpio_dir = GPIO_DIR_OUTPUT;
    gpio_init_structure.gpio_fen = GPIO_FEN_GPIO;
    gpio_init_structure.gpio_fdir = GPIO_FDIR_SELF;
    gpio_init_structure.gpio_mode = GPIO_MODE_DIGITAL;
    gpio_init_structure.gpio_pupd = GPIO_PUPD_PU10K;
    gpio_init_structure.gpio_drv = GPIO_DRV_6MA;

    gpio_init_structure.gpio_pin = RST_PIN;
    gpio_init(GPIOA_REG, &gpio_init_structure);
    gpio_reset_bits(GPIOA_REG, RST_PIN);

    delay_ms(5);//RST

    gpio_init_structure.gpio_dir = GPIO_DIR_INPUT;
    gpio_init_structure.gpio_pin = INT_PIN;
    gpio_init(GPIOA_REG, &gpio_init_structure);
    gpio_set_bits(GPIOA_REG, INT_PIN);
    delay_ms(80);
    gpio_set_bits(GPIOA_REG, RST_PIN);

    enable_INT_irq = FALSE;
    enable_ESD_check = FALSE;
    tmos_stop_task(TaskID, CHECK_TOUCH_INT_EVT);

    SearchAddress(100);

    PRINT("JD series\n");
    JD_Init();
    /*
    if(isBerlinSeries)
    {
        PRINT("Berlin series\n");

        BT_Init();
    }
    else
    {
        PRINT("GT9XXX series\n");

        GT_Init();
    }
    */
    io_interrupt_init();

    tmos_start_task(TaskID, CHECK_TOUCH_INT_EVT, 2 );

    enable_INT_irq = TRUE;
    enable_ESD_check = TRUE;
    PRINT("Reset touch chip\n");
}

BOOL SearchAddress( UINT8 num )
{
  while(num--)
  {
    GT_CMD_WR = 0xD0;
    GT_CMD_RD = 0xD1;
    if(GT_Check_I2C_Address(GT_CMD_WR))
    {
        return 1;
    }
  }
  return 0;
}

static void SetTouchEvent()
{
  JD_SetTouchEvent();
  //PRINT("have touch\n");
}

void CheckTouchInt()
{
    if( (GioInterruptFlag) && (!DisableDigiterInterface))
    {
        if(enable_INT_irq)
        {
          //if(!IsUsbBusy())
          {
            SetTouchEvent();
          }
        }

        GioInterruptFlag = FALSE;

        return;
    }
}

#ifdef UART_ENABLE
void USART2_SendData(PUINT8 txbuf, UINT16 length)
{
    UINT8 TxCnt = 0;

    while(TxCnt < length)
    {
        //PRINT("TxCnt:%d\r\n", TxCnt);
        //USART_SendData(USART2, txbuf[TxCnt++]);
        //while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET)
        {
            /* waiting for sending finish */
        }
    //        while(USART_GetFlagStatus(USART2, USART_FLAG_RXNE) == RESET)
    //        {
    //            /* waiting for receiving finish */
    //        }
    //        RxBuffer[RxCnt++] = (USART_ReceiveData(USART2));

        //PRINT("TxCnt:%d\r\n", TxCnt);
    }
}
//__attribute__((section(".highcode")))
void UartUpdatePos(POINTER * pTP)
{
#ifdef SELF_UART_PROTOCOL
  UINT8 t,i;
  UINT8 bParity = 0x56;
  UINT16 x,y;

  Press_Flag = Press_Flag_Bak0 | Press_Flag_Bak1;

  for(i = 0; i < MAX_POINT; i++)
  {
    if(Press_Flag & (1L << i))
    {
      break;
    }
  }
  if(i==MAX_POINT)
  {
    return;
  }

  t = i << 3;

  if(pTP[i].Tip_Switch == 0)
  {
    t |= 0x04;
  }
  else
  {
    if(Press_Flag_Bak1==0)
    {
      t |= 0x01;
    }
    else
    {
      t |= 0x02;
    }
  }

  x = pTP[i].X_pos_back;
  y = pTP[i].Y_pos_back;

  bParity += t;

  bParity+= (UINT8)x;
  bParity+= (UINT8)(x>>8);
  bParity+= (UINT8)y;
  bParity+= (UINT8)(y>>8);

  TxBuff[0] = 0x55;
  TxBuff[1] = 0x56;
  TxBuff[2] = t;
  TxBuff[3] = x&0xFF;
  TxBuff[4] = x>>8;
  TxBuff[5] = y&0xFF;
  TxBuff[6] = y>>8;
  TxBuff[7] = 0xFF;
  TxBuff[8] = 0x00;
  TxBuff[9] = bParity;

  USART2_SendData( TxBuff, 10 );
#else
  UINT8 t,i;
  UINT8 bParity = 0x52;
  UINT16 x,y;

  Press_Flag = Press_Flag_Bak0 | Press_Flag_Bak1;

  for(i = 0; i < MAX_POINT; i++)
  {
    if(Press_Flag & (1L << i))
    {
      break;
    }
  }
  if(i==MAX_POINT)
  {
    return;
  }

  if(pTP[i].Tip_Switch == 0)
  {
    t = 0x84;
  }
  else
  {
    if(Press_Flag_Bak1==0)
    {
      t = 0x81;
    }
    else
    {
      t = 0x82;
    }
  }


    x = (UINT32)pTP[i].X_pos * 4095 / 16383;
    y = (UINT32)pTP[i].Y_pos * 4095 / 9599;
//    x = (UINT32)UartPosX * 4095 / 16383;
//    y = (UINT32)UartPosY * 4095 / 9599;


  bParity += t;

  bParity+= (UINT8)x;
  bParity+= (UINT8)(x>>8);
  bParity+= (UINT8)y;
  bParity+= (UINT8)(y>>8);

  if (config.uart_protocol==EN_UART_PROTOCAL_10)
  {
    TxBuff[0] = 0x55;
    TxBuff[1] = 0x54;
    TxBuff[2] = t;
    TxBuff[3] = x&0xFF;
    TxBuff[4] = x>>8;
    TxBuff[5] = y&0xFF;
    TxBuff[6] = y>>8;
    TxBuff[7] = 0xFF;
    TxBuff[8] = 0x00;
    TxBuff[9] = bParity;

    if(bTransmitEn && !UsbReportPosEn)
    {
      //DevEp1In(EP1_BUFF_SIZE);

      //RF_Enqueue(1, RF_PACKAGE_REPORT, 9, Ep1Buffer);
      //PRINT("Mouse\n");

      //memcpy(USBFS_EP1_Buf, TxBuff, 10);
      //RF_Enqueue(1, RF_PACKAGE_REPORT, 10, Ep1UartBuffer);
      //memcpy(Ep1UartBuffer, TxBuff, 10);

    }
    else
    {
      USART2_SendData(TxBuff, 10);
    }


  }
  else
  {
    TxBuff[0] = 0xAA;
    TxBuff[1] = 0x55;
    TxBuff[2] = x&0xFF;
    TxBuff[3] = x>>8;
    TxBuff[4] = y&0xFF;
    TxBuff[5] = y>>8;
    TxBuff[6] = t;
    TxBuff[7] = bParity-0x53;

    if(bTransmitEn && !UsbReportPosEn)
    {
      //DevEp1In(EP1_BUFF_SIZE);

      //RF_Enqueue(1, RF_PACKAGE_REPORT, 9, Ep1Buffer);
      //PRINT("Mouse\n");

      //memcpy(USBFS_EP1_Buf, TxBuff, 10);
      //RF_Enqueue(1, RF_PACKAGE_REPORT, 10, Ep1UartBuffer);
      //memcpy(Ep1UartBuffer, TxBuff, 10);

    }
    else
    {
      USART2_SendData(TxBuff, 8);
    }
  }

#endif
}


#ifdef NEW_REVOLVE_PROTOCAL

BOOL PosConvert(POINTER* TP, UINT8 index)
{
    INT16 tmpX ,tmpY;

    tmpX = TP[index].X_pos;
    tmpY = TP[index].Y_pos;
    //�����ڱߵ�����ü���

    switch(TpOption.uart_cmd)
    {
      case UART_COMMAND_A_0:
        tmpX = (INT32)((INT16)TP[index].X_pos - TpOption.uart_long_cmd.ax) * RESOLUTION_X / (TpOption.uart_long_cmd.dx-TpOption.uart_long_cmd.ax);
        tmpY = (INT32)((INT16)TP[index].Y_pos - TpOption.uart_long_cmd.ay) * RESOLUTION_Y / (TpOption.uart_long_cmd.dy-TpOption.uart_long_cmd.ay);
        break;

      case UART_COMMAND_B_0:
        if(UsbReportPosEn)  //�ü�USB�����꣬OSD�˵�����������ʾ���������겻��
        {

          tmpX = (INT32)((INT16)TP[index].X_pos - TpOption.uart_long_cmd.ax) * RESOLUTION_X / (TpOption.uart_long_cmd.dx-TpOption.uart_long_cmd.ax);
          tmpY = (INT32)((INT16)TP[index].Y_pos - TpOption.uart_long_cmd.ay) * RESOLUTION_Y / (TpOption.uart_long_cmd.dy-TpOption.uart_long_cmd.ay);
        }
        break;

      case UART_COMMAND_A_90:
      case UART_COMMAND_B_90:
      {
        tmpX  = TpOption.uart_long_cmd.ax  + (((INT32)((INT16)TpOption.uart_long_cmd.Ay - TP[index].Y_pos)*TpOption.uart_long_cmd.mx)>>10);
        tmpY  = TpOption.uart_long_cmd.ay  + (((INT32)((INT16)TP[index].X_pos - TpOption.uart_long_cmd.Ax)*TpOption.uart_long_cmd.my)>>10);
      }
      case UART_SWITCH_90:
      {
        if(UartRevolveEnable)
        {
          TP[index].X_pos_back  = RESOLUTION_X - (UINT32)TP[index].Y_pos * RESOLUTION_X / RESOLUTION_Y;
          TP[index].Y_pos_back   = (UINT32)TP[index].X_pos * RESOLUTION_Y / RESOLUTION_X;
        }
        break;
      }

      case UART_COMMAND_A_180:
      case UART_COMMAND_B_180:
      {
        tmpX  = (INT16)RESOLUTION_X - (INT32)((INT16)TP[index].X_pos - (INT16)TpOption.uart_long_cmd.ax) * RESOLUTION_X / (TpOption.uart_long_cmd.dx-TpOption.uart_long_cmd.ax);
        tmpY  = (INT16)RESOLUTION_Y - (INT32)((INT16)TP[index].Y_pos - (INT16)TpOption.uart_long_cmd.ay) * RESOLUTION_Y / (TpOption.uart_long_cmd.dy-TpOption.uart_long_cmd.ay);
      }
      case UART_SWITCH_180:
      {
        if(UartRevolveEnable)
        {
          TP[index].X_pos_back  = RESOLUTION_X - TP[index].X_pos;
          TP[index].Y_pos_back   = RESOLUTION_Y - TP[index].Y_pos;
        }
        break;
      }

      case UART_COMMAND_A_270:
      case UART_COMMAND_B_270:
      {
        tmpX  = (INT16)TpOption.uart_long_cmd.ax  + (((INT32)((INT16)TP[index].Y_pos - (INT16)TpOption.uart_long_cmd.Ay)*TpOption.uart_long_cmd.mx)>>10);
        tmpY  = (INT16)TpOption.uart_long_cmd.ay  + (((INT32)((INT16)TpOption.uart_long_cmd.Ax - (INT16)TP[index].X_pos)*TpOption.uart_long_cmd.my)>>10);
      }
      case UART_SWITCH_270:
      {
        if(UartRevolveEnable)
        {
          TP[index].X_pos_back  = (UINT32)TP[index].Y_pos * RESOLUTION_X / RESOLUTION_Y;
          TP[index].Y_pos_back  = RESOLUTION_Y - (UINT32)TP[index].X_pos * RESOLUTION_Y / RESOLUTION_X;
        }
        break;
      }
      default:
        break;
    }


    if(TpOption.uart_cmd == UART_COMMAND_A_0
        || TpOption.uart_cmd == UART_COMMAND_A_90
        || TpOption.uart_cmd == UART_COMMAND_A_180
        || TpOption.uart_cmd == UART_COMMAND_A_270
        )
    {
      if(tmpX >= (INT16)TpOption.uart_long_cmd.dx)
      {
        tmpX = TpOption.uart_long_cmd.dx-1;
      }
      if(tmpY >= (INT16)TpOption.uart_long_cmd.dy)
      {
        tmpY = TpOption.uart_long_cmd.dy-1;
      }
      if(tmpX < (INT16)TpOption.uart_long_cmd.ax)
      {
        tmpX = TpOption.uart_long_cmd.ax;
      }
      if(tmpY < (INT16)TpOption.uart_long_cmd.ay)
      {
        tmpY = TpOption.uart_long_cmd.ay;
      }
    }
    else {
      if(tmpX < 0)
      {
        tmpX = 0;
        OutRangeFlag &= ~(1L<<index);
      }
      if(tmpX >= RESOLUTION_X)
      {
        tmpX = RESOLUTION_X;
        OutRangeFlag &= ~(1L<<index);
      }
      if(tmpY < 0)
      {
        tmpY = 0;
        OutRangeFlag &= ~(1L<<index);
      }
      if(tmpY >= RESOLUTION_Y)
      {
        tmpY = RESOLUTION_Y;
        OutRangeFlag &= ~(1L<<index);
      }
    }

    TP[index].X_pos = tmpX;
    TP[index].Y_pos = tmpY;

    return TRUE;
}


extern BOOL IsBLEConnected(void);
void CheckUart0Comand( void )
{
  static UINT8 offset = 0;
  static UINT8 cmd_len = 0;

  UINT8 d;
  //OPERATE_SYSTEM os;
  UINT8* pBuf = &UartCmdBuf[1];
#if 0
  while( R8_UART0_RFC )
  {
    d = R8_UART0_RBR;

    if(uart_state == UART_STATE_IDLE)
    {
      switch(d)
      {
        case UART_COMMAND_B_180:
        case UART_COMMAND_B_0:
          cmd_len = 14;
          uart_state = UART_STATE_RECV_CMD;
          break;
        case UART_COMMAND_B_90:
        case UART_COMMAND_B_270:
        case UART_COMMAND_A_90:
        case UART_COMMAND_A_270:
          cmd_len = sizeof(UART_LONG_CMD) - 2;
          uart_state = UART_STATE_RECV_CMD;
          break;
        default:
          cmd_len = 2;
          uart_state = UART_STATE_RECV_CMD;
          break;
      }
      offset = 0;
    }

    if(uart_state==UART_STATE_RECV_CMD)
    {
      if(offset <  cmd_len)
      {
        pBuf[offset] = d;
        offset++;
        if(offset>=cmd_len)
        {
          UINT8 chksum = 0;
          do
          {
            chksum += pBuf[--offset];
          }while(offset);

          if(chksum==0)
          {
            uart_state = UART_STATE_CHECK_CMD;
          }
          else
          {
            uart_state = UART_STATE_IDLE;
          }
        }
      }
    }
  }
#else

    while(USART_GetFlagStatus(USART2, USART_FLAG_RXNE) != RESET)
    {
      pipe_write_c(&uart_cmd_pipe, (UINT8)USART2->DATAR);

    }

//      while(pipe_read(&uart_cmd_pipe, &d, 1))
//    {
//           USART2_SendData(&d, 1);
//    }

    if(uart_state != UART_STATE_CHECK_CMD)
    {
      while(pipe_read(&uart_cmd_pipe, &d, 1))
      {
      if(uart_state==UART_STATE_IDLE)
      {
         switch(d)
        {
          case UART_COMMAND_B_180:
          case UART_COMMAND_B_0:
            cmd_len = 14;
            uart_state = UART_STATE_RECV_CMD;
            break;
          case UART_COMMAND_B_90:
          case UART_COMMAND_B_270:
          case UART_COMMAND_A_90:
          case UART_COMMAND_A_270:
            cmd_len = sizeof(UART_LONG_CMD) - 2;
            uart_state = UART_STATE_RECV_CMD;
            break;
          default:
            cmd_len = 1;
            uart_state = UART_STATE_RECV_CMD;
            break;
        }

        offset = 0;
      }
      if(uart_state==UART_STATE_RECV_CMD)
      {

        if(offset <  cmd_len)
        {
          pBuf[offset] = d;
          offset++;
          if(offset>=cmd_len)
          {
            uart_state = UART_STATE_CHECK_CMD;
            break;
          }
        }
      }
    }
  }
#endif

  if(uart_state == UART_STATE_CHECK_CMD)
  {

    {
      switch(pBuf[0])
      {
        case EN_UART_DIS_USB:
        {
//          if( NoTouchTimer > 1)
//          {
//            UsbReportPosEn = DISABLE;
//            UartReportPosEn = ENABLE;
//          }
//          else
//          {
//            return;
//          }
          tmos_start_task(TaskID, ENABLE_UART_EVT, 10);
          break;
        }
        case EN_USB_DIS_UART:
        case EN_USB_EN_UART:
//          if(NoTouchTimer==0)
//          {
////            TP[0].Tip_Switch = 0;
////            UartUpdatePos(&TP[0]);
//            UartReportPosEn = DISABLE;
//            return;
//          }
//          {
//            UartReportPosEn = DISABLE;
//            UsbReportPosEn = ENABLE;
//          }
          tmos_start_task(TaskID, ENABLE_USB_EVT, 10);
          break;
//        case EN_USB_EN_UART:
//          UsbReportPosEn = ENABLE;
//          UartReportPosEn = ENABLE;
//          break;
//        case GET_DEVICE_NAME:
//        {
//            USART2_SendData((PUINT8)DeviceName,strlen(DeviceName)+1);
//          break;
//        }
//        case GET_BLE_CONNECT_STATE:
//        {
//          if(IsBLEConnected())
//          {
////            os = GetOperateSystem();
////            if(os != IOS)
////            {
//              d = 1;
////            }
////            else
////            {
////              d = 2;
////            }
//             USART2_SendData(&d, 1);
//          }
//          else
//          {
//            d = 0;
//            USART2_SendData(&d, 1);
//          }
//          break;
//        }

//        case ERASE_ALL_BONDS:
//        {
//          HidDev_SetParameter(HIDDEV_ERASE_ALLBONDS,0,0);
//          break;
//        }
//        case DISCONNECT_BLE:
//        {
//          if(IsBLEConnected())
//          {
//             GAPBondMgr_SetParameter(GAPBOND_DISABLE_SINGLEBOND, sizeof(UINT8)*7, (UINT8*)HostAddr);
//             GAPRole_TerminateLink( gapConnHandle );
//          }
//          //UINT8 adv_Event_Type = GAP_ADTYPE_ADV_IND;
//          //GAPRole_SetParameter(GAPROLE_ADV_EVENT_TYPE, sizeof(UINT8), &adv_Event_Type);
//          break;
//        }
        case ENABLE_GRAB_CONNECT:
        {

          break;
        }
        case EN_BLE_APPLE_REPORT:
//          os = GetOperateSystem();
//          if(os != IOS)
//          {
//            SetOperateSystem(IOS);
////            USART2_SendData(&pBuf[0], 1);
//            R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;
//            R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;
//            R8_RST_WDOG_CTRL |= RB_SOFTWARE_RESET;
//          }
          break;
        case EN_BLE_WIN_REPORT:
//          os = GetOperateSystem();
//          if(os != ANDROID)
//          {
//            SetOperateSystem(ANDROID);
//            USART2_SendData(&pBuf[0], 1);
//            R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;
//            R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;
//            R8_RST_WDOG_CTRL |= RB_SOFTWARE_RESET;
//          }

          DeviceMode  = DEVICE_MODE_MULTITOUCH;

          break;
      #ifdef MOUSE_REPORT
        case SET_OS_TYPE_NEW_MAC:
            DeviceMode  = DEVICE_MODE_MOUSE;
          break;
        case SET_OS_TYPE_OLD_MAC:
            DeviceMode = DEVICE_MODE_MOUSE;
          break;
      #endif
        case UART_SWITCH_90:
        case UART_SWITCH_270:
        case UART_SWITCH_180:
        {
          UartRevolveEnable = 1;
          TpOption.uart_cmd = (UART_COMMAND)pBuf[0];;
          break;
        }
        case UART_SWITCH_0:
        {
          UartRevolveEnable = 0;
        }
        break;
        case UART_COMMAND_A_90:
        case UART_COMMAND_A_270:
        case UART_COMMAND_B_90:
        case UART_COMMAND_B_270:
        {
          UINT16  mx = (pBuf[9]<<8) + pBuf[10];
          UINT16  my = (pBuf[11]<<8) + pBuf[12];
          if(mx!=0 && my!=0)
          {
            TpOption.uart_cmd = (UART_COMMAND)pBuf[0];

            TpOption.uart_long_cmd.ax = ((UINT16)pBuf[1]<<8) + pBuf[2];
            TpOption.uart_long_cmd.ay = ((UINT16)pBuf[3]<<8) + pBuf[4];

            TpOption.uart_long_cmd.dx = ((UINT16)pBuf[5]<<8) + pBuf[6];
            TpOption.uart_long_cmd.dy = ((UINT16)pBuf[7]<<8) + pBuf[8];

            TpOption.uart_long_cmd.Ax = ((UINT16)pBuf[13]<<8) + pBuf[14];
            TpOption.uart_long_cmd.Ay = ((UINT16)pBuf[15]<<8) + pBuf[16];

            TpOption.uart_long_cmd.Dx = ((UINT16)pBuf[17]<<8) + pBuf[18];
            TpOption.uart_long_cmd.Dy = ((UINT16)pBuf[19]<<8) + pBuf[20];

            if(TpOption.uart_cmd == UART_COMMAND_B_90 || TpOption.uart_cmd == UART_COMMAND_B_270)
            {
              TpOption.uart_long_cmd.ax = 0;
              TpOption.uart_long_cmd.ay = 0;

              TpOption.uart_long_cmd.dx = RESOLUTION_X;
              TpOption.uart_long_cmd.dy = RESOLUTION_Y;
            }
            else
            {
              TpOption.uart_long_cmd.ax = (UINT32)TpOption.uart_long_cmd.ax*RESOLUTION_X/mx;
              TpOption.uart_long_cmd.ay = (UINT32)TpOption.uart_long_cmd.ay*RESOLUTION_Y/my;

              TpOption.uart_long_cmd.dx = (UINT32)TpOption.uart_long_cmd.dx*RESOLUTION_X/mx;
              TpOption.uart_long_cmd.dy = (UINT32)TpOption.uart_long_cmd.dy*RESOLUTION_Y/my;
            }

            TpOption.uart_long_cmd.Ax = (UINT32)TpOption.uart_long_cmd.Ax*RESOLUTION_X/mx;
            TpOption.uart_long_cmd.Ay = (UINT32)TpOption.uart_long_cmd.Ay*RESOLUTION_Y/my;

            TpOption.uart_long_cmd.Dx = (UINT32)TpOption.uart_long_cmd.Dx*RESOLUTION_X/mx;
            TpOption.uart_long_cmd.Dy = (UINT32)TpOption.uart_long_cmd.Dy*RESOLUTION_Y/my;

            if(TpOption.uart_cmd == UART_COMMAND_A_90 || TpOption.uart_cmd == UART_COMMAND_B_90)
            {
              TpOption.uart_long_cmd.mx = ((UINT32)(TpOption.uart_long_cmd.dx - TpOption.uart_long_cmd.ax) << 10) /(TpOption.uart_long_cmd.Ay - TpOption.uart_long_cmd.Dy);
              TpOption.uart_long_cmd.my = ((UINT32)(TpOption.uart_long_cmd.dy - TpOption.uart_long_cmd.ay) << 10) /(TpOption.uart_long_cmd.Dx - TpOption.uart_long_cmd.Ax);
            }
            else
            {
              TpOption.uart_long_cmd.mx = ((UINT32)(TpOption.uart_long_cmd.dx - TpOption.uart_long_cmd.ax) << 10) /(TpOption.uart_long_cmd.Dy - TpOption.uart_long_cmd.Ay);
              TpOption.uart_long_cmd.my = ((UINT32)(TpOption.uart_long_cmd.dy - TpOption.uart_long_cmd.ay) << 10) /(TpOption.uart_long_cmd.Ax - TpOption.uart_long_cmd.Dx);
            }
          }

          break;
        }
        case UART_COMMAND_A_0:
        case UART_COMMAND_A_180:
        case UART_COMMAND_B_0:
        case UART_COMMAND_B_180:
        {
            TpOption.uart_cmd = (UART_COMMAND)pBuf[0];

            if(TpOption.uart_cmd == UART_COMMAND_B_0 || TpOption.uart_cmd == UART_COMMAND_B_180)
            {
              UINT16  mx = (pBuf[9]<<8) + pBuf[10];
              UINT16  my = (pBuf[11]<<8) + pBuf[12];
              if(mx!=0 && my!=0)
              {
                TpOption.uart_long_cmd.ax = ((UINT16)pBuf[1]<<8) + pBuf[2];
                TpOption.uart_long_cmd.ay = ((UINT16)pBuf[3]<<8) + pBuf[4];

                TpOption.uart_long_cmd.dx = ((UINT16)pBuf[5]<<8) + pBuf[6];
                TpOption.uart_long_cmd.dy = ((UINT16)pBuf[7]<<8) + pBuf[8];

                TpOption.uart_long_cmd.ax = (UINT32)TpOption.uart_long_cmd.ax*RESOLUTION_X/mx;
                TpOption.uart_long_cmd.ay = (UINT32)TpOption.uart_long_cmd.ay*RESOLUTION_Y/my;

                TpOption.uart_long_cmd.dx = (UINT32)TpOption.uart_long_cmd.dx*RESOLUTION_X/mx;
                TpOption.uart_long_cmd.dy = (UINT32)TpOption.uart_long_cmd.dy*RESOLUTION_Y/my;
              }
            }
            else
            {
                TpOption.uart_long_cmd.ax = 0;
                TpOption.uart_long_cmd.ay = 0;

                TpOption.uart_long_cmd.dx = RESOLUTION_X;
                TpOption.uart_long_cmd.dy = RESOLUTION_Y;
            }
          }
          break;
        default:
          break;
      }

      d = pBuf[0];
      USART2_SendData(&d, 1);

      uart_state = UART_STATE_IDLE;
    }
  }
}

#endif
#endif

BOOL  CheckUsbStatus()
{
//  if(config.remote_wakeup_en || config.usb_bus_check_en==0)
//    return FALSE;
//
//
//   if(((DeviceMode == DEVICE_MODE_MULTITOUCH) && (USBFS_UEP_T_RES_NAK != (USBFSD->UEP1_CTRL_H & USBFS_UEP_T_RES_MASK)))
//       ||(DeviceMode != DEVICE_MODE_MULTITOUCH && (USBFS_UEP_T_RES_NAK != (USBFSD->UEP3_CTRL_H & USBFS_UEP_T_RES_MASK))))
//   {
//
//       IsDebugMode  = 0;
//
//       USBFS_Device_Init( ENABLE , PWR_VDD_SupplyVoltage());
//
//       PRINT("reset usb\n");
//
//       return TRUE;
//   }
//   else
//   {
//       if(DeviceMode == DEVICE_MODE_MULTITOUCH)
//       {
//           USBFS_EP1_Buf[0] = 0;
//           USBFSD->UEP1_TX_LEN  = 0;
//           USBFSD->UEP1_CTRL_H = (USBFSD->UEP1_CTRL_H & ~ USBFS_UEP_T_RES_MASK) | USBFS_UEP_T_RES_ACK;
//       }
//       else
//       {
//           USBFSD->UEP3_TX_LEN  = 0;
//           USBFSD->UEP3_CTRL_H = (USBFSD->UEP3_CTRL_H & ~ USBFS_UEP_T_RES_MASK) | USBFS_UEP_T_RES_ACK;
//       }
//   }
   return FALSE;
}



__attribute__((section(".highcode")))
UINT16 PosReverse(UINT16 pos, UINT16 res)
{
  if(pos < res)
    pos = res - pos;
  else
    pos  = 0;

  return pos;
}

#ifdef CHIP_TYPE_GT738X
void AppendReleaseFrame()
{
  if(Press_Flag_Bak0==0 && Press_Flag!=0)
  {
    Press_Flag = 0;
    GioInterruptFlag = TRUE;
    ReleaseFlag = 1;
  }
  else
  {
    ReleaseFlag = 0;
  }
}
#endif


UINT16 GetCheckSum8(UINT8* pBuf, UINT8 len)
{
    UINT16 wChksum = 0;
    UINT8 i;
    for(i=0; i<len; i++)
    {
        wChksum+=pBuf[i];
    }
    return wChksum;
}

BOOL IsBerlinChipType(CHIP_TYPE type)
{
    if(type!=CHIP_TYPE_9XXX && type!=CHIP_TYPE_9PXX && type!=CHIP_TYPE_73XX)
    {
        return TRUE;
    }
    return FALSE;
}

