/*******************************************************************************
*
* File:         Mi12Lite.c
* Description:  系统测试文件
* Version:      V0.1
* Date:         2020-02-22
* Author:       Tempest
 *******************************************************************************/
#include "Mi12Lite.h"
#include "ArmCM0.h"
#include "tau_device_datatype.h"
#include "tau_log.h"
#include "tau_operations.h"
#include "tau_common.h"
#include "tau_delay.h"
#include "hal_dsi_rx_ctrl.h"
#include "hal_dsi_tx_ctrl.h"
#include "hal_swire.h"
#include "hal_timer.h"
#include "hal_system.h"
#include "hal_gpio.h"
#include "test_cfg_global.h"
#include "hal_pwr.h"
#include "hal_pwm.h"

#ifdef LOG_TAG
#undef LOG_TAG
#endif
#define LOG_TAG "Mi12Lite"

#if _DEMO_MI_12_LITE_EN

/******************** FEATURE开关 ********************/
#define TOUCH_ENABLE                   false    /* Touch转换开关 */
#define RX_START_WITHOUT_RST           false    /* 不等待AP RESET直接启动RX,仅作为调试使用 */
#define RX_WAIT_TEAR_ON                true     /* 等待AP_TEAR_ON */
#define RX_RESOLUTION_CHANGE_ENABLE    true     /* 支持分辨率切换开关, AP存在分辨率切换时需要打开 */
#define RX_READ_HW_ACK                 false    /* AP DCS读命令使用硬件回复 */
#define TX_START_AFTER_APRST           false    /* 等待AP_reset 后做Panel初始化, 用于热拔插电源不稳定导致初始化失败 */
#define TX_USE_CMD_MODE                false    /* command mode输出开关 配置为True时需要把TD TE与 AP TE 接一起*/
#define TX_CMD_MODE_WITHOUT_TE         false    /* 屏端TE直接输出给AP,Scaler不看TE信号,AP每输入一帧输出一帧(C2C 60Hz->60Hz) */
#define AP_SWIRE_OUTPUT                true     /* swire信号输出,OLED项目配置 */
#define ANALOG_PWM_OUTPUT              true     /* 模拟PWM 调光开关 */
#define SHARE_FLASH_ENABLE             false    /* 共享flash开关 */
/*****************************************************/

/******************** 输出屏幕选择 ********************/
#define AMOLED_NT37280                 0                   /* 4lane FHD Panel */
#define TFT_FT8720                     1                   /* 4lane FHD Panel */
/*****************************************************/

/****************** 系统相关参数配置 ******************/
#define MAIN_POWER_SELECT              PWR_SEL_VCC           /* 主供电电源选择 */
#define SLEEP_MODE_POWER               PWR_SLEEP_IN_TP18     /* 息屏电源选择 */
#define SLEEP_MODE_SELECT              PWR_DEEP_SLEEP_MODE   /* sleep mode 配置 */
#define SWIRE_DEFAULT_PULSE            9                     /* SWIRE 波形配置 */
#define PWM_FREQUENCY                  30000                 /* PWM输出频率30Khz */
#define PWM_DUTY_STEP                  255                   /* PWM调光阶数255阶 */
/*****************************************************/

/********************RX 基本参数配置*******************/
//AP MIPI数据信息
/* 输入分辨率 */
#define INPUT_WIDTH  1080
#define INPUT_HEIGHT 2400
/* 输入 MIPI lane rate,需要正确配置,可50M step调整 */
#define INPUT_MIPI_LANE_RATE 1200000000
/* 输入图像格式 */
#define INPUT_COLOR_MODE DSI_RGB10_10_10
/* 输出数据格式(DSI_DATA_CMD_MODE , DSI_DATA_VIDEO_MODE) */
#define INPUT_DATA_MODE DSI_DATA_CMD_MODE
/* 输入mipi lane数量(DSI_RX_LANE_x     x为1-4) */
#define INPUT_MIPI_LANE_NUM DSI_LANE_4
/* 输入为video mode 时数据格式 */
#define INPUT_VIDEO_MODEL DSI_NONBURST_EVENT
/* 输入虚拟通道(0-3) */
#define INPUT_VC DSI_VC_0
/* 输入的帧率(60/90/120/144Hz) */
#define INPUT_FRAME_RATE DSI_FRAME_RATE_60HZ
/* 输入数据是否DSC压缩 */
#define INPUT_COMPRESS true
/*****************************************************/

/********************TX 基本参数配置*******************/
#if AMOLED_NT37280
//almoled NT37280输出MIPI数据信息
/* 输出分辨率配置 */
#define OUTPUT_WIDTH 1080
#define OUTPUT_HEIGHT 2280
/* 输出虚拟通道(0-3) */
#define OUTPUT_VC DSI_VC_0
/* 输出mipi lane数量(DSI_RX_LANE_x     x为1-4) */
#define OUTPUT_LANE_NUMBER DSI_LANE_4
/* 输出数据格式(DSI_DATA_CMD_MODE , DSI_DATA_VIDEO_MODE) */
#if TX_USE_CMD_MODE
#define OUTPUT_DATA_MODE DSI_DATA_CMD_MODE
#else
#define OUTPUT_DATA_MODE DSI_DATA_VIDEO_MODE
#endif
/* 输出为video mode时的数据格式 */
#define OUTPUT_VIDEO_MODEL DSI_BURST_MODE
/* 输出 VSA */
#define OUTPUT_VSA  4
/* 输出 VBP */
#define OUTPUT_VBP  28
/* 输出 VBP */
#define OUTPUT_VFP  10
/* 输出 VSA */
#define OUTPUT_HSA  8
/* 输出 HBP */
#define OUTPUT_HBP  16
/* 输出 HFP */
#define OUTPUT_HFP  36
/* 初始化模式命令传输类型 LP/HS */
#define TX_INIT_TYPE            DSI_CMD_TX_LP
#elif TFT_FT8720
/* 输出分辨率配置 */
#define OUTPUT_WIDTH   1080
#define OUTPUT_HEIGHT  2400
/* 输出虚拟通道(0-3) */
#define OUTPUT_VC DSI_VC_0
/* 输出mipi lane数量(DSI_RX_LANE_x     x为1-4) */
#define OUTPUT_LANE_NUMBER DSI_LANE_4
/* 输出数据格式(DSI_DATA_CMD_MODE , DSI_DATA_VIDEO_MODE) */
#define OUTPUT_DATA_MODE DSI_DATA_VIDEO_MODE
/* 输出为video mode 的数据格式 */
#define OUTPUT_VIDEO_MODEL DSI_BURST_MODE
/* 输出 VSA */
#define OUTPUT_VSA  4
/* 输出 VBP */
#define OUTPUT_VBP  28
/* 输出 VBP */
#define OUTPUT_VFP  110
/* 输出 VSA */
#define OUTPUT_HSA  4
/* 输出 HBP */
#define OUTPUT_HBP  16
/* 输出 HFP */
#define OUTPUT_HFP  16
/* 初始化模式命令传输类型 LP/HS */
#define TX_INIT_TYPE            DSI_CMD_TX_LP
#endif
/******************************************************/

#if TOUCH_ENABLE
#include "app_tp_transfer.h"
#endif

/* 全局handle */
static hal_dsi_rx_ctrl_handle_t *g_rx_ctrl_handle = NULL;
static hal_dsi_tx_ctrl_handle_t *g_tx_ctrl_handle = NULL;

/* 屏初始化完成标志位 */
static bool panel_display_done = false;
static bool sg_system_resume = false;
static bool sg_system_suspend = false;
static bool sg_exit_idle_mode_flag = false;

#if RX_WAIT_TEAR_ON
static bool sg_ap_set_tear_on = false;
#endif
#if TX_START_AFTER_APRST
static bool sg_tx_start_in_process = false;
#endif


