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

/***************************************************************/
/*                   事件任务相关打点                                  */
//uint32_t g_u32_ape1_event_num  = 0;     // (30) 0xB7E0 0278
//uint32_t g_u32_ape1_event_free = 0;     // (31) 0xB7E0 027C
uint32_t g_u32_ape1_event1_allc_err = 0;// (32) 0xB7E0 0280
uint32_t g_u32_ape1_event1_send_err = 0;// (33) 0xB7E0 0284
uint32_t g_u32_ape1_event1_num = 0;     // (34) 0xB7E0 0288
uint32_t g_u32_ape1_event1_send_ok  = 0;// (35) 0xB7E0 028C
uint32_t g_u32_ape1_event2_num = 0;     // (36) 0xB7E0 0290

/* 收到对方(Timer300)发来的消息后给对方另一个事件任务(Event2)发消息 */
void ape1_event_task1(uint32_t address, uint32_t size)
{
    uint32_t ape_id = get_core_id();
    int  ret = 0;
    char *addr = NULL;

    g_u32_ape1_event1_num++;

    addr = osp_alloc_msg(TEST_MSG_SIZE);
    if (NULL == addr)
    {
        g_u32_ape1_event1_allc_err++;
        debug_write(DBG_DDR_COMMON_IDX(ape_id, 32), g_u32_ape1_event1_allc_err);
        return ;
    }

    do_write(addr, g_u32_ape1_event1_num);
    do_write((addr+4), 0xA001B002);

    ret = osp_send_msg((uint32_t)(addr),
                        TEST_MSG_SIZE,
                        UCP4008_KERNEL_INTER,
                        ape_id+0,   // src que id
                        ape_id-1,   // dst que id
                        47,         // src task id
                        48);        // dst task id
    
    if (0 != ret)
    {
        g_u32_ape1_event1_send_err++;
        debug_write(DBG_DDR_COMMON_IDX(ape_id, 33), g_u32_ape1_event1_send_err);
        return ;
    }
    g_u32_ape1_event1_send_ok++;
    debug_write(DBG_DDR_COMMON_IDX(ape_id, 34), g_u32_ape1_event1_num);
    debug_write(DBG_DDR_COMMON_IDX(ape_id, 35), g_u32_ape1_event1_send_ok);
    return ;
}

void ape1_event_task2(uint32_t address, uint32_t size)
{
    uint32_t ape_id = get_core_id();
    g_u32_ape1_event2_num++;
    debug_write(DBG_DDR_COMMON_IDX(ape_id, 36), g_u32_ape1_event2_num);
    return ;
}

/***************************************************************/
/*                   定时点任务相关打点                                 */
uint32_t g_u32_ape1_timer0_slot_err   = 0;   // (37) 0xB7E0 0294
uint32_t g_u32_ape1_timer0_sfn_err    = 0;   // (38) 0xB7E0 0298
uint32_t g_u32_ape1_timer0_tick       = 0;   // (39) 0xB7E0 029C
uint32_t g_u32_ape1_timer0_tick_err   = 0;   // (40) 0xB7E0 02A0
uint32_t g_u32_ape1_timer0_in         = 0;   // (41) 0xB7E0 02A4
uint32_t g_u32_ape1_timer0_out        = 0;   // (42) 0xB7E0 02A8

uint32_t g_u32_ape1_timer80_tick      = 0;   // (43) 0xB7E0 02AC
uint32_t g_u32_ape1_timer80_tick_err  = 0;   // (44) 0xB7E0 02B0
uint32_t g_u32_ape1_timer80_in        = 0;   // (45) 0xB7E0 02B4
uint32_t g_u32_ape1_timer80_out       = 0;   // (46) 0xB7E0 02B8

uint32_t g_u32_ape1_timer100_tick     = 0;   // (47) 0xB7E0 02BC
uint32_t g_u32_ape1_timer100_tick_err = 0;   // (48) 0xB7E0 02C0
uint32_t g_u32_ape1_timer100_in       = 0;   // (49) 0xB7E0 02C4
uint32_t g_u32_ape1_timer100_out      = 0;   // (50) 0xB7E0 02C8

