#include "ecpri_timer.h"

#include "ucp_sfr_c.h"
#include "ucp_ecpri.h"
#include "phy_para.h"
#include "mtimer_com.h"
#include "ucp_utility.h"
#include "ucp_printf.h"
#include "ucp_mtimer.h"
#include "inter_vector.h"
#include "ecs_rfm_dm_mgt.h"
#include "mtimer_drv.h"
#include "ucp_js_ctrl.h"
#include "ctc_intr.h"
#include "ucp_handshake.h"

extern stPhyScsPara* phyPara;
extern stMtimerIntStat gMtimerIntCnt[SCS_MAX_NUM];
extern stMtimerPhyPara gMtimerSfnNum[SCS_MAX_NUM];
extern stMtimerSfnCal gMtimerSfnCalPara[SCS_MAX_NUM];

extern uint32_t reCfgFlag;

extern void rfm1_fapi_callback();

void ecpri_timer_cprimode_clk_init()
{
	// bit11：A: eth_src_clk_sel, B: cpri_div33_tx_clk
	// bit19: A: PLL0分频，B: cpri_div33_tx_clk分频
	JECS_CRG_PLLSEL |= BIT19; //BIT11+ 
	// manticore tx
	JECS_CRG_MANTICORE3_RST_CTRL |= BIT24;

	return;
}


void ecpri_mtimer_init(int32_t nScsId, int32_t nTddSlotNum)
{
	stMtimerIntStat* pMtimerInt = &gMtimerIntCnt[MTIMER_ECPRI_ID];
	stMtimerPhyPara* pMtimerSfn = &gMtimerSfnNum[MTIMER_ECPRI_ID];
	stMtimerSfnCal* pMtimerCalPara = &gMtimerSfnCalPara[MTIMER_ECPRI_ID];
	
	memset(pMtimerInt, 0, sizeof(stMtimerIntStat));
	memset(pMtimerSfn, 0, sizeof(stMtimerPhyPara));
	memset(pMtimerCalPara, 0, sizeof(stMtimerSfnCal));
	
	mtimer_para_init(MTIMER_ECPRI_ID, nScsId, nTddSlotNum);
	
    ecpri_timer_init(nScsId, nTddSlotNum);
}

void ecpri_timer_init(int32_t nScsId, int32_t nTddSlotNum)
{
	stMtimerIntStat* pMtimerInt = &gMtimerIntCnt[MTIMER_ECPRI_ID];

	mtimer_clear_all_event(MTIMER_ECPRI_ID);
	set_ecpri_tmr_period();
	ecpri_1pps_src_init(MTIMER_PP1S_SRC_TOD);
	//set_ecpri_1pps_scratch();
	set_ecpri_timer_int();

	pMtimerInt->tmrIntInitFinished = 1;
}

void ecpri_timer_reconfig(phy_timer_config_ind_t *my_ecpritmr)
{
    EcsRfmDmLocalMgt_t* pEcsDmLocalMgt = get_ecs_rfm_dm_local_mgt();
	stMtimerPara* pMtimerPara = pEcsDmLocalMgt->pMtimerPara[MTIMER_ECPRI_ID];
	stMtimerPhyPara* pMtimerSfn = &gMtimerSfnNum[MTIMER_ECPRI_ID];
	uint8_t nBsType = get_protocol_sel(); 
	
	pMtimerPara->scsId = my_ecpritmr->scsId;
	pMtimerPara->runCoreId = (uint16_t)my_ecpritmr->runCoreId;
	pMtimerPara->tddPeriod = my_ecpritmr->t_period; // us
	pMtimerPara->tddSlotNum = my_ecpritmr->num_tti;
	pMtimerPara->slotPeriod = my_ecpritmr->t_us;
	pMtimerPara->slotMaxNum = my_ecpritmr->num_tti_per_sfn;
	pMtimerSfn->slotMaxNum = my_ecpritmr->num_tti_per_sfn;
	pMtimerSfn->slotNumPP1s = gMtimerSfnNum[SCS_1st_MTIMER_ID].slotNumPP1s;
	if (PROTOCOL_ECPRI == get_protocol_sel())
	{
		pMtimerPara->symbolMaxNum = SLOT_SYMBOL_NUM;
		pMtimerSfn->symbolMaxNum = SLOT_SYMBOL_NUM;
	}

	do_write_short((&(phyPara[my_ecpritmr->scsId].slotNumOfTdd)), my_ecpritmr->num_tti);
	__ucps2_synch(0);

	reCfgFlag = 1;

	//set_ecpri_tmr_period();					// set OVF value, every slot int and 10ms int, cevent0/2 for ape0, report link status
	//set_ecpri_tdd_offset();				// 5ms int, tevent2 for all ape cores, dma
	//enable_mtimer_cevent_int(MTIMER_ECPRI_ID, MTMR_CEVENT_CNT14H, MTMR_INT_10ms);	// 10ms int
	set_ecpri_tx_slot_offset();
	set_ecpri_rx_slot_offset();

	if (LTE_SCS_ID == my_ecpritmr->scsId)
	{
		set_ecpri_lte_fapi_offset();
	}

	if (PROTOCOL_ECPRI == nBsType)
	{
		for (int32_t i = 0; i < SLOT_SYMBOL_NUM; i++)
		{
			set_ecpri_tx_symbol_offset(i);
		}
	}

	reCfgFlag = 2;
}

