/**********************************************************************************************************************
*  Copyright (C), 2022-2026, SMARTLOGIC TECHNOLOGY LTD.
*  File Name: cpri_test_case80.c
*  Create Date: 24/2/20
*  Description: 
*  Change History: 
*      <author>      <time>      <version>   <desc>
*    1. cheng.wan    24/02/20      2.0       refactor
**********************************************************************************************************************/
/* -------------------------------------------------- <INC FILE> --------------------------------------------------- */
#include "typedef.h"
#include "ucp_utility.h"
#include "ucp_printf.h"
#include "cpri_timer.h"
#include "cpri_driver.h"
#include "rfm1_drv.h"
#include "cpri_test.h"
#include "cpri_csu.h"
#include "cpri_test_case.h"
#include "cpri_csu_8nr_8lte.h"



//void UCP_API_CPRI_CSU_START(void);

//* --------------------------------------------------- <DEF&DEC> --------------------------------------------------- */




/* -------------------------------------------------- <FUNC DEF> --------------------------------------------------- */
/**********************************************************************************************************************
*  function: axc_data_init
*  description: 
*  input : none
*  output: none
*  return: none
*  others: none
**********************************************************************************************************************/
void axc_data_init()
{
    uint32_t    data_id   = 0;
    uint32_t    slot_type = 0;
    uint32_t    bf_idx    = 0;

    uint32_t    *p_addr  = 0;
    uint32_t    dst_addr = 0;
    uint32_t    data_len = 0;
    uint16_t    byte_num_per_bf = 0;
    uint32_t	word_num_per_bf = 0;
    uint32_t    bf_num_per_slot = (LONGCP_BF_CNT + SHORTCP_BF_CNT * 13) * 2;
    uint32_t    word_idx_in_slot= 0;
    uint32_t    word_idx_in_bf  = 0;
    uint32_t    value = 0;


    /* compress factor */
    for(slot_type = 0; slot_type <= 1; slot_type++)
    {
        byte_num_per_bf = 8;
        word_num_per_bf = byte_num_per_bf >> 2;

        if(slot_type == 0)
        {		
            dst_addr = CPRI_8NR8LTE_TX_SLOT_EVEN_COMPRESS_ADDR;
        }
        else
        {			
            dst_addr = CPRI_8NR8LTE_TX_SLOT_ODD_COMPRESS_ADDR;
        }

        p_addr  = ((uint32_t*)dst_addr);
        data_id = 0;
        for(bf_idx = 0; bf_idx < bf_num_per_slot; bf_idx++)
        {
            for(word_idx_in_bf = 0; word_idx_in_bf < word_num_per_bf; word_idx_in_bf++)
            {
                value = (slot_type << 28)|(data_id << 24)|(bf_idx << 8)|(word_idx_in_bf);
                do_write((uint32_t)p_addr, value);
                p_addr++;
            }
        }
    }


    /* iq data */
    for(data_id = 1; data_id < 6; data_id++)
    {
        byte_num_per_bf = 64*2;
        word_num_per_bf = byte_num_per_bf >> 2;

        for(slot_type = 0; slot_type <= 1; slot_type++)
        {
            word_idx_in_slot = 0;
            data_len = byte_num_per_bf * bf_num_per_slot;

            if(slot_type == 0)
            {
                if(data_id == 1)
                {
                    dst_addr = CPRI_8NR8LTE_TX_SLOT_EVEN_NR_AXC1_2_ADDR;
                }else if(data_id == 2)
                {
                    dst_addr = CPRI_8NR8LTE_TX_SLOT_EVEN_NR_AXC3_4_ADDR;
                }else if(data_id == 3)
                {
                    dst_addr = CPRI_8NR8LTE_TX_SLOT_EVEN_NR_AXC5_6_ADDR;
                }else if(data_id == 4)
                {
                    dst_addr = CPRI_8NR8LTE_TX_SLOT_EVEN_NR_AXC7_8_ADDR;
                }else if(data_id == 5)
                {
                    dst_addr = CPRI_8NR8LTE_TX_SLOT_EVEN_LTE_AXC1_8_ADDR;
                }
            }else if(slot_type == 1)
            {
                if(data_id == 1)
                {
                    dst_addr = CPRI_8NR8LTE_TX_SLOT_ODD_NR_AXC1_2_ADDR;
                }else if(data_id == 2)
                {
                    dst_addr = CPRI_8NR8LTE_TX_SLOT_ODD_NR_AXC3_4_ADDR;
                }else if(data_id == 3)
                {
                    dst_addr = CPRI_8NR8LTE_TX_SLOT_ODD_NR_AXC5_6_ADDR;
                }else if(data_id == 4)
                {
                    dst_addr = CPRI_8NR8LTE_TX_SLOT_ODD_NR_AXC7_8_ADDR;
                }else if(data_id == 5)
                {
                    dst_addr = CPRI_8NR8LTE_TX_SLOT_ODD_LTE_AXC1_8_ADDR;
                }
            }

            p_addr = ((uint32_t*)dst_addr);   
            for(bf_idx = 0; bf_idx < bf_num_per_slot; bf_idx++)
            {
                for(word_idx_in_bf = 0; word_idx_in_bf < word_num_per_bf; word_idx_in_bf++)
                {
                    value = (slot_type << 28)|(data_id << 24)|((word_idx_in_slot++)/2 << 8)|(word_idx_in_bf);
                    do_write((uint32_t)p_addr, value);
                    p_addr++;
                }
            }
        }
    }
}


