/*******************************************************************************
*
*
* File:         demo_hal_dsi_rx.c
* Description:  dsi rx 测试文件
* Version:      V0.1
* Date:         2020-06-12
* Author:       lzy
 *******************************************************************************/

#include "tau_device_datatype.h"
#include "tau_log.h"
#include "tau_operations.h"
#include "tau_common.h"
#include "hal_dsi_rx_ctrl.h"

#ifdef LOG_TAG
#undef LOG_TAG
#endif
#define LOG_TAG "demo_hal_dsi_rx"

//客户可配参数
//输入配置
#define INPUT_WIDTH  720
#define INPUT_HEIGHT 1280
//输入 MIPI lane rate,video mode 下需要计算delay, command mode可以不设置或者随便设置
#define INPUT_MIPI_LANE_RATE 481000000
//输入图像格式
#define INPUT_COLOR_MODE DSI_RGB888
//输出数据格式(DSI_DATA_CMD_MODE , DSI_DATA_VIDEO_MODE)
#define INPUT_DATA_MODE DSI_DATA_VIDEO_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 false

//输出配置
#define OUTPUT_WIDTH 720
#define OUTPUT_HEIGHT 1280

static hal_dsi_rx_ctrl_handle_t *g_rx_ctrl_handle = NULL;

//客制化DCS处理函数
static bool cus_dsc_execute(hal_dsi_rx_ctrl_handle_t *handler, hal_dcs_packet_t *dcs_packet)
{
    TAU_LOGD("cus_dsc_execute DCS[0x%x]\n", dcs_packet->dcs_command);
    for (int i = 0; i < dcs_packet->param_length; i ++)
    {
        TAU_LOGD("cus_dsc_execute param[%d]:0x%x\n", i, dcs_packet->packet_param[i]);
    }

#if 0
    /* ack long cmd */
    hal_dsi_rx_ctrl_send_ack_cmd(g_rx_ctrl_handle,
                                 DSI_ACK_DT_GEN_LONG_RESPONSE,
                                 DSI_VC_0,
                                 5,
                                 0x1,
                                 0x2,
                                 0x3,
                                 0x4,
                                 0x5);
#else
    /* ack short cmd */
    hal_dsi_rx_ctrl_send_ack_cmd(g_rx_ctrl_handle,
                                 DSI_ACK_DT_DCS_SHORT_RESPONSE_1B,
                                 DSI_VC_0,
                                 1,
                                 0xC1);
#endif
    return true;
}