uint32_t g_u32_ape1_timer150_tick     = 0;   // (51) 0xB7E0 02CC
uint32_t g_u32_ape1_timer150_tick_err = 0;   // (52) 0xB7E0 02D0
uint32_t g_u32_ape1_timer150_in       = 0;   // (53) 0xB7E0 02D4
uint32_t g_u32_ape1_timer150_out      = 0;   // (54) 0xB7E0 02D8

uint32_t g_u32_ape1_timer200_tick     = 0;   // (55) 0xB7E0 02DC
uint32_t g_u32_ape1_timer200_tick_err = 0;   // (56) 0xB7E0 02E0
uint32_t g_u32_ape1_timer200_in       = 0;   // (57) 0xB7E0 02E4
uint32_t g_u32_ape1_timer200_out      = 0;   // (58) 0xB7E0 02E8

uint32_t g_u32_ape1_timer300_tick     = 0;   // (59) 0xB7E0 02EC
uint32_t g_u32_ape1_timer300_tick_err = 0;   // (60) 0xB7E0 02F0
uint32_t g_u32_ape1_timer300_allo_err = 0;   // (61) 0xB7E0 02F4
uint32_t g_u32_ape1_timer300_send_err = 0;   // (62) 0xB7E0 02F8
uint32_t g_u32_ape1_timer300_in       = 0;   // (63) 0xB7E0 02FC
uint32_t g_u32_ape1_timer300_send_ok  = 0;   // (64) 0xB7E0 0300

uint32_t g_u32_ape1_timer400_tick     = 0;   // (65) 0xB7E0 0304
uint32_t g_u32_ape1_timer400_tick_err = 0;   // (66) 0xB7E0 0308
uint32_t g_u32_ape1_timer400_in       = 0;   // (67) 0xB7E0 030C
uint32_t g_u32_ape1_timer400_out      = 0;   // (68) 0xB7E0 0310

static uint16_t g_ape1_PreviousSlot = 0;
static uint16_t g_ape1_CurrentSlot  = 0;
static uint8_t  g_ape1_SlotFlagInit = 1;
static uint8_t  g_ape1_SfnFlagInit  = 1;
static uint16_t g_ape1_PreviousSfn  = 0;
static uint16_t g_ape1_CurrentSfn   = 0;

static inline void check_continuous_slot(uint16_t slot)
{
    uint16_t delta = 0;
    uint32_t ape_id = get_core_id();

    if (g_ape1_SlotFlagInit == 1)
    {
        g_ape1_SlotFlagInit = 0;
        g_ape1_CurrentSlot = slot;
    }
    else
    {
        g_ape1_PreviousSlot = g_ape1_CurrentSlot;
        g_ape1_CurrentSlot = slot;
        delta = (20 + g_ape1_CurrentSlot - g_ape1_PreviousSlot) % 20;
        if (delta != 1)
        {
            g_u32_ape1_timer0_slot_err++;
            debug_write(DBG_DDR_COMMON_IDX(ape_id, 37), g_u32_ape1_timer0_slot_err);
            UCP_PRINT_ERROR("slot number is not continuous;current sfn[0x%x], current slot[0x%x],previous slot[0x%x].", g_ape1_CurrentSfn, g_ape1_CurrentSlot, g_ape1_PreviousSlot);
        }
    }
    return;
}

static inline void check_continuous_sfn(uint16_t sfn)
{
    uint16_t delta = 0;
    uint32_t ape_id = get_core_id();

    if (g_ape1_SfnFlagInit == 1)
    {
        g_ape1_SfnFlagInit = 0;
        g_ape1_CurrentSfn = sfn;
    }
    else
    {
        g_ape1_PreviousSfn = g_ape1_CurrentSfn;
        g_ape1_CurrentSfn = sfn;
        delta = (1024 + g_ape1_CurrentSfn - g_ape1_PreviousSfn) % 1024;
        if (delta != 1)
        {
            g_u32_ape1_timer0_sfn_err++;
            debug_write(DBG_DDR_COMMON_IDX(ape_id, 38), g_u32_ape1_timer0_sfn_err);
            UCP_PRINT_ERROR("slot number is not continuous;current sfn[0x%x], previous sfn[0x%x].", g_ape1_CurrentSfn, g_ape1_PreviousSfn);
        }
    }
    return;
}

