// +FHDR------------------------------------------------------------
//                 Copyright (c) 2022 SmartLogic.
//                       ALL RIGHTS RESERVED
// -----------------------------------------------------------------
// Filename      : ape0_recv_task.s.c
// Author        : 
// Created On    : 2022-10-24
// Last Modified :
// -----------------------------------------------------------------
// Description:
//
//
// -FHDR------------------------------------------------------------
#include "ucp_utility.h"
#include "msg_transfer_layer.h"
#include "phy_para.h"
#include "ucp_tick.h"
#include "ucp_testcase.h"
#include "ucp_printf.h"
#include "ape_mtimer.h"
#include "osp_task.h"
#include "osp_timer.h"

static uint32_t g_u32_ape0_recv_tick         = 0;
static uint32_t g_u32_ape0_recv_addr_err     = 0;   //(12) 0xB7E00030
static uint32_t g_u32_ape0_recv_num          = 0;   //(13) 0xB7E00034
static uint32_t g_u32_ape0_recv_ok           = 0;   //(14) 0xB7E00038
static uint32_t g_u32_ape0_recv_tick_err     = 0;   //(15) 0xB7E0003C
static uint32_t g_u32_ape0_recv_sfn_slot_err = 0;   //(17) 0xB7E00044

static uint32_t g_u32_ape0_recv_msg_tick_err = 0;   //MSG

/* 收到 RFM发来的消息，并释放资源 */
void ape0_recv_task(uint32_t addr, uint32_t size)
{
    uint32_t ape_id = get_core_id();
    uint32_t msg_addr = 0;
    uint32_t que_num  = 0;
    uint32_t value = 0;
    uint16_t scs  = 1;//30KHz
    uint16_t sfn  = 0;
    uint16_t slot = 0;
    uint16_t sfn_l  = 0;
    uint16_t slot_l = 0;
    uint32_t tick_from_ape_tx = 0;
    uint32_t tick_from_arm_rx = 0;
    uint32_t tick_from_arm_tx = 0;
    uint32_t tick_from_rfm_rx = 0;
    uint32_t tick_from_rfm_tx = 0;
    uint32_t tick_from_ape_rx = 0;
    uint32_t offset_loopback  = 0;
    uint32_t u32_clock_offset = 0;
    uint32_t u32_clock_tick   = 0;

    g_u32_ape0_recv_num++;
    if (0 == addr)
    {
        debug_write(DBG_DDR_COMMON_IDX(ape_id, 12), ++g_u32_ape0_recv_addr_err);
        return ;
    }

    msg_addr = do_read(addr);
    que_num  = do_read(addr+4);

    value = do_read(msg_addr);
    sfn  = value >> 16;
    slot = value & 0xffff;
    g_u32_ape0_recv_ok++;

    debug_write(DBG_DDR_COMMON_IDX(ape_id, 13), g_u32_ape0_recv_num);
    debug_write(DBG_DDR_COMMON_IDX(ape_id, 14), g_u32_ape0_recv_ok);

    /*if(UCP4008_TRAFFIC_NR_eMBB_DATA != que_num)
    {
        return;
    }*/

    rdmcycle(&u32_clock_tick);
    tick_from_ape_tx = do_read(msg_addr+4);
    tick_from_arm_rx = do_read(msg_addr+8);
    tick_from_arm_tx = do_read(msg_addr+12);
    tick_from_rfm_rx = do_read(msg_addr+16);
    tick_from_rfm_tx = do_read(msg_addr+20);
    tick_from_ape_rx = u32_clock_tick;
    offset_loopback = (tick_from_ape_rx - tick_from_ape_tx + TICK_PP1S_OFFSET)%TICK_PP1S_OFFSET;
    if (offset_loopback >= LOOPBACK_APE_OFFSET) {
        if (g_u32_ape0_recv_msg_tick_err < CASE0_APE0_RX_ERR_MAX_NUM) {
            debug_write(DBG_DDR_MSG_IDX(que_num, (CASE0_APE0_RX_ERR_MAX_NUM*g_u32_ape0_recv_msg_tick_err + 21)), offset_loopback);	
            debug_write(DBG_DDR_MSG_IDX(que_num, (CASE0_APE0_RX_ERR_MAX_NUM*g_u32_ape0_recv_msg_tick_err + 22)), tick_from_ape_tx);	
            debug_write(DBG_DDR_MSG_IDX(que_num, (CASE0_APE0_RX_ERR_MAX_NUM*g_u32_ape0_recv_msg_tick_err + 23)), tick_from_arm_rx);	
            debug_write(DBG_DDR_MSG_IDX(que_num, (CASE0_APE0_RX_ERR_MAX_NUM*g_u32_ape0_recv_msg_tick_err + 24)), tick_from_arm_tx);	
            debug_write(DBG_DDR_MSG_IDX(que_num, (CASE0_APE0_RX_ERR_MAX_NUM*g_u32_ape0_recv_msg_tick_err + 25)), tick_from_rfm_rx);	
            debug_write(DBG_DDR_MSG_IDX(que_num, (CASE0_APE0_RX_ERR_MAX_NUM*g_u32_ape0_recv_msg_tick_err + 26)), tick_from_rfm_tx);	
            debug_write(DBG_DDR_MSG_IDX(que_num, (CASE0_APE0_RX_ERR_MAX_NUM*g_u32_ape0_recv_msg_tick_err + 27)), tick_from_ape_rx);	
        }
        g_u32_ape0_recv_msg_tick_err++;
        debug_write(DBG_DDR_MSG_IDX(que_num, 20), g_u32_ape0_recv_msg_tick_err);
        UCP_PRINT_ERROR("ape[%d] recv_task msg tick err[%d], cnt[%d]", ape_id, offset_loopback, g_u32_ape0_recv_msg_tick_err);
    }

    if (0 == g_u32_ape0_recv_tick)
    {
        g_u32_ape0_recv_tick = u32_clock_tick;
    }
    else
    {
        if (u32_clock_tick > g_u32_ape0_recv_tick)
        {
            u32_clock_offset = u32_clock_tick - g_u32_ape0_recv_tick;
            if ((u32_clock_offset > TIMER_OFFSET_MAX) || (u32_clock_offset < TIMER_OFFSET_MIN))
            {
                g_u32_ape0_recv_tick_err++;
                debug_write(DBG_DDR_COMMON_IDX(ape_id, 15), g_u32_ape0_recv_tick_err);
                debug_write(DBG_DDR_COMMON_IDX(ape_id, 16), u32_clock_offset);
            }
        }
        g_u32_ape0_recv_tick = u32_clock_tick;
    }

    sfn_l  = get_tx_nr_sfn(scs);
    slot_l = get_tx_nr_slot(scs);
    if ((sfn != sfn_l) || (slot != slot_l))
    {
        g_u32_ape0_recv_sfn_slot_err++;
        debug_write(DBG_DDR_COMMON_IDX(ape_id, 17), g_u32_ape0_recv_sfn_slot_err);  //34~38打点有重复
        debug_write(DBG_DDR_COMMON_IDX(ape_id, 18), sfn);
        debug_write(DBG_DDR_COMMON_IDX(ape_id, 19), sfn_l);
        debug_write(DBG_DDR_COMMON_IDX(ape_id, 20), slot);
        debug_write(DBG_DDR_COMMON_IDX(ape_id, 21), slot_l);
        UCP_PRINT_ERROR("ape[%d] sfn[%d]:[%d], slot[%d]:[%d], cnt[%d]", ape_id, sfn, sfn_l, slot, slot_l, g_u32_ape0_recv_sfn_slot_err);
    }
    return ;
}