static bool ap_dcs_read(uint8_t data_type, uint8_t dcs_cmd, uint8_t param)
{
    if (dcs_cmd == 0xaa)
    {
        uint8_t cmd[] = {DSI_ACK_DT_DCS_LONG_RESPONSE,
                         212, 0, 1,
                         0x21, 0x07, 0x2C, 0x27, 0x2B, 0x7A, 0x78, 0x7A,
                         0x7D, 0x7D, 0x7E, 0x7F, 0x7E, 0x7E, 0x7F, 0x7F,
                         0x71, 0xE8, 0x36, 0x2A, 0x2E, 0x07, 0x89, 0x17,
                         0x8B, 0x84, 0x28, 0x26, 0x6D, 0xEB, 0x12, 0x34,
                         0x79, 0x78, 0x79, 0x7C, 0x7C, 0x7C, 0x7C, 0x7C,
                         0x7D, 0x7D, 0x7E, 0x7F, 0x7E, 0x7E, 0x7F, 0x7F,
                         0x7C, 0x67, 0x6E, 0x6c, 0x8A, 0x5B, 0x71, 0x00,
                         0x7D, 0x7D, 0x7E, 0x7F, 0x7E, 0x7E, 0x7F, 0x7F,
                         0x7d, 0x68, 0x61, 0xd9, 0x1A, 0x5B, 0xa7, 0x00,
                         0x7D, 0x7D, 0x7E, 0x7F, 0x7E, 0x7E, 0x7F, 0x7F,
                         0x7e, 0x69, 0x63, 0xe9, 0x3c, 0x5B, 0xfE, 0x00,
                         0x7D, 0x7D, 0x7E, 0x7F, 0x7E, 0x7E, 0x7F, 0x7F,
                         0x7f, 0x60, 0x3E, 0x6f, 0x9b, 0x5B, 0x45, 0x00,
                         0x7D, 0x7D, 0x7E, 0x7F, 0x7E, 0x7E, 0x7F, 0x7F,
                         0x70, 0x61, 0x4E, 0xc9, 0xdA, 0x5B, 0x69, 0x00,
                         0x7D, 0x7D, 0x7E, 0x7F, 0x7E, 0x7E, 0x7F, 0x7F,
                         0x71, 0x63, 0xaE, 0x88, 0x0A, 0x5B, 0x30, 0x00,
                         0x12, 0x34, 0x56, 0x78, 0x9a, 0xab, 0xcd, 0xef,
                         0x11, 0x22, 0x33, 0x44, 0x0A, 0x5B, 0x30, 0x00,
                         0x12, 0x34, 0x56, 0x78, 0x9a, 0xab, 0xcd, 0xef,
                         0x7f, 0x60, 0x3E, 0x6f, 0x9b, 0x5B, 0x45, 0x00,
                         0x7D, 0x7D, 0x7E, 0x7F, 0x7E, 0x7E, 0x7F, 0x7F,
                         0x7f, 0x60, 0x3E, 0x6f, 0x9b, 0x5B, 0x45, 0x00,
                         0x7D, 0x7D, 0x7E, 0x7F, 0x7E, 0x7E, 0x7F, 0x7F,
                         0x71, 0xE8, 0x36, 0x2A, 0x2E, 0x07, 0x89, 0x17,
                         0x8B, 0x84, 0x28, 0x26, 0x6D, 0xEB, 0x12, 0x34,
                         0x11, 0x22, 0x33, 0x44
                        };
        /*长包超128字节发送*/
        hal_dsi_rx_ctrl_ack_long_cmd(g_rx_ctrl_handle, sizeof(cmd) / sizeof(uint8_t), cmd);
    }
    else if (dcs_cmd == 0xFE)
    {
        uint16_t return_size;
        return_size = hal_dsi_rx_ctrl_get_max_ret_size(g_rx_ctrl_handle);
        if (return_size == 3)
        {
            uint8_t cmd[] = {DSI_ACK_DT_DCS_LONG_RESPONSE, 3, 0, 1, 0x40, 0x00, 0x03};

            hal_dsi_rx_ctrl_ack_long_cmd(g_rx_ctrl_handle, sizeof(cmd) / sizeof(uint8_t), cmd);
        }
        else if (return_size == 32)
        {

            uint8_t cmd[] = {DSI_ACK_DT_DCS_LONG_RESPONSE,
                             32, 0, 1, 0x01, 0xc4, 0x01, 0xcd, 0x01, 0xfb, 0x55, 0x55,
                             0x55, 0x4e, 0x4c, 0x4e, 0x2e, 0x2d, 0x31, 0x30,
                             0x30, 0x38, 0x49, 0x42, 0x49, 0x3c, 0x39, 0x47,
                             0x01, 0x07, 0x2b, 0xfa, 0x22, 0x19, 0x32, 0x02
                            };

            hal_dsi_rx_ctrl_ack_long_cmd(g_rx_ctrl_handle, sizeof(cmd) / sizeof(uint8_t), cmd);
        }
    }

    TAU_LOGD("r %x\n", dcs_cmd);
    return true;
}


static const hal_dcs_execute_entry_t g_cus_rx_dcs_execute_table[] =
{
    {0x83, cus_dsc_execute, false},         //cus dcs 0x83, 处理函数为cus_dsc_execute，不需要立即运行，在while里异步即可
    {0, NULL, false}                        //{0,NULL,false} 数组最后一个固定成员，作为table结尾的判断标准
};