static inline void update_sfn_slot(void)
{
    uint16_t scs  = 1;//30KHz
    uint16_t sfn  = get_tx_nr_sfn(scs);
    uint16_t slot = get_tx_nr_slot(scs);
    check_continuous_slot(slot);

    if (slot == 0) {
        check_continuous_sfn(sfn);
    }

    return;
}

void ape1_test_timer0(void)
{
    uint32_t ape_id = get_core_id();
    uint32_t clock_tick = 0;
    uint32_t tick_offset = 0;
    g_u32_ape1_timer0_in++;
    rdmcycle(&clock_tick);

    if (0 == g_u32_ape1_timer0_tick)
    {
        g_u32_ape1_timer0_tick = clock_tick;
    }
    else
    {
        if (clock_tick > g_u32_ape1_timer0_tick)
        {
            tick_offset = clock_tick - g_u32_ape1_timer0_tick;
            if ((tick_offset > TIMER_OFFSET_MAX) || (tick_offset < TIMER_OFFSET_MIN))
            {
                g_u32_ape1_timer0_tick_err++;
            }
        }
        g_u32_ape1_timer0_tick = clock_tick;
    }

    update_sfn_slot();
    g_u32_ape1_timer0_out++;
    debug_write(DBG_DDR_COMMON_IDX(ape_id, 39), g_u32_ape1_timer0_tick);
    debug_write(DBG_DDR_COMMON_IDX(ape_id, 40), g_u32_ape1_timer0_tick_err);
    debug_write(DBG_DDR_COMMON_IDX(ape_id, 41), g_u32_ape1_timer0_in);
    debug_write(DBG_DDR_COMMON_IDX(ape_id, 42), g_u32_ape1_timer0_out);
    return ;
}

void ape1_test_timer80(void)
{
    uint32_t ape_id = get_core_id();
    uint32_t clock_tick = 0;
    uint32_t tick_offset = 0;
    g_u32_ape1_timer80_in++;
    rdmcycle(&clock_tick);

    if (0 == g_u32_ape1_timer80_tick)
    {
        g_u32_ape1_timer80_tick = clock_tick;
    }
    else
    {
        if (clock_tick > g_u32_ape1_timer80_tick)
        {
            tick_offset = clock_tick - g_u32_ape1_timer80_tick;
            if ((tick_offset > (TIMER_OFFSET_MAX+TIMER_SFN_OFFSET)) || (tick_offset < (TIMER_OFFSET_MIN+TIMER_SFN_OFFSET)))
            {
                g_u32_ape1_timer80_tick_err++;
            }
        }
        g_u32_ape1_timer80_tick = clock_tick;
    }

    g_u32_ape1_timer80_out++;

    debug_write(DBG_DDR_COMMON_IDX(ape_id, 43), g_u32_ape1_timer80_tick);
    debug_write(DBG_DDR_COMMON_IDX(ape_id, 44), g_u32_ape1_timer80_tick_err);
    debug_write(DBG_DDR_COMMON_IDX(ape_id, 45), g_u32_ape1_timer80_in);
    debug_write(DBG_DDR_COMMON_IDX(ape_id, 46), g_u32_ape1_timer80_out);
    return ;
}

