#include "phy_para.h"
#include "ucp_cpri.h"
#include "ucp_param.h"
#include "ucp_drv_common.h"
#include "ucp_utility.h"
#include "ucp_printf.h"

uint32_t* 		pProtoSel = (uint32_t*)PROTO_SEL_ADDR;
uint32_t* 		pProtoOpt = (uint32_t*)PROTO_OPT_ADDR;
stPhyScsPara*	phyPara = (stPhyScsPara*)PHY_PARA_ADDR;
stSfnPara		gCellSfnPara[2]; // cell para
uint32_t		gScsId = 0;
uint32_t 		gMtimerId = 0;
uint32_t* 		gCpriCsuStopCmd = (uint32_t*)CSU_STOP_CMD_ADDR;

void sfn_para_init(void)
{
	memset(&gCellSfnPara[0], 0, sizeof(stSfnPara) * SCS_MAX_NUM);

	gCellSfnPara[SCS_1st_MTIMER_ID].scsId = SCS_NULL;
	gCellSfnPara[SCS_2nd_MTIMER_ID].scsId = SCS_NULL;
}

void drv_sm_init()
{
	memset_ext((void*)SPU_DRV_SM_ADDR, 0, SPU_DRV_SM_LEN); // init sm for drv, 0x0a4d7000~0x0a4d7FFF
    __ucps2_synch(0);
}

void phy_para_init(uint32_t protocol, uint32_t option)
{
	int32_t i = 0;
	
    do_write(PROTO_SEL_ADDR, protocol);
    do_write(PROTO_OPT_ADDR, option);
	do_write(CSU_STOP_CMD_ADDR, 1);
	do_write(SERDES_INIT_FLAG_ADDR, 0);
	do_write(STC_ONEPPS_OUT_ADDR, 0);

	do_write(ARM_SFN_VALID_ADDR, ARM_SFN_NOTVALID_FLAG); // write nonvalid flag
	
	memset_ext((void*)SLOT_NUM_DEBUG_ADDR, 0, 256);
	memset_ext((void*)APE_INT_INFO_ADDR, 0, APE_INT_MAXNUM*sizeof(stCoreInt)*12*4);
    memset_ext((void*)PHY_PARA_ADDR, 0, sizeof(stPhyScsPara)*PHY_SCS_MAX_NUM);
    do_write(PHY_CELL_ADDR, 0);
	for (i = 0; i < PHY_SCS_MAX_NUM; i++)
	{
		phy_scs_para_init(i);
	}
    __ucps2_synch(0);
}

void phy_scs_para_init(int32_t scsId)
{
	uint32_t addr = 0;
	switch (scsId)
	{
	case (NR_SCS_30K):
	{
		addr = (uint32_t)&(phyPara[NR_SCS_30K].scsId);
		do_write_short(addr, NR_SCS_30K);
		addr = (uint32_t)&(phyPara[NR_SCS_30K].mtimerId);
		do_write_short(addr, MTIMER_NULL);
		addr = (uint32_t)&(phyPara[NR_SCS_30K].gpsOffset);
		do_write_short(addr, GPS_NR_OFFSET);
		addr = (uint32_t)&(phyPara[NR_SCS_30K].slotPeriod);
		do_write_short(addr, 500);
		addr = (uint32_t)&(phyPara[NR_SCS_30K].slotNumOfTdd);	// temp to change
		do_write_short(addr, 10);
		addr = (uint32_t)&(phyPara[NR_SCS_30K].slotNumOfSfn);
		do_write_short(addr, 20);
		break;
	}
	case (NR_SCS_60K):
	{
		addr = (uint32_t)&(phyPara[NR_SCS_60K].scsId);
		do_write_short(addr, NR_SCS_60K);
		addr = (uint32_t)&(phyPara[NR_SCS_60K].mtimerId);
		do_write_short(addr, MTIMER_NULL);
		addr = (uint32_t)&(phyPara[NR_SCS_60K].gpsOffset);
		do_write_short(addr, GPS_NR_OFFSET);
		addr = (uint32_t)&(phyPara[NR_SCS_60K].slotPeriod);
		do_write_short(addr, 250);
		addr = (uint32_t)&(phyPara[NR_SCS_60K].slotNumOfSfn);
		do_write_short(addr, 40);
		break;
	}
	case (NR_SCS_120K):
	{
		addr = (uint32_t)&(phyPara[NR_SCS_120K].scsId);
		do_write_short(addr, NR_SCS_120K);
		addr = (uint32_t)&(phyPara[NR_SCS_120K].mtimerId);
		do_write_short(addr, MTIMER_NULL);
		addr = (uint32_t)&(phyPara[NR_SCS_120K].gpsOffset);
		do_write_short(addr, GPS_NR_OFFSET);
		addr = (uint32_t)&(phyPara[NR_SCS_120K].slotPeriod);
		do_write_short(addr, 125);
		addr = (uint32_t)&(phyPara[NR_SCS_120K].slotNumOfSfn);
		do_write_short(addr, 80);
		break;
	}
	case (LTE_SCS_ID):
	{
		addr = (uint32_t)&(phyPara[LTE_SCS_ID].scsId);
		do_write_short(addr, LTE_SCS_ID);
		addr = (uint32_t)&(phyPara[LTE_SCS_ID].mtimerId);
		do_write_short(addr, MTIMER_NULL);
		addr = (uint32_t)&(phyPara[LTE_SCS_ID].gpsOffset);
		do_write_short(addr, GPS_LTE_OFFSET);
		addr = (uint32_t)&(phyPara[LTE_SCS_ID].slotPeriod);
		do_write_short(addr, 1000);
		addr = (uint32_t)&(phyPara[LTE_SCS_ID].slotNumOfTdd);	// temp to change
		do_write_short(addr, 10);
		addr = (uint32_t)&(phyPara[LTE_SCS_ID].slotNumOfSfn);
		do_write_short(addr, 10);
		break;
	}
	default:
	{
		UCP_PRINT_EMPTY("scs id error! \n");
		break;
	}
	}
}

int32_t get_protocol_sel()
{
	int32_t val = do_read_volatile(PROTO_SEL_ADDR);
	return val;
}

int32_t get_protocol_opt()
{
	int32_t val = do_read_volatile(PROTO_OPT_ADDR);
	return val;
}

void set_tx_slot_intflag(uint8_t scs, int32_t flag)
{
	do_write(&phyPara[scs].txSlotIntFlag, flag);
}

int32_t get_tx_slot_intflag(uint8_t scs)
{
	return do_read_volatile(&phyPara[scs].txSlotIntFlag);
}

void set_rx_slot_intflag(uint8_t scs, int32_t flag)
{
	do_write(&phyPara[scs].rxSlotIntFlag, flag);
}

int32_t get_rx_slot_intflag(uint8_t scs)
{
	return do_read_volatile(&phyPara[scs].rxSlotIntFlag);
}

int32_t send_cpri_csu_stop_cmd()
{
	if (1 == *gCpriCsuStopCmd)
	{
		return -1;
	}

	*gCpriCsuStopCmd = 1;

	return 0;
}

int32_t send_cpri_csu_start_cmd()
{
	if (0 == *gCpriCsuStopCmd)
	{
		return -1;
	}

	*gCpriCsuStopCmd = 0;

	return 0;
}

