#include "ecpri_queue_proc.h"


/* 循环队列结构 */
STRU_RING_BUF g_struRingBuf = {0};
/* 读取数据包总数 */
uint64_t g_u64RdPktTotal = 0;
/* 读取数据包循环计数 */
uint32_t g_u32RdPktCnt = 0;


/* ecpri循环队列初始化 */
void ecpri_queue_init(void)
{
    /* 数据包存放位置，单位：32Byte */
    uint32_t u32DescPtr = 0;
    /* 数据包内存地址，单位：Byte */
    uint32_t u32MemAddr = 0;

    /* 初始化循环缓冲区管理结构 */
    g_struRingBuf.u32WrIdx = 0;
    g_struRingBuf.u32RdIdx = 0;
    g_struRingBuf.pu8Buf= (uint8_t *)ECPRI_DATA_BUF_ADDR;
    g_struRingBuf.u32BufSize = ECPRI_DATA_BUF_SIZE;

    /* 初始化读取数据包总数 */
    g_u64RdPktTotal = 0;

    /* 获取数据包存放位置 */
    u32DescPtr = do_read_volatile(&DESC_PTR_2);

    /* 计算数据包内存地址并进行校验 */
    u32MemAddr = u32DescPtr * ECPRI_DESC_ADDR_UNIT;
    if ((u32MemAddr < ECPRI_DATA_BUF_ADDR) || 
        (u32MemAddr >= (ECPRI_DATA_BUF_ADDR + ECPRI_DATA_BUF_SIZE)) || 
        (((u32MemAddr - ECPRI_DATA_BUF_ADDR) % ECPRI_DATA_PKT_SIZE) != 0))
    {
        do_write(ECPRI_DBG_BUF_ADDR + 0x10, 0x11111111);
        do_write(ECPRI_DBG_BUF_ADDR + 0x20, u32DescPtr);
        do_write(ECPRI_DBG_BUF_ADDR + 0x24, u32MemAddr);

        return;
    }

    /* 更新描述符下一个地址和当前接收数据包存放位置相同 */
    do_write(&DESC_TAIL_ADDR_2, u32DescPtr);

    /* 更新读/写索引 */
    g_struRingBuf.u32WrIdx = (u32MemAddr - ECPRI_DATA_BUF_ADDR) / ECPRI_DATA_PKT_SIZE;
    g_struRingBuf.u32RdIdx = g_struRingBuf.u32WrIdx;

    /* 清空eCPRI数据和调试缓冲区 */
    memset_ucp(ECPRI_DATA_BUF_ADDR, 0x00, ECPRI_DATA_BUF_SIZE);
    memset_ucp(ECPRI_DBG_BUF_ADDR, 0x00, ECPRI_DBG_BUF_SIZE);

    do_write(ECPRI_DBG_BUF_ADDR + 0x10, 0x00000000);
    do_write(ECPRI_DBG_BUF_ADDR + 0x20, u32DescPtr);
    do_write(ECPRI_DBG_BUF_ADDR + 0x24, u32MemAddr);
    do_write(ECPRI_DBG_BUF_ADDR + 0x28, g_struRingBuf.u32WrIdx);
    do_write(ECPRI_DBG_BUF_ADDR + 0x2C, g_struRingBuf.u32RdIdx);
}

