#include "rfm1_drv.h"
#include "inter_vector.h"
#include "ucp_printf.h"
#include "ucp_csu.h"

#include "phy_para.h"
#include "ape_csu.h"
#include "ucp_tick.h"
#include "ucp_utility.h"
#include "ctc_intr.h"
#include "spu_hw_queue.h"
#include "spu_log.h"
#include "app_interface.h"
#include "gtimer_drv.h"
#include "rfm1_gtimer2.h"
#include "ecs_rfm_spu1_heap.h"
#include "mtimer_cell.h"
#include "gpio_drv.h"

#ifdef DISTRIBUTED_BS
#include "hw_cpri.h"
#include "cpri_timer.h"
#include "cpri_delay.h"
#include "ecpri_timer.h"
#include "cpri_driver.h"
#endif
#ifdef INTEGRATED_BS
#include "jesd_timer.h"
#endif
//extern UINT32 g10msOffsetIntFlag;
extern stPhyScsPara*	phyPara;
#ifdef CPRI_10G_TEST
uint32_t CPRI_OPTION = CPRI_OPTION_8;
#endif
#ifdef CPRI_24G_TEST
 uint32_t CPRI_OPTION = CPRI_OPTION_10;
#endif
void ecs_rfm1_drv_init(void)
{
    int32_t apeId = get_core_id();
#ifdef PALLADIUM_TEST
    int32_t flag = 1;
    debug_write((DBG_DDR_IDX_DRV_BASE+1+(apeId<<2)), flag);	// 0xB4
#endif

    //SET_CLK_CFG_EMU();
    //APC0_CSU_ELEVELMASK = 0xFFFFFFFF;
    int32_t ret = 0;
#if 1
    ret = smart_irq_debug_init(DBG_DDR_IRQ_ADDR_BASE+apeId*DBG_DDR_IRQ_LEN, DBG_DDR_IRQ_LEN);
    if (0 != ret)
    {
        debug_write(DBG_DDR_ERR_IDX(apeId, 12), ret);
    }
#endif
    ret = smart_irq_init(apeId);
    if (0 != ret)
    {
        debug_write(DBG_DDR_ERR_IDX(apeId, 15), ret);
    }
    UCP_PRINT_EMPTY("interrupt init. \r\n");
#ifdef PALLADIUM_TEST
    flag++;
    debug_write((DBG_DDR_IDX_DRV_BASE+1+(apeId<<2)), flag);	// 0xB4
#endif

    ape_csu_init();
    UCP_PRINT_EMPTY("ape csu init. \r\n");
#ifdef PALLADIUM_TEST
    flag++;
    debug_write((DBG_DDR_IDX_DRV_BASE+1+(apeId<<2)), flag);	// 0xB4
#endif

    sfn_para_init();
    UCP_PRINT_EMPTY("sfn para init.\r\n");
#ifdef PALLADIUM_TEST
    flag++;
    debug_write((DBG_DDR_IDX_DRV_BASE+1+(apeId<<2)), flag);	// 0xB4
#endif

    ctc_cal_intr_init();
    UCP_PRINT_EMPTY("ctc cal intr init.\r\n");
#ifdef PALLADIUM_TEST
    flag++;
    debug_write((DBG_DDR_IDX_DRV_BASE+1+(apeId<<2)), flag);
#endif

#if 1
	gtimer2_init(0);
	rfm1_gtimer2_1_set_int();
#ifdef PALLADIUM_TEST
	flag++;
	debug_write((DBG_DDR_IDX_DRV_BASE+1+(apeId<<2)), flag);	// 0xB4
#endif
#endif

#ifdef DISTRIBUTED_BS

    cpri_init(CPRI_OPTION);
    UCP_PRINT_EMPTY("cpri init finished. \r\n");

    HeaderTxRam_init();
#ifdef PALLADIUM_TEST
    flag++;
    debug_write((DBG_DDR_IDX_DRV_BASE+1+(apeId<<2)), flag);	// 0xB4
#endif
	
	ecpri_init();
#ifdef PALLADIUM_TEST
    flag++;
    debug_write((DBG_DDR_IDX_DRV_BASE+1+(apeId<<2)), flag);
#endif
#endif

#ifdef INTEGRATED_BS
    jesd_init();
    flag++;
    debug_write((DBG_DDR_IDX_DRV_BASE+1+(apeId<<2)), flag);
#endif

	hw_gpio_init();
#ifdef PALLADIUM_TEST
    flag++;
    debug_write((DBG_DDR_IDX_DRV_BASE+1+(apeId<<2)), flag);
#endif

    ecs_hw_que_init(apeId);
    ecs_hw_que_init_noirq(apeId, apeId);
    ecs_msg_que_init(apeId);
    ecs_hw_que_init_noirq(apeId, ECS_RFM_SPU1_HW_QUEUE);
    spu_log_init(LOG_ERROR);
    ecs_heap_mem_init(ECS_PHY_DDR_ADDR, ECS_PHY_DDR_SIZE);
#ifdef PALLADIUM_TEST
    flag++;
    debug_write((DBG_DDR_IDX_DRV_BASE+1+(apeId<<2)), flag);	// 0xB4
#endif
}

