#include "osp_timer.h"
#include "err_num.h"
#include "osp_msg.h"
#include "osp_sw_queue.h"
#include "osp_task.h"
#include "osp_sem.h"
#include "ucp_printf.h"
#include "ucp_tick.h"

osp_id_timer_t   g_task_off_tbl[10][100] = {0};  /* 根据定时点任务，分解成时隙，偏移，任务ID */
osp_timer_desc   g_osp_timer_desc[OSP_TIMER_TASK_MAX] ={0}; /* 定时点任务与定时点信息汇总 */
int g_osp_timer_desc_idx = 0;

extern int find_lsb(uint32_t u32_val);
extern void ape_mtimer_sync(int nScsId);
extern void ape_mtimer_unsync(int nScsId);

uint8_t gu8_register_task_group[10][OSP_TIMER_TASK_MAX] = {0};  /* 100 -> OSP_TIMER_TASK_MAX，一个时隙最多20个定时点任务 */
uint16_t g_reg_task_index = 0;

stStcTimerPoint g_stcTimerPoint[OSP_TMR_POINT_MAX] = {0};

void osp_timer_clear_stctimer()
{
    uint16_t u16_loop = 0;
    memset(g_stcTimerPoint, 0, sizeof(g_stcTimerPoint));
    for (u16_loop = 0; u16_loop < 10; u16_loop++)
    {
        g_stcTimerPoint[u16_loop*OSP_TIMER_TASK_MAX].pointVal = 0;
        g_stcTimerPoint[u16_loop*OSP_TIMER_TASK_MAX].lastFlag = 1;
    }
    stc_timer_set_tmrpoint(g_stcTimerPoint);
}

/* 删除所有定时点任务 */
void osp_timer_clear_task()
{
    uint16_t u16_loop = 0;

    for (u16_loop = 0; u16_loop < g_osp_timer_desc_idx; u16_loop++)
    {
        if ((g_osp_timer_desc[u16_loop].task_id) > 0)
        {
            osp_del_timer_task(g_osp_timer_desc[u16_loop].task_id);
        }
    }
}

/* OSP侧定时点任务初始化 */
void osp_timer_init()
{
    g_osp_timer_desc_idx = 0;
    g_reg_task_index = 0;
    memset(g_osp_timer_desc, 0, sizeof(g_osp_timer_desc));
    memset(gu8_register_task_group, 0, sizeof(gu8_register_task_group));
    memset(g_task_off_tbl, 0, sizeof(g_task_off_tbl));
    memset(g_stcTimerPoint, 0, sizeof(g_stcTimerPoint));
    return ;
}

/* 静态定时点注册 */
uint32_t osp_task_timer_cfg(osp_timer_cfg_inf *timer_tbl, int apeid)
{
    while(timer_tbl->apeid_bitmap != 0xffff)
    {
        if(timer_tbl->apeid_bitmap & (1<<apeid))
        {
            if(g_osp_timer_desc_idx >= OSP_TIMER_COUNTS)
            {
                UCP_PRINT_ERROR("timer cfg is overflow\n\r");
                return -OSP_PAR_ILL;
            }
            g_osp_timer_desc[g_osp_timer_desc_idx].t_offset = timer_tbl->t_offset;
            g_osp_timer_desc[g_osp_timer_desc_idx].slot_bitmap = timer_tbl->slot_bitmap;
            g_osp_timer_desc[g_osp_timer_desc_idx].task_id = timer_tbl->task_id;
            g_osp_timer_desc_idx++;
        }
        timer_tbl++;
    }
    return OSP_OK;
}

