/**************************************************************************
 * @file     pan_timer.h
 * @version  V1.00
 * $Revision: 2 $
 * $Date: 2023/11/08 15:51 $
 * @brief    Panchip series TIMER driver header file
 *
 * @note
 * Copyright (C) 2023 Panchip Technology Corp. All rights reserved.
 *****************************************************************************/
#ifndef __PAN_TIMER_H__
#define __PAN_TIMER_H__

/**
 * @brief Timer Interface
 * @defgroup timer_interface Timer Interface
 * @{
 */

#ifdef __cplusplus
extern "C"
{
#endif

#include "pan271x.h"


#define	FIXED_DEVIATION			(12)	/*!< deviation from hw timer counter count to compare value to interrupt*/

/**@defgroup TIMER_WORK_MODE Timer work mode selection 
 * @brief       Timer work mode selection definition
 * @{ */
typedef enum TIMER_WorkMode
{
    TIMER_PERIOD_WORK_MODE            = 0x0,
    TIMER_CONTINUOUS_WORK_MODE        = 0x1,
} TIMER_WorkModeDef;
/**@} */

/**@defgroup TIMER_CAPTURE_EDGE Timer capture edge selection 
 * @brief       Timer capture edge selection definition
 * @{ */
typedef enum TIMER_CaptureEdge
{
    TIMER_CAPTURE_EDGE_SEL_RISING        = 0x0,
    TIMER_CAPTURE_EDGE_SEL_FALLING       = 0x1,
    TIMER_CAPTURE_EDGE_SEL_BOTH          = 0x2,
} TIMER_CaptureEdgeDef;
/**@} */

/**
  * @brief This function is used to start Timer counting
  * @param[in] timer The base address of Timer module
  * @return None
  */
__STATIC_INLINE void TIMER_Start(TIMER_T *timer)
{
    timer->TIMER_CTL |= TIMER_CTL_CNT_EN_Msk;
}

/**
  * @brief This function is used to stop Timer counting
  * @param[in] timer The base address of Timer module
  * @return None
  */
__STATIC_INLINE void TIMER_Stop(TIMER_T *timer)
{
    timer->TIMER_CTL &= ~TIMER_CTL_CNT_EN_Msk;
}

/**
  * @brief This function is used to clear timer count
  * @param[in] timer The base address of Timer module
  * @return None
  */
__STATIC_INLINE void TIMER_ResetCount(TIMER_T *timer)
{
	timer->TIMER_CTL |= TIMER_CTL_SOFTWARE_CNT_CLEAR_Msk;
    timer->TIMER_CTL &= ~TIMER_CTL_SOFTWARE_CNT_CLEAR_Msk;
}


/**
  * @brief This function is used to enable the Timer time-out interrupt function.
  * @param[in] timer The base address of Timer module
  * @return None
  */
__STATIC_INLINE void TIMER_EnableInt(TIMER_T *timer)
{
    timer->TIMER_CTL |= TIMER_CTL_INT_EN_Msk;
}

/**
  * @brief This function is used to disable the Timer time-out interrupt function.
  * @param[in] timer The base address of Timer module
  * @return None
  */
__STATIC_INLINE void TIMER_DisableInt(TIMER_T *timer)
{
    timer->TIMER_CTL &= ~TIMER_CTL_INT_EN_Msk;
}


/**
  * @brief This function is used to enable the Timer capture interrupt function.
  * @param[in] timer The base address of Timer module
  * @return None
  */
__STATIC_INLINE void TIMER_EnableCaptureInt(TIMER_T *timer)
{
    timer->TIMER_CTL |= TIMER_CTL_CAPTURE_INT_EN_Msk;
}

/**
  * @brief This function is used to disable the Timer capture interrupt function.
  * @param[in] timer The base address of Timer module
  * @return None
  */
__STATIC_INLINE void TIMER_DisableCaptureInt(TIMER_T *timer)
{
    timer->TIMER_CTL &= ~TIMER_CTL_CAPTURE_INT_EN_Msk;
}

/**
  * @brief This function indicates Timer time-out event occurred or not.
  * @param[in] timer The base address of Timer module
  * @return Timer time-out event occurred or not
  * @retval 0 Timer time-out event did not occur
  * @retval Timer time-out event occurred
  */
__STATIC_INLINE uint32_t TIMER_GetTFFlag(TIMER_T *timer)
{
	return (timer->TIMER_CTL & TIMER_CTL_TIMER_FLAG_Msk); 
}

/**
  * @brief This function indicates Timer capture event occurred or not.
  * @param[in] timer The base address of Timer module
  * @return 1 Timer capture event occurred or not
  * @retval 0 Timer capture event did not occur
  * @retval Timer capture event occurred
  */
__STATIC_INLINE uint32_t TIMER_GetCapFlag(TIMER_T *timer)
{
	return (timer->TIMER_CTL & TIMER_CTL_CAPTURE_FLAG_Msk); 
}

/**
  * @brief This function clears the Timer time-out evnet flag.
  * @param[in] timer The base address of Timer module
  * @param[in] flag timer flag, it could be:
  *                \ref TIMER_CTL_TIMER_FLAG_Msk
  *                \ref TIMER_CTL_CAPTURE_FLAG_Msk
  * @return None
  */
__STATIC_INLINE void TIMER_ClearTFFlag(TIMER_T *timer, uint32_t flag)
{
	timer->TIMER_CTL |= flag; 
}


/**
  * @brief This function reports the current timer counter value.
  * @param[in] timer The base address of Timer module
  * @return Timer counter value
  */
__STATIC_INLINE uint32_t TIMER_GetCounter(TIMER_T *timer)
{
    return (timer->TIMER_CTL & TIMER_CTL_CMPDATA_Msk);
}

/**
  * @brief This function set timer work mode.
  * @param[in] timer The base address of Timer module
  * @param[in] mode work mode selection, \ref TIMER_WORK_MODE
  * @return none
  */
__STATIC_INLINE void TIMER_SetWorkMode(TIMER_T *timer, TIMER_WorkModeDef mode)
{
    timer->TIMER_CTL = (timer->TIMER_CTL & ~TIMER_CTL_WORK_MODE_Msk) | (mode << TIMER_CTL_WORK_MODE_Pos);
}


/**
  * @brief This function enable timer capture function.
  * @param[in] timer The base address of Timer module
  * @param[in] mode work mode selection, \ref TIMER_WORK_MODE
  * @return none
  */
__STATIC_INLINE void TIMER_CaptureEnable(TIMER_T *timer, FunctionalState NewState)
{
	(NewState == ENABLE)?(timer->TIMER_CAPTURE |= TIMER_CAPTURE_CAPTURE_EN_Msk):(timer->TIMER_CAPTURE &= ~TIMER_CAPTURE_CAPTURE_EN_Msk);
}

/**
  * @brief This function select capture edge.
  * @param[in] timer The base address of Timer module
  * @param[in] TIMER_CaptureEdgeDef: capture edge selection
  * @return none
  */
__STATIC_INLINE void TIMER_SetCaptureEdge(TIMER_T *timer, TIMER_CaptureEdgeDef capEdge)
{
	timer->TIMER_CAPTURE = (timer->TIMER_CAPTURE & ~TIMER_CAPTURE_CAPTURE_SEL_Msk) | (capEdge << TIMER_CAPTURE_CAPTURE_SEL_Pos);
}

/**
  * @brief This function get capture count.
  * @param[in] timer The base address of Timer module
  * @return capture count value
  */
__STATIC_INLINE uint32_t TIMER_GetCaptureCount(TIMER_T *timer)
{
	return (timer->TIMER_CAPTURE & TIMER_CAPTURE_CAP_CNT_Msk) >> TIMER_CAPTURE_CAP_CNT_Pos;
}


/**
  * @brief This API stops Timer counting and disable the Timer interrupt function
  * @param[in] timer The base address of Timer module
  * @return None
  */
void TIMER_Close(TIMER_T *timer);

/**
  * @brief This API is used to create a delay loop for u32usec micro seconds
  * @param[in] timer The base address of Timer module
  * @param[in] u32Usec Delay period in micro seconds with 10 usec every step. Valid values are between 10~1000000 (10 micro second ~ 1 second)
  * @return None
  * @note This API overwrites the register setting of the timer used to count the delay time.
  * @note This API use polling mode. So there is no need to enable interrupt for the timer module used to generate delay
  */
void TIMER_Delay(TIMER_T *timer, uint32_t u32Usec);


/**
  * @brief This function is used to set new Timer compared value
  * @param[in] timer The base address of Timer module
  * @param[in] u32Value  Timer compare value. Valid values are between 2 to 0xFFFFFF
  * @return None
  */
void TIMER_SetCmpValue(TIMER_T *timer, uint32_t u32Value);

/**@} */


#ifdef __cplusplus
}
#endif

#endif //__PAN_TIMER_H__

/*** (C) COPYRIGHT 2023 Panchip Technology Corp. ***/
