#include "jesd_timer.h"

#include "ucp_ecpri.h"
#include "phy_para.h"
#include "mtimer_com.h"
#include "mtimer_drv.h"
#include "ucp_utility.h"
#include "ucp_printf.h"
#include "ucp_js_ctrl.h"
#include "inter_vector.h"
#include "jesd204.h"
#include "ctc_intr.h"
#include "typedef.h"
#include "jesd_csu.h"
#include "jesd_csu_nr_7ds2u.h"
#include "dw_apb_gpio.h"
#include "ecs_rfm_dm_mgt.h"
#include "ucp_mtimer.h"
#include "mtimer_cal.h"
#include "log_server.h"
#include "gtimer_drv.h"
#include "gpio_drv.h"

//#ifdef INTEGRATED_BS
#ifdef TEST_ENABLE
#include "jesd_test.h"
#endif
//#endif

//stJesdTimerPara gJesdTmrPara[2];
extern stPhyScsPara* phyPara;
extern stSfnPara     gCellSfnPara[2];
extern uint32_t		 gScsId;
extern uint32_t		 gMtimerId;

uint32_t gJesdTestMode = 0;
uint32_t gJesdIOMode = JESD_CSU_CTRL;
uint32_t gJesdTFMode = TDD_MODE;

uint32_t gJesdAlarmSfnCnt = 0;

extern stMtimerIntStat 		gMtimerIntCnt[SCS_MAX_NUM];
extern stMtimerPhyPara 		gMtimerSfnNum[SCS_MAX_NUM];
extern stMtimerSfnCal 		gMtimerSfnCalPara[SCS_MAX_NUM];

stJesdDelay gJesdDelay;

int32_t gCsuTxAdvanceSam = JESD_TX_ADVANCE_SAMPLE;
int32_t gCsuRxAdvanceSam = JESD_RX_ADVANCE_SAMPLE - JESD_RRU_TD;

extern void rfm1_fapi_callback();

//#ifdef INTEGRATED_BS

//volatile uint32_t reCfgFlag = 0;
extern uint32_t reCfgFlag;

void jesd_init()
{
	int32_t apeId = get_core_id();
#ifdef PALLADIUM_TEST
	int32_t flag = 1;
	debug_write((DBG_DDR_IDX_DRV_BASE+2+(apeId<<2)), flag);	// 0xB8
#endif
	phy_para_init(PROTOCOL_JESD, PROTO_OPTION_NULL);

	do_write(CSU_RX_TD_SAMPLE, JESD_RRU_TD);
	do_write(CSU_TX_ADVANCE_SAMPLE, gCsuTxAdvanceSam);

	while (1 > (do_read_volatile(SERDES_INIT_FLAG_ADDR)))	// wait jesd serdes clk init finished
	{
		ucp_nop(1);
	}
#ifdef PALLADIUM_TEST
	flag++;
	debug_write((DBG_DDR_IDX_DRV_BASE+2+(apeId<<2)), flag);	// 0xB8
#endif

    jesd_mtimer_init(MTIMER_JESD_RX0_ID, NR_SCS_30K, 10);
    jesd_mtimer_init(MTIMER_JESD_RX1_ID, NR_SCS_30K, 10);
#ifdef PALLADIUM_TEST
    flag++;
    debug_write((DBG_DDR_IDX_DRV_BASE+2+(apeId<<2)), flag);	// 0xB8
#endif

#if 0
	if (JESD_CSU_CTRL == gJesdIOMode)
	{
	    jesd_csu_init_nr_7ds2u();
	}
	else if (JESD_IO_CTRL == gJesdIOMode)
	{
		jesd_csu_init_nr_7ds2u_iomode();
	}

#ifdef PALLADIUM_TEST
    flag++;
    debug_write((DBG_DDR_IDX_DRV_BASE+2+(apeId<<2)), flag);	// 0x1B8
#endif
#endif
}

void jesd_delay_init()
{
	gJesdDelay.txOffset = INT_DELAY; //CPRI_RE_TOFFSET;
	gJesdDelay.rxOffset = INT_DELAY; //CPRI_RE_TOFFSET;
	gJesdDelay.tddOffset = INT_DELAY + EDMA_OFFSET; //CPRI_RE_TOFFSET + CPRI_EDMA_OFFSET;
}

int32_t jesd_mtimer_init(int32_t nTmrId, int32_t nScsId, int32_t nTddSlotNum)
{
	stMtimerIntStat* pMtimerInt = &gMtimerIntCnt[nTmrId];
	stMtimerPhyPara* pMtimerSfn = &gMtimerSfnNum[nTmrId];
	stMtimerSfnCal* pMtimerCalPara = &gMtimerSfnCalPara[nTmrId];
	
	memset(pMtimerInt, 0, sizeof(stMtimerIntStat));
	memset(pMtimerSfn, 0, sizeof(stMtimerPhyPara));
	memset(pMtimerCalPara, 0, sizeof(stMtimerSfnCal));
	
	if (MTIMER_JESD_RX0_ID == nTmrId)
	{
		jesd_delay_init();
		mtimer_para_init(MTIMER_JESD_RX0_ID, nScsId, nTddSlotNum);
		mtimer_para_init(MTIMER_JESD_TX0_ID, nScsId, nTddSlotNum);
	}
	else if (MTIMER_JESD_RX1_ID == nTmrId)
	{
		mtimer_para_init(MTIMER_JESD_RX1_ID, nScsId, nTddSlotNum);
	}
	else
	{
		return -1;
	}
	
    jesd_timer_init(nTmrId, nScsId, nTddSlotNum);
	
	return 0;
}

int32_t jesd_timer_init(int32_t nTmrId, int32_t nScsId, int32_t nTddSlotNum)
{
	if ((MTIMER_JESD_RX0_ID != nTmrId) && (MTIMER_JESD_RX1_ID != nTmrId))
	{
		return -1;
	}
	
	jesd_1pps_src_init(JESD_PP1S_SRC_STC);
	mtimer_clear_all_event(nTmrId);
	set_jesd_tmr_period(nTmrId);
	set_jesd_1pps_scratch(nTmrId);
	set_jesd_sfn_offset(nTmrId);
	
	if (MTIMER_JESD_RX0_ID == nTmrId)
	{
		//jesd_pin_ctrl(MTIMER_JESD_RX0_ID);
		//jesd_pin_ctrl(MTIMER_JESD_TX0_ID);
		mtimer_clear_all_event(MTIMER_JESD_TX0_ID);
		set_jesd_tmr_period(MTIMER_JESD_TX0_ID);
	}
	
	set_jesd_timer_int(nTmrId);

	return 0;
}

