/**
* @file DFM_Time.c
* @brief Driver Function Module: 时钟相关功能
* @details
* 本机精确时钟、上电周期号管理
* 延时功能的实现
* @author GT-BU
* @date 2021.02.20
* @version V1.0
* @copyright TCT
* @par 修改日志
* <table>
* <tr><th>Date        <th>Version  <th>Author     <th>Description
* <tr><td>2021.02.01  <td>V1.0     <td>GT-BU      <td>创建初始版本
* </table>
*/
#include "DFM_Time.h"
#include "CM_Time.h"
#include "PFM_Log.h"
#include "CM_Atomic.h"
/** 系统上电周期号（从系统上电开始计时，不受时钟同步等操作的影响） */
CM_UINT32 g_MSCP_BirthCount;

CM_ATOMIC CM_UINT64 g_CycTick = 0u;  /**< CPU精确时钟 */
CM_ATOMIC CM_INT64 g_CycBaseTick = 0; /* 周期运行基准时间 */
CM_ATOMIC CM_UINT64 g_UTCBaseTick = 0u; /* UTC基准时间 -us*/


/**
* @brief 获取进入周期运行距今的时间
* @return 从系统首次进入周期运行值调用时刻经过的时间，单位：100us
*/
CM_UINT64 DFM_GetCycTick(void)
{
	CM_UINT64 tick = 0u;
	CM_UINT64 currTick = CM_GetTick();
    /*- 获取进入周期运行距今的时间 */
	if(((CM_INT64)currTick - CM_ATOMIC_LOAD(&g_CycBaseTick)) >= 0)
	{
		tick = CM_GetTick() - CM_ATOMIC_LOAD(&g_CycBaseTick);
	}
	else
	{
		MSCP_LOG_MSG("CM_GetTick():%llu - CM_ATOMIC_LOAD(&g_CycBaseTick):%llu < 0\n",currTick,CM_ATOMIC_LOAD(&g_CycBaseTick));
		
	}

    /*- 返回 */
    return tick;
}

/**
* @brief 获取进入周期运行距今的时间
* @return 从系统首次进入周期运行值调用时刻经过的时间，单位：100us
*/
CM_UINT64 DFM_GetUTCRelativeTick(void)
{
    /*- 获取进入周期运行距今的时间 */
    CM_UINT64 tick = (CM_GetUTCTick() - CM_ATOMIC_LOAD(&g_UTCBaseTick))/100;
    /*- 返回 */
    return tick;
}
/**
* @brief 获取进入周期运行距今的时间
* @return 从系统首次进入周期运行值调用时刻经过的时间，单位：us
*/
CM_UINT64 DFM_GetUTCBaseTick(void)
{
    return CM_ATOMIC_LOAD(&g_UTCBaseTick);
}
/**
* @brief 延时到指定时刻
* @param tarTick 目标精确时刻（ns数）
* @return 实际设定的延时us数
* @details 本函数先获取当前精确时刻，再根据与目标精确时刻的差值确定sleep时间
*/
CM_UINT64 DFM_WaitUntill(IN CM_UINT64 tarTick)
{
    /*- 变量初始化 */
	CM_UINT64 leftTime = 0u;     /* 剩余时间 */
    CM_UINT64 curTick = CM_GetTick(); /* 当前时刻 */
    /*- 计算剩余时间 */
    if(tarTick >= curTick)
    {
    	leftTime = (tarTick - curTick) / 1000u;
    }
    else
    {
    	MSCP_LOG_MSG("tarTick = %lld, curTick = %lld, leftTime = %lld\n", tarTick, curTick, leftTime);
    	CM_RE_ASSERT(0, TIME_MODE, DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_1);
    }
#ifdef WIN32		
    /*- @alias sleep延时等待剩余时间 */
    if (leftTime > 0)
    {
        Sleep((unsigned long)(leftTime / 1000));
    }
#else
    /*- @alias sleep延时等待剩余时间 */
    if (leftTime == (CM_UINT32)leftTime)
    {
    	CM_Sleep((CM_UINT32)leftTime/1000U);
    }
    else
	{
    	MSCP_LOG_MSG("leftTime = %lld, (CM_UINT32)leftTime = %d\n", leftTime, (CM_UINT32)leftTime);
    	CM_RE_ASSERT(0, TIME_MODE, DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_2);
	}
#endif
    /*- 返回剩余时间 */
    return leftTime;
}

/**
* @brief 获取上电周期号
* @return 上电完成至调用时刻的周期数
* @details 从1开始，不受时钟同步等的影响
*/
CM_UINT32 DFM_GetBirthCount(void)
{
    /*- 返回上电周期号 */
    return g_MSCP_BirthCount;
}