/* AP reset 回调函数声明 */
static void ap_rstn_pull_high_cb(void *data);
static void ap_rstn_pull_down_cb(void *data);
static void app_mipi_rx_start_cb(void *data);


/*************************DCS 命令处理函数 BEGIN*************************/
#if RX_READ_HW_ACK
/**
* @brief  配置AP硬件回读
* @param  none
* @retval none
*/
static void app_set_dcs_hw_ack()
{
    hal_dsi_rx_ctrl_set_auto_ack(g_rx_ctrl_handle, HAL_RX_QRESP_CODE0, DSI_ACK_DT_DCS_SHORT_RESPONSE_1B, 0xFA, 1, 0x00);
}
#endif
/**
* @brief  ap 读回调函数
* @param  handler：rx_ctrl_handle
*         dcs_packet: dcs 命令
* @retval true/false
*/
static bool ap_dcs_read(uint8_t data_type, uint8_t dcs_cmd, uint8_t param)
{
    static uint8_t B2_cnt = 0;
    static uint8_t B5_cnt = 0;
    static uint8_t B8_cnt = 0;
    static uint8_t AC_cnt = 0;
    if (dcs_cmd == 0xA3)
    {
        hal_dsi_rx_ctrl_send_ack_cmd(g_rx_ctrl_handle,
                                     DSI_ACK_DT_DCS_LONG_RESPONSE,
                                     DSI_VC_0,
                                     8, 0x01, 0xF4, 0x03, 0x00, 0x00, 0x03, 0x01, 0x05);
    }
    else if (dcs_cmd == 0xB2)
    {
        B2_cnt++;
        if (B2_cnt == 1)
        {
            hal_dsi_rx_ctrl_send_ack_cmd(g_rx_ctrl_handle,
                                         DSI_ACK_DT_DCS_SHORT_RESPONSE_2B,
                                         DSI_VC_0,
                                         2, 0x0b, 0x0f);
        }
        else if (B2_cnt == 2)
        {
            hal_dsi_rx_ctrl_send_ack_cmd(g_rx_ctrl_handle,
                                         DSI_ACK_DT_DCS_SHORT_RESPONSE_2B,
                                         DSI_VC_0,
                                         2, 0x07, 0x43);
        }
        else if (B2_cnt == 3)
        {
            hal_dsi_rx_ctrl_send_ack_cmd(g_rx_ctrl_handle,
                                         DSI_ACK_DT_DCS_SHORT_RESPONSE_2B,
                                         DSI_VC_0,
                                         2, 0x07, 0x85);
        }
        else
        {
            TAU_LOGD("r %x ng need return [%d]\n", dcs_cmd, hal_dsi_rx_ctrl_get_max_ret_size(g_rx_ctrl_handle));
        }
    }
    else if (dcs_cmd == 0xB5)
    {
        B5_cnt++;
        if (B5_cnt == 1)
        {
            hal_dsi_rx_ctrl_send_ack_cmd(g_rx_ctrl_handle,
                                         DSI_ACK_DT_DCS_SHORT_RESPONSE_2B,
                                         DSI_VC_0,
                                         2, 0x09, 0xC2);
        }
        else if (B5_cnt == 2)
        {
            hal_dsi_rx_ctrl_send_ack_cmd(g_rx_ctrl_handle,
                                         DSI_ACK_DT_DCS_SHORT_RESPONSE_2B,
                                         DSI_VC_0,
                                         2, 0x06, 0x7e);
        }
        else if (B5_cnt == 3)
        {
            hal_dsi_rx_ctrl_send_ack_cmd(g_rx_ctrl_handle,
                                         DSI_ACK_DT_DCS_SHORT_RESPONSE_2B,
                                         DSI_VC_0,
                                         2, 0x06, 0xc0);
        }
        else if (B5_cnt == 4)
        {
            hal_dsi_rx_ctrl_send_ack_cmd(g_rx_ctrl_handle,
                                         DSI_ACK_DT_DCS_SHORT_RESPONSE_2B,
                                         DSI_VC_0,
                                         2, 0x08, 0xe5);
        }
        else
        {
            TAU_LOGD("r %x ng need return [%d]\n", dcs_cmd, hal_dsi_rx_ctrl_get_max_ret_size(g_rx_ctrl_handle));
        }
    }
    else if (dcs_cmd == 0xB8)
    {
        B8_cnt++;
        if (B8_cnt == 1)
        {
            hal_dsi_rx_ctrl_send_ack_cmd(g_rx_ctrl_handle,
                                         DSI_ACK_DT_DCS_SHORT_RESPONSE_2B,
                                         DSI_VC_0,
                                         2, 0x0C, 0x71);
        }
        else if (B8_cnt == 2)
        {
            hal_dsi_rx_ctrl_send_ack_cmd(g_rx_ctrl_handle,
                                         DSI_ACK_DT_DCS_SHORT_RESPONSE_2B,
                                         DSI_VC_0,
                                         2, 0x08, 0x1a);
        }
        else if (B8_cnt == 3)
        {
            hal_dsi_rx_ctrl_send_ack_cmd(g_rx_ctrl_handle,
                                         DSI_ACK_DT_DCS_SHORT_RESPONSE_2B,
                                         DSI_VC_0,
                                         2, 0x08, 0x5c);
        }
        else if (B8_cnt == 4)
        {
            hal_dsi_rx_ctrl_send_ack_cmd(g_rx_ctrl_handle,
                                         DSI_ACK_DT_DCS_LONG_RESPONSE,
                                         DSI_VC_0,
                                         4, 0x00, 0x00, 0x00, 0x1b);
        }
        else if (B8_cnt == 5)
        {
            hal_dsi_rx_ctrl_send_ack_cmd(g_rx_ctrl_handle,
                                         DSI_ACK_DT_DCS_LONG_RESPONSE,
                                         DSI_VC_0,
                                         4, 0x05, 0x72, 0x00, 0x6f);
        }
        else
        {
            TAU_LOGD("r %x ng need return [%d]\n", dcs_cmd, hal_dsi_rx_ctrl_get_max_ret_size(g_rx_ctrl_handle));
        }
    }
    else if (dcs_cmd == 0xAC)
    {
        AC_cnt++;
        if (AC_cnt == 0x01)
        {
            hal_dsi_rx_ctrl_send_ack_cmd(g_rx_ctrl_handle,
                                         DSI_ACK_DT_DCS_LONG_RESPONSE,
                                         DSI_VC_0,
                                         9, 0x0A, 0x1D, 0x05, 0x05, 0x02, 0x01, 0x16, 0x00, 0x03);
        }
        else if (AC_cnt == 2)
        {
            hal_dsi_rx_ctrl_send_ack_cmd(g_rx_ctrl_handle,
                                         DSI_ACK_DT_DCS_LONG_RESPONSE,
                                         DSI_VC_0,
                                         4, 0x10, 0x0B, 0x10, 0x09);
        }
        else
        {
            TAU_LOGD("r %x ng need return [%d]\n", dcs_cmd, hal_dsi_rx_ctrl_get_max_ret_size(g_rx_ctrl_handle));
        }
    }
#if !RX_READ_HW_ACK
    else if (dcs_cmd == 0xFA)
    {
        hal_dsi_rx_ctrl_send_ack_cmd(g_rx_ctrl_handle,
                                     DSI_ACK_DT_DCS_SHORT_RESPONSE_1B,
                                     DSI_VC_0,
                                     1, 0x00);
    }
#endif
    else
    {
        TAU_LOGD("r %x ng need return [%d]\n", dcs_cmd, hal_dsi_rx_ctrl_get_max_ret_size(g_rx_ctrl_handle));
    }
    return true;
}

