#include "rfm0_cpri_timer.h"
#include "ucp_drv_common.h"
#include "ucp_cpri.h"
#include "ucp_param.h"
#include "mtimer_com.h"
#include "ucp_printf.h"
#include "ucp_utility.h"
#include "phy_para.h"
#include "inter_vector.h"

// int cnt
//UINT32 gRfm0TxSlotIntCnt = 0;
//UINT32 gRfm0RxSlotIntCnt = 0;
extern stPhyScsPara* phyPara;
extern stSfnPara gCellSfnPara[2];
#if 0
void set_cpri_timer_rfm0_int(void)
{
    int32_t apeId = get_core_id();

    // tx slot
    uint32_t intNum = APC_CPRI_TMR_INTR0 + MTMR_INT_RFM0_SLOT;
    int32_t ret = smart_irq_request(intNum, isr_cpri_rfm0_slot_offset);
    if (0 != ret)
    {
        UCP_PRINT_EMPTY("attach int num: 0x%x error. errno = 0x%x. \r\n", intNum, ret);
        debug_write(DBG_DDR_ERR_IDX(apeId, 6), ret);
    }
}

int32_t gRfm0CalFlag = 0;
int32_t gRfm0CalCnt = 0;
int ecs_rfm0_cal_sfn(void)
{
	if (1 == gCellSfnPara[MTIMER_CPRI_ID].ctcIntFlag)
	{
		gCellSfnPara[MTIMER_CPRI_ID].ctcIntFlag = 0;
		int scsId = gCellSfnPara[MTIMER_CPRI_ID].scsId;
		gCellSfnPara[MTIMER_CPRI_ID].txSfnNum = do_read_volatile(&(phyPara[scsId].txSfnNum));
		gCellSfnPara[MTIMER_CPRI_ID].rxSfnNum = do_read_volatile(&(phyPara[scsId].rxSfnNum));
		gCellSfnPara[MTIMER_CPRI_ID].txSlotNum = do_read_volatile(&(phyPara[scsId].txSlotNum));
		gCellSfnPara[MTIMER_CPRI_ID].rxSlotNum = do_read_volatile(&(phyPara[scsId].rxSlotNum));
		
		gCellSfnPara[MTIMER_CPRI_ID].txSlotIntCnt = 0;
		gCellSfnPara[MTIMER_CPRI_ID].rxSlotIntCnt = 0;

		gRfm0CalFlag = 1;
		gRfm0CalCnt++;
		
		debug_write((DBG_DDR_IDX_DRV_BASE+556+10), GET_STC_CNT());	// 0x8b0, 10:apeId
	}
	return 0;
}