int32_t jesd_timer_reconfig(int32_t nTmrId, phy_timer_config_ind_t *my_jesdtmr)
{
	if ((MTIMER_JESD_RX0_ID != nTmrId) && (MTIMER_JESD_RX1_ID != nTmrId))
	{
		return -1;
	}
	
	int32_t apeId = get_core_id();
#ifdef PALLADIUM_TEST
	int32_t flag = 1;
	debug_write((DBG_DDR_IDX_DRV_BASE+3+(apeId<<2)), flag);	// 0xBC
#endif	
    EcsRfmDmLocalMgt_t* pEcsDmLocalMgt = get_ecs_rfm_dm_local_mgt();
	stMtimerPara* pMtimerPara = pEcsDmLocalMgt->pMtimerPara[nTmrId];
	stMtimerPhyPara* pMtimerSfn = &gMtimerSfnNum[nTmrId];
	
	int32_t scsId = my_jesdtmr->scsId;
	pMtimerPara->scsId = scsId;
	pMtimerPara->runCoreId = (uint16_t)my_jesdtmr->runCoreId;
	pMtimerPara->tddPeriod = my_jesdtmr->t_period; // us
	pMtimerPara->tddSlotNum = my_jesdtmr->num_tti;
	pMtimerPara->slotPeriod = my_jesdtmr->t_us;
	pMtimerPara->slotMaxNum = my_jesdtmr->num_tti_per_sfn;
	pMtimerSfn->slotMaxNum = my_jesdtmr->num_tti_per_sfn;
	if (FDD_MODE == my_jesdtmr->frameType)
	{
		gJesdIOMode = JESD_IO_CTRL;
		gJesdTFMode = FDD_MODE;
	}
	
	do_write_short((&(phyPara[scsId].slotNumOfTdd)), my_jesdtmr->num_tti);
	do_write_short((&(phyPara[scsId].mtimerId)), nTmrId);
	__ucps2_synch(0);

	while (2 != (do_read_volatile(SERDES_INIT_FLAG_ADDR)))	// wait jesd serdes clk init finished
	{
		ucp_nop(1);
	}
	jesd_pin_ctrl(MTIMER_JESD_RX0_ID);
	jesd_pin_ctrl(MTIMER_JESD_TX0_ID);
#ifdef PALLADIUM_TEST
	flag++;
	debug_write((DBG_DDR_IDX_DRV_BASE+3+(apeId<<2)), flag); // 0xBC
#endif

#if 0
	set_jesd_tmr_period(nTmrId);					// set OVF value, every slot int and 10ms int, cevent0/2 for ape0, report link status
	if (MTIMER_JESD_RX0_ID == nTmrId)
	{
		set_jesd_tmr_period(MTIMER_JESD_TX0_ID);
	}
#endif

	enable_mtimer_cevent_int(nTmrId, MTMR_CEVENT_CNT14H, MTMR_INT_10ms);	// 10ms int
#ifdef PALLADIUM_TEST
	flag++;
	debug_write((DBG_DDR_IDX_DRV_BASE+3+(apeId<<2)), flag);	// 0xBC
#endif

	set_jesd_sfn_offset(nTmrId);					// 10ms offset int, log
#ifdef PALLADIUM_TEST
	flag++;
	debug_write((DBG_DDR_IDX_DRV_BASE+3+(apeId<<2)), flag);	// 0xBC
#endif

	set_jesd_tdd_offset(nTmrId);					// 5ms int, dma
#ifdef PALLADIUM_TEST
	flag++;
	debug_write((DBG_DDR_IDX_DRV_BASE+3+(apeId<<2)), flag);	// 0xBC
#endif

	set_jesd_tx_slot_offset(nTmrId);
	set_jesd_rx_slot_offset(nTmrId);
#ifdef PALLADIUM_TEST
	flag++;
	debug_write((DBG_DDR_IDX_DRV_BASE+3+(apeId<<2)), flag);	// 0xBC
#endif

	if ((JESD_CSU_CTRL == gJesdIOMode) && (MTIMER_JESD_RX0_ID == nTmrId))
	{
		gCsuRxAdvanceSam = JESD_RX_ADVANCE_SAMPLE - do_read_volatile(CSU_RX_TD_SAMPLE);
		gCsuTxAdvanceSam = do_read_volatile(CSU_TX_ADVANCE_SAMPLE);
		
		set_jesd_csu_point(MTIMER_JESD_RX0_ID, my_jesdtmr);
		set_jesd_csu_point(MTIMER_JESD_TX0_ID, my_jesdtmr);
		
		set_jesd_rxon_point(nTmrId, my_jesdtmr);
		set_jesd_rxoff_point(nTmrId, my_jesdtmr);
		set_jesd_txon_point(nTmrId, my_jesdtmr);
		set_jesd_txoff_point(nTmrId, my_jesdtmr);
#ifdef PALLADIUM_TEST
		flag++;
		debug_write((DBG_DDR_IDX_DRV_BASE+3+(apeId<<2)), flag); // 0xBC
#endif
	}

	reCfgFlag = 1;

	return 0;
}

int32_t jesd_timer_clear_cell(int32_t nTmrId, uint8_t scsId)
{
	//UCP_API_CPRI_CSU_STOP(); // 是否需要等几个ms

	clear_jesd_tdd_offset(nTmrId);
	clear_jesd_tx_slot_offset(nTmrId);
	clear_jesd_rx_slot_offset(nTmrId);
	if (LTE_SCS_ID == scsId)
	{
		//clear_jesd_lte_fapi_offset();
	}

	return 0;
}

void jesd_timer_rcfg_act(int32_t nTmrId)
{
    EcsRfmDmLocalMgt_t* pEcsDmLocalMgt = get_ecs_rfm_dm_local_mgt();
	stMtimerPara* pMtimerPara = pEcsDmLocalMgt->pMtimerPara[nTmrId];
	stMtimerPhyPara* pMtimerSfn = &gMtimerSfnNum[nTmrId];
	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_jesd_tmr_period(nTmrId);					// set OVF value, every slot int and 10ms int, cevent0/2 for ape0, report link status
	if (MTIMER_JESD_RX0_ID == nTmrId)
	{
		set_jesd_tmr_period(MTIMER_JESD_TX0_ID);
	}

	//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 = 0;
		pMtimerSfn->rxSfnNum = 0; //1023;
		//pMtimerSfn->rxSlotNum = pMtimerSfn->slotMaxNum - 1;
	}
	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);
	
	debug_write((DBG_DDR_IDX_DRV_BASE+556), cellCore);	// 0x8b0
	debug_write((DBG_DDR_IDX_DRV_BASE+557), runCore);	// 0x8b4
	debug_write((DBG_DDR_IDX_DRV_BASE+558), pMtimerSfn->txSfnNum);	// 0x8b8
	debug_write((DBG_DDR_IDX_DRV_BASE+559), pMtimerSfn->rxSfnNum);	// 0x8bc
	
	do_write(CTC_INT_TYPE_ADDR, nTmrId+1);
	// 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;
}

int32_t jesd_pin_ctrl(int32_t nTmrId)
{
	uint32_t tmrBaseAddr = 0;
	if ((MTIMER_JESD_RX1_ID == nTmrId) || (MTIMER_JESD_TX1_ID == nTmrId))
	{
		return -1;
	}
	tmrBaseAddr = JS_RX0_TMR_BASE + nTmrId * 0x1000;

	if (JESD_CSU_CTRL == gJesdIOMode)
	{
		do_write((tmrBaseAddr+MTMR_PIN_CTRL_REG), 0x3);		//CTRL_SEL
		do_write((tmrBaseAddr+MTMR_IO_CTRL_REG), 0);		//IO ctrl
	}
	else
	{
		do_write((tmrBaseAddr+MTMR_PIN_CTRL_REG), 0x1);				//CTRL_SEL
		do_write((tmrBaseAddr+MTMR_IO_CTRL_REG), (1<<(4+(nTmrId>>1))));	//IO ctrl
		if (MTIMER_JESD_RX0_ID == nTmrId)
		{
			if (TDD_MODE == gJesdTFMode)
			{
			#if 1
			    set_jesd_rf_state(JESD_RF_RX, GPIO_OFF); // RxOff();
			    ucp_nop(100000);
			    set_jesd_rf_state(JESD_RF_TX, GPIO_ON); // TxOn();
		   #else
				set_jesd_rf_state(JESD_RF_TX, GPIO_OFF); 
				ucp_nop(100000);
				set_jesd_rf_state(JESD_RF_RX, GPIO_ON); 
		   #endif
			}
			else if (FDD_MODE == gJesdTFMode)
			{
			    set_jesd_rf_state(JESD_RF_TX, GPIO_ON); // TxOn();
			    set_jesd_rf_state(JESD_RF_RX, GPIO_ON); // RxOn();
			}
			else
			{
				return -1;
			}
		}
	}

	return 0;
}