#if RX_RESOLUTION_CHANGE_ENABLE
/* PPS update callback 用于分辨率切换case */
static bool pps_update_handle(uint8_t *pps, uint8_t size, uint32_t pic_width, uint32_t pic_height)
{
    /* AVDD 上电, 用于解决息屏开屏PPS不更新问题 */
    hal_gpio_set_output_data(IO_PAD_AP_PWMEN, IO_LVL_HIGH);
    if (pic_width != g_rx_ctrl_handle->base_info.src_w || pic_height != g_rx_ctrl_handle->base_info.src_h)
    {
        hal_dsi_tx_ctrl_set_tear_mode(g_tx_ctrl_handle, TE_USER_MODE);
        /* PPS Update 且分辨率发生变化 */
        g_rx_ctrl_handle->base_info.src_w = pic_width;
        g_rx_ctrl_handle->base_info.src_h = pic_height;
        /* 注意部分基板更新PPS前不发 Compression Mode Command的情况 */
        g_rx_ctrl_handle->compress_en = hal_dsi_rx_ctrl_get_compressen_en(g_rx_ctrl_handle);
        g_tx_ctrl_handle->base_info.src_w = pic_width;
        g_tx_ctrl_handle->base_info.src_h = pic_height;
        hal_dsi_rx_ctrl_toggle_resolution(g_rx_ctrl_handle);
        TAU_LOGD("resolution update w[%d] h[%d] compress[%d]\n", pic_width, pic_height, g_rx_ctrl_handle->compress_en);
        hal_dsi_tx_ctrl_set_tear_mode(g_tx_ctrl_handle, TE_60HZ_MODE);
    }
    TAU_LOGD("PPS Update[%d][%d] [%d][%d]\n", pic_width, pic_height, g_rx_ctrl_handle->base_info.src_w, g_rx_ctrl_handle->base_info.src_h);
    return true;
}
#endif

/**
* @brief  ap display on处理函数
* @param  handler：rx_ctrl_handle
*         dcs_packet: dcs 命令
* @retval true/false
*/
static bool ap_dcs_set_display_on(hal_dsi_rx_ctrl_handle_t *handler, hal_dcs_packet_t *dcs_packet)
{
    TAU_LOGD("disp on \n");
    return true;
}

/**
* @brief  ap display off处理函数
* @param  handler：rx_ctrl_handle
*         dcs_packet: dcs 命令
* @retval true/false
*/
static bool ap_dcs_set_display_off(hal_dsi_rx_ctrl_handle_t *handler, hal_dcs_packet_t *dcs_packet)
{
    TAU_LOGD("disp off %d\n", panel_display_done);
    if (panel_display_done)
    {
        hal_dsi_tx_ctrl_write_cmd(0x05, 0, 2, 0x28);
    }
#if ANALOG_PWM_OUTPUT
    hal_pwm_enable(false);
#endif
    return true;
}

/**
* @brief  ap enter sleep mode处理函数
* @param  handler：rx_ctrl_handle
*         dcs_packet: dcs 命令
* @retval true/false
*/
static bool ap_dcs_set_enter_sleep_mode(hal_dsi_rx_ctrl_handle_t *handler, hal_dcs_packet_t *dcs_packet)
{
    TAU_LOGD("enter sleep mode \n", panel_display_done);
    if (panel_display_done)
    {
        hal_dsi_tx_ctrl_write_cmd(0x05, 0, 2, 0x10);
    }

#if AP_SWIRE_OUTPUT
    /* Swire close */
    hal_swire_enable(false);
    /* AVDD_EN close*/
    hal_gpio_set_output_data(IO_PAD_AP_PWMEN, IO_LVL_LOW);
#endif

    /* Wait AP reset down*/
    hal_gpio_set_ap_reset_int(ENABLE, ap_rstn_pull_down_cb, DETECT_LOW_LVL);
    return true;
}

/**
* @brief  ap exit sleep mode处理函数
* @param  handler：rx_ctrl_handle
*         dcs_packet: dcs 命令
* @retval true/false
*/
static bool ap_dcs_set_exit_sleep_mode(hal_dsi_rx_ctrl_handle_t *handler, hal_dcs_packet_t *dcs_packet)
{
#if AP_SWIRE_OUTPUT
    /* AVDD 上电, 用于解决息屏开屏PPS不更新问题 */
    hal_gpio_set_output_data(IO_PAD_AP_PWMEN, IO_LVL_HIGH);
#endif

#if TX_START_AFTER_APRST
    if (panel_display_done == false)
    {
        sg_tx_start_in_process = true;
    }
#endif

    TAU_LOGD("exit sleep mode \n");

    return true;
}

/**
* @brief  调光处理函数
* @param  handler：rx_ctrl_handle
*         dcs_packet: dcs 命令
* @retval true/false
*/
static bool ap_dcs_set_backlight(hal_dsi_rx_ctrl_handle_t *handler, hal_dcs_packet_t *dcs_packet)
{
    if (sg_exit_idle_mode_flag)
    {
        hal_dsi_rx_ctrl_set_hw_cmd_filter(g_rx_ctrl_handle, HAL_RX_DCS_FILTER_B, 0x3A, 0x3A);
        sg_exit_idle_mode_flag = false;
        TAU_LOGD("rcv 0x2C now\n");
    }
    uint32_t backlight = dcs_packet->packet_param[1] + (dcs_packet->packet_param[0] << 8);
#if ANALOG_PWM_OUTPUT
    backlight = (backlight * PWM_DUTY_STEP) / 2047;
    backlight = MAX(10, backlight); /* 避免最暗完全黑屏 */
    hal_pwm_set_duty(backlight);
#endif
    TAU_LOGD("BL %d size %d,crc %x\n", backlight, dcs_packet->param_length, dcs_packet->crc_data);
    return true;
}

#if RX_WAIT_TEAR_ON
/**
* @brief  ap set tear on 处理函数
* @param  handler：rx_ctrl_handle
*         dcs_packet: dcs 命令
* @retval true/false
*/
static bool ap_dcs_set_tear_on(hal_dsi_rx_ctrl_handle_t *handler, hal_dcs_packet_t *dcs_packet)
{
    TAU_LOGD("ap_set_tear_on\n");
    sg_ap_set_tear_on = true;
    if (panel_display_done == false)
    {
        TAU_LOGD("gen a tear\n");
        hal_dsi_tx_ctrl_gen_a_tear_signal();
    }
    else
    {
        hal_dsi_tx_ctrl_set_tear_mode(g_tx_ctrl_handle, TE_60HZ_MODE);
    }
    return true;
}

/**
* @brief  ap set tear off 处理函数
* @param  handler：rx_ctrl_handle
*         dcs_packet: dcs 命令
* @retval true/false
*/
static bool ap_dcs_set_tear_off(hal_dsi_rx_ctrl_handle_t *handler, hal_dcs_packet_t *dcs_packet)
{
    TAU_LOGD("ap_set_tear_off \n");
    sg_ap_set_tear_on = false;
    hal_dsi_tx_ctrl_set_tear_mode(g_tx_ctrl_handle, TE_USER_MODE);
    return true;
}
#endif

/**
* @brief  护眼模式回调函数
* @param  rx_ctrl_handle: dsi rx handle;
*         dcs packet: dcs_packet
* @retval true/false
*/
static bool ap_dcs_set_exit_idle_mode(hal_dsi_rx_ctrl_handle_t *handler, hal_dcs_packet_t *dcs_packet)
{
    sg_exit_idle_mode_flag = true;
    hal_dsi_rx_ctrl_set_hw_cmd_filter(g_rx_ctrl_handle, HAL_RX_DCS_FILTER_B, 0x2C, 0x2C);
    TAU_LOGD("exit idle mode,skip 0x2C\n");
    return true;
}

