#include "bsp_tim.h"
#include <stdio.h>

// tick_1ms_cnt在SysTick_Handler()中1ms +1
volatile uint32_t tick_1ms_cnt = 0;

/**
 * @description: 以SysTick（1ms）为基础
 * @return {uint32_t}
 */
uint32_t BSP_Get_Tick(void)
{
    /* Platform implementation */
    // return tick_1ms_cnt;
    // return (uint32_t)((double)TMOS_GetSystemClock() / 1.6);
    uint32_t tmos_time = TMOS_GetSystemClock();
                                     // 精确地使用整数计算而非浮点数进行转换
    return (tmos_time * 417) / 1000; // 0.625ms到ms的转换  //417=625/1.5
}


// SysTick中断函数
__INTERRUPT
__HIGH_CODE
void SysTick_Handler()
{
    static uint8_t cnt_ms = 0;

    SysTick->SR = 0;    // 清除中断标志
    tick_1ms_cnt++;
    
    cnt_ms++;
}



/* Timer handle list head. */
static MultiTimer* timerList = NULL;

/* Timer tick */
static PlatformTicksFunction_t platformTicksFunction = NULL;

int MultiTimerInstall(PlatformTicksFunction_t ticksFunc)
{
    platformTicksFunction = ticksFunc;
    return 0;
}

int MultiTimerStart(MultiTimer* timer, uint64_t timing, MultiTimerCallback callback, void* userData)
{
    if (!timer || !callback )
    {
        return -1;
    }
    MultiTimer** nextTimer = &timerList;
    /* Remove the existing target timer. */
    for (; *nextTimer; nextTimer = &(*nextTimer)->next)
    {
        if (timer == *nextTimer)
        {
            *nextTimer = timer->next; /* remove from list */
            break;
        }
    }

    /* Init timer. */
    timer->deadline = platformTicksFunction() + timing;
    timer->callback = callback;
    timer->userData = userData;

    /* Insert timer. */
    for (nextTimer = &timerList;; nextTimer = &(*nextTimer)->next)
    {
        if (!*nextTimer)
        {
            timer->next = NULL;
            *nextTimer = timer;
            break;
        }
        if (timer->deadline < (*nextTimer)->deadline)
        {
            timer->next = *nextTimer;
            *nextTimer = timer;
            break;
        }
    }
    return 0;
}

int MultiTimerStop(MultiTimer* timer)
{
    MultiTimer** nextTimer = &timerList;
    /* Find and remove timer. */
    for (; *nextTimer; nextTimer = &(*nextTimer)->next)
    {
        MultiTimer* entry = *nextTimer;
        if (entry == timer) {
            *nextTimer = timer->next;
            break;
        }
    }
    return 0;
}

int MultiTimerYield(void)
{
    MultiTimer* entry = timerList;
    for (; entry; entry = entry->next)
    {
        /* Sorted list, just process with the front part. */
        if (platformTicksFunction() < entry->deadline)
        {
            return (int)(entry->deadline - platformTicksFunction());
        }
        /* remove expired timer from list */
        timerList = entry->next;

        /* call callback */
        if (entry->callback)
        {
            entry->callback(entry, entry->userData);
        }
    }
    return 0;
}