/* ecpri循环队列轮询处理 */
void ecpri_queue_proc(void)
{
    /* 数据包存放位置，单位：32Byte */
    uint32_t u32DescPtr = 0;
    /* 数据包内存地址，单位：Byte */
    uint32_t u32MemAddr = 0;
    /* 读取包数 */
    uint32_t u32RdPktNum = 0;
    /* 数据包地址 */
    uint32_t u32PktAddr = 0;
    /* 计数索引 */
    uint32_t i = 0;

    /* 获取数据包存放位置 */
    u32DescPtr = do_read_volatile(&DESC_PTR_2);

    /* 计算数据包内存地址并进行校验 */
    u32MemAddr = u32DescPtr * ECPRI_DESC_ADDR_UNIT;
    if ((u32MemAddr < ECPRI_DATA_BUF_ADDR) || 
        (u32MemAddr >= (ECPRI_DATA_BUF_ADDR + ECPRI_DATA_BUF_SIZE)) || 
        (((u32MemAddr - ECPRI_DATA_BUF_ADDR) % ECPRI_DATA_PKT_SIZE) != 0))
    {
        do_write(ECPRI_DBG_BUF_ADDR + 0x30, 0x11111111);
        do_write(ECPRI_DBG_BUF_ADDR + 0x40, u32DescPtr);
        do_write(ECPRI_DBG_BUF_ADDR + 0x44, u32MemAddr);

        return;
    }

    /* 计算写索引 */
    g_struRingBuf.u32WrIdx = (u32MemAddr - ECPRI_DATA_BUF_ADDR) / ECPRI_DATA_PKT_SIZE;

    /* 读/写索引相同，没有数据包要读 */
    if (g_struRingBuf.u32WrIdx == g_struRingBuf.u32RdIdx)
    {
        do_write(ECPRI_DBG_BUF_ADDR + 0x30, 0x22222222);
        do_write(ECPRI_DBG_BUF_ADDR + 0x40, u32DescPtr);
        do_write(ECPRI_DBG_BUF_ADDR + 0x44, u32MemAddr);
        do_write(ECPRI_DBG_BUF_ADDR + 0x48, g_struRingBuf.u32WrIdx);
        do_write(ECPRI_DBG_BUF_ADDR + 0x4C, g_struRingBuf.u32RdIdx);

        return;
    }

    /* 计算所要读取的包数 */
    u32RdPktNum = (g_struRingBuf.u32WrIdx + ECPRI_DATA_PKT_MAX - g_struRingBuf.u32RdIdx) % ECPRI_DATA_PKT_MAX;

    for (i = 0; i < u32RdPktNum; i++)
    {
        /* 计算数据包地址 */
        u32PktAddr = ECPRI_DATA_BUF_ADDR + g_struRingBuf.u32RdIdx * ECPRI_DATA_PKT_SIZE;

        /* ecpri数据包处理 */
        ecpri_packet_proc(u32PktAddr);

        /* 更新描述符下一个地址 */
        do_write(&DESC_TAIL_ADDR_2, ((u32PktAddr + ECPRI_DATA_PKT_SIZE) / ECPRI_DESC_ADDR_UNIT));

        //printf("[ecpri_queue_proc] u32PktAddr[0x%08x], u32PktLen[0x%08x].\n", u32PktAddr, u32PktLen);
        //printf("[ecpri_queue_proc] u32RdIdx[0x%08x], u32WrIdx[0x%08x].\n", u32RdIdx, u32WrIdx);

        //UCP_PRINT_ERROR("[ecpri_queue_proc] u32PktAddr[0x%08x], u32PktLen[0x%08x].\n", u32PktAddr, u32PktLen);
        //UCP_PRINT_ERROR("[ecpri_queue_proc] u32RdIdx[0x%08x], u32WrIdx[0x%08x].\n", u32RdIdx, u32WrIdx);

        do_write(ECPRI_DBG_BUF_ADDR + 0x100 + g_u32RdPktCnt * 0x20 + 0x00, g_struRingBuf.u32WrIdx);
        do_write(ECPRI_DBG_BUF_ADDR + 0x100 + g_u32RdPktCnt * 0x20 + 0x04, g_struRingBuf.u32RdIdx);

        /* 更新读索引 */
        g_struRingBuf.u32RdIdx++;
        g_struRingBuf.u32RdIdx %= ECPRI_DATA_PKT_MAX;

        /* 更新读取数据包循环计数 */
        g_u32RdPktCnt++;
        g_u32RdPktCnt %= ECPRI_DATA_PKT_MAX;
    }

    /* 更新读取数据包总数 */
    g_u64RdPktTotal += u32RdPktNum;

    do_write(ECPRI_DBG_BUF_ADDR + 0x30, 0x00000000);
    do_write(ECPRI_DBG_BUF_ADDR + 0x34, ((g_u64RdPktTotal & 0xFFFFFFFF00000000) >> 8));
    do_write(ECPRI_DBG_BUF_ADDR + 0x38, (g_u64RdPktTotal & 0xFFFFFFFF));
    do_write(ECPRI_DBG_BUF_ADDR + 0x3C, u32RdPktNum);
    do_write(ECPRI_DBG_BUF_ADDR + 0x40, u32DescPtr);
    do_write(ECPRI_DBG_BUF_ADDR + 0x44, u32MemAddr);
}