/**
* @brief  帧率切换处理函数
* @param  handler：rx_ctrl_handle
*         dcs_packet: dcs 命令
* @retval true/false
*/
static bool ap_dcs_set_frame_change(hal_dsi_rx_ctrl_handle_t *handler, hal_dcs_packet_t *dcs_packet)
{
    if (dcs_packet->param_length == 1)
    {
        if (dcs_packet->packet_param[0] == 3)
        {
            hal_dsi_tx_ctrl_set_tear_mode(g_tx_ctrl_handle, TE_120HZ_MODE);
        }
        else if (dcs_packet->packet_param[0] == 2)
        {
            hal_dsi_tx_ctrl_set_tear_mode(g_tx_ctrl_handle, TE_60HZ_MODE);
        }
    }
    TAU_LOGD("frame_change %x ,size %d, data %d\n", dcs_packet->dcs_command, dcs_packet->param_length, dcs_packet->packet_param[0]);
    return true;
}

/*************************DCS 命令处理函数 END*************************/

/* 客制化DCS command 处理函数表格 */
static const hal_dcs_execute_entry_t g_cus_rx_dcs_execute_table[] =
{
    {DCS_SET_DISPLAY_ON, ap_dcs_set_display_on, false},
    {DCS_SET_DISPLAY_OFF, ap_dcs_set_display_off, true},
    {0x51, ap_dcs_set_backlight, false},
    {DCS_ENTER_SLEEP_MODE, ap_dcs_set_enter_sleep_mode, true},
    {DCS_EXIT_SLEEP_MODE, ap_dcs_set_exit_sleep_mode, true},
    {0x2F, ap_dcs_set_frame_change, true},
#if RX_WAIT_TEAR_ON
    {DCS_SET_TEAR_ON, ap_dcs_set_tear_on, true},
    {DCS_SET_TEAR_OFF, ap_dcs_set_tear_off, true},
#endif
    {0x38, ap_dcs_set_exit_idle_mode, true},
    {0, NULL, false}                        //{0,NULL,false} 数组最后一个固定成员，作为table结尾的判断标准
};

/**
* @brief  panel reset
* @param  none
* @retval none
*/
static void app_tx_panel_reset(void)
{
#if SHARE_FLASH_ENABLE
    hal_flash_share_mode(true);
#endif
    hal_gpio_set_output_data(IO_PAD_TD_RSTN, IO_LVL_HIGH);
    delayMs(10);
    hal_gpio_set_output_data(IO_PAD_TD_RSTN, IO_LVL_LOW);
    delayMs(50);
    hal_gpio_set_output_data(IO_PAD_TD_RSTN, IO_LVL_HIGH);
    delayMs(10);
}

