// +FHDR------------------------------------------------------------
//                 Copyright (c) 2022 SmartLogic.
//                       ALL RIGHTS RESERVED
// -----------------------------------------------------------------
// Filename      : cpri_test_case36.c
// Author        : xinxin.li
// Created On    : 2023-01-12s
// Last Modified :
// -----------------------------------------------------------------
// Description:
//
//
// -FHDR------------------------------------------------------------

#include "typedef.h"
#include "ucp_utility.h"
#include "cpri_csu_nr_7ds2u.h"
#include "cpri_test_case36.h"
#include "cpri_timer.h"
#include "ape_csu.h"
#include "cpri_test.h"
#include "ucp_printf.h"
#include "HeaderRam.h"
#include "cpri_driver.h"

extern uint32_t compressData[1920];
extern uint32_t antData[61440];

extern uint32_t 		gCpriTestMode;
extern stMtimerIntStat 		gMtimerIntCnt[SCS_MAX_NUM];
extern stCpriCsuCmdFifoInfo txCmdFifo;
extern stCpriCsuCmdFifoInfo rxCmdFifo;

extern uint32_t 			gCpriTestMode;
extern uint32_t           	CPRI_OPTION;
extern uint32_t			gCpriCsuDummyFlag;

#define HeaderTestCnt   10

void cpri_csu_test_init()
{
	stCpriCsuCmdFifoInfo		txTestCmdFifo;
	stCpriCsuCmdFifoInfo		rxTestCmdFifo;
	
	cpri_csu_axc_init_nr_7ds2u(CPRI_DUMMY_USE_DDR_ADDR, &txTestCmdFifo, &rxTestCmdFifo);
	cpri_csu_axcctrl_init_timing();
	UCP_API_CPRI_CSU_Get_CmdFIFO(&txTestCmdFifo, &rxTestCmdFifo);
}

void Cpri_data_init()
{
	gCpriTestMode = CPRI_TEST_MODE;
	gCpriCsuDummyFlag = 0;
	debug_write((DBG_DDR_IDX_DRV_BASE+192), gCpriTestMode); // 0x300

	Get_Cpri_OptionId();//get cpri option value
	debug_write((DBG_DDR_IDX_DRV_BASE+193), CPRI_OPTION); // 0x304
		
	Axc_data_init();//init axc data
	UCP_PRINT_EMPTY("Axc data init.\r\n");
	HeaderTxRam_data_init();
//	HeaderTxRam_init();
}

void Get_Cpri_OptionId()
{
	CPRI_OPTION = CPRI_OPTION_8;
    return;
}

void HeaderTxRam_data_init()
{
	for(int i=0;i<16*HeaderTestCnt;i++)
	{
		do_write(((uint32_t *)HeaderTxDataAddr0 +i),0x12345678+i);
	}
#if 0
	for(int i=0;i<16*HeaderTestCnt;i++)
	{
		do_write(((uint32_t *)HeaderTxDataAddr1 +i),0x87654321+i);
	}
#endif
}
#if 0
void HeaderTxRam_init()
{
	uint32_t i,j;
	HeaderRam_ins_disable();
	for(i=0;i<64;i++)//Ns
	{
		for(j=0;j<4;j++)//
		{
			HeaderRam_Tx(i+64*j,0,0,0);//vendor
			HeaderRam_Tx(i+64*j,1,0,0);//vendor
			HeaderRam_Tx(i+64*j,2,0,0);//vendor
			HeaderRam_Tx(i+64*j,3,0,0);//vendor
		}
	}
	do_write(&CPRI_FRAME_RX_HDR_ADDR,0);
}
#endif

