/*
  ******************************************************************************
  * @file    HAL_RTC.h
  * @version V1.0.0
  * @date    2022
  * @brief   Header file of RTC HAL module.
  ******************************************************************************
*/

#ifndef __HAL_RTC_H__
#define __HAL_RTC_H__

#include "acm32g103_hal_conf.h"






/**
  * @brief  RTC Configuration Structure definition
  */
typedef struct
{
    uint32_t ClockSource;           /*!< The RTC Clock Source to be configured.*/

    uint32_t Compensation;          /*!< The RTC Clock Compensation to be configured.*/

    uint32_t CompensationValue;     /*!< The RTC Clock Compensation Value to be configured.*/
}RTC_ConfigTypeDef;


/**
  * @brief  RTC Date structure definition
  */
typedef struct
{
    uint8_t Year;     /*!< Specifies the RTC Date Year.
                              This parameter must be a number between Min_Data = 0x00 and Max_Data = 0x99 */

    uint8_t Month;    /*!< Specifies the RTC Date Month (in BCD format).*/

    uint8_t Date;     /*!< Specifies the RTC Date.
                              This parameter must be a number between Min_Data = 0x01 and Max_Data = 0x31 */

    uint8_t WeekDay;  /*!< Specifies the RTC Date WeekDay.*/
}RTC_DateTypeDef;
/* Attention: Year¡¢Month¡¢Date¡¢Week use BCD code */


/**
  * @brief  RTC Time structure definition
  */
typedef struct
{
    uint8_t Hour;       /*!< Specifies the RTC Time Hour.
                                 This parameter must be a number between Min_Data = 0x00 and Max_Data = 0x23 */

    uint8_t Minute;     /*!< Specifies the RTC Time Minute.
                                 This parameter must be a number between Min_Data = 0x00 and Max_Data = 0x59 */

    uint8_t Second;     /*!< Specifies the RTC Time Seconds.
                                 This parameter must be a number between Min_Data = 0x00 and Max_Data = 0x59 */
}RTC_TimeTypeDef;
/* Attention: Hour¡¢Minute¡¢Second use BCD code */


/**
  * @brief  RTC Time structure definition
  */
typedef struct
{
    uint32_t u32_AlarmMode;         /*!< Specifies the RTC alarm Mode.*/

    uint32_t u32_AlarmInterrupt;    /*!< Specifies the RTC alarm interrupt Enable or Disable.*/

    uint32_t u32_DayMask;           /*!< Specifies the RTC alarm Day/Week Mask.*/
    
    uint32_t u32_HourMask;          /*!< Specifies the RTC alarm Hour Mask.*/
    
    uint32_t u32_MinMask;           /*!< Specifies the RTC alarm Min Mask.*/
    
    uint32_t u32_AlarmWeek;         /*!< Specifies the RTC alarm week select(Select WeekMode this parameter is valid).*/
    
    uint32_t u32_AlarmDay;          /*!< Specifies the RTC alarm day  select(Select DayMode this parameter is valid).
                                         This parameter must be a number between Min_Data = 0x01 and Max_Data = 0x31 */
    
    uint32_t u32_Hours;             /*!< Specifies the RTC alarm Hour.
                                         This parameter must be a number between Min_Data = 0x00 and Max_Data = 0x23 */

    uint32_t u32_Minutes;           /*!< Specifies the RTC alarm Minute.
                                         This parameter must be a number between Min_Data = 0x00 and Max_Data = 0x59 */

    uint32_t u32_Seconds;           /*!< Specifies the RTC alarm Seconds.
                                         This parameter must be a number between Min_Data = 0x00 and Max_Data = 0x59 */
}RTC_AlarmTypeDef;


/**
  * @brief  RTC Temper structure definition
  */