void set_jesd_tmr_period(int32_t nTmrId)
{
	//uint32_t tmrBaseAddr = JS_RX0_TMR_BASE + nTmrId * 0x1000;
    EcsRfmDmLocalMgt_t* pEcsDmLocalMgt = get_ecs_rfm_dm_local_mgt();
	stMtimerPara* pMtimerPara = pEcsDmLocalMgt->pMtimerPara[nTmrId];
	
	// 设置计数器溢出值
	uint32_t tempL = pMtimerPara->tmrMsPeriod * pMtimerPara->slotPeriod / 1000;
	uint32_t tempM = pMtimerPara->tddSlotNum;
	uint32_t tempH = SFN_PERIOD / pMtimerPara->slotPeriod / pMtimerPara->tddSlotNum;

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

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

void set_jesd_1pps_scratch(int32_t nTmrId)
{
	set_mtimer_1pps_scratch(nTmrId);
}

// 10ms
void set_jesd_sfn_offset(int32_t nTmrId)
{
    //EcsRfmDmLocalMgt_t* pEcsDmLocalMgt = get_ecs_rfm_dm_local_mgt();
    uint32_t tmr0Point = SFN_PERIOD - gJesdDelay.txOffset; // us

	set_mtimer_tmrpoint(nTmrId, MTMR_10ms_OFFSET, tmr0Point, MTIMER_MASK_62BIT);
	enable_mtimer_tmrpoint_int(nTmrId, MTMR_10ms_OFFSET, MTMR_INT_10ms);
}

void set_jesd_tdd_offset(int32_t nTmrId)
{
    EcsRfmDmLocalMgt_t* pEcsDmLocalMgt = get_ecs_rfm_dm_local_mgt();
	stMtimerPara* pMtimerPara = pEcsDmLocalMgt->pMtimerPara[nTmrId];
	
	uint32_t tmr2Point = pMtimerPara->tddPeriod - gJesdDelay.tddOffset;  // us // 5ms
	set_mtimer_tmrpoint(nTmrId, MTMR_TDD_OFFSET, tmr2Point, MTIMER_MASK_48BIT);
	enable_mtimer_tmrpoint_int(nTmrId, MTMR_TDD_OFFSET, MTMR_INT_TDD_OFFSET);
}

void clear_jesd_tdd_offset(int32_t nTmrId)
{
	disable_mtimer_tmrpoint_int(nTmrId, MTMR_TDD_OFFSET, MTMR_INT_TDD_OFFSET);
}

void set_jesd_tx_slot_offset(int32_t nTmrId)
{
    //EcsRfmDmLocalMgt_t* pEcsDmLocalMgt = get_ecs_rfm_dm_local_mgt();
	
	uint32_t tmr3Point = SFN_PERIOD - gJesdDelay.txOffset; // us
	set_mtimer_tmrpoint(nTmrId, MTMR_TXSLOT_OFFSET, tmr3Point, MTIMER_MASK_32BIT);
	enable_mtimer_tmrpoint_int(nTmrId, MTMR_TXSLOT_OFFSET, MTMR_INT_SLOT_OFFSET);
	
	//uint32_t tempL = gCpriTimerPara.tmrMsPeriod * (tmr3Point % gCpriTimerPara.slotPeriod) / 1000;
	//uint32_t addr = (uint32_t)&(phyPara[gCpriTimerPara.scsId].txSetVal);
	//do_write(addr, tempL);

#if 0
	// ape tmrpoints
	for (int32_t i = 0; i < APE_NUM; i++)
	{
		int32_t tmrId = MTMR_APE0_TXSLOT + (i<<1);
		set_mtimer_tmrpoint(nTmrId, tmrId, tmr3Point, MTIMER_MASK_32BIT);
		enable_mtimer_tmrpoint_int(nTmrId, tmrId, (MTMR_INT_APE0_SLOT+i));
	}
	// rfm0 tmrpoints
	int32_t tmrId = MTMR_RFM0_TXSLOT;
	set_mtimer_tmrpoint(nTmrId, tmrId, tmr3Point, MTIMER_MASK_32BIT);
	enable_mtimer_tmrpoint_int(nTmrId, tmrId, MTMR_INT_RFM0_SLOT);
#endif
}

void clear_jesd_tx_slot_offset(int32_t nTmrId)
{
	disable_mtimer_tmrpoint_int(nTmrId, MTMR_TXSLOT_OFFSET, MTMR_INT_SLOT_OFFSET);
}

void set_jesd_rx_slot_offset(int32_t nTmrId)
{
    //EcsRfmDmLocalMgt_t* pEcsDmLocalMgt = get_ecs_rfm_dm_local_mgt();

	uint32_t tmr4Point = SFN_PERIOD - gJesdDelay.txOffset; //gJesdDelay.rxOffset; //   // us
	set_mtimer_tmrpoint(nTmrId, MTMR_RXSLOT_OFFSET, tmr4Point, MTIMER_MASK_32BIT);
	enable_mtimer_tmrpoint_int(nTmrId, MTMR_RXSLOT_OFFSET, MTMR_INT_SLOT_OFFSET);
	
	//uint32_t tempL = gCpriTimerPara.tmrMsPeriod * (tmr3Point % gCpriTimerPara.slotPeriod) / 1000;
	//uint32_t addr = (uint32_t)&(phyPara[gCpriTimerPara.scsId].txSetVal);
	//do_write(addr, tempL);

#if 0
	// ape tmrpoints
	for (int32_t i = 0; i < APE_NUM; i++)
	{
		int32_t tmrId = MTMR_APE0_RXSLOT + (i<<1);
		set_mtimer_tmrpoint(nTmrId, tmrId, tmr4Point, MTIMER_MASK_32BIT);
		enable_mtimer_tmrpoint_int(nTmrId, tmrId, (MTMR_INT_APE0_SLOT+i));
	}
	// rfm0 tmrpoints
	int32_t tmrId = MTMR_RFM0_RXSLOT;
	set_mtimer_tmrpoint(nTmrId, tmrId, tmr4Point, MTIMER_MASK_32BIT);
	enable_mtimer_tmrpoint_int(nTmrId, tmrId, MTMR_INT_RFM0_SLOT);
#endif
}
void clear_jesd_rx_slot_offset(int32_t nTmrId)
{
	disable_mtimer_tmrpoint_int(nTmrId, MTMR_RXSLOT_OFFSET, MTMR_INT_SLOT_OFFSET);
}

int32_t set_jesd_ape_slot_offset(int32_t nTmrId, 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;

	EcsRfmDmLocalMgt_t* pEcsDmLocalMgt = get_ecs_rfm_dm_local_mgt();
	stMtimerPara* pMtimerPara = pEcsDmLocalMgt->pMtimerPara[nTmrId];
	pMtimerPara->runCoreId = apeCoreId;
	txOffset = gJesdDelay.txOffset;
	rxOffset = gJesdDelay.rxOffset;

	uint32_t tmr3Point = SFN_PERIOD - txOffset; // us
	uint32_t tmr4Point = SFN_PERIOD - txOffset; // us
	if (rxOffset < 0)
	{
		tmr4Point = (~rxOffset) + 1;
	}
	else
	{
		tmr4Point = SFN_PERIOD - 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(nTmrId, tmrId, tmr3Point, MTIMER_MASK_32BIT);
		enable_mtimer_tmrpoint_int(nTmrId, tmrId, (MTMR_INT_APE0_SLOT+apeId));
		// rx slot int
		tmrId = MTMR_APE0_RXSLOT + (apeId<<1);
		set_mtimer_tmrpoint(nTmrId, tmrId, tmr4Point, MTIMER_MASK_32BIT);
		enable_mtimer_tmrpoint_int(nTmrId, tmrId, (MTMR_INT_APE0_SLOT+apeId));

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

	return 0;
}

int32_t clear_jesd_ape_slot_offset(int32_t nTmrId, 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(nTmrId, tmrId, (MTMR_INT_APE0_SLOT+apeId));
		// rx slot int
		tmrId = MTMR_APE0_RXSLOT + (apeId<<1);
		disable_mtimer_tmrpoint_int(nTmrId, tmrId, (MTMR_INT_APE0_SLOT+apeId));

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

	return 0;
}

void set_jesd_csu_point(int32_t nTmrId, phy_timer_config_ind_t *my_jesdtmr)
{
	if ((MTIMER_JESD_RX0_ID != nTmrId) && (MTIMER_JESD_TX0_ID != nTmrId))
	{
		return;
	}
	
    EcsRfmDmLocalMgt_t* pEcsDmLocalMgt = get_ecs_rfm_dm_local_mgt();
	stMtimerPara* pMtimerPara = pEcsDmLocalMgt->pMtimerPara[nTmrId];
	
	uint32_t tmrBaseAddr = 0;
	tmrBaseAddr = JS_RX0_TMR_BASE + nTmrId * 0x1000;
	uint32_t longcp_symbol_p,shortcp_symbol_p;
	uint32_t shortcp;
	uint32_t gapSymbolCnt = 0;
	//uint32_t ulStartSymbol = 0;
	uint32_t val = 0;

	longcp_symbol_p = LONGCP_SAM_CNT; // 4448;		//sample
	shortcp_symbol_p = SHORTCP_SAM_CNT; // 4384;
	gapSymbolCnt = 14-my_jesdtmr->num_t_dl_symb[0]-my_jesdtmr->num_t_ul_symb[0];	// 14-6-4=4
    shortcp = my_jesdtmr->num_t_dl_symb[0] + gapSymbolCnt - 1; // ul start point
    //ulStartSymbol = my_jesdtmr->num_t_dl_symb + gapSymbolCnt - 1; // ul start point, 6+4-1, symbol9


	if (MTIMER_JESD_RX0_ID == nTmrId)
	{
		/* rx */
		val = do_read_volatile(tmrBaseAddr+MTMR_CMSK_REG);
		val |= ((1<<16) | (1<<18));
		do_write(tmrBaseAddr+MTMR_CMSK_REG, val);
		
		val = longcp_symbol_p + shortcp*shortcp_symbol_p - gCsuRxAdvanceSam - 1; // rx start point
		do_write((tmrBaseAddr+MTMR_RXEN2CSU0L_REG), val);	/* csu RxOn */
#ifdef PALLADIUM_TEST
				debug_write((DBG_DDR_IDX_DRV_BASE+116+(nTmrId<<2)), val); // 0x1D0
#endif
		val = 0xC0000000 |(my_jesdtmr->num_t_dl[0]);			// special slot
		do_write((tmrBaseAddr+MTMR_RXEN2CSU0H_REG), val);	/* enable jesd rxdma */
#ifdef PALLADIUM_TEST
				debug_write((DBG_DDR_IDX_DRV_BASE+117+(nTmrId<<2)), val); // 0x1D4
#endif
		__ucps2_synch(0);
	    while (do_read_volatile(tmrBaseAddr+MTMR_RXEN2CSU0H_REG)&BIT31);
		
		val = pMtimerPara->tmrMsPeriod * pMtimerPara->slotPeriod / 1000 - 1;
		val -= gCsuRxAdvanceSam;
		do_write((tmrBaseAddr+MTMR_RXEN2CSU1L_REG), val); // -g_rfc_1us*(13-2)+RX_DELAY-OFFSET;//+CSU_RX_DELAY-OFFSET;			/* csu RxOff */
#ifdef PALLADIUM_TEST
				debug_write((DBG_DDR_IDX_DRV_BASE+118+(nTmrId<<2)), val); // 0x1D8
#endif
		val = 0x80000000 | (my_jesdtmr->num_tti - 1);			// last slot of tdd
		do_write((tmrBaseAddr+MTMR_RXEN2CSU1H_REG), val);
#ifdef PALLADIUM_TEST
				debug_write((DBG_DDR_IDX_DRV_BASE+119+(nTmrId<<2)), val); // 0x1DC
#endif
		__ucps2_synch(0);
	    while (do_read_volatile(tmrBaseAddr+MTMR_RXEN2CSU1H_REG)&BIT31);
#if 0
		val = do_read_volatile(tmrBaseAddr+MTMR_CINTE0_REG+2*(MTMR_INT_TDD_OFFSET<<2));
		val |= (BIT11|BIT12);
		do_write((tmrBaseAddr+MTMR_CINTE0_REG+2*(MTMR_INT_TDD_OFFSET<<2)), val);
#endif
	}
	else
	{
		/* tx */
		val = do_read_volatile(tmrBaseAddr+MTMR_CMSK_REG);
		val = ((1<<20) | (1<<22));
		do_write(tmrBaseAddr+MTMR_CMSK_REG, val);
		
		val = longcp_symbol_p+(my_jesdtmr->num_t_dl_symb[0]-1)*shortcp_symbol_p - gCsuTxAdvanceSam - 1; // -TX_DELAY+g_rfc_1us*(1)-OFFSET;
		do_write((tmrBaseAddr+MTMR_TXEN2CSU0L_REG), val); /* csu TxOff */
#ifdef PALLADIUM_TEST
				debug_write((DBG_DDR_IDX_DRV_BASE+116+(nTmrId<<2)), val); // 0x1F0
#endif
		val = 0x80000000 |(my_jesdtmr->num_t_dl[0]);  			// special slot
		do_write((tmrBaseAddr+MTMR_TXEN2CSU0H_REG), val);
#ifdef PALLADIUM_TEST
				debug_write((DBG_DDR_IDX_DRV_BASE+117+(nTmrId<<2)), val); // 0x344
#endif
		__ucps2_synch(0);
	    while (do_read_volatile(tmrBaseAddr+MTMR_TXEN2CSU0H_REG)&BIT31);

		val = pMtimerPara->tmrMsPeriod * pMtimerPara->slotPeriod / 1000 - 1;
		val -= (gCsuTxAdvanceSam);
		do_write((tmrBaseAddr+MTMR_TXEN2CSU1L_REG), val); // -TX_DELAY-OFFSET;					/* csu TxOn */
#ifdef PALLADIUM_TEST
				debug_write((DBG_DDR_IDX_DRV_BASE+118+(nTmrId<<2)), val); // 0x348
#endif
		val = 0xC0000000|(my_jesdtmr->num_tti - 1);			// last slot of tdd
		do_write((tmrBaseAddr+MTMR_TXEN2CSU1H_REG), val);	/* enable jesd txdma */
#ifdef PALLADIUM_TEST
				debug_write((DBG_DDR_IDX_DRV_BASE+119+(nTmrId<<2)), val); // 0x34C
#endif
		__ucps2_synch(0);
	    while (do_read_volatile(tmrBaseAddr+MTMR_TXEN2CSU1H_REG)&BIT31);
#if 0	
		val = do_read_volatile(tmrBaseAddr+MTMR_CINTE0_REG+2*(MTMR_INT_TDD_OFFSET<<2));
		val |= (BIT13|BIT14);
		do_write(tmrBaseAddr+MTMR_CINTE0_REG+2*(MTMR_INT_TDD_OFFSET<<2), val);
#endif
	}

	return;
}
void set_jesd_txon_point(int32_t nTmrId, phy_timer_config_ind_t *my_jesdtmr)
{
	uint32_t tmrBaseAddr = 0; 
	if (MTIMER_JESD_RX0_ID != nTmrId)
	{
		UCP_PRINT_EMPTY("jesd timer clear event error! nTmrId = 0x%x. \r\n", nTmrId);
		return;
	}
	tmrBaseAddr = JS_RX0_TMR_BASE + nTmrId * 0x1000;

    EcsRfmDmLocalMgt_t* pEcsDmLocalMgt = get_ecs_rfm_dm_local_mgt();
	stMtimerPara* pMtimerPara = pEcsDmLocalMgt->pMtimerPara[nTmrId];
	
	uint32_t tmr29Point = pMtimerPara->tddPeriod - JESD_RF_ON_GAP;

	set_mtimer_tmrpoint(nTmrId, MTMR_JESD_TXON, tmr29Point, MTIMER_MASK_48BIT);
	enable_mtimer_tmrpoint_int(nTmrId, MTMR_JESD_TXON, MTMR_INT_TDD_OFFSET);
}

void set_jesd_txoff_point(int32_t nTmrId, phy_timer_config_ind_t *my_jesdtmr)
{
	uint32_t tmrBaseAddr = 0; 
	if (MTIMER_JESD_RX0_ID != nTmrId)
	{
		return;
	}
	tmrBaseAddr = JS_RX0_TMR_BASE + nTmrId * 0x1000;

    EcsRfmDmLocalMgt_t* pEcsDmLocalMgt = get_ecs_rfm_dm_local_mgt();
	stMtimerPara* pMtimerPara = pEcsDmLocalMgt->pMtimerPara[nTmrId];

	uint32_t sSymbolStart = (LONGCP_SAM_CNT+13*SHORTCP_SAM_CNT)*my_jesdtmr->num_t_dl[0];
	uint32_t gapSymbolStart = LONGCP_SAM_CNT + (my_jesdtmr->num_t_dl_symb[0]-1) * SHORTCP_SAM_CNT;
	uint32_t tmr28Point = (sSymbolStart + gapSymbolStart) * 1000 / pMtimerPara->tmrMsPeriod;

	set_mtimer_tmrpoint(nTmrId, MTMR_JESD_TXOFF, tmr28Point, MTIMER_MASK_48BIT);
	enable_mtimer_tmrpoint_int(nTmrId, MTMR_JESD_TXOFF, MTMR_INT_TDD_OFFSET);
}

void set_jesd_rxon_point(int32_t nTmrId, phy_timer_config_ind_t *my_jesdtmr)
{
	uint32_t tmrBaseAddr = 0; 
	if (MTIMER_JESD_RX0_ID != nTmrId)
	{
		UCP_PRINT_EMPTY("jesd timer clear event error! nTmrId = 0x%x. \r\n", nTmrId);
		return;
	}
	tmrBaseAddr = JS_RX0_TMR_BASE + nTmrId * 0x1000;

    EcsRfmDmLocalMgt_t* pEcsDmLocalMgt = get_ecs_rfm_dm_local_mgt();
	stMtimerPara* pMtimerPara = pEcsDmLocalMgt->pMtimerPara[nTmrId];
	
	uint32_t sSymbolStart = (LONGCP_SAM_CNT+13*SHORTCP_SAM_CNT)*my_jesdtmr->num_t_dl[0];
	uint32_t gapSymbolStart = LONGCP_SAM_CNT + (my_jesdtmr->num_t_dl_symb[0]-1) * SHORTCP_SAM_CNT;
	uint32_t tmr26Point = (sSymbolStart + gapSymbolStart) * 1000 / pMtimerPara->tmrMsPeriod + JESD_TXRX_CHANGE_GAP;

	set_mtimer_tmrpoint(nTmrId, MTMR_TDD_OFFSET_2500, tmr26Point, MTIMER_MASK_48BIT);
	enable_mtimer_tmrpoint_int(nTmrId, MTMR_TDD_OFFSET_2500, MTMR_INT_TDD_OFFSET);
}

void set_jesd_rxoff_point(int32_t nTmrId, phy_timer_config_ind_t *my_jesdtmr)
{
	uint32_t tmrBaseAddr = 0; 
	if (MTIMER_JESD_RX0_ID != nTmrId)
	{
		UCP_PRINT_EMPTY("jesd timer clear event error! nTmrId = 0x%x. \r\n", nTmrId);
		return;
	}
	tmrBaseAddr = JS_RX0_TMR_BASE + nTmrId * 0x1000;

    EcsRfmDmLocalMgt_t* pEcsDmLocalMgt = get_ecs_rfm_dm_local_mgt();
	stMtimerPara* pMtimerPara = pEcsDmLocalMgt->pMtimerPara[nTmrId];
	
	uint32_t tmr27Point = pMtimerPara->tddPeriod - JESD_TXRX_CHANGE_GAP;

	set_mtimer_tmrpoint(nTmrId, MTMR_TDD_OFFSET_7500, tmr27Point, MTIMER_MASK_48BIT);
	enable_mtimer_tmrpoint_int(nTmrId, MTMR_TDD_OFFSET_7500, MTMR_INT_TDD_OFFSET);
}

void start_jesd_timer(int32_t nTmrId)
{
	start_mtimer(nTmrId);
}

void stop_jesd_timer(int32_t nTmrId)
{
	stop_mtimer(nTmrId);
}

int32_t set_jesd_timer_int(int32_t nTmrId)
{
	int32_t apeId = get_core_id();
	uint32_t intNum = 0;
	uint32_t baseIntNum = 0;
	irq_handler func10ms;
	irq_handler funcTdd;
	irq_handler funcSlot;
	
	if (MTIMER_JESD_RX0_ID == nTmrId)
	{
		baseIntNum = APC_JESD_RX0_SBU0_TMR_INTR0;
		func10ms = isr_jesd_10ms_rx0;
		funcTdd = isr_jesd_tdd_offset_rx0;
		funcSlot = isr_jesd_slot_rx0;
	}
	else if (MTIMER_JESD_RX1_ID == nTmrId)
	{
		baseIntNum = APC_JESD_RX1_SBU0_TMR_INTR0;
		func10ms = isr_jesd_10ms_rx1;
		funcTdd = NULL;
		funcSlot = isr_jesd_slot_rx1;
	}
	else
	{
		return -1;
	}
	
	// attach interrupt func
	int32_t ret = 0;
	intNum = baseIntNum + MTMR_INT_10ms;
	ret = smart_irq_request(intNum, func10ms);
	if (0 != ret)
	{
		debug_write(DBG_DDR_ERR_IDX(apeId, 34), ret);
	}

	intNum = baseIntNum + MTMR_INT_TDD_OFFSET;
	ret = smart_irq_request(intNum, funcTdd);
	if (0 != ret)
	{
		debug_write(DBG_DDR_ERR_IDX(apeId, 35), ret);
	}

	intNum = baseIntNum + MTMR_INT_SLOT_OFFSET;
	ret = smart_irq_request(intNum, funcSlot);
	if (0 != ret)
	{
		debug_write(DBG_DDR_ERR_IDX(apeId, 36), ret);
	}

	return 0;
}

uint32_t gRxOnCnt = 0;
uint32_t gRxOffCnt = 0;
uint32_t gTxOnCnt = 0;
uint32_t gTxOffCnt = 0;
uint32_t gRxCsuOnCnt = 0;
uint32_t gRxCsuOffCnt = 0;
uint32_t gTxCsuOnCnt = 0;
uint32_t gTxCsuOffCnt = 0;
//extern int32_t gPP1sLockCnt;
void jesd_10ms_callback(uint8_t nTmrId)
{
	uint32_t tmrBaseAddr = JS_RX0_TMR_BASE + nTmrId*0x1000;
	uint32_t tmrIntcFlag = 0;
	uint32_t cEventFlag = 0;
	uint32_t tEventFlag = 0;
    EcsRfmDmLocalMgt_t* pEcsDmLocalMgt = get_ecs_rfm_dm_local_mgt();
	stMtimerPara* pMtimerPara = pEcsDmLocalMgt->pMtimerPara[nTmrId];
	stMtimerSfnCal* pMtimerCal = &gMtimerSfnCalPara[nTmrId];
	stMtimerIntStat* pMtimerInt = &gMtimerIntCnt[nTmrId];
	//stMtimerPhyPara* pMtimerSfn = &gMtimerSfnNum[nTmrId];

	tmrIntcFlag = do_read_volatile(tmrBaseAddr+MTMR_INTC_REG) ;
	__ucps2_synch(0);
	if ((tmrIntcFlag & (1 << MTMR_INT_10ms)))  /* tmr int */
	{
		uint32_t cFlagAddr = tmrBaseAddr+MTMR_CINTF0_REG+2*(MTMR_INT_10ms<<2);
		uint32_t tFlagAddr = tmrBaseAddr+MTMR_TINTF00_REG+6*(MTMR_INT_10ms<<2);
		cEventFlag = do_read_volatile(cFlagAddr);
		tEventFlag = do_read_volatile(tFlagAddr);
		__ucps2_synch(0);
		if ((cEventFlag & BIT17) || (cEventFlag & BIT2) || (tEventFlag & (1<<MTMR_10ms_OFFSET)))
		{
			if (cEventFlag & BIT17) // 1pps int
			{
				do_write((tmrBaseAddr+MTMR_CEVENT_REG), BIT17);
				do_write(cFlagAddr, BIT17); // clear int flag
//uint32_t start = GET_STC_CNT();
				if (0 == pMtimerInt->pp1sIntCnt)
				{
					gtimer2_start(0);
					start_jesd_timer(nTmrId);
					if (MTIMER_JESD_RX0_ID == nTmrId)
					{
						start_jesd_timer(MTIMER_JESD_TX0_ID);
					}
				}
	
#ifdef ENABLE_SFNCAL
				mtimer_1pps_func(nTmrId);
#endif
				pMtimerInt->pp1sIntCnt++;
				debug_write((DBG_DDR_IDX_DRV_BASE+64+1), pMtimerInt->pp1sIntCnt); // 0x104
				
#ifdef PALLADIUM_TEST
				uint32_t val = 0;
				for (int32_t core = 0; core < 12; core++)
				{
					val = do_read_volatile(SLOT_NUM_DEBUG_ADDR+((core<<2)<<2));
					debug_write(((DBG_DDR_IDX_DRV_BASE+832+(core<<2))), val);	// 0xd00
					
					val = do_read_volatile(SLOT_NUM_DEBUG_ADDR+((1+(core<<2))<<2));
					debug_write(((DBG_DDR_IDX_DRV_BASE+832+(core<<2)) + 1), val);	// 0xd00
					
					val = do_read_volatile(SLOT_NUM_DEBUG_ADDR+((2+(core<<2))<<2));
					debug_write(((DBG_DDR_IDX_DRV_BASE+832+(core<<2)) + 2), val);	// 0xd00
					
					val = do_read_volatile(SLOT_NUM_DEBUG_ADDR+((3+(core<<2))<<2));
					debug_write(((DBG_DDR_IDX_DRV_BASE+832+(core<<2)) + 3), val);	// 0xd00
				}
#endif
//debug_write((DBG_DDR_IDX_DRV_BASE+288), (GET_STC_CNT()-start));	// 0x480
			}
			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+64+2), pMtimerInt->sfnIntCnt);	// 0x108
#endif
				uint16_t runCore = do_read_volatile_short(&(phyPara[gScsId].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
//uint32_t start = GET_STC_CNT();
					jesd_timer_rcfg_act(nTmrId);
//debug_write((DBG_DDR_IDX_DRV_BASE+288), (GET_STC_CNT()-start)); // 0x480
					pMtimerCal->sfnCalFinished = 1;
					debug_write((DBG_DDR_IDX_DRV_BASE+910), cEventFlag); // pMtimerInt->txSlotIntCnt); // 0xe38
					debug_write((DBG_DDR_IDX_DRV_BASE+911), get_mtimer_rt_scr_value(MTIMER_CPRI_ID)); // pMtimerInt->tddOffsetIntCnt); // 0xe3C
				}
			}
			if (tEventFlag & (1<<MTMR_10ms_OFFSET))				// 10ms offset int
			{
				do_write((tmrBaseAddr+MTMR_TEVENT0_REG), (1<<MTMR_10ms_OFFSET));
				do_write(tFlagAddr, (1<<MTMR_10ms_OFFSET));	// clear int flag
				pMtimerInt->sfnOffsetIntFlag = 1;
				pMtimerInt->sfnOffsetIntCnt++;
#ifdef PALLADIUM_TEST
				debug_write((DBG_DDR_IDX_DRV_BASE+64+3), pMtimerInt->sfnOffsetIntCnt); // 0x10C
#endif
				if ((MTIMER_JESD_RX0_ID == nTmrId) && (0 == (pMtimerInt->sfnOffsetIntCnt&0x3)))
				{
					spu_log_server_isr();
				}
			}
			cEventFlag = do_read_volatile(cFlagAddr);
			tEventFlag = do_read_volatile(tFlagAddr);
		}
		do_write((tmrBaseAddr+MTMR_INTC_REG), (1 << MTMR_INT_10ms));			// clear int
	}
}

