/*******************************************************************************
*
*
* File:        app_tp_for_custom.c
* Description  tp 协议处理文件，包括报点协议转换、start/sleep/awake 等固定传输数据的配置
* Version      V0.1
* Date         2021-10-14
* Author       zhanghz
*******************************************************************************/
#include "test_cfg_global.h"

#if _DEMO_S8_EN

#if 0
#include "s8_update_firmware.c"
#else
#include "app_tp_for_custom_s8.h"
#include "app_tp_phone_transfer_data_s8.h"
#include "app_tp_screen_transfer_data_s8.h"
#include "tau_log.h"
#include "tau_delay.h"
#include "hal_i2c_slave.h"
#include "tau_operations.h"
#include "hal_system.h"
#ifdef LOG_TAG
#undef LOG_TAG
#endif
#define LOG_TAG "s8_tp"

#define S8_TP_DEBUG_LOG 0

#define Touch_Release_Event_Time    2   //手指松开时间 50ms步进
#define Touch_MAX_Point 10  //最大触摸点
typedef struct
{
    uint16_t X; // 坐标
    uint16_t Y; // 坐标
    uint16_t X_in; // 坐标
    uint16_t Y_in; // 坐标
    uint16_t Z; // 触摸面积
    uint8_t  Event;//0无触 1按下 2移动 3松开
    uint8_t  Eventbk;//0无触 1按下 2移动 3松开
    uint16_t  Event_Time;//事件保持时间
} Touch_Single_Point_str;
typedef struct
{
    Touch_Single_Point_str Touch_Single_Point[Touch_MAX_Point];//最大 10 个触摸点
    uint8_t Event_Hold;//事件保持 1表示有触摸点事件
    uint8_t Event_Single_Flag;//单次触发触摸点事件,1表示当前可以触发一次触点事件,可给中断
} Touch_str;
Touch_str Touch = //初始化值
{
    .Touch_Single_Point[0] = (Touch_Single_Point_str){.X = 0, .Y = 0, .X_in = 0, .Y_in = 0, .Z = 0, .Event = 0, .Eventbk = 0, .Event_Time = 0,},
    .Touch_Single_Point[1] = (Touch_Single_Point_str){.X = 0, .Y = 0, .X_in = 0, .Y_in = 0, .Z = 0, .Event = 0, .Eventbk = 0, .Event_Time = 0,},
    .Touch_Single_Point[2] = (Touch_Single_Point_str){.X = 0, .Y = 0, .X_in = 0, .Y_in = 0, .Z = 0, .Event = 0, .Eventbk = 0, .Event_Time = 0,},
    .Touch_Single_Point[3] = (Touch_Single_Point_str){.X = 0, .Y = 0, .X_in = 0, .Y_in = 0, .Z = 0, .Event = 0, .Eventbk = 0, .Event_Time = 0,},
    .Touch_Single_Point[4] = (Touch_Single_Point_str){.X = 0, .Y = 0, .X_in = 0, .Y_in = 0, .Z = 0, .Event = 0, .Eventbk = 0, .Event_Time = 0,},
#if (Touch_MAX_Point==10)
    .Touch_Single_Point[5] = (Touch_Single_Point_str){.X = 0, .Y = 0, .X_in = 0, .Y_in = 0, .Z = 0, .Event = 0, .Eventbk = 0, .Event_Time = 0,},
    .Touch_Single_Point[6] = (Touch_Single_Point_str){.X = 0, .Y = 0, .X_in = 0, .Y_in = 0, .Z = 0, .Event = 0, .Eventbk = 0, .Event_Time = 0,},
    .Touch_Single_Point[7] = (Touch_Single_Point_str){.X = 0, .Y = 0, .X_in = 0, .Y_in = 0, .Z = 0, .Event = 0, .Eventbk = 0, .Event_Time = 0,},
    .Touch_Single_Point[8] = (Touch_Single_Point_str){.X = 0, .Y = 0, .X_in = 0, .Y_in = 0, .Z = 0, .Event = 0, .Eventbk = 0, .Event_Time = 0,},
    .Touch_Single_Point[9] = (Touch_Single_Point_str){.X = 0, .Y = 0, .X_in = 0, .Y_in = 0, .Z = 0, .Event = 0, .Eventbk = 0, .Event_Time = 0,},
#endif
    .Event_Hold = 0,
    .Event_Single_Flag = 0,
};
io_pad_e g_screen_input_rst_pad = IO_PAD_TD_TP_RESX; /* FIXME Cuckoo没有TD TPRSTN,QFN 封装片上使用的是FC IO2 */
io_pad_e g_screen_input_int_pad = IO_PAD_TD_INT;
io_pad_e g_phone_input_rst_pad  = IO_PAD_AP_TPRSTN;
io_pad_e g_phone_output_int_pad = IO_PAD_AP_INT;
static uint8_t start_now = 1;
/*************************************报点协议 master 相关 buffer ****************************************/

