/*
 * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD
 * All rights reserved.
 *
 * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use
 * exclusively with CVA's microcontroller products. This file can be freely
 * distributed within development tools that are supporting such microcontroller
 * products.
 *
 * THIS SOFTWARE IS PROVIDED "AS IS".  NO WARRANTIES, WHETHER EXPRESS, IMPLIED
 * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
 * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL,
 * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
 */

#ifndef _STIMER_H_
#define _STIMER_H_

/*! \brief  Contains public interface to various functions related
 *          to the Software Timer (STIMER) object.
 */

/*******************************************************************************
 * the includes
 ******************************************************************************/

#include <stdint.h>
#include <stdbool.h>

#ifdef __cplusplus
extern "C" {
#endif

/*******************************************************************************
 * the defines
 ******************************************************************************/

/*******************************************************************************
 * the typedefs
 ******************************************************************************/

/*! \brief  Declaration of STIMER object
 */
typedef struct _StimerType_
{
    uint32_t counter;  /*!< The counter register */
    uint32_t period;   /*!< The period, time out will occur when count reach period */
    bool     enable;   /*!< Whether the timer is started */
    bool     overflow; /*!< Whether the timer is overflow */

} StimerType;

/*******************************************************************************
 * the globals
 ******************************************************************************/

/*******************************************************************************
 * the function prototypes
 ******************************************************************************/

/*! \brief The constructor of the timer object
 *
 * This function initialize the Stimer object
 *
 * \param[in] obj : pointer to Stimer instance
 */
static inline void Stimer_Init(StimerType *obj)
{
    obj->counter  = 0;
    obj->period   = 0;
    obj->enable   = false;
    obj->overflow = false;
}

/*! \brief Start the timer for the period, this is one shot
 *
 * This function start the timer. This is one-shot.
 *
 * \note The real time is based on the time base running Ticker()
 * \note Call this function if already started will restart the timer
 *
 * \param[in] obj : pointer to Stimer instance
 * \param[in] period : the period value
 */
static inline void Stimer_Start(StimerType *obj, uint32_t period)
{
    obj->counter  = 0;
    obj->period   = period;
    obj->enable   = true;
    obj->overflow = false;
}

/*! \brief The time base of the timer object
 *
 * This function provide the real time base of the stimer instance.
 *
 * \param[in] obj : pointer to Stimer instance
 */
static inline void Stimer_Tick(StimerType *obj)
{
    if(obj->enable && obj->overflow == false)
    {
        if(obj->counter < obj->period)
        {
            obj->counter++;
            if(obj->counter == obj->period)
            {
                obj->overflow = true;
            }
        }
    }
}

/*! \brief Whether timeout
 *
 * This function returns whether it's timeout
 *
 * \param[in] obj : pointer to Stimer instance
 * \return Whether it's timeout
 *         - true : the timer is time-out
 *         - false : the timer is not time-out
 */
static inline bool Stimer_Timeout(const StimerType *obj)
{
    return obj->overflow;
}

/*! \brief Whether it's started
 *
 * This function returns whether the Timer instance is started
 *
 * \param[in] obj : pointer to Stimer instance
 * \return Whether it's started
 *         - true : the timer is started
 *         - false : the timer is not started
 */
static inline bool Stimer_IsActive(StimerType *obj)
{
    return obj->enable;
}

#ifdef __cplusplus
}
#endif /* extern "C" */

#endif /* _STIMER_H_ */