void Axc_data_init()
{
	uint8_t idID = 0;
	uint8_t idSlot = 0;			// even slot, odd slot
//	uint8_t idSymbolBlock = 0;	// symbol0~6, symbol7~13
	uint32_t  srcAddr = 0;
	uint32_t  dstAddr = 0;
	uint32_t  dataLen = 0;
	uint16_t  bfByteCnt = 0;
	uint32_t  slotBfCnt = LONGCP_BF_CNT+SHORTCP_BF_CNT*13;
//	uint32_t  f7BfCnt = LONGCP_BF_CNT+SHORTCP_BF_CNT*6;
//	uint32_t  b7BfCnt = SHORTCP_BF_CNT*7;

	uint32_t cpyCnt = 0;
	
	// valid data
	// compress factor
	bfByteCnt = 2;
	srcAddr = (uint32_t)(&compressData[960+686]);
	dstAddr = CPRI_NR7DS2U_TX_DUMMY_COMPRESS_ADDR + ((SHORTCP_BF_CNT<<2)<<1);
	dataLen = (bfByteCnt*(SHORTCP_BF_CNT<<2)); 
	debug_write((DBG_DDR_IDX_DRV_BASE+196+(cpyCnt<<2)), (uint32_t)srcAddr); // 0x310
	debug_write((DBG_DDR_IDX_DRV_BASE+196+((cpyCnt<<2)+1)), (uint32_t)dstAddr);
	debug_write((DBG_DDR_IDX_DRV_BASE+196+((cpyCnt<<2)+2)), (uint32_t)dataLen);
	cpyCnt++;
	memcpy_ucp((void*)dstAddr,(void*)srcAddr, dataLen);
	
	for (idSlot = 0; idSlot <= 1; idSlot++)
	{
		bfByteCnt = 2;
		
		if (0 == idSlot)	// even slot
		{
			srcAddr = (uint32_t)(&compressData[0]);
			dstAddr = CPRI_NR7DS2U_TX_DUMMY_COMPRESS_ADDR+((SHORTCP_BF_CNT<<3)<<1);
		}
		else				// odd slot
		{
			srcAddr = (uint32_t)(&compressData[1920>>1]);
			dstAddr = CPRI_NR7DS2U_TX_DUMMY_COMPRESS_ADDR+((SHORTCP_BF_CNT<<3)<<1)+(slotBfCnt<<1);
		}
		dataLen = (bfByteCnt*slotBfCnt); 
		debug_write((DBG_DDR_IDX_DRV_BASE+196+(cpyCnt<<2)), (uint32_t)srcAddr); // 0x310
		debug_write((DBG_DDR_IDX_DRV_BASE+196+((cpyCnt<<2)+1)), (uint32_t)dstAddr);
		debug_write((DBG_DDR_IDX_DRV_BASE+196+((cpyCnt<<2)+2)), (uint32_t)dataLen);
		cpyCnt++;
		memcpy_ucp((void*)dstAddr,(void*)srcAddr, dataLen);
	}

	// IQ data	
	for (idID = 1; idID < 5; idID++)
	{
		bfByteCnt = 64;
		srcAddr = (uint32_t)(&antData[30720+21952]);
		dstAddr = CPRI_NR7DS2U_TX_DUMMY_AXC1DATA_ADDR + (idID-1)*CPRI_NR7DS2U_TX_DUMMY_AXCDATA_LEN + ((SHORTCP_BF_CNT<<2)<<6);
		dataLen = (bfByteCnt*(SHORTCP_BF_CNT<<2)); 
		debug_write((DBG_DDR_IDX_DRV_BASE+196+(cpyCnt<<2)), (uint32_t)srcAddr); // 0x310
		debug_write((DBG_DDR_IDX_DRV_BASE+196+((cpyCnt<<2)+1)), (uint32_t)dstAddr);
		debug_write((DBG_DDR_IDX_DRV_BASE+196+((cpyCnt<<2)+2)), (uint32_t)dataLen);
		cpyCnt++;
		memcpy_ucp((void*)dstAddr,(void*)srcAddr, dataLen);
		
		for (idSlot = 0; idSlot <= 1; idSlot++)
		{
//			for (idSymbolBlock = 0; idSymbolBlock <= 1; idSymbolBlock++)
			{
				if (0 == idSlot)	// even slot
				{
					dataLen = bfByteCnt * slotBfCnt;
					srcAddr = (uint32_t)(&antData[0]);
					dstAddr = CPRI_NR7DS2U_TX_DUMMY_AXC1DATA_ADDR + (idID-1)*CPRI_NR7DS2U_TX_DUMMY_AXCDATA_LEN + ((SHORTCP_BF_CNT<<3)<<6);
				}
				else if (1 == idSlot)	// odd slot
				{
					dataLen = bfByteCnt * slotBfCnt;
					srcAddr = (uint32_t)(&antData[30720]);
					dstAddr = CPRI_NR7DS2U_TX_DUMMY_AXC1DATA_ADDR + (idID-1)*CPRI_NR7DS2U_TX_DUMMY_AXCDATA_LEN + ((SHORTCP_BF_CNT<<3)<<6)+(slotBfCnt<<6);
				}
				debug_write((DBG_DDR_IDX_DRV_BASE+196+(cpyCnt<<2)), (uint32_t)srcAddr); // 0x310
				debug_write((DBG_DDR_IDX_DRV_BASE+196+((cpyCnt<<2)+1)), (uint32_t)dstAddr);
				debug_write((DBG_DDR_IDX_DRV_BASE+196+((cpyCnt<<2)+2)), (uint32_t)dataLen);
				cpyCnt++;
				memcpy_ucp((void*)dstAddr,(void*)srcAddr, dataLen);
			}
		}
	}
}

