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

#include "typedef.h"
#include "ucp_utility.h"
#include "cpri_csu_nr_7ds2u.h"
#include "cpri_test_case33.h"
#include "cpri_timer.h"
#include "ape_csu.h"
#include "cpri_test.h"
#include "ucp_printf.h"

#include <malloc.h>

uint32_t 					srcImData[4*1024] = {0};	// 16KB
extern uint32_t 			gCpriTestMode;
extern stMtimerPhyPara  	gMtimerSfnNum[SCS_MAX_NUM];
extern stMtimerIntStat 		gMtimerIntCnt[SCS_MAX_NUM];

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

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 = 1;
	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");
}

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

void Axc_data_init()
{
	uint8_t idID = 0;
	uint8_t idSlot = 0;			// even slot, odd slot
	uint8_t idSymbolBlock = 0;	// symbol0~6, symbol7~13
	uint8_t idSymbol = 0;
	uint16_t idBF = 0;
	uint16_t idWord = 0;

	uint32_t* pSrcAddr = 0;
	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  symbolBfCnt = 0;
	uint32_t  idSlotBf = 0;
	uint32_t  val = 0;
	
	//uint32_t* srcImData = dmalloc(10240, DM0);
	
	debug_write((DBG_DDR_IDX_DRV_BASE+192), (uint32_t)(&txCmdFifo)); // 0x300
	debug_write((DBG_DDR_IDX_DRV_BASE+193), (uint32_t)(&rxCmdFifo)); // 0x304

	uint32_t cpyCnt = 0;
//	debug_write((DBG_DDR_IDX_DRV_BASE+196+(cpyCnt<<2)), (uint32_t)srcImData); // 0x310
//	debug_write((DBG_DDR_IDX_DRV_BASE+196+((cpyCnt<<2)+1)), (uint32_t)dstAddr);
	cpyCnt++;

	// valid data
	// compress factor
	for (idSlot = 0; idSlot <= 1; idSlot++)
	{
		bfByteCnt = 2;
		
		pSrcAddr = srcImData;
		if (0 == idSlot)	// even slot
		{
			dstAddr = CPRI_NR7DS2U_TX_SLOT_EVEN_COMPRESS_ADDR;
		}
		else				// odd slot
		{
			dstAddr = CPRI_NR7DS2U_TX_SLOT_ODD_COMPRESS_ADDR;
		}
		for (idBF = 0; idBF < (slotBfCnt>>1); idBF++)	// basic frame
		{
			val = (idSlot<<28) | ((idBF<<1)<<8) | (0);
			*pSrcAddr = val;
			//do_write(((uint32_t)pSrcAddr), val);
			pSrcAddr++;
		}
		dataLen = (bfByteCnt*slotBfCnt); 
//		debug_write((DBG_DDR_IDX_DRV_BASE+196+(cpyCnt<<2)), (uint32_t)srcImData); // 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*)srcImData, dataLen);
//		ape_csu_dma_1D_L2G_ch0ch1_transfer(srcAddr, dstAddr, dataLen, tag++, 1);
	}

	// IQ data	
	for (idID = 1; idID < 5; idID++)
	{
		bfByteCnt = 64;
		for (idSlot = 0; idSlot <= 1; idSlot++)
		{
			idSlotBf = 0;
			for (idSymbolBlock = 0; idSymbolBlock <= 1; idSymbolBlock++)
			{
				if ((0 == idSlot) && (0 == idSymbolBlock))	// even slot, symbol0~6
				{
					dstAddr = CPRI_NR7DS2U_TX_SLOT_EVEN_F7SYMBOL_ADDR+(idID-1)*(f7BfCnt<<6);
				}
				else if ((0 == idSlot) && (1 == idSymbolBlock))	// even slot, symbol7~13
				{
					dstAddr = CPRI_NR7DS2U_TX_SLOT_EVEN_B7SYMBOL_ADDR+(idID-1)*(b7BfCnt<<6);
				}
				else if ((1 == idSlot) && (0 == idSymbolBlock))	// odd slot, symbol0~6
				{
					dstAddr = CPRI_NR7DS2U_TX_SLOT_ODD_F7SYMBOL_ADDR+(idID-1)*(f7BfCnt<<6);
				}
				else if ((1 == idSlot) && (1 == idSymbolBlock))	// odd slot, symbol7~13
				{
					dstAddr = CPRI_NR7DS2U_TX_SLOT_ODD_B7SYMBOL_ADDR+(idID-1)*(b7BfCnt<<6);
				}
				for (idSymbol = 0; idSymbol < 7; idSymbol++)
				{
					pSrcAddr = srcImData;
					if ((0 == idSymbol) && (0 == idSymbolBlock))
					{
						symbolBfCnt = LONGCP_BF_CNT;
					}
					else
					{
						symbolBfCnt = SHORTCP_BF_CNT;
					}
					for (idBF = 0; idBF < symbolBfCnt; idBF++)	// basic frame
			 		{
						for (idWord = 0; idWord < (bfByteCnt>>2); idWord++)
						{
							val = (idSlot<<28) | (idID<<24) | ((idSlotBf++)<<8) | (idWord);
							*pSrcAddr = val;
							//do_write(((uint32_t)pSrcAddr), val);
							pSrcAddr++;
						}
			 		}
					dataLen = symbolBfCnt*bfByteCnt;
//					debug_write((DBG_DDR_IDX_DRV_BASE+196+(cpyCnt<<2)), (uint32_t)srcImData); // 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*)srcImData, dataLen);
					dstAddr += dataLen;
				}
			}
		}
	}

	// agc factor
	for (idSlot = 0; idSlot <= 1; idSlot++)
	{
		bfByteCnt = 2;
		
		pSrcAddr = srcImData;
		if (0 == idSlot)	// even slot
		{
			dstAddr = CPRI_NR7DS2U_TX_SLOT_EVEN_AGC_ADDR;
		}
		else				// odd slot
		{
			dstAddr = CPRI_NR7DS2U_TX_SLOT_ODD_AGC_ADDR;
		}
		for (idBF = 0; idBF < (slotBfCnt>>1); idBF++)	// basic frame
		{
			val = (idSlot<<28) | (5<<24) | ((idBF<<1)<<8) | (0);
			*pSrcAddr = val;
			//do_write(((uint32_t)pSrcAddr), val);
			pSrcAddr++;
		}
		dataLen = (bfByteCnt*slotBfCnt); 
//		debug_write((DBG_DDR_IDX_DRV_BASE+196+(cpyCnt<<2)), (uint32_t)srcImData); // 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*)srcImData, dataLen);
//		ape_csu_dma_1D_L2G_ch0ch1_transfer(srcAddr, dstAddr, dataLen, tag++, 1);
	}

	// dummy data
	// compress factor
	uint8_t bitOffset = 1; // one bf, 2B
	uint8_t tag = 0;
	// S slot, symbol6~13, odd slot
	srcAddr = CPRI_NR7DS2U_TX_SLOT_ODD_COMPRESS_ADDR + ((LONGCP_BF_CNT + SHORTCP_BF_CNT*5)<<bitOffset);
	dstAddr = CPRI_NR7DS2U_TX_DUMMY_COMPRESS_ADDR;
	dataLen = (SHORTCP_BF_CNT*8)<<bitOffset;
	ape_csu_dma_1D_G2L_ch0ch1_transfer(srcAddr, dstAddr, dataLen, tag++, 1);
	// slot8, even slot
	srcAddr = CPRI_NR7DS2U_TX_SLOT_EVEN_COMPRESS_ADDR;
	dstAddr += dataLen;
	dataLen = slotBfCnt<<bitOffset;
	ape_csu_dma_1D_G2L_ch0ch1_transfer(srcAddr, dstAddr, dataLen, tag++, 1);
	// slot9, odd slot
	srcAddr = CPRI_NR7DS2U_TX_SLOT_ODD_COMPRESS_ADDR;
	dstAddr += dataLen;
	dataLen = slotBfCnt<<bitOffset;
	ape_csu_dma_1D_G2L_ch0ch1_transfer(srcAddr, dstAddr, dataLen, tag++, 1);

	// axc data
	bitOffset = 6;		// one bf, 64B
	for (uint8_t antId = 0; antId < 4; antId++)
	{
		// S slot, symbol6, odd slot
		srcAddr = CPRI_NR7DS2U_TX_SLOT_ODD_F7SYMBOL_ADDR + (antId*(f7BfCnt<<bitOffset)) + ((LONGCP_BF_CNT + SHORTCP_BF_CNT*5)<<bitOffset);
		dstAddr = CPRI_NR7DS2U_TX_DUMMY_AXC1DATA_ADDR + antId*CPRI_NR7DS2U_TX_DUMMY_AXCDATA_LEN;
		dataLen = (SHORTCP_BF_CNT)<<bitOffset;
		ape_csu_dma_1D_G2L_ch0ch1_transfer(srcAddr, dstAddr, dataLen, tag++, 1);
		// S slot, symbol7~13
		srcAddr = CPRI_NR7DS2U_TX_SLOT_ODD_B7SYMBOL_ADDR + (antId*(b7BfCnt<<bitOffset));
		dstAddr += dataLen;
		dataLen = b7BfCnt<<bitOffset;
		ape_csu_dma_1D_G2L_ch0ch1_transfer(srcAddr, dstAddr, dataLen, tag++, 1);
		// slot8, even slot, symbol0~6
		srcAddr = CPRI_NR7DS2U_TX_SLOT_EVEN_F7SYMBOL_ADDR + (antId*(f7BfCnt<<bitOffset));
		dstAddr += dataLen;
		dataLen = f7BfCnt<<bitOffset;
		ape_csu_dma_1D_G2L_ch0ch1_transfer(srcAddr, dstAddr, dataLen, tag++, 1);
		// slot8, even slot, symbol7~13
		srcAddr = CPRI_NR7DS2U_TX_SLOT_EVEN_B7SYMBOL_ADDR + (antId*(b7BfCnt<<bitOffset));
		dstAddr += dataLen;
		dataLen = b7BfCnt<<bitOffset;
		ape_csu_dma_1D_G2L_ch0ch1_transfer(srcAddr, dstAddr, dataLen, tag++, 1);
		// slot9, odd slot, symbol0~6
		srcAddr = CPRI_NR7DS2U_TX_SLOT_ODD_F7SYMBOL_ADDR + (antId*(f7BfCnt<<bitOffset));
		dstAddr += dataLen;
		dataLen = f7BfCnt<<bitOffset;
		ape_csu_dma_1D_G2L_ch0ch1_transfer(srcAddr, dstAddr, dataLen, tag++, 1);
		// slot9, odd slot, symbol7~13
		srcAddr = CPRI_NR7DS2U_TX_SLOT_ODD_B7SYMBOL_ADDR + (antId*(b7BfCnt<<bitOffset));
		dstAddr += dataLen;
		dataLen = b7BfCnt<<bitOffset;
		ape_csu_dma_1D_G2L_ch0ch1_transfer(srcAddr, dstAddr, dataLen, tag++, 1);
	}

	// AGC factor
	bitOffset = 1; // one bf, 2B
	// S slot, symbol6~13, odd slot
	srcAddr = CPRI_NR7DS2U_TX_SLOT_ODD_AGC_ADDR + ((LONGCP_BF_CNT + SHORTCP_BF_CNT*5)<<bitOffset);
	dstAddr = CPRI_NR7DS2U_TX_DUMMY_AGC_ADDR;
	dataLen = (SHORTCP_BF_CNT*8)<<bitOffset;
	ape_csu_dma_1D_G2L_ch0ch1_transfer(srcAddr, dstAddr, dataLen, tag++, 1);
	// slot8, even slot
	srcAddr = CPRI_NR7DS2U_TX_SLOT_EVEN_AGC_ADDR;
	dstAddr += dataLen;
	dataLen = slotBfCnt<<bitOffset;
	ape_csu_dma_1D_G2L_ch0ch1_transfer(srcAddr, dstAddr, dataLen, tag++, 1);
	// slot9, odd slot
	srcAddr = CPRI_NR7DS2U_TX_SLOT_ODD_AGC_ADDR;
	dstAddr += dataLen;
	dataLen = slotBfCnt<<bitOffset;
	ape_csu_dma_1D_G2L_ch0ch1_transfer(srcAddr, dstAddr, dataLen, tag++, 1);
}