void isr_jesd_10ms_rx0(void)
{
	uint32_t tmrId = MTIMER_JESD_RX0_ID;

	jesd_10ms_callback(tmrId);
}

void isr_jesd_10ms_rx1(void)
{
	uint32_t tmrId = MTIMER_JESD_RX1_ID;

	jesd_10ms_callback(tmrId);
}

void jesd_tdd_callback(uint8_t nTmrId)
{
	uint32_t tmrIntcFlag = 0;
	uint32_t tEventFlag = 0;
	uint32_t cEventFlag = 0;
	uint32_t tmrBaseAddr = JS_RX0_TMR_BASE + nTmrId*0x1000;
	stMtimerIntStat* pMtimerInt = &gMtimerIntCnt[nTmrId];
	
	tmrIntcFlag = do_read_volatile(tmrBaseAddr+MTMR_INTC_REG);
	__ucps2_synch(0);
	if ((tmrIntcFlag & (1 << MTMR_INT_TDD_OFFSET)))  /* tmr int */
	{
		uint32_t cFlagAddr = tmrBaseAddr+MTMR_CINTF0_REG+2*(MTMR_INT_TDD_OFFSET<<2);
		uint32_t tFlagAddr = tmrBaseAddr+MTMR_TINTF00_REG+6*(MTMR_INT_TDD_OFFSET<<2);
		cEventFlag = do_read_volatile(cFlagAddr);
		tEventFlag = do_read_volatile(tFlagAddr);
		__ucps2_synch(0);
		
		if ((tEventFlag & ((1<<MTMR_TDD_OFFSET)|(1<<MTMR_JESD_TXOFF)|(1<<MTMR_JESD_TXON)|(1<<MTMR_TDD_OFFSET_2500)|(1<<MTMR_TDD_OFFSET_7500))) || (cEventFlag & (BIT11|BIT12)))
		{
			if (tEventFlag & (1<<MTMR_TDD_OFFSET))		// tdd offset int
			{
				do_write((tmrBaseAddr+MTMR_TEVENT0_REG), (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+64+4), pMtimerInt->tddOffsetIntCnt); // 0x110
#endif
#if 1
//				if (0 == do_read_volatile(CSU_STOP_CMD_ADDR))
				{
//					uint32_t startTick = GET_STC_CNT();
					jesd_csu_start();
					if ((FDD_MODE == gJesdTFMode) || (JESD_IO_CTRL == gJesdIOMode))
					{
						jesd_csu_rx_start();
					}
//					uint32_t cost = GET_STC_CNT() - startTick;
//					do_write(DDR_ADDR_90, cost);
				}
#endif
			}
			if (tEventFlag & (1<<MTMR_TDD_OFFSET_2500)) 		// rx on int
			{
				do_write((tmrBaseAddr+MTMR_TEVENT0_REG), (1<<MTMR_TDD_OFFSET_2500));
				do_write(tFlagAddr, (1<<MTMR_TDD_OFFSET_2500));	// clear int flag
				gRxOnCnt++;
				debug_write((DBG_DDR_IDX_DRV_BASE+64+5), gRxOnCnt); // 0x114
			//RxOn();
			set_jesd_rf_state(JESD_RF_RX, GPIO_ON);
				jesd_csu_rx_start();
			}
			if (tEventFlag & (1<<MTMR_TDD_OFFSET_7500)) 		// rx off int
			{
				do_write((tmrBaseAddr+MTMR_TEVENT0_REG), (1<<MTMR_TDD_OFFSET_7500));
				do_write(tFlagAddr, (1<<MTMR_TDD_OFFSET_7500));	// clear int flag
				gRxOffCnt++;
				debug_write((DBG_DDR_IDX_DRV_BASE+64+6), gRxOffCnt); // 0x118
			//RxOff();
			set_jesd_rf_state(JESD_RF_RX, GPIO_OFF);
			}
			if (tEventFlag & (1<<MTMR_JESD_TXON)) 		// tx on int
			{
				do_write((tmrBaseAddr+MTMR_TEVENT0_REG), (1<<MTMR_JESD_TXON));
				do_write(tFlagAddr, (1<<MTMR_JESD_TXON));	// clear int flag
				gTxOnCnt++;
				debug_write((DBG_DDR_IDX_DRV_BASE+76), gTxOnCnt); // 0x130
			//TxOn();
			set_jesd_rf_state(JESD_RF_TX, GPIO_ON);
				//jesd_csu_start();
			}
			if (tEventFlag & (1<<MTMR_JESD_TXOFF)) 		// tx off int
			{
				do_write((tmrBaseAddr+MTMR_TEVENT0_REG), (1<<MTMR_JESD_TXOFF));
				do_write(tFlagAddr, (1<<MTMR_JESD_TXOFF));	// clear int flag
				gTxOffCnt++;
				debug_write((DBG_DDR_IDX_DRV_BASE+77), gTxOffCnt); // 0x134
			//TxOff();
			set_jesd_rf_state(JESD_RF_TX, GPIO_OFF);
			}
			if (cEventFlag & BIT11)
			{
				do_write((tmrBaseAddr+MTMR_CEVENT_REG), BIT11);
				do_write(cFlagAddr, BIT11); // clear int flag
				do_write(GPIO1B_DATA_REG_ADDR, (do_read_volatile(GPIO1B_DATA_REG_ADDR)|BIT24)); // GPIO1B24, high
				gRxCsuOnCnt++;
				debug_write((DBG_DDR_IDX_DRV_BASE+64+8), gRxCsuOnCnt); // 0x120
				debug_write((DBG_DDR_IDX_DRV_BASE+64+9), GET_STC_CNT()); // 0x124
			}
			if (cEventFlag & BIT12)
			{
				do_write((tmrBaseAddr+MTMR_CEVENT_REG), BIT12);
				do_write(cFlagAddr, BIT12); // clear int flag
				do_write(GPIO1B_DATA_REG_ADDR, (do_read_volatile(GPIO1B_DATA_REG_ADDR)&(~(BIT24)))); // GPIO1B24, high
				gRxCsuOffCnt++;
				debug_write((DBG_DDR_IDX_DRV_BASE+64+10), gRxCsuOffCnt); // 0x128
				debug_write((DBG_DDR_IDX_DRV_BASE+64+11), GET_STC_CNT()); // 0x12C
			}
			cEventFlag = do_read_volatile(cFlagAddr);
			tEventFlag = do_read_volatile(tFlagAddr);
		}
		do_write((tmrBaseAddr+MTMR_INTC_REG), (1 << MTMR_INT_TDD_OFFSET));			// clear int
	}
}