void ecpri_timer_clear_cell(uint8_t scsId)
{
	clear_ecpri_tx_slot_offset();
	clear_ecpri_rx_slot_offset();
	if (LTE_SCS_ID == scsId)
	{
		clear_ecpri_lte_fapi_offset();
	}
}

void ecpri_timer_rcfg_act()
{
    EcsRfmDmLocalMgt_t* pEcsDmLocalMgt = get_ecs_rfm_dm_local_mgt();
	stMtimerPara* pMtimerPara = pEcsDmLocalMgt->pMtimerPara[MTIMER_ECPRI_ID];
	stMtimerPhyPara* pMtimerSfn = &gMtimerSfnNum[SCS_1st_MTIMER_ID];
	int32_t nScsId = pMtimerPara->scsId;
	uint16_t runCore = pMtimerPara->runCoreId;
	uint32_t addr = (uint32_t)&(phyPara[nScsId].runCoreId);
	uint16_t cellCore = do_read_volatile_short(addr);

	set_ecpri_tmr_period();					// set OVF value, every slot int and 10ms int, cevent0/2 for ape0, report link status

	//pMtimerSfn->txSfnNum = 0;
	pMtimerSfn->txSlotNum = pMtimerSfn->slotNumPP1s; // 0
	//pMtimerSfn->rxSfnNum = 0; // 1023;
	pMtimerSfn->rxSlotNum = pMtimerSfn->slotNumPP1s; // 0 // pMtimerSfn->slotMaxNum - 1;

	if ((0 == pMtimerSfn->slotNumPP1s) && (runCore == cellCore)) // no frame header offset, and the first cell
	{
		pMtimerSfn->txSfnNum++;
		pMtimerSfn->txSfnNum &= 0x3FF;
		pMtimerSfn->rxSfnNum = pMtimerSfn->txSfnNum;
	}
	addr = (uint32_t)&(phyPara[nScsId].txSfnNum);
	do_write(addr, pMtimerSfn->txSfnNum);
	addr = (uint32_t)&(phyPara[nScsId].rxSfnNum);
	do_write(addr, pMtimerSfn->rxSfnNum);
	addr = (uint32_t)&(phyPara[nScsId].txSlotNum);
	do_write(addr, pMtimerSfn->txSlotNum);
	addr = (uint32_t)&(phyPara[nScsId].rxSlotNum);
	do_write(addr, pMtimerSfn->rxSlotNum);
	
	
	do_write(CTC_INT_TYPE_ADDR, (MTIMER_ECPRI_ID+1));
	if (PROTOCOL_ECPRI == get_protocol_sel())
	{
		// ecs rfm0 cal
		set_ctc_cal_int(ECS_RFM_SPU0_CORE_ID);
	}

	// ape tmrpoints
	volatile uint32_t h1Pos = __builtin_clz(runCore); // 从高bit开始，第一个1前面的0的个数
	uint8_t apeId = 0;
	__ucps2_synch(0);
	while (32 > h1Pos)
	{
		apeId = 31 - h1Pos;
		if (8 <= apeId)
		{
			return;
		}

		set_ctc_cal_int(apeId);

		runCore &= (~(1 << apeId));
		h1Pos = __builtin_clz(runCore);
		__ucps2_synch(0);
	}

	reCfgFlag = 5;
	disable_mtimer_cevent_int(MTIMER_ECPRI_ID, MTMR_CEVENT_CNT14H, MTMR_INT_10ms);	// disable 10ms int
}