/**
* @brief  panel init
* @param  none
* @retval none
*/
static void app_init_panel(void)
{
    /* reset panel*/
    app_tx_panel_reset();

#if TFT_FT8720
    TAU_LOGD("TFT_FT8720\n");
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0x00);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 4, 0xff, 0x87, 0x20, 0x01);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0x80);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 3, 0xff, 0x87, 0x20);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0x00);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 5, 0x2A, 0x00, 0x00, 0x04, 0x37); //1080x2400
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0x00);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 5, 0x2B, 0x00, 0x00, 0x09, 0x5F); //1080x2400
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0xa3);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 5, 0xb3, 0x09, 0x60, 0x00, 0x18); //1080x2400
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0x60);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 7, 0xC0, 0x00, 0x87, 0x00, 0x85, 0x00, 0x13);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0x70);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 8, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x0F, 0x02, 0x58);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0x79);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 4, 0xC0, 0x15, 0x00, 0xE5);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0x80);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 7, 0xC0, 0x00, 0x87, 0x00, 0x85, 0x00, 0x13);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0x90);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 7, 0xC0, 0x00, 0x87, 0x00, 0x85, 0x00, 0x13);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0xA0);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 7, 0xC0, 0x00, 0x87, 0x00, 0x85, 0x00, 0x13);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0xB0);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 6, 0xC0, 0x00, 0x93, 0x00, 0x85, 0x13);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0xA3);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 7, 0xC1, 0x00, 0x41, 0x00, 0x32, 0x00, 0x02);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0x80);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 9, 0xCE, 0x01, 0x81, 0xFF, 0xFF, 0x00, 0xC0, 0x00, 0xC0);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0x8C);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 5, 0xCE, 0x00, 0xC0, 0x00, 0xC0);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0x90);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 15, 0xCE, 0x00, 0x90, 0x0E, 0x10, 0x00, 0x90, 0x80, 0xFF, 0xFF, 0x00, 0x04, 0x00, 0x0F, 0x0F);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0xA0);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 4, 0xCE, 0x00, 0x00, 0x00);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0xB0);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 4, 0xCE, 0x22, 0x00, 0x00);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0xE1);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 6, 0xCE, 0x0A, 0x02, 0x58, 0x02, 0x58);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0xF1);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 3, 0xCE, 0x15, 0x15);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0xF4);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 5, 0xCE, 0x00, 0xE5, 0x00, 0xE5);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0xB0);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 5, 0xCF, 0x00, 0x00, 0xAE, 0xB2);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0xB5);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 5, 0xCF, 0x04, 0x04, 0xE7, 0xEB);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0xC0);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 5, 0xCF, 0x09, 0x09, 0x1F, 0x23);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0xC5);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 5, 0xCF, 0x09, 0x09, 0x25, 0x29);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0xD1);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 13, 0xC1, 0x05, 0x5D, 0x07, 0x82, 0x0C, 0xF2, 0x05, 0x5D, 0x07, 0x82, 0x0C, 0xF2);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0xE1);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 3, 0xC1, 0x07, 0x82);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0xE4);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 13, 0xCF, 0x09, 0xBD, 0x09, 0xBC, 0x09, 0xBC, 0x09, 0xBC, 0x09, 0xBC, 0x09, 0xBC);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0x80);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 3, 0xC1, 0x33, 0x33);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0x90);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0xC1, 0x02);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0xCC);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0xC1, 0x18);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0xE0);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0xC1, 0x00);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0x91);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0xC4, 0x88);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0x80);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 9, 0xC2, 0x82, 0x02, 0x1f, 0x1f, 0x00, 0x00, 0x00, 0x00);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0x90);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 5, 0xC2, 0x00, 0x0, 0x00, 0x00);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0xA0);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 16, 0xC2, 0x00, 0x01, 0x00, 0x28, 0x9B, 0x01, 0x02, 0x00, 0x28, 0x9B, 0x02, 0x03, 0x00, 0x28, 0x9B);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0xB0);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 11, 0xC2, 0x03, 0x04, 0x00, 0x28, 0x9B, 0x80, 0x08, 0x03, 0x00, 0x00);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0xCA);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 6, 0xC2, 0x80, 0x08, 0x03, 0x00, 0x00);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0xE0);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 6, 0xC2, 0x33, 0x33, 0x70, 0x00, 0x70);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0xE8);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 9, 0xC2, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0xD0);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 17, 0xC3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0x80);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 17, 0xCB, 0x00, 0x01, 0x00, 0x03, 0xCD, 0x01, 0x02, 0x00, 0x00, 0x00, 0xCD, 0x01, 0x00, 0x03, 0x00, 0x00);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0x90);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 17, 0xCB, 0x00, 0x00, 0x00, 0x0C, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0xA0);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 9, 0xCB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0xB0);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 5, 0xCB, 0x13, 0x58, 0x05, 0x30);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0xC0);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 5, 0xCB, 0x13, 0x58, 0x05, 0x30);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0xD5);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 12, 0xCB, 0x83, 0x00, 0x83, 0x83, 0x00, 0x83, 0x83, 0x00, 0x83, 0x83, 0x00);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0xE0);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 14, 0xCB, 0x83, 0x83, 0x00, 0x83, 0x83, 0x00, 0x83, 0x83, 0x00, 0x83, 0x83, 0x00, 0x83);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0xCA);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0xC0, 0x80);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0x80);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 17, 0xCC, 0x23, 0x12, 0x23, 0x1C, 0x23, 0x0A, 0x23, 0x23, 0x09, 0x08, 0x07, 0x06, 0x23, 0x23, 0x23, 0x23);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0x90);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 9, 0xCC, 0x23, 0x18, 0x16, 0x17, 0x23, 0x19, 0x1A, 0x1B);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0xA0);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 17, 0xCC, 0x23, 0x12, 0x23, 0x1D, 0x23, 0x0a, 0x23, 0x23, 0x06, 0x07, 0x08, 0x09, 0x23, 0x23, 0x23, 0x23);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0xB0);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 9, 0xCC, 0x23, 0x18, 0x16, 0x17, 0x23, 0x19, 0x1A, 0x1B);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0x80);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 17, 0xCD, 0x23, 0x23, 0x23, 0x02, 0x23, 0x0A, 0x23, 0x23, 0x09, 0x08, 0x07, 0x06, 0x23, 0x23, 0x23, 0x23);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0x90);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 9, 0xCD, 0x23, 0x18, 0x16, 0x17, 0x23, 0x19, 0x1A, 0x1B);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0xA0);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 17, 0xCD, 0x23, 0x23, 0x23, 0x02, 0x23, 0x0a, 0x23, 0x23, 0x06, 0x07, 0x08, 0x09, 0x23, 0x23, 0x23, 0x23);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0xB0);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 9, 0xCD, 0x23, 0x18, 0x16, 0x17, 0x23, 0x19, 0x1A, 0x1B);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0x89);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 4, 0xC0, 0x01, 0x21, 0x01);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0x69);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 4, 0xC0, 0x01, 0x21, 0x05);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0x82);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 3, 0xa7, 0x10, 0x00);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0x8d);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0xa7, 0x01);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0x8f);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0xa7, 0x01);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0x93);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0xC5, 0x37);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0x97);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0xC5, 0x37);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0x9A);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0xC5, 0x32);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0x9C);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0xC5, 0x32);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0xB6);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 9, 0xC5, 0x10, 0x10, 0x0E, 0x0E, 0x10, 0x10, 0x0E, 0x0E);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0x88);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0xC4, 0x08);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0x80);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0xA7, 0x03); // R -> G -> B rotate
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0x00);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x1C, 0x02);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0xC3);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0xC5, 0xff);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0xFA);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0xC2, 0x23);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0x90);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0xC3, 0x08);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0x80);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0xB3, 0x22);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0xB0);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0xB3, 0x00);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0x83);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0xB0, 0x63);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0x82);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0xF5, 0x01);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0x93);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0xF5, 0x01);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0x9b);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0xF5, 0x49);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0x9d);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0xF5, 0x49);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0xbe);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 3, 0xc5, 0xF0, 0xF0);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0xdc);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0xc3, 0x37);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0xA0);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 4, 0xC3, 0x31, 0x21, 0x00);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0xA4);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 3, 0xC3, 0x01, 0x20);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0x8D);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0xc5, 0x01);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0x8a);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0xc5, 0x00);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0x99);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0xCF, 0x50);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0x9C);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0xF5, 0x00);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0x9E);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0xF5, 0x00);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0xB0);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 7, 0xC5, 0xD0, 0x4A, 0x31, 0xD0, 0x4A, 0x0C);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0x94);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0xe9, 0xff);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0x00);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 41, 0xE1, 0x00, 0x00, 0x03, 0x08, 0x30, 0x13, 0x1C, 0x23, 0x2E, 0x0B, 0x38, 0x3F, 0x46, 0x4C, 0x29, 0x51, 0x5A, 0x62, 0x6A, 0xAE, 0x72, 0x7A, 0x82, 0x8B, 0x45, 0x95, 0x9B, 0xA1, 0xA9, 0x58, 0xB1, 0xBC, 0xC9, 0xD2, 0xDF, 0xDD, 0xED, 0xF8, 0xFF, 0x90);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0x30);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 41, 0xE1, 0x00, 0x00, 0x03, 0x08, 0x30, 0x13, 0x1C, 0x23, 0x2E, 0x0B, 0x38, 0x3F, 0x46, 0x4C, 0x29, 0x51, 0x5A, 0x62, 0x6A, 0xAE, 0x72, 0x7A, 0x82, 0x8B, 0x45, 0x95, 0x9B, 0xA1, 0xA9, 0x58, 0xB1, 0xBC, 0xC9, 0xD2, 0xDF, 0xDD, 0xED, 0xF8, 0xFF, 0x90);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0x60);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 41, 0xE1, 0x00, 0x00, 0x03, 0x08, 0x30, 0x13, 0x1C, 0x23, 0x2E, 0x0B, 0x38, 0x3F, 0x46, 0x4C, 0x29, 0x51, 0x5A, 0x62, 0x6A, 0xAE, 0x72, 0x7A, 0x82, 0x8B, 0x45, 0x95, 0x9B, 0xA1, 0xA9, 0x58, 0xB1, 0xBC, 0xC9, 0xD2, 0xDF, 0xDD, 0xED, 0xF8, 0xFF, 0x90);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0x90);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 41, 0xE1, 0x00, 0x00, 0x03, 0x08, 0x30, 0x13, 0x1C, 0x23, 0x2E, 0x0B, 0x38, 0x3F, 0x46, 0x4C, 0x29, 0x51, 0x5A, 0x62, 0x6A, 0xAE, 0x72, 0x7A, 0x82, 0x8B, 0x45, 0x95, 0x9B, 0xA1, 0xA9, 0x58, 0xB1, 0xBC, 0xC9, 0xD2, 0xDF, 0xDD, 0xED, 0xF8, 0xFF, 0x90);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0xC0);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 41, 0xE1, 0x00, 0x00, 0x03, 0x08, 0x30, 0x13, 0x1C, 0x23, 0x2E, 0x0B, 0x38, 0x3F, 0x46, 0x4C, 0x29, 0x51, 0x5A, 0x62, 0x6A, 0xAE, 0x72, 0x7A, 0x82, 0x8B, 0x45, 0x95, 0x9B, 0xA1, 0xA9, 0x58, 0xB1, 0xBC, 0xC9, 0xD2, 0xDF, 0xDD, 0xED, 0xF8, 0xFF, 0x90);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0xF0);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 17, 0xE1, 0x00, 0x00, 0x03, 0x08, 0x30, 0x13, 0x1C, 0x23, 0x2E, 0x0B, 0x38, 0x3F, 0x46, 0x4C, 0x29, 0x51);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0x00);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 25, 0xE2, 0x5A, 0x62, 0x6A, 0xAE, 0x72, 0x7A, 0x82, 0x8B, 0x45, 0x95, 0x9B, 0xA1, 0xA9, 0x58, 0xB1, 0xBC, 0xC9, 0xD2, 0xDF, 0xDD, 0xED, 0xF8, 0xFF, 0x90);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0xE8);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0xC0, 0x40);

#if 0
    /* bist mode*/
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0x88);
    delayUs(50);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0xf6, 0x5a);
    delayUs(50);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0x00);
    delayUs(50);
#endif

    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 2, 0x00, 0x00);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 4, 0xFF, 0xFF, 0xFF, 0xFF);

    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 1, 0x11);
    delayMs(120);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 1, 0x29);