typedef struct 
{
    uint32_t u32_TemperEdge;      /*!< Specifies the RTC Temper edge select. */

    uint32_t u32_InterruptEN;     /*!< Specifies the RTC Temper interrupt enable.*/

    uint32_t u32_ClearBackup;     /*!< Specifies the RTC Temper clear backup register. */
                                       
    uint32_t u32_FilterClk;         /*!< Specifies the RTC Temper Filter Clock select. */

    uint32_t u32_Filter;          /*!< Specifies the RTC Temper Filter select.*/
}RTC_TemperTypeDef;


/**
  * @brief  RTC Wakeup Timer structure definition
  */
typedef struct 
{
	uint32_t u32_WuckSel;          /*!< The RTC WUCKSEL Value to be configured. 
                                             This parameter can be a value of @ref WUCKSEL_1Hz */
	
	uint32_t u32_InterruptEN;     /*!< Specifies the RTC Temper interrupt enable.
                                       This parameter can be a value of @ref RTC_WUTIMER Interrupt */
    uint32_t WakeUpCounter;

}RTC_WUTimerTypeDef;

/**
  * @brief  RTC Temper index definition
  */
typedef enum
{
    RTC_TEMPER_1,
    RTC_TEMPER_2,
}RTC_Temper_t;


/** @defgroup ClockSource
  * @{
  */
#define RTC_CLOCK_RC32K       (0x00000000)
#define RTC_CLOCK_XTL         (0x00000004)

/** @defgroup Clock_Compensation
  * @{
  */
#define COMPENSATION_INCREASE      (0x00000000)
#define COMPENSATION_DECREASE      (0x00000200)



/** @defgroup RTC_Month_Date_Definitions RTC Month Date Definitions
  * @{
  */
/* Coded in BCD format */
#define RTC_MONTH_JANUARY           (0x01)
#define RTC_MONTH_FEBRUARY          (0x02)
#define RTC_MONTH_MARCH             (0x03)
#define RTC_MONTH_APRIL             (0x04)
#define RTC_MONTH_MAY               (0x05)
#define RTC_MONTH_JUNE              (0x06)
#define RTC_MONTH_JULY              (0x07)
#define RTC_MONTH_AUGUST            (0x08)
#define RTC_MONTH_SEPTEMBER         (0x09)
#define RTC_MONTH_OCTOBER           (0x10)
#define RTC_MONTH_NOVEMBER          (0x11)
#define RTC_MONTH_DECEMBER          (0x12)



/** @defgroup RTC_WeekDay_Definitions RTC WeekDay Definitions
  * @{
  */
#define RTC_WEEKDAY_MONDAY          (0x01)
#define RTC_WEEKDAY_TUESDAY         (0x02)
#define RTC_WEEKDAY_WEDNESDAY       (0x03)
#define RTC_WEEKDAY_THURSDAY        (0x04)
#define RTC_WEEKDAY_FRIDAY          (0x05)
#define RTC_WEEKDAY_SATURDAY        (0x06)
#define RTC_WEEKDAY_SUNDAY          (0x07)

/** @defgroup RTC_AlarmInterrupt Definitions
  * @{
  */
#define RTC_ALARM_INT_ENABLE       (0x00000000)
#define RTC_ALARM_INT_DISABLE      (0x00000001)



/** @defgroup RTC_DayMask Definitions
  * @{
  */
#define RTC_ALARM_DAY_MASK_ENABLE       RTC_CR_ALM_MKSD
#define RTC_ALARM_DAY_MASK_DISABLE      (0x00000000)



/** @defgroup RTC_HourMask Definitions
  * @{
  */
#define RTC_ALARM_HOUR_MASK_ENABLE       RTC_CR_ALM_MSKH
#define RTC_ALARM_HOUR_MASK_DISABLE      (0x00000000)



/** @defgroup RTC_MinMask Definitions
  * @{
  */
#define RTC_ALARM_MIN_MASK_ENABLE       RTC_CR_ALM_MSKM
#define RTC_ALARM_MIN_MASK_DISABLE      (0x00000000)

/** @defgroup RTC_Alarm_WeekSelect Definitions
  * @{
  */