/* 使能任务定时点      */
/*
函数参数：tti：时间周期的长度（如：1000us/500us/250us/125us等）
*/
short lastOffset = 0;
void osp_timer_sync(int scsId)
{
#ifdef UCP_TICK_ENABLE
    uint32_t clockBegin,clockEnd;
    int32_t  clockCnt;
    rdmcycle(&clockBegin);
#endif

    int i = 0;
    int stc_timer_index = 0;

    ape_mtimer_sync(scsId); // scs id

    int tmp_bitmap;
    int tbl_index = 0;
    int slot_id = 0;
    int j,tmp_cnt = 0;
    osp_timer_desc *ptr = g_osp_timer_desc;
    for(i = 0; i < g_osp_timer_desc_idx; i++)
    {
        tmp_bitmap = ptr->slot_bitmap;
        tbl_index  = ptr->t_offset/10;
        while(tmp_bitmap != 0)
        {
            slot_id = find_lsb(tmp_bitmap);
            tmp_bitmap &= ~(1 << slot_id);
            g_task_off_tbl[slot_id][tbl_index].task_id = ptr->task_id;
            g_task_off_tbl[slot_id][tbl_index].t_offset = ptr->t_offset;
            //UCP_PRINT_ERROR("i=%d,j=%d,taskid=%d,offset=%d", slot_id,tbl_index, ptr->task_id, ptr->t_offset);
        }
        tmp_cnt++;
        ptr++;
    }

    if (tmp_cnt > 0)
    {
        for(i = 0; i < 10;i++)
        {
            stc_timer_index = 0;
            for(j = 0; j < 100;j++)
            {
                if (OSP_TIMER_TASK_MAX <= stc_timer_index)
                {
                    UCP_PRINT_ERROR("one slot timer tasks overflow\n\r");
                    return ;
                }
                if (0 == j)
                {
                    g_stcTimerPoint[i*OSP_TIMER_TASK_MAX + stc_timer_index].pointVal = 0;
                    g_stcTimerPoint[i*OSP_TIMER_TASK_MAX + stc_timer_index].lastFlag = 0;
                    stc_timer_index++;
                    lastOffset = 0;

                    if ((0 == g_task_off_tbl[i][j].t_offset) && (0 != g_task_off_tbl[i][j].task_id))
                    {
                        gu8_register_task_group[i][stc_timer_index-1] = (uint8_t)(g_task_off_tbl[i][j].task_id);
                        g_reg_task_index++;
                    }
                    else
                    {
                        /* 第一个点：无task id      或偏移非0，需要加一个假的 */
                        gu8_register_task_group[i][stc_timer_index-1] = 0;
                        g_reg_task_index++;
                    }
                }
                else
                {
                    if(g_task_off_tbl[i][j].task_id != 0)
                    {
                        g_stcTimerPoint[i*OSP_TIMER_TASK_MAX + stc_timer_index].pointVal = g_task_off_tbl[i][j].t_offset - lastOffset; //g_stcTimerPoint[i*50 + stc_timer_index-1].pointVal;
                        g_stcTimerPoint[i*OSP_TIMER_TASK_MAX + stc_timer_index].lastFlag = 0;
                        lastOffset = g_task_off_tbl[i][j].t_offset;
                        stc_timer_index++;

                        gu8_register_task_group[i][stc_timer_index-1] = (uint8_t)(g_task_off_tbl[i][j].task_id);
                        g_reg_task_index++;
                    }
                }
            }
            /* 补最后一个的状态 */
            g_stcTimerPoint[i*OSP_TIMER_TASK_MAX + stc_timer_index -1].lastFlag = 1;
        }
        stc_timer_set_tmrpoint(g_stcTimerPoint);
#ifdef OSP_DEBUG_TEST
        debug_write(OSP_DEBUG_POT(g_ape_id, 90), g_reg_task_index);
#endif
    }
#ifdef UCP_TICK_ENABLE
    rdmcycle(&clockEnd);
    clockCnt = clockEnd - clockBegin;
    debug_write(OSP_DEBUG_POT(g_ape_id, 205), clockCnt);
#endif

    return ;
}

void osp_timer_unsync(int scsId)
{
    ape_mtimer_unsync(scsId); // scs id

    /* 删除所有定时点配置 */
    osp_timer_clear_stctimer();

    /* 删除所有定时点任务 */
    osp_timer_clear_task();

    /* 定时点模块初始化 */
    osp_timer_init();
}

void osp_timer_unsync_notask(int scs_id)
{
    ape_mtimer_unsync(scs_id); // scs id

    /* 删除所有定时点配置 */
    osp_timer_clear_stctimer();

    /* 定时点模块初始化 */
    osp_timer_init();

    return ;
}


#ifdef UCP_OSP_DBG_ENABLE
uint32_t g_timer_num = 0;
uint32_t g_timer_task = 0;
uint32_t g_timer_notask = 0;
uint32_t g_u16_osp_timer_call_loop = 0;
#endif

#if 0
int get_register_task_id(int index)
{
    return (int)g_register_task_buf[index];
}

void osp_timer_call_task()
{
    int task_id = 0;

#ifdef UCP_OSP_DBG_ENABLE
    g_timer_num++;
    debug_write(OSP_DEBUG_POT(g_ape_id, 94), g_timer_num);

    uint32_t clockTick = 0;
    rdmcycle(&clockTick);
    debug_write(OSP2_DEBUG_POT(g_ape_id, g_u16_osp_timer_call_loop), clockTick);
    g_u16_osp_timer_call_loop = (g_u16_osp_timer_call_loop+1)&0x1FF;   /* 512个计数循环覆盖 */
#endif

    if (g_mtimer_loop >= g_mtimer_cnt)
    {
        g_mtimer_loop = 0;
    }
    task_id = get_register_task_id(g_mtimer_loop);

    if(task_id > 0)
    {
#ifdef UCP_OSP_DBG_ENABLE
        g_timer_task++;
        debug_write(OSP_DEBUG_POT(g_ape_id, 95), g_timer_task);
        debug_write(OSP_DEBUG_POT(g_ape_id, 92), task_id);
#endif
        osp_post_timer_event_sem(task_id);
    }
    else
    {
#ifdef UCP_OSP_DBG_ENABLE
        g_timer_notask++;
        debug_write(OSP_DEBUG_POT(g_ape_id, 96), g_timer_notask);
#endif
    }
    g_mtimer_loop++;

    return ;
}

void osp_timer_restart(void)
{
    g_mtimer_loop = 0;

    return ;
}
#endif

void osp_timer_call_task_spe(uint8_t u8slot, uint8_t u8taskidx)
{
    int task_id = gu8_register_task_group[u8slot][u8taskidx];

    if(task_id > 0)
    {
#ifdef UCP_OSP_DBG_ENABLE
        g_timer_task++;
        debug_write(OSP_DEBUG_POT(g_ape_id, 95), g_timer_task);
        debug_write(OSP_DEBUG_POT(g_ape_id, 92), task_id);
#endif
        osp_post_timer_event_sem(task_id);
    }
    else
    {
#ifdef UCP_OSP_DBG_ENABLE
        g_timer_notask++;
        debug_write(OSP_DEBUG_POT(g_ape_id, 96), g_timer_notask);
#endif
    }

    return ;
}