void isr_jesd_tdd_offset_rx0(void)
{
	uint32_t tmrId = MTIMER_JESD_RX0_ID;

	jesd_tdd_callback(tmrId);
}

extern uint32_t lastTxSlotCnt; // = 0;
extern uint32_t nowTxSlotCnt; // = 0;
extern uint32_t rfmSlotErrCnt; // = 0;
extern uint32_t rfmSlotErrMax; // = 0;
void jesd_slot_callback(uint8_t nTmrId)
{
	uint32_t tmrIntcFlag = 0;
	uint32_t tEventFlag = 0;
	uint32_t tmrBaseAddr = JS_RX0_TMR_BASE + nTmrId * 0x1000;
	stMtimerIntStat* pMtimerInt = &gMtimerIntCnt[nTmrId];
	//stMtimerSfnCal* pMtimerCal = &gMtimerSfnCalPara[nTmrId];
	stMtimerPhyPara* pMtimerSfn = &gMtimerSfnNum[nTmrId];
	int32_t apeId = get_core_id();
	stCoreInt* apeCoreIntInfo = (stCoreInt*)APE_INT_INFO_ADDR + APE_INT_MAXNUM*apeId;

	tmrIntcFlag = do_read_volatile(tmrBaseAddr+MTMR_INTC_REG);
	if ((tmrIntcFlag & (1 << MTMR_INT_SLOT_OFFSET)))  /* tmr int */
	{
		uint32_t tFlagAddr = tmrBaseAddr+MTMR_TINTF00_REG+6*(MTMR_INT_SLOT_OFFSET<<2);
		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((tmrBaseAddr+MTMR_TEVENT0_REG), (1<<MTMR_TXSLOT_OFFSET));
				do_write(tFlagAddr, (1<<MTMR_TXSLOT_OFFSET));	// clear int flag
//uint32_t start = GET_STC_CNT();
				if (5 == reCfgFlag)
				{
					reCfgFlag = 0;
				}
#if 0
				if (0 == pMtimerInt->txSlotIntCnt)
				{
					// init cal
					pMtimerCal->sfnCalFinished = 0;
					uint32_t lockFlag = do_read_volatile(ARM_LOCK_FLAG_ADDR);
					if (0 == lockFlag)
					{
						do_write(ARM_SFN_VALID_ADDR, ARM_SFN_VALID_FLAG);
						do_write(ARM_SFN_NUM_ADDR, 0x1);
						do_write(ARM_SFN_FLIP_ADDR, 0x1);
						do_write(ARM_LOCK_FLAG_ADDR, 0x1);
					}
					__ucps2_synch(f_SMW);
				}
#endif
				pMtimerSfn->txSlotTiming = GET_STC_CNT();
				pMtimerSfn->txSlotNum++;
				__ucps2_synch(0);
				if (pMtimerSfn->txSlotNum == pMtimerSfn->slotMaxNum)
				{
					pMtimerSfn->txSfnNum++;
					pMtimerSfn->txSfnNum &= 0x3FF;
					pMtimerSfn->txSlotNum = 0;
				}
				// test for trigger
				if (0 == pMtimerSfn->txSlotNum)
				{
					set_trigger_state(GPIO_ON);
				}
				else if ((pMtimerSfn->slotMaxNum >> 1) == pMtimerSfn->txSlotNum)
				{
					set_trigger_state(GPIO_OFF);
				}
				__ucps2_synch(0);
				if (8 > pMtimerInt->txSlotIntCnt)
				{
					debug_write((DBG_DDR_IDX_DRV_BASE+576+(5<<3)+pMtimerInt->txSlotIntCnt), (GET_STC_CNT())); // -gRfm0LastTxTiming)); // 0x900
				}
				pMtimerInt->txSlotIntCnt++;
#ifdef PALLADIUM_TEST
				debug_write((DBG_DDR_IDX_DRV_BASE+80), pMtimerInt->txSlotIntCnt);	// 0x140
#endif

				do_write(SLOT_NUM_DEBUG_ADDR+((apeId<<2)<<2), pMtimerSfn->txSfnNum);
				do_write(SLOT_NUM_DEBUG_ADDR+((1+(apeId<<2))<<2), pMtimerSfn->txSlotNum);
				// write sm
				do_write(&(apeCoreIntInfo[APE_INT_TX_SLOT].intNum), APE_INT_TX_SLOT);
				do_write(&(apeCoreIntInfo[APE_INT_TX_SLOT].intCnt), pMtimerInt->txSlotIntCnt);
				__ucps2_synch(f_SMW);
//debug_write((DBG_DDR_IDX_DRV_BASE+290), (GET_STC_CNT()-start)); // 0x488
#if 0 // def PALLADIUM_TEST
				debug_write(((DBG_DDR_IDX_DRV_BASE+8192) + (gCpriTimerPara.txSlotIntCnt&0x1FF)), gCpriTimerPara.txSlotIntCnt);		// 0x8000
				debug_write(((DBG_DDR_IDX_DRV_BASE+8704) + (gCpriTimerPara.txSlotIntCnt&0x1FF)), get_tx_nr_slot(1)); 		// 0x8800
				nowTxSlotStcCnt = GET_STC_CNT();
				debug_write(((DBG_DDR_IDX_DRV_BASE+9216) + (gCpriTimerPara.txSlotIntCnt&0x1FF)), nowTxSlotStcCnt); 			// 0x9000
				debug_write(((DBG_DDR_IDX_DRV_BASE+9728) + (gCpriTimerPara.txSlotIntCnt&0x1FF)), (nowTxSlotStcCnt-lastTxSlotStcCnt)); 	// 0x9800
				lastTxSlotStcCnt = nowTxSlotStcCnt;
#endif
#if 0
				nowTxSlotCnt = GET_STC_CNT();
				if ((nowTxSlotCnt > lastTxSlotCnt) && (2 < pMtimerInt->txSlotIntCnt))
				{
					uint32_t cost = nowTxSlotCnt - lastTxSlotCnt;
					if ((505000 < cost) || (495000 > cost))
					{
						rfmSlotErrCnt++;
						debug_write((DBG_DDR_IDX_DRV_BASE+108), rfmSlotErrCnt);	// 0x1b0
						debug_write((DBG_DDR_IDX_DRV_BASE+109), cost);			// 0x1b4
					}
					if (cost > rfmSlotErrMax)
					{
						rfmSlotErrMax = cost;
					}
					debug_write((DBG_DDR_IDX_DRV_BASE+110), rfmSlotErrMax); // 0x1b8
				}
				lastTxSlotCnt = nowTxSlotCnt;
#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
//uint32_t start = GET_STC_CNT();
				pMtimerSfn->rxSlotNum++;
				__ucps2_synch(0);
				if (pMtimerSfn->rxSlotNum == pMtimerSfn->slotMaxNum)
				{
					pMtimerSfn->rxSfnNum++;
					pMtimerSfn->rxSfnNum &= 0x3FF;
					pMtimerSfn->rxSlotNum = 0;
				}
				__ucps2_synch(0);

#ifdef PALLADIUM_TEST
				if (8 > pMtimerInt->rxSlotIntCnt)
				{
					debug_write((DBG_DDR_IDX_DRV_BASE+624+(5<<3)+pMtimerInt->rxSlotIntCnt), (GET_STC_CNT())); // -gRfm0LastTxTiming)); // 0x900
				}
#endif

				pMtimerInt->rxSlotIntCnt++;
#ifdef PALLADIUM_TEST
				debug_write((DBG_DDR_IDX_DRV_BASE+81), pMtimerInt->rxSlotIntCnt);	// 0x144
#endif

				do_write(SLOT_NUM_DEBUG_ADDR+((2+(apeId<<2))<<2), pMtimerSfn->rxSfnNum);
				do_write(SLOT_NUM_DEBUG_ADDR+((3+(apeId<<2))<<2), pMtimerSfn->rxSlotNum);
				// write sm
				do_write(&(apeCoreIntInfo[APE_INT_RX_SLOT].intNum), APE_INT_RX_SLOT);
				do_write(&(apeCoreIntInfo[APE_INT_RX_SLOT].intCnt), pMtimerInt->rxSlotIntCnt);
				__ucps2_synch(f_SMW);
//debug_write((DBG_DDR_IDX_DRV_BASE+291), (GET_STC_CNT()-start)); // 0x48c
			}
			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+64+14), pMtimerInt->lteFapiIntCnt);	// 0x138
				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
	}
}

void isr_jesd_slot_rx0(void)
{
	uint32_t tmrId = MTIMER_JESD_RX0_ID;

	jesd_slot_callback(tmrId);
}

void isr_jesd_slot_rx1(void)
{
	uint32_t tmrId = MTIMER_JESD_RX1_ID;

	jesd_slot_callback(tmrId);
}

void jesd_tdd_start_csu()
{
	//uint32_t tmrBaseAddr = JS_RX0_TMR_BASE;
	stMtimerIntStat* pMtimerInt = &gMtimerIntCnt[MTIMER_JESD_RX0_ID];
#if 0	
	if (JESD_TEST_MODE == gJesdTestMode)
	{
		// start csu
#ifdef INTEGRATED_BS
#ifdef TEST_ENABLE
		jesd_test_case();
#endif
#endif
		pMtimerInt->csuEnCnt++;
	}
	else
#endif
	{
		// start csu
		jesd_csu_start();
		pMtimerInt->csuEnCnt++;
		debug_write((DBG_DDR_IDX_DRV_BASE+64+7), pMtimerInt->csuEnCnt); // 0x11c
	}
}

//#endif