void ape1_test_timer100(void)
{
    static uint8_t su8_index = 0;
    uint32_t ape_id = get_core_id();
    uint32_t clock_tick = 0;
    uint32_t tick_offset = 0;
    g_u32_ape1_timer100_in++;
    rdmcycle(&clock_tick);
    su8_index++;

    if (0 == g_u32_ape1_timer100_tick)
    {
        g_u32_ape1_timer100_tick = clock_tick;
    }
    else
    {
        if (clock_tick > g_u32_ape1_timer100_tick)
        {
            tick_offset = clock_tick - g_u32_ape1_timer100_tick;
            if (1 == su8_index)
            {
                if ((tick_offset > (TIMER_OFFSET_MAX+TIMER_SLOT_OFFSET)) || (tick_offset < (TIMER_OFFSET_MIN+TIMER_SLOT_OFFSET)))
                {
                    g_u32_ape1_timer100_tick_err++;
                }
            }
            else
            {
                if ((tick_offset > TIMER_OFFSET_MAX) || (tick_offset < TIMER_OFFSET_MIN))
                {
                    g_u32_ape1_timer100_tick_err++;
                }
                if (9 ==su8_index)
                {
                    su8_index = 0;
                }
            }
        }
        g_u32_ape1_timer100_tick = clock_tick;
    }

    g_u32_ape1_timer100_out++;

    debug_write(DBG_DDR_COMMON_IDX(ape_id, 47), g_u32_ape1_timer100_tick);
    debug_write(DBG_DDR_COMMON_IDX(ape_id, 48), g_u32_ape1_timer100_tick_err);
    debug_write(DBG_DDR_COMMON_IDX(ape_id, 49), g_u32_ape1_timer100_in);
    debug_write(DBG_DDR_COMMON_IDX(ape_id, 50), g_u32_ape1_timer100_out);
    return ;
}

void ape1_test_timer150(void)
{
    uint32_t ape_id = get_core_id();
    uint32_t clock_tick = 0;
    uint32_t tick_offset = 0;
    g_u32_ape1_timer150_in++;
    rdmcycle(&clock_tick);

    if (0 == g_u32_ape1_timer150_tick)
    {
        g_u32_ape1_timer150_tick = clock_tick;
    }
    else
    {
        if (clock_tick > g_u32_ape1_timer150_tick)
        {
            tick_offset = clock_tick - g_u32_ape1_timer150_tick;
            if ((tick_offset > (TIMER_OFFSET_MAX+TIMER_SFN_OFFSET)) || (tick_offset < (TIMER_OFFSET_MIN+TIMER_SFN_OFFSET)))
            {
                g_u32_ape1_timer150_tick_err++;
            }
        }
        g_u32_ape1_timer150_tick = clock_tick;
    }

    g_u32_ape1_timer150_out++;

    debug_write(DBG_DDR_COMMON_IDX(ape_id, 51), g_u32_ape1_timer150_tick);
    debug_write(DBG_DDR_COMMON_IDX(ape_id, 52), g_u32_ape1_timer150_tick_err);
    debug_write(DBG_DDR_COMMON_IDX(ape_id, 53), g_u32_ape1_timer150_in);
    debug_write(DBG_DDR_COMMON_IDX(ape_id, 54), g_u32_ape1_timer150_out);
    return ;
}

void ape1_test_timer200(void)
{
    static uint8_t su8_index = 0;
    uint32_t ape_id = get_core_id();
    uint32_t clock_tick = 0;
    uint32_t tick_offset = 0;
    g_u32_ape1_timer200_in++;
    rdmcycle(&clock_tick);
    su8_index++;

    if (0 == g_u32_ape1_timer200_tick)
    {
        g_u32_ape1_timer200_tick = clock_tick;
    }
    else
    {
        if (clock_tick > g_u32_ape1_timer200_tick)
        {
            tick_offset = clock_tick - g_u32_ape1_timer200_tick;
            if (1 == su8_index)
            {
                if ((tick_offset > (TIMER_OFFSET_MAX+TIMER_SLOT_OFFSET)) || (tick_offset < (TIMER_OFFSET_MIN+TIMER_SLOT_OFFSET)))
                {
                    g_u32_ape1_timer200_tick_err++;
                }
            }
            else
            {
                if ((tick_offset > TIMER_OFFSET_MAX) || (tick_offset < TIMER_OFFSET_MIN))
                {
                    g_u32_ape1_timer200_tick_err++;
                }
                if (9 ==su8_index)
                {
                    su8_index = 0;
                }
            }
        }
        g_u32_ape1_timer200_tick = clock_tick;
    }

    g_u32_ape1_timer200_out++;

    debug_write(DBG_DDR_COMMON_IDX(ape_id, 55), g_u32_ape1_timer200_tick);
    debug_write(DBG_DDR_COMMON_IDX(ape_id, 56), g_u32_ape1_timer200_tick_err);
    debug_write(DBG_DDR_COMMON_IDX(ape_id, 57), g_u32_ape1_timer200_in);
    debug_write(DBG_DDR_COMMON_IDX(ape_id, 58), g_u32_ape1_timer200_out);
    return ;
}