/*************************************************************************/
/* 收到消息后创建任务 */
void ape0_recv_task(uint32_t addr, uint32_t size); // A
void ape_slot_process_task(void);
void ape0_stc_timer_task(void);                          // C 给APE1事件任务发消息

void ape0_event_task(uint32_t addr, uint32_t size)
{
    uint32_t ape_id = get_core_id();
    debug_write(DBG_DDR_COMMON_IDX(ape_id, 29), 0x01010101);
    osp_task_info_ex ape0_event_task_recv = {40, (int8_t*)"ape0_test_taska", 40, 1024, OSP_EVENT_TYPE, 0, 0,     0,   NULL, (OSP_TASKENTRY_FUNC)ape0_recv_task};
    osp_task_info_ex ape0_timer_task_cpri = {41, (int8_t*)"ape0_test_taskb", 41, 2048, OSP_TIMER_TYPE, 0, 0x3ff, 0,   NULL, (OSP_TASKENTRY_FUNC)ape_slot_process_task};
    osp_task_info_ex ape0_timer_task_stc  = {42, (int8_t*)"ape0_test_taskc", 42, 2048, OSP_TIMER_TYPE, 0, 0x3ff, 200, NULL, (OSP_TASKENTRY_FUNC)ape0_stc_timer_task};

    osp_task_create(&ape0_event_task_recv);
    osp_task_create(&ape0_timer_task_cpri);
    osp_task_create(&ape0_timer_task_stc);

    osp_timer_sync(LTE_SCS_ID);

    debug_write(DBG_DDR_COMMON_IDX(ape_id, 29), 0x03030303);
    return;
}