/* ecpri数据包处理 */
void ecpri_packet_proc(uint32_t u32PktAddr)
{
    /* eCPRI包类型字段偏移 */
    uint32_t u32TypeOffset = 16;
    /* eCPRI包长字段偏移 */
    uint32_t u32LenOffset = 20;
    /* 数据包类型 */
    uint16_t u16PktType = 0;
    /* 数据包长度 */
    uint16_t u16PktLen = 0;
#if 0
    /* 净荷地址 */
    uint32_t u32PayloadAddr = 0;
#endif

    /* 判断包类型是否是eCPRI报文 */
    u16PktType = do_read_short(u32PktAddr + u32TypeOffset);
    u16PktType = ((u16PktType & 0xFF) << 8) | ((u16PktType & 0xFF00) >> 8);
    if (ECPRI_PKT_TYPE_ECPRI == u16PktType)
    {
        /* 获取eCPRI数据包净荷长度，单位：Byte */
        u16PktLen = do_read_short(u32PktAddr + u32LenOffset);
        u16PktLen = ((u16PktLen & 0xFF) << 8) | ((u16PktLen & 0xFF00) >> 8);

#if 1
        /* 计数eCPRI数据包总长度 */
        u16PktLen += 18;

        //TODO:
        /* 将eCPRI数据包净荷地址和净荷长度发送给APE */
        do_write(ECPRI_DBG_BUF_ADDR + 0x100 + g_u32RdPktCnt * 0x20 + 0x08, u32PktAddr);
        do_write(ECPRI_DBG_BUF_ADDR + 0x100 + g_u32RdPktCnt * 0x20 + 0x0C, u16PktLen);
        (void)ecpri_inform_ape(u32PktAddr, u16PktLen);
#else
        /* 计数eCPRI数据包净荷地址 */
        u32PayloadAddr = u32PktAddr + 18;

        //TODO:
        /* 将eCPRI数据包净荷地址和净荷长度发送给APE */
        do_write(ECPRI_DBG_BUF_ADDR + 0x100 + g_u32RdPktCnt * 0x20 + 0x08, u32PayloadAddr);
        do_write(ECPRI_DBG_BUF_ADDR + 0x100 + g_u32RdPktCnt * 0x20 + 0x0C, u16PktLen);
        (void)ecpri_inform_ape(u32PayloadAddr, u16PktLen);
#endif
    }
    else
    {
        /* 获取非eCPRI数据包（如1588等）总长度，单位：Byte */
        u32LenOffset = ECPRI_DATA_PKT_SIZE - 0x1C;
        u16PktLen = do_read_short(u32PktAddr + u32LenOffset);

        //TODO:
        /* 将非eCPRI数据包地址和总长度发送给ARM */
        do_write(ECPRI_DBG_BUF_ADDR + 0x100 + g_u32RdPktCnt * 0x20 + 0x08, u32PktAddr);
        do_write(ECPRI_DBG_BUF_ADDR + 0x100 + g_u32RdPktCnt * 0x20 + 0x0C, u16PktLen);
#if 0
        (void)ecpri_inform_arm(u32PktAddr, u16PktLen);
#else
        (void)ecpri_inform_arm_ex(u32PktAddr);
#endif
    }
}

