/**************************************************************************/ /**
                                                                              * \file     Sys_Tick.c
                                                                              * \brief    System tick timer driver file
                                                                              * \details
                                                                              * \author   Zhang Xuan
                                                                              * \version  V1.0.0
                                                                              * \date     19-Jul-2018
                                                                              * \par      History:
                                                                              *           V1.0.0 Initial release
                                                                              * \par      Copyright:
                                                                              *           (c) Heilongjiang TYW Electronics co., LTD
                                                                              ******************************************************************************/

/* Includes ------------------------------------------------------------------*/
#include "stdlib.h"
#include "r_typedefs.h"
#include "dr7f701401.dvf.h"
#include "r_dev_api.h"
#include "Sys_Tick.h"

/* Private typedef -----------------------------------------------------------*/
typedef struct
{
    uint32_t u32MainCnt;
    uint32_t u32DstVal1ms;
    uint32_t u32DstVal100ms;
} Sys_Tick_Timer_st_t;

/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
#define CLK_AWOTCLK_FREQ_Hz (8000000UL)

/* Private variables ---------------------------------------------------------*/
void (*pfnSysTickCallBack [ SYS_TICK_CALL_BACK_TYPE_NUM ])(void);
Sys_Tick_Timer_st_t g_stSysTickTimer;
volatile uint16_t   g_u16SysRollingCounter50us;
volatile uint16_t   g_u16SysRollingCounter1ms;

/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/

/**************************************************************************/ /**
                                                                              * \brief      Start tick timer
                                                                              * \retval     None
                                                                              ******************************************************************************/
void Sys_Tick_Timer_Start(void)
{
    g_stSysTickTimer.u32MainCnt     = 0U;
    g_stSysTickTimer.u32DstVal1ms   = 1000UL / SYS_TICK_INT_INTERVAL;
    g_stSysTickTimer.u32DstVal100ms = 100000UL / SYS_TICK_INT_INTERVAL;

    g_u16SysRollingCounter50us = 0U;
    g_u16SysRollingCounter1ms  = 0U;

    AWOT0CTL = 0x00U; /* Disable AWOT before configuration */
    AWOT0TOE = 0x00U; /* Disable output of AWOTOUT pin */
    AWOT0EMU = 0x00U; /* Debug enable */
    AWOT0CCR = SYS_TICK_INT_INTERVAL * CLK_AWOTCLK_FREQ_Hz / 1000000UL;

    R_DEV_IntEnable(R_DEV_INT_AWOTM0, 1U); /* Enable interrupt */

    AWOT0CTL = 0x80U; /* Start AWOT */
}

/**************************************************************************/ /**
                                                                              * \brief      GPIO initialization for sleep mode
                                                                              * \retval     None
                                                                              ******************************************************************************/
void Sys_Tick_Timer_Stop(void)
{
    R_DEV_IntEnable(R_DEV_INT_AWOTM0, 0U); /* Disable interrupt */
    AWOT0CTL = 0x00U;                      /* Disable AWOT  */
}

void Sys_Tick_Timer_Call_Back_Reg(Sys_Tick_Call_Back_Type_en_t enType, void (*pfnIsr)(void))
{
    if ( enType < SYS_TICK_CALL_BACK_TYPE_NUM )
    {
        pfnSysTickCallBack [ enType ] = pfnIsr;
    }
}

/**************************************************************************/ /**
                                                                              * \brief      Tick timer interrupt service routines
                                                                              * \retval     None
                                                                              ******************************************************************************/
void Sys_Tick_Timer_ISR(void)
{
    uint16_t u16Counter;

    // UDS_50us_Service();

    if ( pfnSysTickCallBack [ SYS_TICK_50us_CB ] != NULL )
    {
        pfnSysTickCallBack [ SYS_TICK_50us_CB ]( );
    }

    g_stSysTickTimer.u32MainCnt++;

    if ( g_stSysTickTimer.u32MainCnt >= g_stSysTickTimer.u32DstVal1ms )
    {
        if ( pfnSysTickCallBack [ SYS_TICK_1ms_CB ] != NULL )
        {
            pfnSysTickCallBack [ SYS_TICK_1ms_CB ]( );
        }

        u16Counter                    = g_u16SysRollingCounter1ms;
        g_u16SysRollingCounter1ms     = u16Counter + 1U;
        g_stSysTickTimer.u32DstVal1ms = g_stSysTickTimer.u32MainCnt + (1000UL / SYS_TICK_INT_INTERVAL);
    }

    if ( g_stSysTickTimer.u32MainCnt >= g_stSysTickTimer.u32DstVal100ms )
    {
        if ( pfnSysTickCallBack [ SYS_TICK_100ms_CB ] != NULL )
        {
            pfnSysTickCallBack [ SYS_TICK_100ms_CB ]( );
        }

        g_stSysTickTimer.u32DstVal100ms = g_stSysTickTimer.u32MainCnt + (100000UL / SYS_TICK_INT_INTERVAL);
    }

    if ( g_stSysTickTimer.u32MainCnt & 0xFFFF0000UL )
    {
        g_stSysTickTimer.u32MainCnt &= 0x0000FFFFUL;
        g_stSysTickTimer.u32DstVal1ms &= 0x0000FFFFUL;
        g_stSysTickTimer.u32DstVal100ms &= 0x0000FFFFUL;
    }

    g_u16SysRollingCounter50us = ( uint16_t )g_stSysTickTimer.u32MainCnt;

    R_DEV_IntClearFlag(R_DEV_INT_AWOTM0);
}