#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"
#include "stc_timer.h"
#include "cpri_timer.h"
#include "cpri_delay.h"
#include "hw_cpri.h"
#include "ecpri_driver.h"
#include "jesd_timer.h"


#ifdef TEST_ENABLE
#include "fh_test.h"
#endif

extern int32_t phy_fh_drv_init();
extern void    cpri_link_monitor();

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;

    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); // 0xB4
#endif

    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

    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

#ifdef TEST_ENABLE
    fh_test_init();
#else
    phy_fh_drv_init();
#endif
#ifdef PALLADIUM_TEST
    flag++;
    debug_write((DBG_DDR_IDX_DRV_BASE+1+(apeId<<2)), flag); // 0xB4
#endif

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

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

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

int32_t 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 (0 > ret)
        {
            UCP_PRINT_ERROR("mtimer_reconfig failed. \r\n");
            return ret;
        }

        //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);
    }

	return 0;
}


void check_10ms_offset(void)
{
    if (1 == get_sfnoffset_int_flag())
    {
        cpri_link_monitor();
        update_cpri_link_status();
        cpri_delay_measurement_ck();
        clear_sfnoffset_int_flag();
    }
}

int32_t fronthaul_drv_cfg(stFrontHaulDrvPara* pFhDrvPara)
{
	if (PROTOCOL_CPRI == pFhDrvPara->protocolSel)
	{
		cpri_init(pFhDrvPara->rateOption, pFhDrvPara->mapOption);
	}
	else if (PROTOCOL_ECPRI == pFhDrvPara->protocolSel)
	{
		ecpri_init(pFhDrvPara->rateOption);
	}
	else if (PROTOCOL_JESD == pFhDrvPara->protocolSel)
	{
		jesd_init(pFhDrvPara->rateOption);
	}
	else
	{
		return -1;
	}

	return 0;
}

void spu_ddr_monitor_start(uint32_t monitorCnt)
{
	do_write(DDR_MONITOR_ENABLE, 1);
	do_write(DDR_MONITOR_CNT, monitorCnt);
}

int32_t set_mtimer_scratch_tod()
{
	uint32_t protocolSel = get_protocol_sel();

	if (PROTOCOL_CPRI == protocolSel)
	{
        set_cpri_1pps_scratch();
	    set_ecpri_1pps_scratch();
	}
	else if (PROTOCOL_ECPRI == protocolSel)
	{
	    set_cpri_1pps_scratch();
	    set_ecpri_1pps_scratch();
	}
	else if (PROTOCOL_JESD == protocolSel)
	{
		set_jesd_1pps_scratch(0);
		//set_jesd_1pps_scratch(1);
	}
	else
	{
		return -1;
	}

	return 0;
}