void ecpri_1pps_src_init(uint8_t srcId)
{
	JECS_CTRL_CPRI_GMAC_PHY_INT &= ~(0x7 << 13);
	JECS_CTRL_CPRI_GMAC_PHY_INT |= (srcId << 13);
}

void set_ecpri_1pps_scratch(void)
{
	set_mtimer_1pps_scratch(MTIMER_ECPRI_ID);
}

void set_ecpri_tmr_period(void)
{
    EcsRfmDmLocalMgt_t* pEcsDmLocalMgt = get_ecs_rfm_dm_local_mgt();
	stMtimerPara* pMtimerPara = pEcsDmLocalMgt->pMtimerPara[MTIMER_ECPRI_ID];
	
	// 设置计数器溢出值
	uint32_t tempL = pMtimerPara->tmrMsPeriod * pMtimerPara->slotPeriod / 1000;
	uint32_t tempM = 2; //gCpriTimerPara.tddSlotNum;
	uint32_t tempH = SFN_PERIOD / pMtimerPara->slotPeriod / 2; //gCpriTimerPara.tddSlotNum;

	set_mtimer_period(MTIMER_ECPRI_ID, tempL, tempM, tempH);
	
	//enable_mtimer_cevent_int(MTIMER_ECPRI_ID, MTMR_CEVENT_CNT14H, MTMR_INT_10ms);	// 10ms int
}

void set_ecpri_tdd_offset(void)
{
    EcsRfmDmLocalMgt_t* pEcsDmLocalMgt = get_ecs_rfm_dm_local_mgt();
	stMtimerPara* pMtimerPara = pEcsDmLocalMgt->pMtimerPara[MTIMER_ECPRI_ID];
	uint32_t offset = 0;
	if (PROTOCOL_CPRI == get_protocol_sel())
	{
		offset = pEcsDmLocalMgt->pCpriDelay->cpri10msOffset;
	}
	
	uint32_t tmr2Point = pMtimerPara->tddPeriod - offset;  // us // 5ms
	set_mtimer_tmrpoint(MTIMER_ECPRI_ID, MTMR_TDD_OFFSET, tmr2Point, MTIMER_MASK_48BIT);
	enable_mtimer_tmrpoint_int(MTIMER_ECPRI_ID, MTMR_TDD_OFFSET, MTMR_INT_TDD_OFFSET);
}

void set_ecpri_tx_slot_offset()
{
	uint32_t offset = 0;
	if (PROTOCOL_CPRI == get_protocol_sel())
	{
		EcsRfmDmLocalMgt_t* pEcsDmLocalMgt = get_ecs_rfm_dm_local_mgt();
		offset = pEcsDmLocalMgt->pCpriDelay->cpri10ms2PP1sTxOffset; // pEcsDmLocalMgt->pCpriDelay->cpri10msOffset;
	}
	
	uint32_t tmr3Point = SFN_PERIOD - offset; // us
	set_mtimer_tmrpoint(MTIMER_ECPRI_ID, MTMR_TXSLOT_OFFSET, tmr3Point, MTIMER_MASK_32BIT);
	enable_mtimer_tmrpoint_int(MTIMER_ECPRI_ID, MTMR_TXSLOT_OFFSET, MTMR_INT_SLOT_OFFSET);
	
}

void clear_ecpri_tx_slot_offset()
{
	disable_mtimer_tmrpoint_int(MTIMER_ECPRI_ID, MTMR_TXSLOT_OFFSET, MTMR_INT_SLOT_OFFSET);
}