#elif AMOLED_NT37280
    TAU_LOGD("NT37280\n");
    hal_dsi_tx_ctrl_write_cmd(0x15, 0, 2, 0xFF, 0xE0);
    hal_dsi_tx_ctrl_write_cmd(0x15, 0, 2, 0xFB, 0x01);
    hal_dsi_tx_ctrl_write_cmd(0x15, 0, 2, 0x18, 0x80);
    hal_dsi_tx_ctrl_write_cmd(0x15, 0, 2, 0x1A, 0x15);
    hal_dsi_tx_ctrl_write_cmd(0x15, 0, 2, 0x73, 0x01);
    hal_dsi_tx_ctrl_write_cmd(0x15, 0, 2, 0x89, 0x7F);
    hal_dsi_tx_ctrl_write_cmd(0x15, 0, 2, 0x0D, 0x9B);
    hal_dsi_tx_ctrl_write_cmd(0x15, 0, 2, 0x46, 0x17);

    hal_dsi_tx_ctrl_write_cmd(0x15, 0, 2, 0xFF, 0xF0);
    hal_dsi_tx_ctrl_write_cmd(0x15, 0, 2, 0xFB, 0x01);
    hal_dsi_tx_ctrl_write_cmd(0x15, 0, 2, 0x54, 0x03);
    hal_dsi_tx_ctrl_write_cmd(0x15, 0, 2, 0x9C, 0x00);

    hal_dsi_tx_ctrl_write_cmd(0x15, 0, 2, 0xFF, 0x20);
    hal_dsi_tx_ctrl_write_cmd(0x15, 0, 2, 0xFB, 0x01);
    hal_dsi_tx_ctrl_write_cmd(0x15, 0, 2, 0x34, 0x00);
    hal_dsi_tx_ctrl_write_cmd(0x15, 0, 2, 0x35, 0x66);
    hal_dsi_tx_ctrl_write_cmd(0x15, 0, 2, 0x36, 0x66);

    hal_dsi_tx_ctrl_write_cmd(0x15, 0, 2, 0xFF, 0x10);
    hal_dsi_tx_ctrl_write_cmd(0x15, 0, 2, 0xFB, 0x01);
    hal_dsi_tx_ctrl_write_cmd(0x15, 0, 2, 0x88, 0x07);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 5, 0x2A, 0x00, 0x00, 0x04, 0x37);
    hal_dsi_tx_ctrl_write_cmd(0x39, 0, 5, 0x2B, 0x00, 0x00, 0x08, 0xE7);
    hal_dsi_tx_ctrl_write_cmd(0x15, 0, 2, 0x7F, 0x07);
    hal_dsi_tx_ctrl_write_cmd(0x15, 0, 2, 0xE9, 0x00);
#if !TX_USE_CMD_MODE
    hal_dsi_tx_ctrl_write_cmd(0x15, 0, 2, 0xBB, 0x13);
#endif
    hal_dsi_tx_ctrl_write_cmd(0x15, 0, 2, 0xBF, 0x00);
    hal_dsi_tx_ctrl_write_cmd(0x15, 0, 2, 0xC0, 0x00);
#if TX_USE_CMD_MODE
    hal_dsi_tx_ctrl_write_cmd(0x15, 0, 2, 0x35, 0x00);
#endif
    hal_dsi_tx_ctrl_write_cmd(0x29, 0, 3, 0x51, 0x0F, 0xFF);

    hal_dsi_tx_ctrl_write_cmd(0x05, 0, 1, 0x11);

#if TX_USE_CMD_MODE
    delayMs(20);
    hal_dsi_tx_ctrl_write_cmd(0x05, 0, 2, 0x29);
#endif

#endif
    delayUs(50);
}

#if TX_CMD_MODE_WITHOUT_TE
/**
* @brief  MIPI RX事件处理函数,demo code 用于command mode 输出发送数据（模式1）
* @param  event:RX事件
* @param  data: user data
* @retval none
*/
static void app_rx_event_cb(hal_rx_event_e event, void *data)
{
    if (panel_display_done && event == HAL_RX_LINE_EVENT)
    {
        hal_dsi_tx_ctrl_gen_a_frame();
    }
}
#endif

#if TX_USE_CMD_MODE
/**
* @brief  TE引脚作为GPIO 输入回调函数,demo code 用于command mode 输出发送数据（模式2）
* @param  none
* @retval none
*/
static void app_tx_cmd_panel_te_cb(void *data)
{
    if (panel_display_done)
    {
        //delayUs(25); /* 撕裂调试 */
        hal_dsi_tx_ctrl_gen_a_frame();
    }
}

/**
* @brief  注册屏端TE信号输入引脚回调函数
* @param  pad :TE输入pad
* @param  trig:触发中断沿配置
* @retval none
*/
static void app_tx_cmd_app_init_panel_te_int(io_pad_e pad, sys_cfg_trigger_e trig)
{
    /*1.关闭中断*/
    hal_gpio_ctrl_eint(pad, DISABLE);

    /*2.中断初始化*/
    hal_gpio_init_eint(pad, trig);

    /*3.注册回调*/
    hal_gpio_reg_eint_cb(pad, app_tx_cmd_panel_te_cb);

    /*4.使能中断*/
    hal_gpio_ctrl_eint(pad, ENABLE);
}
#endif

/**
* @brief  mipi rx 初始化
* @param  none
* @retval none
*/
static void app_mipi_rx_init(void)
{
    if (g_rx_ctrl_handle == NULL)
    {
        /* 创建rx   ctrl handle */
        g_rx_ctrl_handle = hal_dsi_rx_ctrl_create_handle();
    }
    /* 配置参数 */
    g_rx_ctrl_handle->base_info.src_w = INPUT_WIDTH;
    g_rx_ctrl_handle->base_info.src_h = INPUT_HEIGHT;
    g_rx_ctrl_handle->base_info.dst_w = OUTPUT_WIDTH;
    g_rx_ctrl_handle->base_info.dst_h = OUTPUT_HEIGHT;
    g_rx_ctrl_handle->base_info.src_frate = INPUT_FRAME_RATE;
    g_rx_ctrl_handle->base_info.src_mode = INPUT_DATA_MODE;
    g_rx_ctrl_handle->base_info.dst_mode = OUTPUT_DATA_MODE;
    g_rx_ctrl_handle->rx_color_mode = INPUT_COLOR_MODE;
    g_rx_ctrl_handle->rx_lanes = INPUT_MIPI_LANE_NUM;
    g_rx_ctrl_handle->rx_nonburst_models = INPUT_VIDEO_MODEL; /* 可不配置 */
    g_rx_ctrl_handle->compress_en = INPUT_COMPRESS;
    g_rx_ctrl_handle->rx_hsclk_rate = INPUT_MIPI_LANE_RATE;
    g_rx_ctrl_handle->cus_dcs_entry_table = g_cus_rx_dcs_execute_table; /* 注册 DCS处理列表 */
    g_rx_ctrl_handle->rx_dcs_read_entry = ap_dcs_read; /* 注册dsc read 回调函数,可选,此函数为空时由cus_dcs_entry_table执行 */
#if RX_RESOLUTION_CHANGE_ENABLE
    g_rx_ctrl_handle->pps_update_entry = pps_update_handle;
#endif
    /* 提前预置PPS,  AP 有PPS cmd也会更新 */
    if (g_rx_ctrl_handle->compress_en == true)
    {
        uint8_t pps[128] = {0x11, 0x00, 0x00, 0xAB, 0x30, 0x80, 0x09, 0x60,
                            0x04, 0x38, 0x00, 0x0C, 0x04, 0x38, 0x04, 0x38,
                            0x02, 0x00, 0x03, 0x1C, 0x00, 0x20, 0x01, 0x7E,
                            0x00, 0x0F, 0x00, 0x0C, 0x08, 0xBB, 0x04, 0x3D,
                            0x18, 0x00, 0x10, 0xF0, 0x07, 0x10, 0x20, 0x00,
                            0x06, 0x0F, 0x0F, 0x33, 0x0E, 0x1C, 0x2A, 0x38,
                            0x46, 0x54, 0x62, 0x69, 0x70, 0x77, 0x79, 0x7B,
                            0x7D, 0x7E, 0x02, 0x02, 0x22, 0x00, 0x2A, 0x40,
                            0x2A, 0xBE, 0x3A, 0xFC, 0x3A, 0xFA, 0x3A, 0xF8,
                            0x3B, 0x38, 0x3B, 0x78, 0x3B, 0xB6, 0x4B, 0xF6,
                            0x4C, 0x34, 0x4C, 0x74, 0x5C, 0x74, 0x8C, 0xF4,
                            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
                           };
        hal_dsi_rx_ctrl_pre_init_pps(g_rx_ctrl_handle, pps, 128);
    }

    /* 初始化rx ctrl */
    hal_dsi_rx_ctrl_init(g_rx_ctrl_handle);

#if RX_READ_HW_ACK
    /* 配置硬件回复 */
    app_set_dcs_hw_ack();
#endif

#if TX_CMD_MODE_WITHOUT_TE
    /* 注册接收一帧帧头事件回调,每接收一帧数据TX再往外发一帧 */
    //hal_dsi_rx_ctrl_register_callback(g_rx_ctrl_handle, app_rx_event_cb, HAL_RX_FS_EVENT, true, NULL);
    /* 注册接收第0行数据事件,接收到数据后再往外发送数据,确保不撕裂 */
    uint32_t line = 0;
    hal_dsi_rx_ctrl_register_callback(g_rx_ctrl_handle, app_rx_event_cb, HAL_RX_LINE_EVENT, true, &line);
#endif

#if RX_START_WITHOUT_RST
    /* 等待ap reset置位再启动rx,否则容易收到错误数据 */
    hal_dsi_rx_ctrl_start(g_rx_ctrl_handle);
#else
    /* 注册RX start callback,确认RX LP11时再启动RX,防止接收错误数据 */
    hal_gpio_set_ap_reset_int(ENABLE, app_mipi_rx_start_cb, DETECT_HIGH_LVL);
#endif
}