void cpri_csu_config()
{
//	 cpri_csu_axc_init_nr_7ds2u();
}

void cpri_test_case()
{
	stMtimerIntStat* pMtimerInt = &gMtimerIntCnt[MTIMER_CPRI_ID];
	// start csu
	if (8 > pMtimerInt->csuEnCnt)	// start 4 timers, test only one radio frame
	{
		UCP_API_CPRI_CSU_START(txCmdFifo, rxCmdFifo);
	}
}

void cpri_test_move_data()
{
	stMtimerIntStat* pMtimerInt = &gMtimerIntCnt[MTIMER_CPRI_ID];
	stMtimerPhyPara* pMtimerSfn = &gMtimerSfnNum[MTIMER_CPRI_ID];
	uint32_t slotId = pMtimerSfn->txSlotNum; // get_tx_nr_slot(NR_SCS_30K);
	if (((10 == slotId) || (0 == slotId)) && (1 < pMtimerInt->csuEnCnt) && (6 > pMtimerInt->csuEnCnt))
	{
		uint32_t srcAddr = 0;
		uint32_t dstAddr = 0;
		uint32_t dataLen = 0;
		uint32_t index = slotId/10;
		// dummy data
		srcAddr = CPRI_NR7DS2U_RX_DUMMY_COMPRESS_ADDR;
		dstAddr = CPRI_CASE33_RX1_DUMMY_DATA_ADDR + index*CPRI_CASE33_TDD_DATA_LEN;
		dataLen = CPRI_CASE33_RX_DUMMY_DATA_LEN;
		ape_csu_dma_1D_G2L_ch0ch1_transfer(srcAddr, dstAddr, dataLen, 0, 0);
		debug_write((DBG_DDR_IDX_DRV_BASE+256+(index<<4)), srcAddr); // 0x400
		debug_write((DBG_DDR_IDX_DRV_BASE+257+(index<<4)), dstAddr); // 0x400
		debug_write((DBG_DDR_IDX_DRV_BASE+258+(index<<4)), dataLen); // 0x400
		debug_write((DBG_DDR_IDX_DRV_BASE+259+(index<<4)), slotId); // 0x400
		
		// slot s data
		srcAddr = CPRI_NR7DS2U_RX_SLOTS_COMPRESS_ADDR;
		dstAddr = CPRI_CASE33_RX1_SLOTS_DATA_ADDR + index*CPRI_CASE33_TDD_DATA_LEN;
		dataLen = CPRI_CASE33_RX_SLOTS_DATA_LEN;
		ape_csu_dma_1D_G2L_ch2ch3_transfer(srcAddr, dstAddr, dataLen, 1, 1);	
		debug_write((DBG_DDR_IDX_DRV_BASE+260+(index<<4)), srcAddr); // 0x400
		debug_write((DBG_DDR_IDX_DRV_BASE+261+(index<<4)), dstAddr); // 0x400
		debug_write((DBG_DDR_IDX_DRV_BASE+262+(index<<4)), dataLen); // 0x400
		debug_write((DBG_DDR_IDX_DRV_BASE+263+(index<<4)), gCpriTimerPara.csuEnCnt); // 0x400
		
		// slot 8 data
		srcAddr = CPRI_NR7DS2U_RX_SLOT_EVEN_COMPRESS_ADDR;
		dstAddr = CPRI_CASE33_RX1_SLOT8_DATA_ADDR + index*CPRI_CASE33_TDD_DATA_LEN;
		dataLen = CPRI_CASE33_RX_SLOTD_DATA_LEN;
//		ape_csu_dma_1D_L2G_ch0ch1_transfer(srcAddr, dstAddr, dataLen, 2, 0);	
		ape_csu_dma_1D_G2L_ch2ch3_transfer(srcAddr, dstAddr, dataLen, 2, 1);	
		debug_write((DBG_DDR_IDX_DRV_BASE+264+(index<<4)), srcAddr); // 0x400
		debug_write((DBG_DDR_IDX_DRV_BASE+265+(index<<4)), dstAddr); // 0x400
		debug_write((DBG_DDR_IDX_DRV_BASE+266+(index<<4)), dataLen); // 0x400
		
		// slot 9 data
		srcAddr = CPRI_NR7DS2U_RX_SLOT_ODD_COMPRESS_ADDR;
		dstAddr = CPRI_CASE33_RX1_SLOT9_DATA_ADDR + index*CPRI_CASE33_TDD_DATA_LEN;
		dataLen = CPRI_CASE33_RX_SLOTD_DATA_LEN;
//		ape_csu_dma_1D_L2G_ch2ch3_transfer(srcAddr, dstAddr, dataLen, 3, 0);	
		ape_csu_dma_1D_G2L_ch2ch3_transfer(srcAddr, dstAddr, dataLen, 3, 0);	
		debug_write((DBG_DDR_IDX_DRV_BASE+268+(index<<4)), srcAddr); // 0x400
		debug_write((DBG_DDR_IDX_DRV_BASE+269+(index<<4)), dstAddr); // 0x400
		debug_write((DBG_DDR_IDX_DRV_BASE+270+(index<<4)), dataLen); // 0x400
	}
}

void Cpri_Header_test()
{
}

void AxC_data_check(uint32_t times)
{
}