void set_ecpri_rx_slot_offset()
{
	int32_t offset = 0;
	if (PROTOCOL_CPRI == get_protocol_sel())
	{
		EcsRfmDmLocalMgt_t* pEcsDmLocalMgt = get_ecs_rfm_dm_local_mgt();
		offset = pEcsDmLocalMgt->pCpriDelay->cpri10ms2PP1sRxOffset; // pEcsDmLocalMgt->pCpriDelay->cpri10msRxOffset;
	}

	uint32_t tmr4Point = 0; // offset; // us
	if (offset < 0)
	{
		tmr4Point = (~offset) + 1;
	}
	else
	{
		tmr4Point = SFN_PERIOD - offset; // us
	}
	set_mtimer_tmrpoint(MTIMER_ECPRI_ID, MTMR_RXSLOT_OFFSET, tmr4Point, MTIMER_MASK_32BIT);
	enable_mtimer_tmrpoint_int(MTIMER_ECPRI_ID, MTMR_RXSLOT_OFFSET, MTMR_INT_SLOT_OFFSET);
	
}

void clear_ecpri_rx_slot_offset()
{
	disable_mtimer_tmrpoint_int(MTIMER_ECPRI_ID, MTMR_RXSLOT_OFFSET, MTMR_INT_SLOT_OFFSET);
}

void set_ecpri_lte_fapi_offset(void)
{
	uint32_t offset = 0;
	if (PROTOCOL_CPRI == get_protocol_sel())
	{
		EcsRfmDmLocalMgt_t* pEcsDmLocalMgt = get_ecs_rfm_dm_local_mgt();
		offset = pEcsDmLocalMgt->pCpriDelay->cpri10ms2PP1sTxOffset; // pEcsDmLocalMgt->pCpriDelay->cpri10msOffset;
	}

	uint32_t tmr30Point = SFN_PERIOD - offset - 500; // us

	set_mtimer_tmrpoint(MTIMER_ECPRI_ID, MTMR_LTE_FAPI, tmr30Point, MTIMER_MASK_32BIT);
	enable_mtimer_tmrpoint_int(MTIMER_ECPRI_ID, MTMR_LTE_FAPI, MTMR_INT_SLOT_OFFSET);

}

void clear_ecpri_lte_fapi_offset(void)
{
	disable_mtimer_tmrpoint_int(MTIMER_ECPRI_ID, MTMR_LTE_FAPI, MTMR_INT_SLOT_OFFSET);
}

int32_t set_ecpri_ape_slot_offset(uint32_t apeCoreId)
{
	uint32_t txOffset = 0;
	uint32_t rxOffset = 0;
	uint32_t runCore = apeCoreId;
	volatile uint32_t h1Pos = 0;
	uint8_t apeId = 0;
	int32_t tmrId = 0;
	if (PROTOCOL_CPRI == get_protocol_sel())
	{
		EcsRfmDmLocalMgt_t* pEcsDmLocalMgt = get_ecs_rfm_dm_local_mgt();
		txOffset = pEcsDmLocalMgt->pCpriDelay->cpri10ms2PP1sTxOffset; // pEcsDmLocalMgt->pCpriDelay->cpri10msOffset;
		rxOffset = pEcsDmLocalMgt->pCpriDelay->cpri10ms2PP1sRxOffset; // pEcsDmLocalMgt->pCpriDelay->cpri10msRxOffset;
	    enable_mtimer_cevent_int(MTIMER_ECPRI_ID, MTMR_CEVENT_CNT14H, MTMR_INT_10ms);	// 10ms int
	}

	uint32_t tmr3Point = SFN_PERIOD*1000 - txOffset; // us
	uint32_t tmr4Point = 0; // offset; // us
	if (rxOffset < 0)
	{
		tmr4Point = (~rxOffset) + 1;
	}
	else
	{
		tmr4Point = SFN_PERIOD*1000 - rxOffset; // us
	}
	
	// ape tmrpoints
	h1Pos = __builtin_clz(runCore); // 从高bit开始，第一个1前面的0的个数
	while (32 > h1Pos)
	{
		apeId = 31 - h1Pos;
		if (8 <= apeId)
		{
			return -1;
		}
		// tx slot int
		tmrId = MTMR_APE0_TXSLOT + (apeId<<1);
		set_mtimer_tmrpoint_ns(MTIMER_ECPRI_ID, tmrId, tmr3Point, MTIMER_MASK_32BIT);
		enable_mtimer_tmrpoint_int(MTIMER_ECPRI_ID, tmrId, (MTMR_INT_APE0_SLOT+apeId));
		// rx slot int
		tmrId = MTMR_APE0_RXSLOT + (apeId<<1);
		set_mtimer_tmrpoint_ns(MTIMER_ECPRI_ID, tmrId, tmr4Point, MTIMER_MASK_32BIT);
		enable_mtimer_tmrpoint_int(MTIMER_ECPRI_ID, tmrId, (MTMR_INT_APE0_SLOT+apeId));

		runCore &= (~(1 << apeId));
		h1Pos = __builtin_clz(runCore);
	}

	reCfgFlag = 4;

	return 0;
}