/**
* @brief  mipi tx 初始化
* @param  none
* @retval none
*/
static void app_mipi_tx_init(void)
{
    if (g_tx_ctrl_handle == NULL)
    {
        g_tx_ctrl_handle = hal_dsi_tx_ctrl_create_handle();
    }
    g_tx_ctrl_handle->channel_id = OUTPUT_VC;
    g_tx_ctrl_handle->lane_num = OUTPUT_LANE_NUMBER;
    g_tx_ctrl_handle->vid_mode = OUTPUT_VIDEO_MODEL;
    g_tx_ctrl_handle->cmd_tx_type = TX_INIT_TYPE;
    g_tx_ctrl_handle->dpi_vsa = OUTPUT_VSA;
    g_tx_ctrl_handle->dpi_vbp = OUTPUT_VBP;
    g_tx_ctrl_handle->dpi_vfp = OUTPUT_VFP;
    g_tx_ctrl_handle->dpi_hsa = OUTPUT_HSA;
    g_tx_ctrl_handle->dpi_hbp = OUTPUT_HBP;
    g_tx_ctrl_handle->dpi_hfp = OUTPUT_HFP;
    g_tx_ctrl_handle->base_info.src_w = INPUT_WIDTH;
    g_tx_ctrl_handle->base_info.src_h = INPUT_HEIGHT;
    g_tx_ctrl_handle->base_info.dst_w = OUTPUT_WIDTH;
    g_tx_ctrl_handle->base_info.dst_h = OUTPUT_HEIGHT;
    g_tx_ctrl_handle->base_info.src_frate = INPUT_FRAME_RATE;
    g_tx_ctrl_handle->base_info.src_mode = INPUT_DATA_MODE;
    g_tx_ctrl_handle->base_info.dst_mode = OUTPUT_DATA_MODE;
    /* 初始化屏时每一条LP CMD都退出LPDT 再进入发送下一条 */
    /* 解决FT8720 TDDI 显示翻转问题 */
    g_tx_ctrl_handle->lp_exit_lpdt = true;

    hal_dsi_tx_ctrl_init(g_tx_ctrl_handle);

    /* FIXME set tear on*/
    hal_dsi_tx_ctrl_set_tear_mode(g_tx_ctrl_handle, TE_60HZ_MODE);

    /* AP 没有发送数据时默认的显示颜色, 量产为0 0 0(黑色), 配置其他颜色仅为debug使用 */
    hal_dsi_tx_ctrl_set_overwrite_rgb(0x00, 0x00, 0xFF);
}

#if !RX_START_WITHOUT_RST
/**
* @brief  mipi rx start函数,开启AP RSTN等待启动配置后使用
* @param  none
* @retval none
*/
static void app_mipi_rx_start_cb(void *data)
{
    /* RX start */
    hal_dsi_rx_ctrl_start(g_rx_ctrl_handle);
    /* close cb */
    hal_gpio_set_ap_reset_int(DISABLE, NULL, DETECT_HIGH_LVL);
    TAU_LOGD("rx start\n");
}
#endif

/**
* @brief  mipi tx 启动
* @param  none
* @retval none
*/
static void app_mipi_tx_start(void)
{
    /* Init panel */
    app_init_panel();
#if AP_SWIRE_OUTPUT
    hal_swire_enable(true);
    hal_swire_set_pulse(41);
#endif

    /* TX start */
    hal_dsi_tx_ctrl_start(g_tx_ctrl_handle);

#if RX_WAIT_TEAR_ON
    te_mode_e default_te = sg_ap_set_tear_on ? TE_60HZ_MODE : TE_USER_MODE;
    hal_dsi_tx_ctrl_set_tear_mode(g_tx_ctrl_handle, default_te);
#else
    hal_dsi_tx_ctrl_set_tear_mode(g_tx_ctrl_handle, TE_60HZ_MODE);
#endif

    panel_display_done = true;

    delayMs(20);
    /* Display on */
    hal_dsi_tx_ctrl_write_cmd(0x05, 0, 2, 0x29);

#if AP_SWIRE_OUTPUT
    hal_swire_set_pulse(SWIRE_DEFAULT_PULSE);
#endif

#if (TX_USE_CMD_MODE & (!TX_CMD_MODE_WITHOUT_TE))
    // hal_dsi_tx_ctrl_gen_a_frame(); /* FIXME */
    app_tx_cmd_app_init_panel_te_int(IO_PAD_AP_TE, DETECT_RISING_EDGE); /* 注册屏端TE中断 */
#endif

    TAU_LOGD("tx_start \n");
}

/**
* @brief  ap rstn 拉高中断回调,用于息屏唤醒
* @param  none
* @retval none
*/
static void ap_rstn_pull_high_cb(void *data)
{
    /* system resume begin */
    sg_system_resume = true;
    /* 关闭AP reset检查     */
    hal_gpio_set_ap_reset_int(DISABLE, NULL, DETECT_HIGH_LVL);
}

/**
* @brief  ap rstn 拉高中断回调,用于息屏待机
* @param  none
* @retval none
*/
static void ap_rstn_pull_down_cb(void *data)
{
    sg_system_suspend = true;
    /* 关闭AP reset检查     */
    hal_gpio_set_ap_reset_int(DISABLE, NULL, DETECT_HIGH_LVL);
    TAU_LOGD("ap_rstn_pull_down_cb\n");
}