void ape1_test_timer300(void)
{
    uint32_t ape_id = get_core_id();
    uint32_t clock_tick = 0;
    uint32_t tick_offset = 0;
    g_u32_ape1_timer300_in++;
    rdmcycle(&clock_tick);

    if (0 == g_u32_ape1_timer300_tick)
    {
        g_u32_ape1_timer300_tick = clock_tick;
    }
    else
    {
        if (clock_tick > g_u32_ape1_timer300_tick)
        {
            tick_offset = clock_tick - g_u32_ape1_timer300_tick;
            if ((tick_offset > TIMER_OFFSET_MAX) || (tick_offset < TIMER_OFFSET_MIN))
            {
                g_u32_ape1_timer300_tick_err++;
            }
        }
        g_u32_ape1_timer300_tick = clock_tick;
    }
    debug_write(DBG_DDR_COMMON_IDX(ape_id, 59), g_u32_ape1_timer300_tick);
    debug_write(DBG_DDR_COMMON_IDX(ape_id, 60), g_u32_ape1_timer300_tick_err);

    /* 给对方事件任务（Event1）发消息 */
    int  ret = 0;
    char *addr = NULL;


    addr = osp_alloc_msg(TEST_MSG_SIZE);
    if (NULL == addr)
    {
        g_u32_ape1_timer300_allo_err++;
        debug_write(DBG_DDR_COMMON_IDX(ape_id, 61), g_u32_ape1_timer300_allo_err);
        return ;
    }

    do_write(addr, g_u32_ape1_timer300_tick);
    do_write((addr+4), 0xA001B002);

    ret = osp_send_msg((uint32_t)(addr),
                        TEST_MSG_SIZE,
                        UCP4008_KERNEL_INTER,
                        ape_id+0,   // src que id
                        ape_id-1,   // dst que id
                        46,         // src task id
                        47);        // dst task id
    
    if (0 != ret)
    {
        g_u32_ape1_timer300_send_err++;
        debug_write(DBG_DDR_COMMON_IDX(ape_id, 62), g_u32_ape1_timer300_send_err);
        return ;
    }
    g_u32_ape1_timer300_send_ok++;
    debug_write(DBG_DDR_COMMON_IDX(ape_id, 63), g_u32_ape1_timer300_in);
    debug_write(DBG_DDR_COMMON_IDX(ape_id, 64), g_u32_ape1_timer300_send_ok);
    return ;

}

void ape1_test_timer400(void)
{
    uint32_t ape_id = get_core_id();
    uint32_t clock_tick = 0;
    uint32_t tick_offset = 0;
    g_u32_ape1_timer400_in++;
    rdmcycle(&clock_tick);

    if (0 == g_u32_ape1_timer400_tick)
    {
        g_u32_ape1_timer400_tick = clock_tick;
    }
    else
    {
        if (clock_tick > g_u32_ape1_timer400_tick)
        {
            tick_offset = clock_tick - g_u32_ape1_timer400_tick;
            if ((tick_offset > TIMER_OFFSET_MAX) || (tick_offset < TIMER_OFFSET_MIN))
            {
                g_u32_ape1_timer400_tick_err++;
            }
        }
        g_u32_ape1_timer400_tick = clock_tick;
    }

    g_u32_ape1_timer400_out++;

    debug_write(DBG_DDR_COMMON_IDX(ape_id, 65), g_u32_ape1_timer400_tick);
    debug_write(DBG_DDR_COMMON_IDX(ape_id, 66), g_u32_ape1_timer400_tick_err);
    debug_write(DBG_DDR_COMMON_IDX(ape_id, 67), g_u32_ape1_timer400_in);
    debug_write(DBG_DDR_COMMON_IDX(ape_id, 68), g_u32_ape1_timer400_out);
    return ;
}