#define RTC_ALARM_WEEK_SUNDAY       (0x01000000)
#define RTC_ALARM_WEEK_MONDAY       (0x02000000)
#define RTC_ALARM_WEEK_TUESDAY      (0x04000000)
#define RTC_ALARM_WEEK_WEDNESDAY    (0x08000000)
#define RTC_ALARM_WEEK_THURSDAY     (0x10000000)
#define RTC_ALARM_WEEK_FRIDAY       (0x20000000)
#define RTC_ALARM_WEEK_SATURDAY     (0x40000000)


/** @defgroup RTC_Temper_edge Definitions
  * @{
  */
#define RTC_TEMP_EDGE_RISING       (0x00000000)
#define RTC_TEMP_EDGE_FALLING      (0x00000001)


/** @defgroup RTC_TemperInterrupt Definitions
  * @{
  */
#define RTC_TEMP_INT_DISABLE      (0x00000000)
#define RTC_TEMP_INT_ENABLE       (0x00000001)


/** @defgroup RTC_ClearBackup Definitions
  * @{
  */
#define RTC_TEMP_CLEAR_DISABLE       (0x00000000)
#define RTC_TEMP_CLEAR_ENABLE        (0x00000001)


/** @defgroup RTC_TemperFilter Clock Definitions
  * @{
  */
#define RTC_TEMP_FILTER_RTCCLK          (0x00000000)
#define RTC_TEMP_FILTER_512_RTCCLK      (0x00000001)

/** @defgroup RTC_TemperFilter Definitions
  * @{
  */
#define RTC_TEMP_FILTER_1_RTCCLK        (0x00000001)
#define RTC_TEMP_FILTER_2_RTCCLK        (0x00000002)
#define RTC_TEMP_FILTER_4_RTCCLK        (0x00000003)
#define RTC_TEMP_FILTER_8_RTCCLK        (0x00000004)

/** @defgroup  RTC Private Macros
  * @{
  */
#define IS_RTC_CLOCKSRC(__CLOCKSRC__)     (((__CLOCKSRC__) == RTC_CLOCK_RC32K) || \
                                           ((__CLOCKSRC__) == RTC_CLOCK_XTL))

#define IS_RTC_COMPENSATION(__COMPENSATION__)     (((__COMPENSATION__) == COMPENSATION_INCREASE) || \
                                                   ((__COMPENSATION__) == COMPENSATION_DECREASE))

#define IS_RTC_COMPENSATION_VALUE(__VALUE__)        ((__VALUE__) <= 0x1ff)                                                    

#define IS_RTC_YEAR(__YEAR__)       ((__YEAR__) >= 0x00 && (__YEAR__) <= 0x99)

#define IS_RTC_MONTH(__MONTH__)     (((__MONTH__) == RTC_MONTH_JANUARY)   || \
                                     ((__MONTH__) == RTC_MONTH_FEBRUARY)  || \
                                     ((__MONTH__) == RTC_MONTH_MARCH)     || \
                                     ((__MONTH__) == RTC_MONTH_APRIL)     || \
                                     ((__MONTH__) == RTC_MONTH_MAY)       || \
                                     ((__MONTH__) == RTC_MONTH_JUNE)      || \
                                     ((__MONTH__) == RTC_MONTH_JULY)      || \
                                     ((__MONTH__) == RTC_MONTH_AUGUST)    || \
                                     ((__MONTH__) == RTC_MONTH_SEPTEMBER) || \
                                     ((__MONTH__) == RTC_MONTH_OCTOBER)   || \
                                     ((__MONTH__) == RTC_MONTH_NOVEMBER)  || \
                                     ((__MONTH__) == RTC_MONTH_DECEMBER))

#define IS_RTC_DAY(__DAY__)          ((__DAY__) >= 0x01 && (__DAY__) <= 0x31)

