/**
 * \file    timer.h
 * \brief   SAL timer
 *
 * \detail  The timer library provides functions for start and stop timers, 
 *          and for checking if a timer has expired. An application must 
 *          "manually" check if its timers have expired; this is not done 
 *          automatically.
 *
 * \par     Copyright (c) 2018 UWE Technologies Corp., Ltd. All Rights Reserved.
 * \author  James
 * \date    2018-03-12
 * \version 
 * 
 * \history 
 *  Date        Note
 *  2018-03-12  Original Creation
 * 
 */
 
#ifndef __TIMER_H_
#define __TIMER_H_

#include "arch.h"
#include "types.h"
#include "drv_rtc.h"


#pragma pack(1)

/**
 * SAL timer structure definition.
 *
 * This structure is used for declaring a timer. The timer must be set
 * with timer_start() before it can be used.
 *
 */
typedef struct timer_s {
    sys_tick_t start;    ///< The start timestamp, microsecond unit
    u32_t interval; ///< The interval before the timer expires, microsecond unit
} timer_t;

#pragma pack()


/**
 * Set and start a timer.
 *
 * This function is used to set a timer for a time sometime in the
 * future. The function timer_expired() will evaluate to true after
 * the timer has expired.
 *
 * \param interval  The interval before the timer expires, microsecond unit.
 * \param timer     A pointer to the timer
 *
 */ 
void timer_start(u32_t interval, volatile timer_t *timer);

/**
 * Check if a timer is started
 *
 * This macro is used to check if a timer is started.
 *
 * \param ptr       A pointer to the timer
 *
 */ 
#define timer_started(ptr) \
    ((ptr)->interval)


/**
 * Stop a timer.
 *
 * This macro is used to stop a timer.
 *
 * \param ptr       A pointer to the timer
 *
 */ 
#define timer_stop(ptr) \
    do { \
        (ptr)->interval = 0; \
    } while(0)

/**
 * Check if a timer is stopped
 *
 * This macro is used to check if a timer is stopped.
 *
 * \param ptr       A pointer to the timer
 *
 */ 
#define timer_stopped(ptr) \
    ((ptr)->interval == 0)

/**
 * Check if a timer has expired.
 *
 * This function tests if a timer has expired and returns true or
 * false depending on its status. If the timer interval is zero, returns false.
 *
 * \param timer     A pointer to the timer
 *
 * \return          Non-zero if the timer has expired, zero otherwise.
 *
 */
int timer_expired(volatile timer_t *timer);

#endif /* #ifndef __TIMER_H_ */