uint8_t screen_data_write_1[1] = {0x87};                                                    //触点/坐标 数据读取对应的发送buffer
uint8_t screen_data_write_2[3] = {0xc0, 0x05, 0x01};                                        //配置buffer
uint8_t screen_data_write_3[3] = {0xc0, 0x05, 0x00};                                        //配置buffer

st_screen_data screen_reg_int_data[] = {    \
    {screen_data_write_1, 1, 10, SCREEN_TRANSFER_READ}, \
    {screen_data_write_2, 3, 0, SCREEN_TRANSFER_WRITE}, \
    {screen_data_write_3, 3, 0, SCREEN_TRANSFER_WRITE}
};
const uint8_t screen_reg_int_data_size = sizeof(screen_reg_int_data) / sizeof(
            st_screen_data);//结构体数组的元素个数，数组按照协议发送数据先后排列


/***********************************报点协议 master 相关 buffer 截止**************************************/

/***********************************开机屏幕初始化 master 相关 buffer ************************************/
// 数组按照协议发送数据先后排列
st_screen_const_data screen_reg_start_data[] = { \
    {data_num_00, screen_87_data, sizeof(screen_87_data), 10, SCREEN_TRANSFER_READ}, \
    {data_num_01, screen_a0_00_ff_data, sizeof(screen_a0_00_ff_data), 0, SCREEN_TRANSFER_WRITE}, \
    {data_num_02, screen_a4_06_c1_data, sizeof(screen_a4_06_c1_data), 0, SCREEN_TRANSFER_WRITE}, \
};
const uint8_t screen_reg_start_data_size = sizeof(screen_reg_start_data) / sizeof(st_screen_const_data);
/*********************************开机屏幕初始化 master 相关 buffer 截止**********************************/



/*************************************报点协议 slave 相关 buffer******************************************/

uint8_t phone_reg_coord_data[] = {0x60};                                                //坐标 数据反馈对应的接收数据
uint8_t phone_reg_coord_back[8] = {0x09, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00};     //坐标 数据反馈对应的数据buffer
uint8_t phone_reg_coord_back_BUF[10][10] = {0x09, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00};     //坐标 数据反馈对应的数据buffer
uint8_t phone_reg_coord_back_X61[80] = {0x09, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00};     //坐标 数据反馈对应的数据buffer
uint8_t phone_reg_coord_BUF_NUM = 0;

st_reg_data phone_reg_int_data[] = {{1, 8, phone_reg_coord_back_X61, phone_reg_coord_back_X61}};
uint8_t phone_reg_int_size = sizeof(phone_reg_int_data) / sizeof(phone_reg_int_data[0]);
/***********************************报点协议 slave 相关 buffer 截止***************************************/

/****************************开机阶段slave需要反馈的数据及其对应的接收开头********************************/