static void open_mipi_rx()
{
    if (g_rx_ctrl_handle == NULL)
    {
        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->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->extra_info.flow_control_mode = FC_AUTO_MODE;
    g_rx_ctrl_handle->cus_dcs_entry_table = g_cus_rx_dcs_execute_table;
    g_rx_ctrl_handle->rx_dcs_read_entry = ap_dcs_read;

    /*PIN28~PIN19依次为21c03*/
    g_rx_ctrl_handle->rx_lane_swap = RX_LANE_SWAP_2103;

    /* 对 lane0~lane3 以及clk lane 进行PN交换*/
    g_rx_ctrl_handle->base_info.pn_swap = RX_LANE_0_PN_SWAP | RX_LANE_1_PN_SWAP | RX_LANE_2_PN_SWAP | RX_LANE_3_PN_SWAP | RX_LANE_CLK_PN_SWAP;

    if (g_rx_ctrl_handle->compress_en == true)
    {
        //hal_dsi_rx_ctrl_pre_init_pps(g_rx_ctrl_handle, pps, 128);
    }
    hal_dsi_rx_ctrl_init(g_rx_ctrl_handle);
#if 0
    //使用盒子发送读命令 0xA,0xB,0xC,0xD,0xE,0xF,0x1E,0x1D
    hal_dsi_rx_ctrl_set_auto_ack(g_rx_ctrl_handle, HAL_RX_QRESP_CODE0, DSI_ACK_DT_DCS_SHORT_RESPONSE_1B, 0x0F, 1, 0xab);
    hal_dsi_rx_ctrl_set_auto_ack(g_rx_ctrl_handle, HAL_RX_QRESP_CODE1, DSI_ACK_DT_DCS_SHORT_RESPONSE_2B, 0x0e, 2, 0xef, 0xcd);
    hal_dsi_rx_ctrl_set_auto_ack(g_rx_ctrl_handle, HAL_RX_QRESP_CODE2, DSI_ACK_DT_GEN_SHORT_RESPONSE_1B, 0x0a, 1, 0x12);
    hal_dsi_rx_ctrl_set_auto_ack(g_rx_ctrl_handle, HAL_RX_QRESP_CODE3, DSI_ACK_DT_GEN_SHORT_RESPONSE_2B, 0x0b, 2, 0x34, 0x56);
    hal_dsi_rx_ctrl_set_auto_ack(g_rx_ctrl_handle, HAL_RX_QRESP_CODE4, DSI_ACK_DT_DCS_LONG_RESPONSE, 0x0c, 4, 0x12, 0x34, 0x56, 0x78);
    hal_dsi_rx_ctrl_set_auto_ack(g_rx_ctrl_handle, HAL_RX_QRESP_CODE5, DSI_ACK_DT_GEN_LONG_RESPONSE, 0x0d, 4, 0xab, 0xcd, 0xef, 0x9a);
    hal_dsi_rx_ctrl_set_auto_ack(g_rx_ctrl_handle, HAL_RX_QRESP_CODE6, DSI_ACK_DT_GEN_LONG_RESPONSE, 0x1e, 8, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8);
    hal_dsi_rx_ctrl_set_auto_ack(g_rx_ctrl_handle, HAL_RX_QRESP_CODE7, DSI_ACK_DT_DCS_LONG_RESPONSE, 0x1d, 8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x10);
#endif
    hal_dsi_rx_ctrl_start(g_rx_ctrl_handle);
}

/**
* @brief  test system 主函数
* @param  none
* @retval none
*/
void demo_hal_dsi_rx_case()
{
    open_mipi_rx();
    TAU_LOGD("open_mipi_rx  done !\n");
    while (1)
    {
        hal_dsi_rx_ctrl_dcs_async_handler(g_rx_ctrl_handle);
    }
}