/* ecpri通知ape */
int32_t ecpri_inform_ape(uint32_t u32PktAddr, uint32_t u32PktLen)
{
    /* 返回值 */
    int32_t s32Ret = 0;
    /* 消息长度 */
    int32_t s32MsgSize = 8;
    /* 消息地址 */
    char *pcMsgAddr = NULL;
    /* 通知消息 */
    STRU_INFORM_MSG struInformMsg = {0};

    /* 申请消息 */
    pcMsgAddr = osp_alloc_msg(s32MsgSize);
    if (NULL == pcMsgAddr)
    {
        /* 返回值 */
        do_write(ECPRI_DBG_BUF_ADDR + 0x100 + g_u32RdPktCnt * 0x20 + 0x10, (uint32_t)(-1));
        return -1;
    }

    /* 组装通知消息 */
#if 1
    struInformMsg.u32PktAddr = u32PktAddr;
    struInformMsg.u32PktLen = u32PktLen;

    memcpy_ucp(pcMsgAddr, &struInformMsg, sizeof(STRU_INFORM_MSG));
#else
    do_write(pcMsgAddr, u32PktAddr);
    do_write(pcMsgAddr + 4, u32PktLen);
#endif

    s32Ret = osp_send_msg((uint32_t)pcMsgAddr, 
                          (uint32_t)sizeof(STRU_INFORM_MSG), 
                          (uint8_t)E_MSG_TYPE_APE, 
                          (uint8_t)ECS_RFM_SPU0_CORE_ID, 
                          (uint8_t)E_CORE_ID_APE0, 
                          (uint8_t)0, // 40 //0
                          (uint8_t)61); // 40 //ECPRI_APE_TEST_TASK_ID
    if (0 != s32Ret)
    {
        /* 返回值 */
        do_write(ECPRI_DBG_BUF_ADDR + 0x100 + g_u32RdPktCnt * 0x20 + 0x10, (uint32_t)(-2));
        return -2;
    }

    /* 返回值 */
    do_write(ECPRI_DBG_BUF_ADDR + 0x100 + g_u32RdPktCnt * 0x20 + 0x10, 0);

    /* 数据包类型-eCPRI */
    do_write(ECPRI_DBG_BUF_ADDR + 0x100 + g_u32RdPktCnt * 0x20 + 0x14, ECPRI_PKT_TYPE_ECPRI);
    return 0;
}

/* ecpri通知arm */
int32_t ecpri_inform_arm(uint32_t u32PktAddr, uint32_t u32PktLen)
{
    /* 返回值 */
    int32_t s32Ret = 0;
    /* 消息长度 */
    int32_t s32MsgSize = 8;
    /* 消息地址 */
    char *pcMsgAddr = NULL;
    /* 通知消息 */
    STRU_INFORM_MSG struInformMsg = {0};

    /* 申请消息 */
    pcMsgAddr = osp_alloc_msg(s32MsgSize);
    if (NULL == pcMsgAddr)
    {
        /* 返回值 */
        do_write(ECPRI_DBG_BUF_ADDR + 0x100 + g_u32RdPktCnt * 0x20 + 0x10, (uint32_t)(-1));
        return -1;
    }

    /* 组装通知消息 */
#if 1
    struInformMsg.u32PktAddr = u32PktAddr;
    struInformMsg.u32PktLen = u32PktLen;

    memcpy_ucp(pcMsgAddr, &struInformMsg, sizeof(STRU_INFORM_MSG));
#else
    do_write(pcMsgAddr, u32PktAddr);
    do_write(pcMsgAddr + 4, u32PktLen);
#endif

    s32Ret = osp_send_msg((uint32_t)pcMsgAddr, 
                          (uint32_t)sizeof(STRU_INFORM_MSG), 
                          (uint8_t)E_MSG_TYPE_ARM, 
                          (uint8_t)ECS_RFM_SPU0_CORE_ID, 
                          (uint8_t)E_CORE_ID_ARM0, 
                          (uint8_t)0, // 0
                          (uint8_t)0); // 61
    if (0 != s32Ret)
    {
        /* 返回值 */
        do_write(ECPRI_DBG_BUF_ADDR + 0x100 + g_u32RdPktCnt * 0x20 + 0x10, (uint32_t)(-2));
        return -2;
    }

    /* 返回值 */
    do_write(ECPRI_DBG_BUF_ADDR + 0x100 + g_u32RdPktCnt * 0x20 + 0x10, 0);

    /* 数据包类型-Other */
    do_write(ECPRI_DBG_BUF_ADDR + 0x100 + g_u32RdPktCnt * 0x20 + 0x14, ECPRI_PKT_TYPE_1588);

    return 0;
}