/**********************************************************************************************************************
*  function: axc_data_check
*  description: 
*  input : none
*  output: none
*  return: none
*  others: none
**********************************************************************************************************************/
uint32_t comp_word_sum_cnt = 0;
uint32_t comp_word_err_cnt = 0;
uint32_t comp_data_id_cnt  = 0;
uint32_t bf_start_err_cnt  = 0;
void axc_data_check(uint32_t slot_idx)
{
    uint32_t    src_addr  = 0;
    uint32_t    real_addr = 0;
    uint32_t    bf_num_per_slot = (LONGCP_BF_CNT + SHORTCP_BF_CNT*13)*2;
    uint32_t	word_num_per_bf = 0;
    uint32_t    word_idx_in_slot= 0;
    uint32_t    word_idx_in_bf  = 0;
    uint32_t    slot_type = 0;
    uint32_t    data_id   = 0;
    int32_t     bf_start  = 0;
    uint32_t    comp_val  = 0;
    uint32_t    recv_val  = 0;
    uint32_t    recv_addr = 0;
    uint32_t    bf_idx    = 0;
 
    for(data_id = 0; data_id < 6; data_id++)
    {
        comp_data_id_cnt++;
        bf_start = 0;

        if((slot_idx&0x1) == 0)
        {
            slot_type = 0;
            if(data_id == 0)
            {
                word_num_per_bf = (8 >> 2);
                src_addr    = CPRI_8NR8LTE_RX_SLOT_EVEN_COMPRESS_ADDR;
            }		
            else if(data_id == 1)
            {
                word_num_per_bf = ((64*2) >> 2);
                src_addr    = CPRI_8NR8LTE_RX_SLOT_EVEN_NR_AXC1_2_ADDR;
            }else if(data_id == 2)
            {
                word_num_per_bf = ((64*2) >> 2);
                src_addr    = CPRI_8NR8LTE_RX_SLOT_EVEN_NR_AXC3_4_ADDR;
            }else if(data_id == 3)
            {
                word_num_per_bf = ((64*2) >> 2);
                src_addr    = CPRI_8NR8LTE_RX_SLOT_EVEN_NR_AXC5_6_ADDR;
            }else if(data_id == 4)
            {
                word_num_per_bf = ((64*2) >> 2);
                src_addr    = CPRI_8NR8LTE_RX_SLOT_EVEN_NR_AXC7_8_ADDR;
            }else if(data_id == 5)
            {
                word_num_per_bf = ((16*8) >> 2);
                src_addr    = CPRI_8NR8LTE_RX_SLOT_EVEN_LTE_AXC1_8_ADDR;
            }else if(data_id == 6)
            {
                word_num_per_bf = (8 >> 2);
                src_addr    = CPRI_8NR8LTE_RX_SLOT_EVEN_AGC_ADDR;
            }

        }else if((slot_idx&0x1) == 1)
        {
            slot_type = 1;
            if(data_id == 0)
            {
                word_num_per_bf = (8 >> 2);
                src_addr    = CPRI_8NR8LTE_RX_SLOT_ODD_COMPRESS_ADDR;
            }		
            else if(data_id == 1)
            {
                word_num_per_bf = ((64*2) >> 2);
                src_addr    = CPRI_8NR8LTE_RX_SLOT_ODD_NR_AXC1_2_ADDR;
            }else if(data_id == 2)
            {
                word_num_per_bf = ((64*2) >> 2);
                src_addr    = CPRI_8NR8LTE_RX_SLOT_ODD_NR_AXC3_4_ADDR;
            }else if(data_id == 3)
            {
                word_num_per_bf = ((64*2) >> 2);
                src_addr    = CPRI_8NR8LTE_RX_SLOT_ODD_NR_AXC5_6_ADDR;
            }else if(data_id == 4)
            {
                word_num_per_bf = ((64*2) >> 2);
                src_addr    = CPRI_8NR8LTE_RX_SLOT_ODD_NR_AXC7_8_ADDR;
            }else if(data_id == 5)
            {
                word_num_per_bf = ((16*8) >> 2);
                src_addr    = CPRI_8NR8LTE_RX_SLOT_ODD_LTE_AXC1_8_ADDR;
            }else if(data_id == 6)
            {
                word_num_per_bf = (8 >> 2);
                src_addr    = CPRI_8NR8LTE_RX_SLOT_ODD_AGC_ADDR;
            }
        }

        if(data_id == 0)
        {
            for(bf_idx = 0; bf_idx < bf_num_per_slot; bf_idx++)
            {
                for(word_idx_in_bf = 0; word_idx_in_bf < word_num_per_bf; word_idx_in_bf++)
                {
                    comp_val = (slot_type << 28)|(data_id << 24)|(bf_idx << 8)|(word_idx_in_bf);
                    debug_write((DBG_DDR_IDX_DRV_BASE + 1026), comp_word_sum_cnt); 
                    comp_word_sum_cnt++;

                    __ucps2_synch(0);

                    recv_addr = (uint32_t)((uint32_t*)src_addr + bf_idx*word_num_per_bf + word_idx_in_bf);
                    real_addr = src_addr;
                    recv_val = do_read_volatile(recv_addr); 
                    __ucps2_synch(0);
                    if(recv_val != comp_val)
                    {
                        if(comp_word_err_cnt < 0x100)
                        {
                            debug_write((DBG_DDR_IDX_DRV_BASE + 1028 + ((comp_word_err_cnt << 3)&0x7FF)), comp_val);	
                            debug_write((DBG_DDR_IDX_DRV_BASE + 1029 + ((comp_word_err_cnt << 3)&0x7FF)), recv_val);
                            debug_write((DBG_DDR_IDX_DRV_BASE + 1030 + ((comp_word_err_cnt << 3)&0x7FF)), recv_addr);
                            debug_write((DBG_DDR_IDX_DRV_BASE + 1031 + ((comp_word_err_cnt << 3)&0x7FF)), real_addr);	
                            debug_write((DBG_DDR_IDX_DRV_BASE + 1032 + ((comp_word_err_cnt << 3)&0x7FF)), (slot_idx + (data_id << 4) + (bf_idx << 8)));
                            debug_write((DBG_DDR_IDX_DRV_BASE + 1033 + ((comp_word_err_cnt << 3)&0x7FF)), bf_start);
                            debug_write((DBG_DDR_IDX_DRV_BASE + 1034 + ((comp_word_err_cnt << 3)&0x7FF)), bf_num_per_slot);
                        }
                        comp_word_err_cnt++;
                    }
                }
            }
        }
        else if((data_id >= 1) && (data_id <= 5))
        {
            word_idx_in_slot = 0;

            for(bf_idx = 0; bf_idx < bf_num_per_slot; bf_idx++)
            {
                for(word_idx_in_bf = 0; word_idx_in_bf < word_num_per_bf; word_idx_in_bf++)
                { 
                    comp_val = (slot_type << 28)|(data_id << 24)|((word_idx_in_slot++)/2 << 8)|(word_idx_in_bf);

                    debug_write((DBG_DDR_IDX_DRV_BASE + 1026), comp_word_sum_cnt); 
                    comp_word_sum_cnt++;					
                    __ucps2_synch(0);

                    recv_addr = (uint32_t)((uint32_t*)src_addr + bf_idx*word_num_per_bf + word_idx_in_bf);
                    real_addr = src_addr;
                    recv_val  = do_read_volatile(recv_addr); 
                    __ucps2_synch(0);

                    if(recv_val != comp_val)
                    {
                        if(comp_word_err_cnt < 0x100)
                        {
                            debug_write((DBG_DDR_IDX_DRV_BASE + 1028 + ((comp_word_err_cnt << 3) & 0x7FF)), comp_val);
                            debug_write((DBG_DDR_IDX_DRV_BASE + 1029 + ((comp_word_err_cnt << 3) & 0x7FF)), recv_val);
                            debug_write((DBG_DDR_IDX_DRV_BASE + 1030 + ((comp_word_err_cnt << 3) & 0x7FF)), recv_addr);
                            debug_write((DBG_DDR_IDX_DRV_BASE + 1031 + ((comp_word_err_cnt << 3) & 0x7FF)), real_addr);
                            debug_write((DBG_DDR_IDX_DRV_BASE + 1032 + ((comp_word_err_cnt << 3) & 0x7FF)), (slot_idx + (data_id << 4) + (bf_idx << 8)));	
                            debug_write((DBG_DDR_IDX_DRV_BASE + 1033 + ((comp_word_err_cnt << 3) & 0x7FF)), bf_start);
                            debug_write((DBG_DDR_IDX_DRV_BASE + 1034 + ((comp_word_err_cnt << 3) & 0x7FF)), bf_num_per_slot);
                        }
                        comp_word_err_cnt++;
                    }
                }
            }
        }

        debug_write((DBG_DDR_IDX_DRV_BASE + 1024), comp_data_id_cnt);
        debug_write((DBG_DDR_IDX_DRV_BASE + 1025), comp_word_err_cnt);
    }
}