void cpri_csu_config()
{


}



void cpri_test_case()
{
	UCP_API_CPRI_CSU_START(txCmdFifo, rxCmdFifo);
}

void cpri_test_move_data()
{
}

void Cpri_Header_test()
{
}

void Cpri_Header_Rx(void)
{
}

uint32_t gCompWordCnt = 0;
uint32_t gErrSlotIdCnt = 0;
uint32_t gCompSlotIdCnt = 0;
void AxC_data_check(uint32_t times)
{
	stMtimerIntStat* pMtimerInt = &gMtimerIntCnt[MTIMER_CPRI_ID];
	if (4 <= pMtimerInt->csuEnCnt)
	{
		gCompWordCnt = 0;
		for (int i = 7; i < (CPRI_CASE36_SLOT_NUM>>1); i++)
		{
			cpri_check_slot_data(i);
		}
	}
}

void cpri_check_slot_data(uint32_t slotNum)
{
	// move data from sm to ddr
	uint32_t slotId = 0;
	uint32_t srcAddr = 0;
	uint32_t dstAddr = 0;
	uint32_t dataLen = 0;
	uint8_t bitOffset = 0;
	uint32_t  slotBfCnt = LONGCP_BF_CNT+SHORTCP_BF_CNT*13;
	uint8_t	bfWordCnt = 0;

	uint8_t slotVal = 0;
	uint8_t idVal = 0;
	uint32_t bfStart = 0;

	uint32_t compVal = 0;
	uint32_t recvVal = 0;
	uint32_t recvAddr = 0;
	
	for (uint32_t i = 0; i < 5; i++)
	{
		gCompSlotIdCnt++;
		slotId = slotNum;	// get_tx_nr_slot(NR_SCS_30K);
		idVal = i;
		bfStart = 0;
		slotBfCnt = LONGCP_BF_CNT+SHORTCP_BF_CNT*13;
		if (7 == slotId)		// compare S slot, odd slot
		{
			bfStart = (LONGCP_BF_CNT+SHORTCP_BF_CNT*9);
			slotBfCnt = (4 * SHORTCP_BF_CNT);
			slotVal = 1;
			if (0 == i)
			{
				bitOffset = 1;	// one BF, 2B
				bfWordCnt = 1;
				srcAddr = CPRI_NR7DS2U_RX_SLOTS_COMPRESS_ADDR;
			}
			else
			{
				bitOffset = 6;	// one BF, 64B
				bfWordCnt = (64>>2);
				srcAddr = CPRI_NR7DS2U_RX_SLOTS_AXCDATA_ADDR + (i-1)*((SHORTCP_BF_CNT*4)<<bitOffset);
			}
			dataLen = (4 * SHORTCP_BF_CNT) << bitOffset;
		}
		else if (8 == slotId)		// current slot is odd slot, compare even slot, slot8
		{
			slotVal = 0;
			if (0 == i)
			{
				bitOffset = 1;	// one BF, 2B
				bfWordCnt = 1;
				srcAddr = CPRI_NR7DS2U_RX_SLOT_EVEN_COMPRESS_ADDR;
			}
			else
			{
				bitOffset = 6;	// one BF, 64B
				bfWordCnt = (64>>2);
				srcAddr = CPRI_NR7DS2U_RX_SLOT_EVEN_AXCDATA_ADDR + ((i-1)*(slotBfCnt<<bitOffset));
			}
			dataLen = slotBfCnt << bitOffset;
		}
		else if (9 == slotId)	// compare odd slot, slot9
		{
			slotVal = 1;
			if (0 == i)
			{
				bitOffset = 1;	// one BF, 2B
				bfWordCnt = 1;
				srcAddr = CPRI_NR7DS2U_RX_SLOT_ODD_COMPRESS_ADDR;
			}
			else
			{
				bitOffset = 6;	// one BF, 64B
				bfWordCnt = (64>>2);
				srcAddr = CPRI_NR7DS2U_RX_SLOT_ODD_AXCDATA_ADDR + ((i-1)*(slotBfCnt<<bitOffset));
			}
			dataLen = slotBfCnt << bitOffset;
		}

		if (0 == i)	// compress factor
		{
			for (uint32_t idBf = 0; idBf < (slotBfCnt>>1); idBf++)
			{
				for (uint32_t idWord = 0; idWord < bfWordCnt; idWord++)
				{
					if (7 == slotId)
					{
						dstAddr = 960 + (686 + idBf)*bfWordCnt + idWord;
					}
					else
					{
						dstAddr = slotVal*(1920>>1) + idBf*bfWordCnt + idWord;
					}
					recvAddr = (uint32_t)((uint32_t*)srcAddr + idBf*bfWordCnt + idWord);
					recvVal = do_read_volatile(recvAddr); // *((uint32_t*)recvAddr);
					compVal = do_read_volatile(&compressData[dstAddr]); // compressData[dstAddr];
					if ((recvVal != compVal) || (recvVal != compVal))
					{
						debug_write((DBG_DDR_IDX_DRV_BASE+200+((gErrSlotIdCnt<<2)&0x3F)), dstAddr);		// 0x320
						debug_write((DBG_DDR_IDX_DRV_BASE+201+((gErrSlotIdCnt<<2)&0x3F)), recvAddr);		// 0x324
						debug_write((DBG_DDR_IDX_DRV_BASE+202+((gErrSlotIdCnt<<2)&0x3F)), (slotId+(i<<4)+(idBf<<8)));		// 0x328
						debug_write((DBG_DDR_IDX_DRV_BASE+203+((gErrSlotIdCnt<<2)&0x3F)), recvVal);		// 0x32c
						gErrSlotIdCnt++;
//						break;
//						break;
					}
				}
			}
		}
		else		// axc data
		{
			for (uint32_t idBf = 0; idBf < slotBfCnt; idBf++)
			{
				for (uint32_t idWord = 0; idWord < bfWordCnt; idWord++)
				{
					if (7 == slotId)
					{
						dstAddr = 30720 +((139+137*9) + idBf)*bfWordCnt + idWord;
					}
					else
					{
						dstAddr = slotVal*30720 + idBf*bfWordCnt + idWord;
					}
					recvAddr = (uint32_t)((uint32_t*)srcAddr + idBf*bfWordCnt + idWord);
					recvVal = do_read_volatile(recvAddr); // *((uint32_t*)recvAddr);
					compVal = do_read_volatile(&antData[dstAddr]); // antData[dstAddr];
					if (recvVal != compVal)
					{
						debug_write((DBG_DDR_IDX_DRV_BASE+200+((gErrSlotIdCnt<<2)&0x3F)), dstAddr);		// 0x320
						debug_write((DBG_DDR_IDX_DRV_BASE+201+((gErrSlotIdCnt<<2)&0x3F)), recvAddr);		// 0x324
						debug_write((DBG_DDR_IDX_DRV_BASE+202+((gErrSlotIdCnt<<2)&0x3F)), (slotId+(i<<4)+(idBf<<8)));		// 0x328
						debug_write((DBG_DDR_IDX_DRV_BASE+203+((gErrSlotIdCnt<<2)&0x3F)), recvVal);		// 0x32c
						gErrSlotIdCnt++;
			//			do_write(a, compValFirst);
			//			do_write(a, recvValFirst);
			//			do_write(a, compValLast);
			//			do_write(a, recvValLast);
//						break;
//						break;
					}
				}
			}
		}
		debug_write((DBG_DDR_IDX_DRV_BASE+196), gCompSlotIdCnt); // 0x310
		debug_write((DBG_DDR_IDX_DRV_BASE+197), gErrSlotIdCnt); // 0x314
	}
}