st_reg_const_data phone_reg_const_data[] = { \
    {sizeof(phone_60_start_back), sizeof(phone_60_start_back), phone_60_start_back, phone_60_start_back}, \
    {sizeof(phone_22_data), sizeof(phone_22_back), phone_22_data, phone_22_back}, \
    {sizeof(phone_21_data), sizeof(phone_21_back), phone_21_data, phone_21_back}, \
    {sizeof(phone_55_data), sizeof(phone_55_back), phone_55_data, phone_55_back}, \
    {sizeof(phone_af_data), sizeof(phone_af_back), phone_af_data, phone_af_back}, \
    {sizeof(phone_f1_data), sizeof(phone_f1_back), phone_f1_data, phone_f1_back}, \
    {sizeof(phone_a5_data), sizeof(phone_a5_back), phone_a5_data, phone_a5_back}, \
    {sizeof(phone_a3_data), sizeof(phone_a3_back), phone_a3_data, phone_a3_back}, \
    {sizeof(phone_a4_data), sizeof(phone_a4_back), phone_a4_data, phone_a4_back}, \
    {sizeof(phone_52_data), sizeof(phone_52_back), phone_52_data, phone_52_back}, \
    {sizeof(phone_23_data), sizeof(phone_23_back), phone_23_data, phone_23_back}, \
    {sizeof(phone_30_data), sizeof(phone_30_back), phone_30_data, phone_30_back}, \
    {sizeof(phone_e4_00_data), sizeof(phone_e4_00_back), phone_e4_00_data, phone_e4_00_back}, \
    {sizeof(phone_e4_01_data), sizeof(phone_e4_01_back), phone_e4_01_data, phone_e4_01_back}, \
    {sizeof(phone_85_data), sizeof(phone_85_back), phone_85_data, phone_85_back}, \
    {sizeof(phone_f5_data), sizeof(phone_f5_back), phone_f5_data, phone_f5_back}, \
    {sizeof(phone_f6_data), sizeof(phone_f6_back), phone_f6_data, phone_f6_back}, \
    {sizeof(phone_ea_data), sizeof(phone_ea_back), phone_ea_data, phone_ea_back}, \
    {sizeof(phone_b1_data), sizeof(phone_b1_back), phone_b1_data, phone_b1_back}, \
    {sizeof(phone_72_data), sizeof(phone_72_back), phone_72_data, phone_72_back}, \
    {sizeof(phone_80_data), sizeof(phone_80_back), phone_80_data, phone_80_back}, \
    {sizeof(phone_90_data), sizeof(phone_90_back), phone_90_data, phone_90_back}  \
};
uint8_t phone_reg_const_data_size = sizeof(phone_reg_const_data) / sizeof(phone_reg_const_data[0]);
/***************************开机阶段slave需要反馈的数据及其对应的接收开头截止******************************/
/**************************************************************************
* @name : app_tp_screen_analysis_const
* @brief : screen start 阶段数据解析函数，由客户定制
* @param[in] :
* @return :
* @retval :
**************************************************************************/
uint8_t app_tp_screen_analysis_const(uint8_t transfer_now, uint8_t *rxbuffer, size_t data_size)
{
    uint8_t return_num = transfer_now + 1;
    static uint8_t  app_tp_count = 0;

    switch (transfer_now)
    {
    case data_num_00:                                   //87
        if (rxbuffer[1] == 0x87 && rxbuffer[2] == 0x03)
        {
#if S8_TP_DEBUG_LOG
            TAU_LOGD("87 wait 03 ok\r\n");
#endif
        }
        else
        {
#if S8_TP_DEBUG_LOG
            TAU_LOGD("TD TP init [%d] \r\n", rxbuffer[2]);
#endif
            app_tp_count++;
            return_num = transfer_now;
            if (app_tp_count >  120)                    //初始化不成功，重新reset screen
            {
                app_tp_count = 0;
                app_tp_screen_init();
                return_num = data_num_00;
            }
            delayMs(10);
        }
        break;
    default:
        break;
    }

    return return_num;
}
/**************************************************************************
* @name : app_tp_screen_analysis_int
* @brief : screen 报点数据解析函数，由客户定制
* @param[in] :
* @return :
* @retval :
**************************************************************************/
uint8_t app_tp_screen_analysis_int(uint8_t transfer_now, uint8_t *rxbuffer, size_t data_size)
{
    for (uint8_t ss = 0; ss < 10; ss++)
        phone_reg_coord_back_BUF[phone_reg_coord_BUF_NUM][ss] = rxbuffer[ss];

    if (++phone_reg_coord_BUF_NUM >= Touch_MAX_Point)
        phone_reg_coord_BUF_NUM = Touch_MAX_Point;

    if ((rxbuffer[9] & 0x1f) > 0)
    {
        return 0;
    }
    for (uint8_t ss = 0; ss < phone_reg_coord_BUF_NUM; ss++)
    {
        uint8_t touch_id = 0;
        uint8_t touch_event_id = 0;

        touch_id = phone_reg_coord_back_BUF[ss][3] >> 4;
        if (touch_id >= Touch_MAX_Point)
            continue; //判断手指编号是否超出范围

        touch_event_id = phone_reg_coord_back_BUF[ss][2] >> 4;//触摸事件

        if (touch_event_id == 0x01)
        {

            Touch.Touch_Single_Point[touch_id].Event = 0x01;

            Touch.Touch_Single_Point[touch_id].Event_Time = Touch_Release_Event_Time;

            Touch.Touch_Single_Point[touch_id].X_in = (((uint16_t)phone_reg_coord_back_BUF[ss][5] & 0x0F) << 8) |
                    (phone_reg_coord_back_BUF[ss][4]);
            Touch.Touch_Single_Point[touch_id].Y_in = ((uint16_t)phone_reg_coord_back_BUF[ss][6] << 4) | ((
                        phone_reg_coord_back_BUF[ss][5] & 0xF0) >> 4);
            Touch.Touch_Single_Point[touch_id].Z = phone_reg_coord_back_BUF[ss][7];
            //分辨率转换
            Touch.Touch_Single_Point[touch_id].X = (((float)Touch.Touch_Single_Point[touch_id].X_in) *
                                                    (float)INPUT_WIDTH_VALUE) / ((float)OUTPUT_WIDTH_VALUE);
            Touch.Touch_Single_Point[touch_id].Y = (((float)Touch.Touch_Single_Point[touch_id].Y_in) *
                                                    (float)INPUT_HEIGHT_VALUE) / ((float)OUTPUT_HEIGHT_VALUE);
        }
        else if (touch_event_id == 0x02)
        {

            Touch.Touch_Single_Point[touch_id].Event = 0x02;

            Touch.Touch_Single_Point[touch_id].Event_Time = Touch_Release_Event_Time;

            Touch.Touch_Single_Point[touch_id].X_in = (((uint16_t)phone_reg_coord_back_BUF[ss][5] & 0x0F) << 8) |
                    (phone_reg_coord_back_BUF[ss][4]);
            Touch.Touch_Single_Point[touch_id].Y_in = ((uint16_t)phone_reg_coord_back_BUF[ss][6] << 4) | ((
                        phone_reg_coord_back_BUF[ss][5] & 0xF0) >> 4);
            Touch.Touch_Single_Point[touch_id].Z = phone_reg_coord_back_BUF[ss][7];
            //分辨率转换
            Touch.Touch_Single_Point[touch_id].X = (((float)Touch.Touch_Single_Point[touch_id].X_in) *
                                                    (float)INPUT_WIDTH_VALUE) / ((float)OUTPUT_WIDTH_VALUE);
            Touch.Touch_Single_Point[touch_id].Y = (((float)Touch.Touch_Single_Point[touch_id].Y_in) *
                                                    (float)INPUT_HEIGHT_VALUE) / ((float)OUTPUT_HEIGHT_VALUE);
        }
        else if (touch_event_id == 0x03)
        {
            Touch.Touch_Single_Point[touch_id].Event = 0x03;
            Touch.Touch_Single_Point[touch_id].Event_Time = Touch_Release_Event_Time;

        }
        else if (touch_event_id == 0x04)
        {
            if (Touch.Touch_Single_Point[touch_id].Event != 0)
            {
                Touch.Touch_Single_Point[touch_id].Event_Time = Touch_Release_Event_Time;
            }
        }
        else if (touch_event_id == 0)
        {
            if (Touch.Touch_Single_Point[touch_id].Event != 0)
            {
                Touch.Touch_Single_Point[touch_id].Event = 0x03;
                Touch.Touch_Single_Point[touch_id].Event_Time = Touch_Release_Event_Time;
            }
        }
        else
        {
            if (Touch.Touch_Single_Point[touch_id].Event != 0)
            {
                Touch.Touch_Single_Point[touch_id].Event = 0x03;
                Touch.Touch_Single_Point[touch_id].Event_Time = Touch_Release_Event_Time;
            }
        }
    }
    Touch.Event_Single_Flag = 1;
    phone_reg_coord_BUF_NUM = 0;
    if (Touch.Event_Single_Flag)
    {
        uint8_t Touch_num = 0;
        for (uint8_t ss = 0; ss < Touch_MAX_Point; ss++)
        {
            if (Touch.Touch_Single_Point[ss].Event == 0)
                continue;
            Touch_num++;
        }
        uint8_t s1 = 0;
        for (uint8_t ss = 0; ss < Touch_MAX_Point; ss++)
        {

            if (Touch.Touch_Single_Point[ss].Event == 0)
                continue;

            uint16_t X0, Y0;
            X0 = ((float)Touch.Touch_Single_Point[ss].X) * 4095.1 / ((float)INPUT_WIDTH_VALUE);
            Y0 = ((float)Touch.Touch_Single_Point[ss].Y) * 4095.1 / ((float)INPUT_HEIGHT_VALUE);
            if (X0 > 0xfff)
                X0 = 0xfff;
            if (Y0 > 0xfff)
                Y0 = 0xfff;

            //bit0-bit1:event id;   0表示触摸类事件；1表示状态事件；2表示手势事件；3表示空事件
            //bit2-bit5:touch id;   表示第几个触摸手指
            //bit6-bit7:touch action; 0：没有触摸事件；1:按下;2:移动;3:松开

            phone_reg_coord_back_X61[((s1) * 8) + 0] = (Touch.Touch_Single_Point[ss].Event << 6) | ((
                        ss + 1) << 2);              //44 press C4 leave 84 move

            phone_reg_coord_back_X61[((s1) * 8) + 1] = (uint8_t)((X0 & 0xFF0) >> 4);      //x 高八位
            phone_reg_coord_back_X61[((s1) * 8) + 2] = (uint8_t)((Y0 & 0xFF0) >> 4);      //y 高八位
            phone_reg_coord_back_X61[((s1) * 8) + 3] = ((X0 & 0xF) << 4) | ((Y0 & 0xF));  //bit0-bit3:y低四位;bit4-bit7:x低四位;
            phone_reg_coord_back_X61[((s1) * 8) + 4] = 4;                                                 //major
            phone_reg_coord_back_X61[((s1) * 8) + 5] = 4;                                                 //minor
            //touch type：0:普通手指触摸；1:盘旋；2:保护套；3:手套;4:尖笔;5:手掌;6:潮湿的;7:接近;8:轻摇
            phone_reg_coord_back_X61[((s1) * 8) + 6] = ((Touch.Touch_Single_Point[ss].Z & 0xFE) >> 2);    //bit0-bit5:z只有6位;bit6-bit7:touch type的高两位
            phone_reg_coord_back_X61[((s1) * 8) + 7] = --Touch_num;                  //bit0-bit5:buffer里面剩余多少个事件;bit6-bit7：touch type 低两位

            Touch.Touch_Single_Point[ss].Eventbk = Touch.Touch_Single_Point[ss].Event;
#if S8_TP_DEBUG_LOG
            TAU_LOGD("[%x] %d %d\r\n", phone_reg_coord_back_X61[((s1) * 8) + 0], X0, Y0);
#endif
            Touch.Touch_Single_Point[ss].Event = 0;
            s1++;
        }

        hal_gpio_set_output_data(g_phone_output_int_pad, IO_LVL_LOW);   //拉低TP中断脚,通知AP读取TP数据
        Touch.Event_Single_Flag = 0;
    }
    return screen_reg_int_data_size + 1;
}
void app_tp_phone_analysis_data(uint8_t *rxbuffer, size_t rxbuffer_size, const uint8_t **txbuffer,
                                size_t *txbuffer_size)
{
    static uint8_t phone_reg_e4_count = 1;
    switch (rxbuffer[0])
    {
    case 0x60:
        if (start_now)
        {
            start_now = 0;
            *txbuffer_size = sizeof(phone_60_start_back);
            *txbuffer = phone_60_start_back;
        }
        else
        {
            hal_gpio_set_output_data(g_phone_output_int_pad, IO_LVL_HIGH);
            *txbuffer = phone_reg_coord_back_X61;
            *txbuffer_size = sizeof(phone_reg_coord_back_X61);
        }
        break;
    case 0x61:
        hal_gpio_set_output_data(g_phone_output_int_pad, IO_LVL_HIGH);
        *txbuffer = &phone_reg_coord_back_X61[8];
        *txbuffer_size = sizeof(phone_reg_coord_back_X61) - 8;
        break;
    case 0x22:
        *txbuffer = phone_22_back;
        *txbuffer_size = sizeof(phone_22_back);
        break;
    case 0x21:
        *txbuffer = phone_21_back;
        *txbuffer_size = sizeof(phone_21_back);
        break;
    case 0x55:
        *txbuffer = phone_55_back;
        *txbuffer_size = sizeof(phone_55_back);
        break;
    case 0xaf:
        *txbuffer = phone_af_back;
        *txbuffer_size = sizeof(phone_af_back);
        break;
    case 0xf1:
        *txbuffer = phone_f1_back;
        *txbuffer_size = sizeof(phone_f1_back);
        break;
    case 0xa5:
        *txbuffer = phone_a5_back;
        *txbuffer_size = sizeof(phone_a5_back);
        break;
    case 0xa3:
        *txbuffer = phone_a3_back;
        *txbuffer_size = sizeof(phone_a3_back);
        break;
    case 0xa4:
        *txbuffer = phone_a4_back;
        *txbuffer_size = sizeof(phone_a4_back);
        break;
    case 0x52:
        *txbuffer = phone_52_back;
        *txbuffer_size = sizeof(phone_52_back);
        break;
    case 0x23:
        *txbuffer = phone_23_back;
        *txbuffer_size = sizeof(phone_23_back);
        break;
    case 0x30:
        *txbuffer = phone_30_back;
        *txbuffer_size = sizeof(phone_30_back);
        break;
    case 0xe4:
        if (rxbuffer_size == 2)
        {
            phone_reg_e4_count = rxbuffer[1];
            return;
        }
        else
        {
            rxbuffer[1] = phone_reg_e4_count;
            rxbuffer_size = 2;
        }
        break;
    case 0x85:
        *txbuffer = phone_85_back;
        *txbuffer_size = sizeof(phone_85_back);
        break;
    case 0xf5:
        *txbuffer = phone_f5_back;
        *txbuffer_size = sizeof(phone_f5_back);
        break;
    case 0xf6:
        *txbuffer = phone_f6_back;
        *txbuffer_size = sizeof(phone_f6_back);
        break;
    case 0xea:
        *txbuffer = phone_ea_back;
        *txbuffer_size = sizeof(phone_ea_back);
        break;
    case 0xb1:
        *txbuffer = phone_b1_back;
        *txbuffer_size = sizeof(phone_b1_back);
        break;
    case 0x72:
        *txbuffer = phone_72_back;
        *txbuffer_size = sizeof(phone_72_back);
#if S8_TP_DEBUG_LOG
        TAU_LOGD("AP Touch Init Ok");
#endif
        break;
    case 0x80:
        *txbuffer = phone_80_back;
        *txbuffer_size = sizeof(phone_80_back);
        break;
    case 0x90:
        *txbuffer = phone_90_back;
        *txbuffer_size = sizeof(phone_90_back);
        break;
    }
}
/**************************************************************************
* @name : app_tp_write_other_operations
* @brief : 根据通信方式处理其它操作,比如拉高拉低中断，reset等
* @param[in] : txbuffer输入数组指针 or null
* @param[in] : buffer_size 输入数组长度 or 事件标志位
* @param[in] :
* @return :
* @retval : 参数可复用，当数组不为NULL时，buffer_size是数组数据长度；当数组为NULL时,buffer_size作为事件标志位
**************************************************************************/
void app_tp_write_other_operations(const uint8_t *txbuffer, uint32_t buffer_size)
{
    if (txbuffer == NULL) //数组为null,buffer_size复用做事件标志
    {
        switch (buffer_size)
        {
        case 0:
            start_now = 1;
            break;
        default:
            break;
        }
    }
    else
    {
        //if(txbuffer[0]=='xx') todo 可按需判断数组功能，目前只有一种功能，所以不需要判断了
        phone_reg_coord_back_X61[0] = 0x84;
        phone_reg_coord_back_X61[7] = 0xff;                         //发送第七BYTE的值0xff，释放全部手指
        hal_gpio_set_output_data(g_phone_output_int_pad, IO_LVL_LOW);   //拉低TP中断脚,通知AP读取TP数据
    }
}

#endif
#endif