void check_phy_cell(void)
{
	//uint32_t clockBegin,clockEnd;
	//int32_t  clockCnt;

    volatile uint32_t phy_cell_flag = do_read_volatile(PHY_CELL_ADDR);
    //debug_write(DBG_DDR_COMMON_IDX(get_core_id(),1), phy_cell_flag);
	__ucps2_synch(f_SM);
	//debug_write(DBG_DDR_COMMON_IDX(get_core_id(),2), 2);
	if (PHY_CELL_FLAG == phy_cell_flag)
	{   
	    //debug_write(DBG_DDR_COMMON_IDX(get_core_id(),3), 3);
		phy_timer_config_ind_t cellPara;
		memcpy_ucp(&cellPara, (PHY_CELL_ADDR+4), sizeof(cellPara));
		//debug_write(DBG_DDR_COMMON_IDX(get_core_id(),4), 4);		
		__ucps2_synch(f_SM);
		//debug_write(DBG_DDR_COMMON_IDX(get_core_id(),5), 5);

		//rdmcycle(&clockBegin);
//		cpri_timer_reconfig(&cellPara);
		int32_t ret = mtimer_reconfig(&cellPara);
		//rdmcycle(&clockEnd);
		//clockCnt = clockEnd - clockBegin;
		//debug_write((DBG_DDR_IDX_DRV_BASE+900), clockCnt);	// 0xe10

		if (-1 == ret)
		{
			UCP_PRINT_ERROR("mtimer_reconfig failed. \r\n");
			return;
		}
		
		//debug_write(DBG_DDR_COMMON_IDX(get_core_id(),6), 6);
		do_write(PHY_CELL_ADDR, 0);
		__ucps2_synch(f_SM);
		//debug_write(DBG_DDR_COMMON_IDX(get_core_id(),7), 7);		
	}
}

void check_10ms_offset(void)
{
#ifdef DISTRIBUTED_BS
	if (1 == get_sfnoffset_int_flag())
	{
		update_cpri_link_status();
		cpri_delay_measurement_ck();
		clear_sfnoffset_int_flag();
	}
#endif
}

void HeaderTxRam_init()
{
#ifdef DISTRIBUTED_BS
	uint32_t i,j;
	HeaderRam_ins_disable();
	for(i=0;i<64;i++)//Ns
	{
		for(j=0;j<4;j++)//
		{
			HeaderRam_Tx(i+64*j,0,0,0);//vendor
			HeaderRam_Tx(i+64*j,1,0,0);//vendor
			HeaderRam_Tx(i+64*j,2,0,0);//vendor
			HeaderRam_Tx(i+64*j,3,0,0);//vendor
		}
	}
	do_write(&CPRI_FRAME_RX_HDR_ADDR,0);
#endif
}