/**
* @brief  GPIO初始化配置,根据实际原理图提前配置IO功能以及状态,默认功能可不配置
*         TP相关I2C/SPI 在tp_transfer.c,也可以挪到此函数初始化
* @param  none
* @retval none
*/
void app_gpio_init(void)
{
    io_pad_attr_t attrs[] =
    {
        {IO_PIN_8,  PIN8_MODE_GPIO7,     IO_IOE_OUTPUT, IO_LVL_LOW},/* PIN_8(TD_RSTN), GPIO,输出,低电平 */
        {IO_PIN_17, PIN17_MODE_GPIO8,   IO_IOE_OUTPUT, IO_LVL_LOW}, /* PIN_17(PWMEN), GPIO,输出,低电平 */
        {IO_PIN_16, PIN16_MODE_GPIO2,   IO_IOE_OUTPUT, IO_LVL_LOW}, /* PIN_16(AP_INT),GPIO,输出,低电平 */
#if (TX_USE_CMD_MODE & (!TX_CMD_MODE_WITHOUT_TE))
        {IO_PIN_29, PIN29_MODE_GPIO3,   IO_IOE_INPUT, IO_LVL_NONE}, /* PIN_29(AP_TE), GPIO,输入 */
#else
        {IO_PIN_29, PIN29_MODE_TEAR,    IO_IOE_NONE, IO_LVL_NONE},  /* PIN_29(AP_TE), 硬件TEAR输出模式 */
#endif
    };
    uint8_t size = sizeof(attrs) / sizeof(io_pad_attr_t);
    hal_gpio_config_pad(attrs, size);
}

/**
* @brief  显示相关模块初始化,包括MIPI RX/TX/PWM/SWIRE/GPIO等
* @param  none
* @retval none
*/
void app_display_init(void)
{
    /* mipi rx初始化 */
    app_mipi_rx_init();

    /* VCC 主供电,等待VCC Power Ready,此时RX初始化完成可以响应MIPI命令 */
    if (MAIN_POWER_SELECT == PWR_SEL_VCC)
    {
        while (hal_pwr_get_vcc_power_ready() == false);
    }

    /* GPIO 初始化   */
    app_gpio_init();

    /* 背光初始化      */
#if AP_SWIRE_OUTPUT
    hal_swire_init();   /*  swire init */
    hal_swire_set_timer(TIMER_NUM0, 16, true); /* swire连续发送,绑定timer进行发送 */
#endif
#if ANALOG_PWM_OUTPUT
    if (hal_pwm_init(PWM_FREQUENCY, PWM_DUTY_STEP))
    {
        hal_pwm_enable(true);
        hal_pwm_set_elvcc_output(true);
    }
#endif

    /* mipi tx 初始化*/
    app_mipi_tx_init();

#if TX_START_AFTER_APRST
    TAU_LOGD("wait exit sleep mode\n");
#else
    app_mipi_tx_start();
#endif
}

/**
* @brief  系统resume
* @param  sleep_mode: sleep 模式
* @retval none
*/
static void app_system_resume(pwr_sleep_mode_e sleep_mode)
{
    /* 退出sleep mode, 电源切换 */
    hal_pwr_exit_sleep_mode();

    /* display resume */
    app_display_init();

#if TOUCH_ENABLE
    /* touch resume */
    app_tp_write_other_operations(NULL, 0);
#endif
    TAU_LOGD("system resume\n");
}

/**
* @brief  系统suspend,进入sleep mode
* @param  sleep_mode: sleep 模式
* @retval none
*/
static void app_system_suspend(pwr_sleep_mode_e sleep_mode)
{
    /* 关闭图像通路 */
    hal_dsi_tx_ctrl_stop(g_tx_ctrl_handle);
    hal_dsi_tx_ctrl_deinit(g_tx_ctrl_handle);
    hal_dsi_rx_ctrl_stop(g_rx_ctrl_handle);
    hal_dsi_rx_ctrl_deinit(g_rx_ctrl_handle);

    /* Tear拉低 */
    hal_gpio_init_output(IO_PAD_AP_TE, IO_LVL_LOW);
    panel_display_done = false;
#if RX_WAIT_TEAR_ON
    sg_ap_set_tear_on = false;
#endif

    /* 关闭外设 比如Swire/I2C/Flash 等 */
#if AP_SWIRE_OUTPUT
    hal_swire_deinit();
#endif
#if ANALOG_PWM_OUTPUT
    hal_pwm_deinit();
#endif

#if SHARE_FLASH_ENABLE
    hal_flash_share_mode(false);
#endif

    /* 切换TP18 供电 */
    hal_pwr_set_sleep_mode_power(SLEEP_MODE_POWER);

    if (sleep_mode == PWR_NORMAL_SLEEP_MODE)
    {
        /* normal sleep mode, MCU可以正常工作 */
        hal_gpio_set_ap_reset_int(ENABLE, ap_rstn_pull_high_cb, DETECT_HIGH_LVL);
        hal_pwr_enter_normal_sleep_mode();
    }
    else if (sleep_mode == PWR_STOP_SLEEP_MODE)
    {
        /* 注册对应 wakeup IO */
        hal_pwr_set_stop_sleep_wakeup_pin(IO_PAD_AP_RSTN, WUP_RISING_EDGE);
        //hal_pwr_set_stop_sleep_wakeup_pin(IO_PAD_AP_SPIS_CSN, WUP_FALLING_EDGE);
        //hal_pwr_set_stop_sleep_wakeup_pin(IO_PAD_TD_INT, WUP_FALLING_EDGE);
        io_pad_e wakeup_io = hal_pwr_enter_stop_sleep_mode();
        if (wakeup_io == IO_PAD_AP_RSTN)
        {
            sg_system_resume = true;
        }
        else
        {
            /* Not impletmented */
            TAU_LOGD("wakeup_io %d FIXME touch wakeup convert to AP\n", wakeup_io);
            hal_gpio_set_ap_reset_int(ENABLE, ap_rstn_pull_high_cb, DETECT_HIGH_LVL);
        }
    }
    else
    {
        /* deep sleep mode,配置AP RSTN 上升沿,TD INT 下降沿唤醒 */
        hal_pwr_enter_deep_sleep_mode(WUP_RISING_EDGE, WUP_FALLING_EDGE);
    }

}

/**
* @brief  系统process处理函数,处理待机唤醒等
* @param  none
* @retval none
*/
static void app_system_process(void)
{
    if (sg_system_suspend)
    {
        /* 系统进入sleep mode */
        app_system_suspend(SLEEP_MODE_SELECT);
        sg_system_suspend = false;
    }

    if (sg_system_resume)
    {
        /* 系统退出sleep mode */
        app_system_resume(SLEEP_MODE_SELECT);
        sg_system_resume = false;
    }

#if TX_START_AFTER_APRST
    if (sg_tx_start_in_process)
    {
        app_mipi_tx_start();
        sg_tx_start_in_process = false;
    }
#endif
}



/**
* @brief  mi12 lite demo 主函数
* @param  none
* @retval none
*/
void mi12_lite_demo(void)
{
    /* 电源选择,上电只需要选择一次 */
    hal_pwr_set_main_power(MAIN_POWER_SELECT);        /* 切换供电*/

    /* 显示模块初始 */
    app_display_init();

    /* touch 相关模块初始化 */
#if TOUCH_ENABLE
    /* TP 初始化 */
    app_tp_init();
    app_tp_phone_clear_reset_on();
    /* 与屏的TP 模块通讯并初始化 */
    app_tp_transfer_screen_start();
#endif

    TAU_LOGD("MI12lite demo init done \n");

    while (1)
    {
#if TOUCH_ENABLE
        /* 等待屏TP中断上报做TP协议转换,注意接口实现不可阻塞!否则会影响sleep mode */
        app_tp_transfer_screen_int();
#endif
        /* DCS 命令异步处理 */
        while (hal_dsi_rx_ctrl_dcs_async_handler(g_rx_ctrl_handle));

        /* 系统事件处理(sleep mode) */
        app_system_process();
    }
}
#endif
