
#ifndef _T1001_VTIMER_H
#define _T1001_VTIMER_H

#ifdef __cplusplus
extern "C" {
#endif

#include "t1001.h"
#include "t1001_sleep.h"

#define VTIMER0                           ((uint16_t)0x0000)
#define VTIMER1                           ((uint16_t)0x0001)

// #define VTIMER_DEBUG

#define CAL_SEL_XT24M (1 << 3)
#define CAL_SEL_XT32K (1 << 2)
#define CAL_SEL_RC24M (1 << 1)
#define CAL_SEL_RC32K (1 << 0)

#define CLKCAL_CLK_RC32K_CYCS_SH_FIRST   (11)    //2^n
#define CLKCAL_CLK_RC32K_CYCS_SH         5    //2^
#define CLKCAL_CLK_RC32K_FIX_SH          5
#define CLKCAL_XT24M_FREQ       (24UL << CLKCAL_CLK_RC32K_FIX_SH)   //24M

#define CLK_CAL_WIN_SZ_BITS (3)
#define CLK_CAL_WIN_SZ      (1 << CLK_CAL_WIN_SZ_BITS)
#define CLK_CAL_PER_SZ_BITS (0)
#define CLK_CAL_PER_SZ      (1 << CLK_CAL_PER_SZ_BITS)

typedef void (*VTIMER_CallbackType)(void *);

typedef struct VTIMER_HandleTypeS {
	struct VTIMER_HandleTypeS *next; /*!< Managed internally when the timer is started */
	uint32_t expiryTime; /*!< Managed internally when the timer is started */
	VTIMER_CallbackType callback; /*!< Pointer to the user callback */
	void *userData; /*!< Pointer to user data */
} VTIMER_HandleType;

typedef struct VTIMER_CONTEXTS {
    VTIMER_HandleType *rootNode;
    uint8_t isClkCal;
	uint8_t cal_cycls_sh;
    uint16_t clkSpeed;

	uint16_t nxt_clkSpeed;
    uint8_t   clk_cal_idx;

	uint16_t  clk_cal_win[CLK_CAL_WIN_SZ];
	uint32_t  ttl_clk_cnts;
}VTIMER_CONTEXT;

void VTIMER_startTimerUs(VTIMER_HandleType *timerHandle, uint32_t usRelTimeout);
int VTIMER_StartTimerMs(VTIMER_HandleType *timerHandle, uint32_t msRelTimeout);
void VTIMER_StopTimer(VTIMER_HandleType *timerHandle);
uint8_t VTIMER_CheckTimerStart(VTIMER_HandleType *timerHandle);
uint32_t VTIMER_GetCurrentSysTime(void);
uint32_t VTIMER_GetTimerTarget(void);
uint8_t VTIMER_TimerPast(uint32_t sysTime1, uint32_t sysTime2);
uint32_t VTIMER_AddSysTimeMs(uint32_t sysTime, int32_t msTime);
int32_t VTIMER_DiffSysTime(uint32_t sysTime1, uint32_t sysTime2);
int32_t VTIMER_DiffSysTimeMs(uint32_t sysTime1, uint32_t sysTime2);
int VTIMER_StartTimerSysTime(VTIMER_HandleType *timerHandle, uint32_t time);
uint32_t VTIMER_ConvertUsToTick(uint32_t us);
uint32_t VTIMER_ConvertTickToUs(uint32_t tick);
uint32_t VTIMER_ConvertTickToMs(uint32_t tick);
void VTIMER_Init(void);
// void VTIMER_IRQHandler(void);

SleepModes Timer_SleepMode_Check(SleepModes sleepMode);

void VTIMER_ClkCali_Trigger(uint32_t cycls);
void VTIMER_ClkCali_Wait(void);

extern volatile VTIMER_CONTEXT VTIMER_Context;

#ifdef __cplusplus
}
#endif
#endif