/**********************************************************************************************************************
*  function: fh_data_init
*  description: 
*  input : none
*  output: none
*  return: none
*  others: none
**********************************************************************************************************************/
extern  uint32_t  gCpriTestMode;

int32_t fh_data_init(void)
{
    gCpriTestMode = CPRI_TEST_MODE;
    debug_write((DBG_DDR_IDX_DRV_BASE + 192), gCpriTestMode);

    axc_data_init();
    return 0;
}


/**********************************************************************************************************************
*  function: fh_data_check
*  description: 
*  input : none
*  output: none
*  return: none
*  others: none
**********************************************************************************************************************/
extern stMtimerIntStat  gMtimerIntCnt[SCS_MAX_NUM];
void fh_data_check(uint32_t times)
{
    uint32_t         slot_idx;
    stMtimerIntStat  *pMtimerInt;
    
     
    pMtimerInt = &gMtimerIntCnt[MTIMER_CPRI_ID];
    if(pMtimerInt->csuEnCnt >= 4)
    {
        comp_word_sum_cnt = 0;

        for(slot_idx = 0; slot_idx < CPRI_CASE_SLOT_NUM; slot_idx++)
        {
            axc_data_check(slot_idx);
        }
    }
}


/**********************************************************************************************************************
*  function: fh_test_case
*  description: 
*  input : none
*  output: none
*  return: none
*  others: none
**********************************************************************************************************************/
void fh_test_case()
{
	UCP_API_CPRI_CSU_START();
}


/**********************************************************************************************************************
*  function: fh_csu_test_init
*  description: 
*  input : none
*  output: none
*  return: none
*  others: none
**********************************************************************************************************************/
int32_t fh_csu_test_init(void)
{
    Phy_Timer_Csu_Config_Nr();
    return 0;
}


/**********************************************************************************************************************
*  function: fh_drv_init
*  description: 
*  input : none
*  output: none
*  return: none
*  others: none
**********************************************************************************************************************/
int32_t fh_drv_init(void)
{
    stFrontHaulDrvPara fhDrvPara;

    memset_ucp(&fhDrvPara, 0, sizeof(stFrontHaulDrvPara));

    fhDrvPara.protocolSel = PROTOCOL_CPRI;
    fhDrvPara.rateOption  = CPRI_OPTION_10;
    fhDrvPara.mapOption   = OTIC_MAP_8NR_8LTE;
    fronthaul_drv_cfg(&fhDrvPara);

    return 0;
}