/* ecpri通知arm扩展接口 */
int32_t ecpri_inform_arm_ex(uint32_t u32PktAddr)
{
    /* 返回值 */
    int32_t s32Ret = 0;

    /* 硬件队列入队 */
    s32Ret = smart_in_que((int)E_CORE_ID_ARM0, u32PktAddr);
    if (0 != s32Ret)
    {
        /* 返回值 */
        do_write(ECPRI_DBG_BUF_ADDR + 0x100 + g_u32RdPktCnt * 0x20 + 0x10, (uint32_t)(-2));
        return -2;
    }

    /* 返回值 */
    do_write(ECPRI_DBG_BUF_ADDR + 0x100 + g_u32RdPktCnt * 0x20 + 0x10, 0);

    /* 数据包类型-Other */
    do_write(ECPRI_DBG_BUF_ADDR + 0x100 + g_u32RdPktCnt * 0x20 + 0x14, ECPRI_PKT_TYPE_1588);

    return 0;
}

/* ecpri内存拷贝测试DDR--->DDR */
void ecpri_memcpy_test(void)
{
    /* 计数索引 */
    uint32_t i = 0;
    /* 计数索引 */
    uint32_t j = 0;
    /* 开始Cycle */
    uint32_t u32StartCycle = 0;
    /* 结束Cycle */
    uint32_t u32EndCycle = 0;
    /* Cycle计数 */
    uint32_t u32CycleNum = 0;

    /* 填充内存 */
    for (i = 0; i < 0x4000; i++)
    {
        do_write_byte((ECPRI_DATA_BUF_ADDR + i), (i % 256));
    }

    /* 64Byte拷贝测试 */
    for (j = 0; j < 100; j++)
    {
        rdmcycle(&u32StartCycle);
        memcpy_ucp((char *)(ECPRI_DATA_BUF_ADDR + (j + 1) * 0x4000), (char *)ECPRI_DATA_BUF_ADDR, 64);
        rdmcycle(&u32EndCycle);

        u32CycleNum = (u32EndCycle + STC_CYCLE_MAX - u32StartCycle) % STC_CYCLE_MAX + 1;

        do_write(ECPRI_DBG_BUF_ADDR + 0x100 + (j + 1) * 0x10 + 0x00, (uint32_t)(ECPRI_DATA_BUF_ADDR + (j + 1) * 0x4000));
        do_write(ECPRI_DBG_BUF_ADDR + 0x100 + (j + 1) * 0x10 + 0x04, 64);
        do_write(ECPRI_DBG_BUF_ADDR + 0x100 + (j + 1) * 0x10 + 0x08, u32CycleNum);
    }

    /* 128Byte拷贝测试 */
    for (j = 0; j < 100; j++)
    {
        rdmcycle(&u32StartCycle);
        memcpy_ucp((char *)(ECPRI_DATA_BUF_ADDR + (j + 101) * 0x4000), (char *)ECPRI_DATA_BUF_ADDR, 128);
        rdmcycle(&u32EndCycle);

        u32CycleNum = (u32EndCycle + STC_CYCLE_MAX - u32StartCycle) % STC_CYCLE_MAX + 1;

        do_write(ECPRI_DBG_BUF_ADDR + 0x100 + (j + 101) * 0x10 + 0x00, (uint32_t)(ECPRI_DATA_BUF_ADDR + (j + 101) * 0x4000));
        do_write(ECPRI_DBG_BUF_ADDR + 0x100 + (j + 101) * 0x10 + 0x04, 128);
        do_write(ECPRI_DBG_BUF_ADDR + 0x100 + (j + 101) * 0x10 + 0x08, u32CycleNum);
    }

    /* 256Byte拷贝测试 */
    for (j = 0; j < 100; j++)
    {
        rdmcycle(&u32StartCycle);
        memcpy_ucp((char *)(ECPRI_DATA_BUF_ADDR + (j + 201) * 0x4000), (char *)ECPRI_DATA_BUF_ADDR, 256);
        rdmcycle(&u32EndCycle);

        u32CycleNum = (u32EndCycle + STC_CYCLE_MAX - u32StartCycle) % STC_CYCLE_MAX + 1;

        do_write(ECPRI_DBG_BUF_ADDR + 0x100 + (j + 201) * 0x10 + 0x00, (uint32_t)(ECPRI_DATA_BUF_ADDR + (j + 201) * 0x4000));
        do_write(ECPRI_DBG_BUF_ADDR + 0x100 + (j + 201) * 0x10 + 0x04, 256);
        do_write(ECPRI_DBG_BUF_ADDR + 0x100 + (j + 201) * 0x10 + 0x08, u32CycleNum);
    }

    /* 512Byte拷贝测试 */
    for (j = 0; j < 100; j++)
    {
        rdmcycle(&u32StartCycle);
        memcpy_ucp((char *)(ECPRI_DATA_BUF_ADDR + (j + 301) * 0x4000), (char *)ECPRI_DATA_BUF_ADDR, 512);
        rdmcycle(&u32EndCycle);

        u32CycleNum = (u32EndCycle + STC_CYCLE_MAX - u32StartCycle) % STC_CYCLE_MAX + 1;

        do_write(ECPRI_DBG_BUF_ADDR + 0x100 + (j + 301) * 0x10 + 0x00, (uint32_t)(ECPRI_DATA_BUF_ADDR + (j + 301) * 0x4000));
        do_write(ECPRI_DBG_BUF_ADDR + 0x100 + (j + 301) * 0x10 + 0x04, 512);
        do_write(ECPRI_DBG_BUF_ADDR + 0x100 + (j + 301) * 0x10 + 0x08, u32CycleNum);
    }

    /* 1024Byte拷贝测试 */
    for (j = 0; j < 100; j++)
    {
        rdmcycle(&u32StartCycle);
        memcpy_ucp((char *)(ECPRI_DATA_BUF_ADDR + (j + 401) * 0x4000), (char *)ECPRI_DATA_BUF_ADDR, 1024);
        rdmcycle(&u32EndCycle);

        u32CycleNum = (u32EndCycle + STC_CYCLE_MAX - u32StartCycle) % STC_CYCLE_MAX + 1;

        do_write(ECPRI_DBG_BUF_ADDR + 0x100 + (j + 401) * 0x10 + 0x00, (uint32_t)(ECPRI_DATA_BUF_ADDR + (j + 401) * 0x4000));
        do_write(ECPRI_DBG_BUF_ADDR + 0x100 + (j + 401) * 0x10 + 0x04, 1024);
        do_write(ECPRI_DBG_BUF_ADDR + 0x100 + (j + 401) * 0x10 + 0x08, u32CycleNum);
    }

    /* 1514Byte拷贝测试 */
    for (j = 0; j < 100; j++)
    {
        rdmcycle(&u32StartCycle);
        memcpy_ucp((char *)(ECPRI_DATA_BUF_ADDR + (j + 501) * 0x4000), (char *)ECPRI_DATA_BUF_ADDR, 1514);
        rdmcycle(&u32EndCycle);

        u32CycleNum = (u32EndCycle + STC_CYCLE_MAX - u32StartCycle) % STC_CYCLE_MAX + 1;

        do_write(ECPRI_DBG_BUF_ADDR + 0x100 + (j + 501) * 0x10 + 0x00, (uint32_t)(ECPRI_DATA_BUF_ADDR + (j + 501) * 0x4000));
        do_write(ECPRI_DBG_BUF_ADDR + 0x100 + (j + 501) * 0x10 + 0x04, 1514);
        do_write(ECPRI_DBG_BUF_ADDR + 0x100 + (j + 501) * 0x10 + 0x08, u32CycleNum);
    }

    /* 11264Byte拷贝测试 */
    for (j = 0; j < 100; j++)
    {
        rdmcycle(&u32StartCycle);
        memcpy_ucp((char *)(ECPRI_DATA_BUF_ADDR + (j + 601) * 0x4000), (char *)ECPRI_DATA_BUF_ADDR, 11264);
        rdmcycle(&u32EndCycle);

        u32CycleNum = (u32EndCycle + STC_CYCLE_MAX - u32StartCycle) % STC_CYCLE_MAX + 1;

        do_write(ECPRI_DBG_BUF_ADDR + 0x100 + (j + 601) * 0x10 + 0x00, (uint32_t)(ECPRI_DATA_BUF_ADDR + (j + 601) * 0x4000));
        do_write(ECPRI_DBG_BUF_ADDR + 0x100 + (j + 601) * 0x10 + 0x04, 11264);
        do_write(ECPRI_DBG_BUF_ADDR + 0x100 + (j + 601) * 0x10 + 0x08, u32CycleNum);
    }
}