int32_t clear_ecpri_ape_slot_offset(uint32_t apeCoreId)
{
	uint32_t runCore = apeCoreId;
	volatile uint32_t h1Pos = 0;
	uint8_t apeId = 0;
	int32_t tmrId = 0;

	// ape tmrpoints
	h1Pos = __builtin_clz(runCore); // 从高bit开始，第一个1前面的0的个数
	while (32 > h1Pos)
	{
		apeId = 31 - h1Pos;
		if (8 <= apeId)
		{
			return -1;
		}
		// tx slot int
		tmrId = MTMR_APE0_TXSLOT + (apeId<<1);
		disable_mtimer_tmrpoint_int(MTIMER_ECPRI_ID, tmrId, (MTMR_INT_APE0_SLOT+apeId));
		// rx slot int
		tmrId = MTMR_APE0_RXSLOT + (apeId<<1);
		disable_mtimer_tmrpoint_int(MTIMER_ECPRI_ID, tmrId, (MTMR_INT_APE0_SLOT+apeId));

		runCore &= (~(1 << apeId));
		h1Pos = __builtin_clz(runCore);
	}

	return 0;
}

int32_t set_ecpri_tx_symbol_offset(uint8_t symbolId)
{
	if (SLOT_SYMBOL_NUM <= symbolId)
	{
		return -1;
	}
	
	uint32_t longCp = (uint32_t)4448*500000/(4448+13*4384); // ns
	uint32_t shortCp = (uint32_t)4384*500000/(4448+13*4384); // ns
	
	uint32_t tmrPoint = SFN_PERIOD*1000 - CPRI_INT_DELAY;
	if (1 >= symbolId)
	{
		tmrPoint += ((longCp*symbolId));
	}
	else
	{
		tmrPoint += ((longCp + shortCp*(symbolId-1)));
	}

	set_mtimer_tmrpoint_ns(MTIMER_ECPRI_ID, MTMR_ECPRI_TX_SYMBOL0+symbolId, tmrPoint, MTIMER_MASK_32BIT);
	enable_mtimer_tmrpoint_int(MTIMER_ECPRI_ID, MTMR_ECPRI_TX_SYMBOL0+symbolId, MTMR_INT_RFM0_SLOT);

	return 0;
}

void set_ecpri_timer_int(void)
{
	int32_t apeId = get_core_id();

	uint32_t intNum = APC_ECPRI_SUB_INTR2;
	// attach interrupt func
	int32_t ret = smart_irq_request(intNum, isr_ecpri_timer);
	if (0 != ret)
	{
		UCP_PRINT_ERROR("attach int num: 0x%x error. errno = 0x%x. \r\n", intNum, ret);
		debug_write(DBG_DDR_ERR_IDX(apeId, 33), ret);
	}
}

void start_ecpri_timer(void)
{
	start_mtimer(MTIMER_ECPRI_ID);
}

void stop_ecpri_timer(void)
{
	stop_mtimer(MTIMER_ECPRI_ID);
}