// temp to be deleted
int32_t gRfm0IntCnt = 0;
uint32_t gRfm0LastTxTiming = 0;
uint32_t gRfm0LastRxTiming = 0;
void isr_cpri_rfm0_slot_offset(void)
{
	uint32_t tmrIntcFlag = 0;
	uint32_t tEventFlag = 0;
	int32_t eventId = MTMR_INT_RFM0_SLOT;
	int32_t apeId = get_core_id();
	stCoreInt* apeCoreIntInfo = (stCoreInt*)APE_INT_INFO_ADDR + APE_INT_MAXNUM*apeId;

	tmrIntcFlag = do_read_volatile(&CPRI_TMR_INTC_REG);
	if (tmrIntcFlag & (1 << eventId))  /* tmr int */
	{
		uint32_t flagAddr = (uint32_t)((uint32_t*)(&CPRI_TMR_TINTF00_REG) + 6*MTMR_INT_RFM0_SLOT);
		int32_t txSlotTmrId = MTMR_RFM0_TXSLOT;
		int32_t rxSlotTmrId = MTMR_RFM0_RXSLOT;
		tEventFlag = do_read_volatile(flagAddr);
		if (tEventFlag & ((1<<txSlotTmrId) | (1<<rxSlotTmrId)))
		{
			if (tEventFlag & (1<<txSlotTmrId)) // tx slot offset
			{
				uint32_t crVal = (1<<txSlotTmrId);
				do_write(((uint32_t*)(&CPRI_TMR_TEVENT0_REG)), crVal);
				do_write(flagAddr, crVal);

				// sfn calibration
				ecs_rfm0_cal_sfn();
				gCellSfnPara[MTIMER_CPRI_ID].txSlotNum++;
				__ucps2_synch(0);
				if (gCellSfnPara[MTIMER_CPRI_ID].txSlotNum == gCellSfnPara[MTIMER_CPRI_ID].slotMaxNum)
				{
					gCellSfnPara[MTIMER_CPRI_ID].txSfnNum++;
					gCellSfnPara[MTIMER_CPRI_ID].txSfnNum &= 0x3FF;
					gCellSfnPara[MTIMER_CPRI_ID].txSlotNum = 0;
				}
				gCellSfnPara[MTIMER_CPRI_ID].txSlotTiming = GET_STC_CNT();

				do_write(SLOT_NUM_DEBUG_ADDR+((apeId<<2)<<2), gCellSfnPara[MTIMER_CPRI_ID].txSfnNum);
				do_write(SLOT_NUM_DEBUG_ADDR+((1+(apeId<<2))<<2), gCellSfnPara[MTIMER_CPRI_ID].txSlotNum);
#if 1
				if (8 > gCellSfnPara[MTIMER_CPRI_ID].txSlotIntCnt)
				{
					debug_write((DBG_DDR_IDX_DRV_BASE+576+(4<<3)+gCellSfnPara[MTIMER_CPRI_ID].txSlotIntCnt), (GET_STC_CNT())); // -gRfm0LastTxTiming));	// 0x900
					gRfm0LastTxTiming = GET_STC_CNT();
				}
#endif
				gCellSfnPara[MTIMER_CPRI_ID].txSlotIntCnt++;
				debug_write((DBG_DDR_IDX_DRV_BASE+82), gCellSfnPara[MTIMER_CPRI_ID].txSlotIntCnt);	// 0x148
				// write sm
				do_write(&(apeCoreIntInfo[APE_INT_TX_SLOT].intNum), APE_INT_TX_SLOT);
				do_write(&(apeCoreIntInfo[APE_INT_TX_SLOT].intCnt), gCellSfnPara[MTIMER_CPRI_ID].txSlotIntCnt);
#if 0 //def PALLADIUM_TEST
				debug_write(((DBG_DDR_IDX_DRV_BASE+448)+(gCellSfnPara[MTIMER_CPRI_ID].txSlotIntCnt&0x3F)), get_tx_nr_slot(1));	// 0x700
				debug_write(((DBG_DDR_IDX_DRV_BASE+512)+(gCellSfnPara[MTIMER_CPRI_ID].txSlotIntCnt&0x3F)), get_tx_nr_sfn(1));	// 0x800
#endif
			}
			if (tEventFlag & (1<<rxSlotTmrId)) // rx slot offset
			{
				uint32_t crVal = ((1<<rxSlotTmrId));
				do_write(((uint32_t*)(&CPRI_TMR_TEVENT0_REG)), crVal);
				do_write(flagAddr, crVal);

				// update sfn and slot num
				gCellSfnPara[MTIMER_CPRI_ID].rxSlotNum++;
				__ucps2_synch(0);
				if (gCellSfnPara[MTIMER_CPRI_ID].rxSlotNum == gCellSfnPara[MTIMER_CPRI_ID].slotMaxNum)
				{
					gCellSfnPara[MTIMER_CPRI_ID].rxSfnNum++;
					gCellSfnPara[MTIMER_CPRI_ID].rxSfnNum &= 0x3FF;
					gCellSfnPara[MTIMER_CPRI_ID].rxSlotNum = 0;
				}
				gCellSfnPara[MTIMER_CPRI_ID].rxSlotTiming = GET_STC_CNT();

				do_write(SLOT_NUM_DEBUG_ADDR+((2+(apeId<<2))<<2), gCellSfnPara[MTIMER_CPRI_ID].rxSfnNum);
				do_write(SLOT_NUM_DEBUG_ADDR+((3+(apeId<<2))<<2), gCellSfnPara[MTIMER_CPRI_ID].rxSlotNum);
#if 1 //def PALLADIUM_TEST
				if (8 > gCellSfnPara[MTIMER_CPRI_ID].rxSlotIntCnt)
				{
					debug_write((DBG_DDR_IDX_DRV_BASE+624+(4<<3)+gCellSfnPara[MTIMER_CPRI_ID].rxSlotIntCnt), (GET_STC_CNT())); // -gRfm0LastTxTiming));	// 0x900
					gRfm0LastRxTiming = GET_STC_CNT();
				}
#endif
				gCellSfnPara[MTIMER_CPRI_ID].rxSlotIntCnt++;
				debug_write((DBG_DDR_IDX_DRV_BASE+83), gCellSfnPara[MTIMER_CPRI_ID].rxSlotIntCnt);	// 0x14c

				// write sm
				do_write(&(apeCoreIntInfo[APE_INT_RX_SLOT].intNum), APE_INT_RX_SLOT);
				do_write(&(apeCoreIntInfo[APE_INT_RX_SLOT].intCnt), gCellSfnPara[MTIMER_CPRI_ID].rxSlotIntCnt);
			}
			tEventFlag = do_read_volatile(flagAddr);
		}
		do_write((&CPRI_TMR_INTC_REG), (1 << eventId));			// clear int
	}
}
#endif