#define IS_RTC_WEEKDAY(__WEEKDAY__)   (((__WEEKDAY__) == RTC_WEEKDAY_MONDAY)    || \
                                       ((__WEEKDAY__) == RTC_WEEKDAY_TUESDAY)   || \
                                       ((__WEEKDAY__) == RTC_WEEKDAY_WEDNESDAY) || \
                                       ((__WEEKDAY__) == RTC_WEEKDAY_THURSDAY)  || \
                                       ((__WEEKDAY__) == RTC_WEEKDAY_FRIDAY)    || \
                                       ((__WEEKDAY__) == RTC_WEEKDAY_SATURDAY)  || \
                                       ((__WEEKDAY__) == RTC_WEEKDAY_SUNDAY))

#define IS_RTC_HOUR(__HOUR__)    ((__HOUR__) >= 0x00 && (__HOUR__) <= 0x23)

#define IS_RTC_MIN(__MIN__)      ((__MIN__) >= 0x00 && (__MIN__) <= 0x59)

#define IS_RTC_SEC(__SEC__)      ((__SEC__) >= 0x00 && (__SEC__) <= 0x59)


#define IS_RTC_ALARM_MODE(__MODE__)      (((__MODE__) == RTC_ALM_ALM_WDS_WEEK) || \
                                          ((__MODE__) == RTC_ALM_ALM_WDS_DAY))

#define IS_RTC_ALARM_INT(__INT__)        (((__INT__) == RTC_ALARM_INT_ENABLE) || \
                                          ((__INT__) == RTC_ALARM_INT_DISABLE))

#define IS_RTC_ALARM_DAY_MASK(__MASKD__)     (((__MASKD__) == RTC_ALARM_DAY_MASK_ENABLE) || \
                                              ((__MASKD__) == RTC_ALARM_DAY_MASK_DISABLE))
                                              
#define IS_RTC_ALARM_HOUR_MASK(__MASKH__)    (((__MASKH__) == RTC_ALARM_HOUR_MASK_ENABLE) || \
                                              ((__MASKH__) == RTC_ALARM_HOUR_MASK_DISABLE))

#define IS_RTC_ALARM_MIN_MASK(__MASKM__)     (((__MASKM__) == RTC_ALARM_MIN_MASK_ENABLE) || \
                                              ((__MASKM__) == RTC_ALARM_MIN_MASK_DISABLE))

#define IS_RTC_ALARM_WEEKDAY(__WEEKDAY__)    (((__WEEKDAY__) == RTC_ALARM_WEEK_SUNDAY)    || \
                                              ((__WEEKDAY__) == RTC_ALARM_WEEK_MONDAY)    || \
                                              ((__WEEKDAY__) == RTC_ALARM_WEEK_TUESDAY)   || \
                                              ((__WEEKDAY__) == RTC_ALARM_WEEK_WEDNESDAY) || \
                                              ((__WEEKDAY__) == RTC_ALARM_WEEK_THURSDAY)  || \
                                              ((__WEEKDAY__) == RTC_ALARM_WEEK_FRIDAY)    || \
                                              ((__WEEKDAY__) == RTC_ALARM_WEEK_SATURDAY)  || \
                                              ((__WEEKDAY__) >= 0x01000000 && (__WEEKDAY__) <= 0x7F000000))


#define IS_RTC_TEMP_EDGE(__EDGE__)           (((__EDGE__) == RTC_TEMP_EDGE_RISING) || \
                                              ((__EDGE__) == RTC_TEMP_EDGE_FALLING))

#define IS_RTC_TEMP_INT(__INT__)             (((__INT__) == RTC_TEMP_INT_ENABLE) || \
                                              ((__INT__) == RTC_TEMP_INT_DISABLE))

#define IS_RTC_TEMP_CLEAR_BACKUP(__CLEAR__)    (((__CLEAR__) == RTC_TEMP_CLEAR_DISABLE) || \
                                                ((__CLEAR__) == RTC_TEMP_CLEAR_ENABLE))

#define IS_RTC_TEMP_FILTER(__FILTER__)         (((__FILTER__) == RTC_TEMP_FILTER_1_RTCCLK)   || \
                                                ((__FILTER__) == RTC_TEMP_FILTER_2_RTCCLK)   || \
                                                ((__FILTER__) == RTC_TEMP_FILTER_4_RTCCLK)   || \
                                                ((__FILTER__) == RTC_TEMP_FILTER_8_RTCCLK))