/* ecpri csu_dma搬数测试 */
void ecpri_csu_dma_test(void)
{
    /* 计数索引 */
    uint32_t i = 0;
    /* 计数索引 */
    uint32_t j = 0;
    /* 开始Cycle */
    uint32_t u32StartCycle = 0;
    /* 结束Cycle */
    uint32_t u32EndCycle = 0;
    /* Cycle计数 */
    uint32_t u32CycleNum = 0;

    /* 填充内存 */
    for (i = 0; i < 0x4000; i++)
    {
        do_write_byte((ECPRI_DATA_BUF_ADDR + i), (i % 256));
    }

    /* 64Byte拷贝测试 */
    for (j = 0; j < 100; j++)
    {
        rdmcycle(&u32StartCycle);
        ape_csu_dma_1D_G2L_ch2ch3_transfer(ECPRI_DATA_BUF_ADDR, 
                                           (ECPRI_DATA_BUF_ADDR + (j + 1) * 0x4000), 
                                           64, 1, 1);
        rdmcycle(&u32EndCycle);

        u32CycleNum = (u32EndCycle + STC_CYCLE_MAX - u32StartCycle) % STC_CYCLE_MAX + 1;

        do_write(ECPRI_DBG_BUF_ADDR + 0x100 + (j + 1) * 0x10 + 0x00, (uint32_t)(ECPRI_DATA_BUF_ADDR + (j + 1) * 0x4000));
        do_write(ECPRI_DBG_BUF_ADDR + 0x100 + (j + 1) * 0x10 + 0x04, 64);
        do_write(ECPRI_DBG_BUF_ADDR + 0x100 + (j + 1) * 0x10 + 0x08, u32CycleNum);
    }

    /* 128Byte拷贝测试 */
    for (j = 0; j < 100; j++)
    {
        rdmcycle(&u32StartCycle);
        ape_csu_dma_1D_G2L_ch2ch3_transfer(ECPRI_DATA_BUF_ADDR, 
                                           (ECPRI_DATA_BUF_ADDR + (j + 101) * 0x4000), 
                                           128, 1, 1);
        rdmcycle(&u32EndCycle);

        u32CycleNum = (u32EndCycle + STC_CYCLE_MAX - u32StartCycle) % STC_CYCLE_MAX + 1;

        do_write(ECPRI_DBG_BUF_ADDR + 0x100 + (j + 101) * 0x10 + 0x00, (uint32_t)(ECPRI_DATA_BUF_ADDR + (j + 101) * 0x4000));
        do_write(ECPRI_DBG_BUF_ADDR + 0x100 + (j + 101) * 0x10 + 0x04, 128);
        do_write(ECPRI_DBG_BUF_ADDR + 0x100 + (j + 101) * 0x10 + 0x08, u32CycleNum);
    }

    /* 256Byte拷贝测试 */
    for (j = 0; j < 100; j++)
    {
        rdmcycle(&u32StartCycle);
        ape_csu_dma_1D_G2L_ch2ch3_transfer(ECPRI_DATA_BUF_ADDR, 
                                           (ECPRI_DATA_BUF_ADDR + (j + 201) * 0x4000), 
                                           256, 1, 1);
        rdmcycle(&u32EndCycle);

        u32CycleNum = (u32EndCycle + STC_CYCLE_MAX - u32StartCycle) % STC_CYCLE_MAX + 1;

        do_write(ECPRI_DBG_BUF_ADDR + 0x100 + (j + 201) * 0x10 + 0x00, (uint32_t)(ECPRI_DATA_BUF_ADDR + (j + 201) * 0x4000));
        do_write(ECPRI_DBG_BUF_ADDR + 0x100 + (j + 201) * 0x10 + 0x04, 256);
        do_write(ECPRI_DBG_BUF_ADDR + 0x100 + (j + 201) * 0x10 + 0x08, u32CycleNum);
    }

    /* 512Byte拷贝测试 */
    for (j = 0; j < 100; j++)
    {
        rdmcycle(&u32StartCycle);
        ape_csu_dma_1D_G2L_ch2ch3_transfer(ECPRI_DATA_BUF_ADDR, 
                                           (ECPRI_DATA_BUF_ADDR + (j + 301) * 0x4000), 
                                           512, 1, 1);
        rdmcycle(&u32EndCycle);

        u32CycleNum = (u32EndCycle + STC_CYCLE_MAX - u32StartCycle) % STC_CYCLE_MAX + 1;

        do_write(ECPRI_DBG_BUF_ADDR + 0x100 + (j + 301) * 0x10 + 0x00, (uint32_t)(ECPRI_DATA_BUF_ADDR + (j + 301) * 0x4000));
        do_write(ECPRI_DBG_BUF_ADDR + 0x100 + (j + 301) * 0x10 + 0x04, 512);
        do_write(ECPRI_DBG_BUF_ADDR + 0x100 + (j + 301) * 0x10 + 0x08, u32CycleNum);
    }

    /* 1024Byte拷贝测试 */
    for (j = 0; j < 100; j++)
    {
        rdmcycle(&u32StartCycle);
        ape_csu_dma_1D_G2L_ch2ch3_transfer(ECPRI_DATA_BUF_ADDR, 
                                           (ECPRI_DATA_BUF_ADDR + (j + 401) * 0x4000), 
                                           1024, 1, 1);
        rdmcycle(&u32EndCycle);

        u32CycleNum = (u32EndCycle + STC_CYCLE_MAX - u32StartCycle) % STC_CYCLE_MAX + 1;

        do_write(ECPRI_DBG_BUF_ADDR + 0x100 + (j + 401) * 0x10 + 0x00, (uint32_t)(ECPRI_DATA_BUF_ADDR + (j + 401) * 0x4000));
        do_write(ECPRI_DBG_BUF_ADDR + 0x100 + (j + 401) * 0x10 + 0x04, 1024);
        do_write(ECPRI_DBG_BUF_ADDR + 0x100 + (j + 401) * 0x10 + 0x08, u32CycleNum);
    }

    /* 1514Byte拷贝测试 */
    for (j = 0; j < 100; j++)
    {
        rdmcycle(&u32StartCycle);
        ape_csu_dma_1D_G2L_ch2ch3_transfer(ECPRI_DATA_BUF_ADDR, 
                                           (ECPRI_DATA_BUF_ADDR + (j + 501) * 0x4000), 
                                           1514, 1, 1);
        rdmcycle(&u32EndCycle);

        u32CycleNum = (u32EndCycle + STC_CYCLE_MAX - u32StartCycle) % STC_CYCLE_MAX + 1;

        do_write(ECPRI_DBG_BUF_ADDR + 0x100 + (j + 501) * 0x10 + 0x00, (uint32_t)(ECPRI_DATA_BUF_ADDR + (j + 501) * 0x4000));
        do_write(ECPRI_DBG_BUF_ADDR + 0x100 + (j + 501) * 0x10 + 0x04, 1514);
        do_write(ECPRI_DBG_BUF_ADDR + 0x100 + (j + 501) * 0x10 + 0x08, u32CycleNum);
    }

    /* 11264Byte拷贝测试 */
    for (j = 0; j < 100; j++)
    {
        rdmcycle(&u32StartCycle);
        ape_csu_dma_1D_G2L_ch2ch3_transfer(ECPRI_DATA_BUF_ADDR, 
                                           (ECPRI_DATA_BUF_ADDR + (j + 601) * 0x4000), 
                                           11264, 1, 1);
        rdmcycle(&u32EndCycle);

        u32CycleNum = (u32EndCycle + STC_CYCLE_MAX - u32StartCycle) % STC_CYCLE_MAX + 1;

        do_write(ECPRI_DBG_BUF_ADDR + 0x100 + (j + 601) * 0x10 + 0x00, (uint32_t)(ECPRI_DATA_BUF_ADDR + (j + 601) * 0x4000));
        do_write(ECPRI_DBG_BUF_ADDR + 0x100 + (j + 601) * 0x10 + 0x04, 11264);
        do_write(ECPRI_DBG_BUF_ADDR + 0x100 + (j + 601) * 0x10 + 0x08, u32CycleNum);
    }
}






