/*
 * Copyright (C) 2017-2020 Alibaba Group Holding Limited
 */

/******************************************************************************
 * @file       rtc.h
 * @brief      header file for rtc driver
 * @version    V1.0
 * @date       29. Apr 2020
 * @model      rtc
 ******************************************************************************/

#ifndef _DRV_RTC_H_
#define _DRV_RTC_H_

#include <drv/common.h>

#ifdef __cplusplus
extern "C" {
#endif  

/****** RTC time *****/
typedef struct {
    int tm_sec;             ///< Second.      [0-59]
    int tm_min;             ///< Minute.      [0-59]
    int tm_hour;            ///< Hour.        [0-23]
    int tm_mday;            ///< Day.         [1-31]
    int tm_mon;             ///< Month.       [0-11]
    int tm_year;            ///< Year-1900.   [70- ]      !NOTE:100=2000       
    int tm_wday;            ///< Day of week. [0-6 ]      !NOTE:Sunday = 0     
    int tm_yday;            ///< Days in year.[0-365]     !NOTE:January 1st = 0
} csi_rtc_time_t;

/****** definition for rtc *****/
typedef struct csi_rtc csi_rtc_t;
struct csi_rtc {
    csi_dev_t           dev;
    void               (*callback)(csi_rtc_t *rtc, void *arg);
    void               *arg;
    void               *priv;
} ;

/**
  \brief       Initialize RTC Interface. Initializes the resources needed for the RTC interface
  \param[in]   rtc    rtc handle to operate
  \param[in]   idx    rtc index
  \return      error code \ref csi_error_t
*/
csi_error_t csi_rtc_init(csi_rtc_t *rtc, uint32_t idx);

/**
  \brief       De-initialize RTC Interface. stops operation and releases the software resources used by the interface
  \param[in]   rtc    rtc handle to operate
  \return      None
*/
void csi_rtc_uninit(csi_rtc_t *rtc);

/**
  \brief       Set system date and wait for synchro
  \param[in]   rtc        rtc handle to operate
  \param[in]   rtctime    pointer to rtc time
  \return      error code \ref csi_error_t
*/
csi_error_t csi_rtc_set_time(csi_rtc_t *rtc, const csi_rtc_time_t *rtctime);

/**
  \brief       Set system date but no wait
  \param[in]   rtc        rtc handle to operate
  \param[in]   rtctime    pointer to rtc time
  \return      error code \ref csi_error_t
*/
csi_error_t csi_rtc_set_time_no_wait(csi_rtc_t *rtc, const csi_rtc_time_t *rtctime);

/**
  \brief       Get system date
  \param[in]   rtc        rtc handle to operate
  \param[out]  rtctime    pointer to rtc time
  \return      error code \ref csi_error_t
*/
csi_error_t csi_rtc_get_time(csi_rtc_t *rtc, csi_rtc_time_t *rtctime);

/**
  \brief       Get alarm remaining time
  \param[in]   rtc    rtc handle to operate
  \return      the remaining time(s)
*/
uint32_t csi_rtc_get_alarm_remaining_time(csi_rtc_t *rtc);

/**
  \brief       Config RTC alarm timer
  \param[in]   rtc         rtc handle to operate
  \param[in]   rtctime     time to wake up
  \param[in]   callback    callback function
  \param[in]   arg         callback's param
  \return      error code \ref csi_error_t
*/
csi_error_t csi_rtc_set_alarm(csi_rtc_t *rtc, const csi_rtc_time_t *rtctime, void *callback, void *arg);

/**
  \brief       Cancel the rtc alarm
  \param[in]   rtc    rtc handle to operate
  \return      error code \ref csi_error_t
*/
csi_error_t csi_rtc_cancel_alarm(csi_rtc_t *rtc);

/**
  \brief       Judge rtc is running
  \param[in]   rtc    rtc handle to operate
  \return      
               true  - rtc is running 
               false - rtc is not running 
*/
bool csi_rtc_is_running(csi_rtc_t *rtc);

/**
  \brief       Enable rtc power manage
  \param[in]   rtc    rtc handle to operate
  \return      error code
*/
csi_error_t csi_rtc_enable_pm(csi_rtc_t *rtc);

/**
  \brief       Disable rtc power manage
  \param[in]   rtc    rtc handle to operate
*/
void csi_rtc_disable_pm(csi_rtc_t *rtc);

#ifdef __cplusplus
}
#endif

#endif /* _DRV_RTC_H_ */