/**
  * @}
  */

/* RTC stamp1 interrupt enable¡¢disable */
#define __HAL_RTC_ENABLE_STAMP1_IT         (RTC->IE |= (RTC_IE_STP1RIE | RTC_IE_STP1FIE))
#define __HAL_RTC_DISABLE_STAMP1_IT        (RTC->IE &= ~(RTC_IE_STP1RIE | RTC_IE_STP1FIE))

/* RTC stamp2 interrupt enable¡¢disable */
#define __HAL_RTC_ENABLE_STAMP2_IT         (RTC->IE |= (RTC_IE_STP2RIE | RTC_IE_STP2FIE))
#define __HAL_RTC_DISABLE_STAMP2_IT        (RTC->IE &= ~(RTC_IE_STP2RIE | RTC_IE_STP2FIE))

/* RTC 32S interrupt enable¡¢disable */
#define __HAL_RTC_ENABLE_32S_IT            (RTC->IE |= RTC_IE_ADJ32)
#define __HAL_RTC_DISABLE_32S_IT           (RTC->IE &= ~RTC_IE_ADJ32)

/* RTC alarm interrupt enable¡¢disable */
#define __HAL_RTC_ENABLE_ALM_IT            (RTC->IE |= RTC_IE_ALM)
#define __HAL_RTC_DISABLE_ALM_IT           (RTC->IE &= RTC_IE_ALM)

/* RTC sec interrupt enable¡¢disable */
#define __HAL_RTC_ENABLE_SEC_IT            (RTC->IE |= RTC_IE_SEC)
#define __HAL_RTC_DISABLE_SEC_IT           (RTC->IE &= ~RTC_IE_SEC)

/* RTC Minute interrupt enable¡¢disable */
#define __HAL_RTC_ENABLE_MIN_IT            (RTC->IE |= RTC_IE_MIN)
#define __HAL_RTC_DISABLE_MIN_IT           (RTC->IE &= ~RTC_IE_MIN)

/* RTC Hour interrupt enable¡¢disable */
#define __HAL_RTC_ENABLE_HOUR_IT           (RTC->IE |= RTC_IE_HOUR)
#define __HAL_RTC_DISABLE_HOUR_IT          (RTC->IE &= ~RTC_IE_HOUR)

/* RTC Date interrupt enable¡¢disable */
#define __HAL_RTC_ENABLE_DATE_IT           (RTC->IE |= RTC_IE_DATE)
#define __HAL_RTC_DISABLE_DATE_IT          (RTC->IE &= ~RTC_IE_DATE)

/* RTC Timer Wakeup interrupt enable¡¢disable */
#define __HAL_RTC_ENABLE_WUTIE_IT           (RTC->IE |= RTC_IE_WUTIE)
#define __HAL_RTC_DISABLE_WUTIE_IT          (RTC->IE &= ~RTC_IE_WUTIE)


HAL_StatusTypeDef HAL_RTC_Config(RTC_ConfigTypeDef *hrtc);

void HAL_RTC_SetTime(RTC_TimeTypeDef *fp_Time);

void HAL_RTC_GetTime(RTC_TimeTypeDef *fp_Time);

void HAL_RTC_SetDate(RTC_DateTypeDef *fp_Date);

void HAL_RTC_GetDate(RTC_DateTypeDef *fp_Date);

void HAL_RTC_AlarmConfig(RTC_AlarmTypeDef *fp_Alarm);

void HAL_RTC_AlarmEnable(void);

void HAL_RTC_AlarmDisable(void);

void HAL_RTC_Tamper(RTC_Temper_t fe_Temper, RTC_TemperTypeDef *fp_Temper);

void HAL_RTC_TamperEnable(RTC_Temper_t fe_Temper);

void HAL_RTC_TamperDisable(RTC_Temper_t fe_Temper);

void HAL_RTC_SetWakeUpTimer(RTC_WUTimerTypeDef *hrtc);

#endif