uint32_t lastEcpriTxSlotCnt = 0;
uint32_t nowEcpriTxSlotCnt = 0;
uint32_t rfmEcpriSlotErrCnt = 0;
uint32_t rfmEcpriSlotErrMax = 0;
void isr_ecpri_timer(void)
{
	uint32_t tmrIntcFlag = 0;
	uint32_t tEventFlag = 0;
	uint32_t cEventFlag = 0;
	uint32_t tEventAddr = 0;
	uint32_t tFlagAddr = 0;
	uint32_t cFlagAddr = 0;
    EcsRfmDmLocalMgt_t* pEcsDmLocalMgt = get_ecs_rfm_dm_local_mgt();
	stMtimerPara* pMtimerPara = pEcsDmLocalMgt->pMtimerPara[MTIMER_ECPRI_ID];
	stMtimerIntStat* pMtimerInt = &gMtimerIntCnt[MTIMER_ECPRI_ID];
	stMtimerPhyPara* pMtimerSfn = &gMtimerSfnNum[MTIMER_ECPRI_ID];
	uint32_t tmrBaseAddr = mtimer_get_baseaddr(MTIMER_ECPRI_ID);

	pMtimerInt->tmrIntCnt++;
	tmrIntcFlag = do_read_volatile(tmrBaseAddr + MTMR_INTC_REG);
#ifdef PALLADIUM_TEST
	debug_write((DBG_DDR_IDX_DRV_BASE+2048), pMtimerInt->tmrIntCnt);	// 0xb7e08000
	debug_write((DBG_DDR_IDX_DRV_BASE+2048+3), tmrIntcFlag); // 0xb7e0800C
#endif	

	uint32_t runApe = 0;
	uint32_t intApeFlag = 0;
	uint8_t  intApeId = 0;
	runApe = do_read_volatile((&(phyPara[pMtimerPara->scsId].runCoreId)));
	if (0 == runApe)
	{
		intApeFlag = ((tmrIntcFlag>>MTMR_INT_APE0_SLOT) & 0xFF) & (~runApe);
		debug_write((DBG_DDR_IDX_DRV_BASE+48), runApe); 	 // 0xb7e08004
		debug_write((DBG_DDR_IDX_DRV_BASE+49), intApeFlag);  // 0xb7e08004
		volatile uint32_t h1Pos = __builtin_clz(intApeFlag); // 从高bit开始，第一个1前面的0的个数
		while (32 > h1Pos)
		{
			intApeId = 31 - h1Pos;
			if (8 <= intApeId)
			{
				return;
			}

			tFlagAddr = tmrBaseAddr+MTMR_TINTF00_REG + 6*((MTMR_INT_APE0_SLOT+intApeId)<<2);
			tEventAddr = tmrBaseAddr + MTMR_TEVENT0_REG;
			
			tEventFlag = do_read_volatile(tFlagAddr);
			do_write(tEventAddr, tEventFlag);
			do_write(tFlagAddr, tEventFlag);	// clear int flag
			
			do_write((tmrBaseAddr+MTMR_INTC_REG), (tmrIntcFlag & 0xFF0));		// clear int
			__ucps2_synch(0);

			tmrIntcFlag = do_read_volatile(tmrBaseAddr + MTMR_INTC_REG);
			intApeFlag = ((tmrIntcFlag>>MTMR_INT_APE0_SLOT) & 0xFF) & (~runApe);
			h1Pos = __builtin_clz(intApeFlag);
		}
	}

	if ((tmrIntcFlag & (1 << MTMR_INT_10ms)))  /* tmr int */
	{
		cFlagAddr = tmrBaseAddr + MTMR_CINTF0_REG + 2*(MTMR_INT_10ms<<2);
		cEventFlag = do_read_volatile(cFlagAddr);
		__ucps2_synch(0);
		if (cEventFlag & BIT17) // 1pps int
		{
			do_write((tmrBaseAddr+MTMR_CEVENT_REG), BIT17);
			do_write(cFlagAddr, BIT17); // clear int flag

			if (0 == pMtimerInt->pp1sIntCnt)
			{
				start_ecpri_timer();
			}

#ifdef ENABLE_SFNCAL
			//mtimer_1pps_func(MTIMER_CPRI_ID);
#endif
			pMtimerInt->pp1sIntCnt++;
			debug_write((DBG_DDR_IDX_DRV_BASE+2048+1), pMtimerInt->pp1sIntCnt); // 0xb7e08004
		}
		if (cEventFlag & (1<<MTMR_CEVENT_CNT14H))			// 10ms int
		{
			do_write((tmrBaseAddr+MTMR_CEVENT_REG), (1<<MTMR_CEVENT_CNT14H));
			do_write(cFlagAddr, (1<<MTMR_CEVENT_CNT14H));	// clear int flag
			pMtimerInt->sfnIntCnt++;
#ifdef PALLADIUM_TEST
			debug_write((DBG_DDR_IDX_DRV_BASE+2048+2), pMtimerInt->sfnIntCnt);	// 0xb7e08008
#endif
#if 0
			nowEcpriTxSlotCnt = GET_STC_CNT();
			if ((nowEcpriTxSlotCnt > lastEcpriTxSlotCnt) && (2 < pMtimerInt->sfnIntCnt))
			{
				uint32_t cost = nowEcpriTxSlotCnt - lastEcpriTxSlotCnt;
				if ((10005000 < cost) || (9995000 > cost))
				{
					rfmEcpriSlotErrCnt++;
					debug_write((DBG_DDR_IDX_DRV_BASE+2048+108), rfmEcpriSlotErrCnt); // 0x81b0
					debug_write((DBG_DDR_IDX_DRV_BASE+2048+109), cost); 		// 0x81b4
				}
				if (cost > rfmEcpriSlotErrMax)
				{
					rfmEcpriSlotErrMax = cost;
				}
				debug_write((DBG_DDR_IDX_DRV_BASE+2048+110), rfmEcpriSlotErrMax); // 0x81b8
			}
			lastEcpriTxSlotCnt = nowEcpriTxSlotCnt;
#endif
			uint16_t nScsId = pMtimerPara->scsId;
			uint16_t runCore = do_read_volatile_short(&(phyPara[nScsId].runCoreId));
			if (((runCore & pMtimerPara->runCoreId) == pMtimerPara->runCoreId) && (4 == reCfgFlag))
			//if ((runCore == pMtimerPara->runCoreId) && (3 == reCfgFlag))
			{
				//debug_write((DBG_DDR_IDX_DRV_BASE+907), GET_STC_CNT()); // 0xe2c	// timer restart finished
				ecpri_timer_rcfg_act();
				//pMtimerCal->sfnCalFinished = 1;
			}
		}
		do_write((tmrBaseAddr+MTMR_INTC_REG), (1 << MTMR_INT_10ms)); 		// clear int
	}
	if ((tmrIntcFlag & (1 << MTMR_INT_TDD_OFFSET)))  /* tmr int */
	{
		tFlagAddr = tmrBaseAddr + MTMR_TINTF00_REG + 6*(MTMR_INT_TDD_OFFSET<<2);
		tEventAddr = tmrBaseAddr + MTMR_TEVENT0_REG;
		tEventFlag = do_read_volatile(tFlagAddr);
		if (tEventFlag & (1<<MTMR_TDD_OFFSET))		// tdd offset int
		{
			do_write(tEventAddr, (1<<MTMR_TDD_OFFSET));
			do_write(tFlagAddr, (1<<MTMR_TDD_OFFSET));	// clear int flag
			pMtimerInt->tddOffsetIntCnt++;
			// start_csu_timing
#ifdef PALLADIUM_TEST
			debug_write((DBG_DDR_IDX_DRV_BASE+2048+2), pMtimerInt->tddOffsetIntCnt); // 0xb7e08008
#endif
			tEventFlag = do_read_volatile(tFlagAddr);
		}
		do_write((tmrBaseAddr+MTMR_INTC_REG), (1 << MTMR_INT_TDD_OFFSET)); 		// clear int
	}

	if ((tmrIntcFlag & (1 << MTMR_INT_SLOT_OFFSET)))  /* tmr int */
	{
		tFlagAddr = tmrBaseAddr + MTMR_TINTF00_REG + 6*(MTMR_INT_SLOT_OFFSET<<2);
		tEventAddr = tmrBaseAddr + MTMR_TEVENT0_REG;
		tEventFlag = do_read_volatile(tFlagAddr);
		if (tEventFlag & ((1<<MTMR_TXSLOT_OFFSET)|(1<<MTMR_RXSLOT_OFFSET)|(1<<MTMR_LTE_FAPI)))
		{
			if (tEventFlag & (1<<MTMR_TXSLOT_OFFSET)) // tx slot offset
			{
				do_write(tEventAddr, (1<<MTMR_TXSLOT_OFFSET));
				do_write(tFlagAddr, (1<<MTMR_TXSLOT_OFFSET));	// clear int flag
				pMtimerInt->txSlotIntCnt++;
				//uint32_t addr = 0;
#ifdef PALLADIUM_TEST
				debug_write((DBG_DDR_IDX_DRV_BASE+2048+4), pMtimerInt->txSlotIntCnt);	// 0xb7e08010
#endif
				if (5 == reCfgFlag)
				{
					reCfgFlag = 0;
				    //disable_mtimer_cevent_int(MTIMER_ECPRI_ID, MTMR_CEVENT_CNT14H, MTMR_INT_10ms);	// 10ms int
				}
				pMtimerSfn->txSlotTiming = GET_STC_CNT();
				pMtimerSfn->txSlotNum++;
				__ucps2_synch(0);
				if (pMtimerSfn->txSlotNum == pMtimerSfn->slotMaxNum)
				{
					pMtimerSfn->txSfnNum++;
					pMtimerSfn->txSfnNum &= 0x3FF;
					pMtimerSfn->txSlotNum = 0;
				}
				__ucps2_synch(0);
#if 1
				nowEcpriTxSlotCnt = GET_STC_CNT();
				if ((nowEcpriTxSlotCnt > lastEcpriTxSlotCnt) && (2 < pMtimerInt->txSlotIntCnt))
				{
					uint32_t cost = nowEcpriTxSlotCnt - lastEcpriTxSlotCnt;
					if ((1005000 < cost) || (995000 > cost))
					{
						rfmEcpriSlotErrCnt++;
						debug_write((DBG_DDR_IDX_DRV_BASE+2048+108), rfmEcpriSlotErrCnt); // 0x81b0
						debug_write((DBG_DDR_IDX_DRV_BASE+2048+109), cost);			// 0x81b4
					}
					if (cost > rfmEcpriSlotErrMax)
					{
						rfmEcpriSlotErrMax = cost;
					}
					debug_write((DBG_DDR_IDX_DRV_BASE+2048+110), rfmEcpriSlotErrMax); // 0x81b8
				}
				lastEcpriTxSlotCnt = nowEcpriTxSlotCnt;
#endif
			}
			if (tEventFlag & (1<<MTMR_RXSLOT_OFFSET)) // rx slot offset
			{
				do_write((tmrBaseAddr+MTMR_TEVENT0_REG), (1<<MTMR_RXSLOT_OFFSET));
				do_write(tFlagAddr, (1<<MTMR_RXSLOT_OFFSET));	// clear int flag
				pMtimerInt->rxSlotIntCnt++;
				//uint32_t addr = 0;
#ifdef PALLADIUM_TEST
				debug_write((DBG_DDR_IDX_DRV_BASE+2048+5), pMtimerInt->rxSlotIntCnt);	// 0xb7e08014
#endif
				pMtimerSfn->rxSlotNum++;
				__ucps2_synch(0);
				if (pMtimerSfn->rxSlotNum == pMtimerSfn->slotMaxNum)
				{
					pMtimerSfn->rxSfnNum++;
					pMtimerSfn->rxSfnNum &= 0x3FF;
					pMtimerSfn->rxSlotNum = 0;
				}
				__ucps2_synch(0);
			}
			if (tEventFlag & (1<<MTMR_LTE_FAPI))				// LTE FAPI
			{
				do_write((tmrBaseAddr+MTMR_TEVENT0_REG), (1<<MTMR_LTE_FAPI));
				do_write(tFlagAddr, (1<<MTMR_LTE_FAPI)); // clear int flag
				pMtimerInt->lteFapiIntCnt++;
#ifdef PALLADIUM_TEST
				debug_write((DBG_DDR_IDX_DRV_BASE+2048+6), pMtimerInt->lteFapiIntCnt);	// 0xb7e08018
				debug_write((DBG_DDR_IDX_DRV_BASE+672+(pMtimerInt->lteFapiIntCnt&0x1f)), (GET_STC_CNT()-pMtimerSfn->txSlotTiming)); //get_tx_nr_slot(1)); // 0xb7e06a80
#endif
				rfm1_fapi_callback();
			}
			
			tEventFlag = do_read_volatile(tFlagAddr);
		}
		do_write((tmrBaseAddr+MTMR_INTC_REG), (1 << MTMR_INT_SLOT_OFFSET));			// clear int
	}
}


