#include "gw3323_rtc.h"

/**
  * @brief  Set the RTC counter register value.
  * @param  cnt: specifies the counter register new value.
  * @retval None
  */
void rtc_set_counter(uint32_t cnt)
{
    RTCCNT = (uint32_t)cnt;
}

/**
  * @brief  Get the RTC counter register value.
  * @param  None
  * @retval specifies the counter register value.
  */
uint32_t rtc_get_counter(void)
{
    return (uint32_t)RTCCNT;
}

/**
  * @brief  Set the RTC alarm register value.
  * @param  alm: specifies the alarm register new value.
  * @retval None
  */
void rtc_set_alarm(uint32_t alm)
{
    RTCALM = (uint32_t)(alm - 1);
}

/**
  * @brief  Get the RTC alarm register value.
  * @param  None
  * @retval specifies the alarm register value.
  */
uint32_t rtc_get_alarm(void)
{
    return (uint32_t)(RTCALM + 1);
}

/**
  * @brief  Configure RTC peripheral related clock.
  * @param  clk_struct: pointer to a rtc_clk_typedef structure that contains
  *         the configuration information for the specified RTC register.
  * @retval None
  */
void rtc_clk_config(rtc_clk_typedef *clk_struct)
{
    if (clk_struct->external_enable != RESET) {
        RTCCON2 &= ~(uint32_t)RTC_CON2_32KSEL;
        RTCCON2 |= (uint32_t)clk_struct->clk_value_flag;

        RTCCON0 |= (uint32_t)RTC_CON0_EXT32KS;
    } else {
        RTCCON2 |= RTC_32K_CLK_MODE;
        RTCCON0 &= ~(uint32_t)RTC_CON0_EXT32KS;

        RTCCON0 &= ~(uint32_t)RTC_CON0_CLK2MRTCSSEL;
        RTCCON0 |= clk_struct->clk_source_sel;

        RTCCON0 |= (uint32_t)RTC_CON0_RCSEL;
        RTCCON0 |= (uint32_t)RTC_CON0_CLK2MEN;
        RTCCON0 |= (uint32_t)RTC_CON0_RCEN;
    }
}

/**
  * @brief  Enable or disable the RTC interrupt.
  * @param  isr: Function to be executed for service interruption.
  * @param  pr: Priority of service interruption.
  * @param  rtc_ie_bit: specifies the RTC interrupt sources to be enable or disable.
  *         this parameter can be one of the following values:
  *             @arg RTC_IT_ALM: RTC alarm interrupt enable bit.
  *             @arg RTC_IT_1S: RTC 1S interrupt enable bit.
  * @param  state: the state of the RTC peripheral.
  *         this parameter can be: ENABLE or DISABLE.
  * @retval None
  */
void rtc_pic_config(isr_t isr, int pr, uint16_t rtc_ie_bit, FUNCTIONAL_STATE state)
{
    if (state != DISABLE) {
        RTCCON |= rtc_ie_bit;
        sys_irq_init(RTC_LVD_WDT_IRQn, pr, isr);
        if (rtc_ie_bit == RTC_IT_1S){
            RTCCON11 |= RTC_CON11_WKSLPEN;
        }
    } else {
        PICEN &= ~BIT(RTC_LVD_WDT_IRQn);
        RTCCON &= ~(uint32_t)rtc_ie_bit;
        if (rtc_ie_bit == RTC_IT_1S){
            RTCCON11 &= ~(uint32_t)RTC_CON11_WKSLPEN;
        }
    }
}

/**
  * @brief  Configure RTC wakeup sleep frequency if that is enable.
  * @param  period_select: wakeup sleep period.
  *         this parameter can be one of the following values:
  *             @arg RTC_WAKEUP_110MS: interval 110ms.
  *             @arg RTC_WAKEUP_220MS: interval 220ms.
  *             @arg RTC_WAKEUP_440MS: interval 440ms.
  *             @arg RTC_WAKEUP_880MS: interval 880ms.
  * @retval None
  */
void rtc_wakeup_period_config(uint16_t period_select)
{
    if ((RTCCON11 & RTC_CON11_WKSLPEN) != RESET) {
        RTCCON11 &= ~(int32_t)RTC_CON11_WKSLPS;
        RTCCON11 |= period_select;
    }
}

/**
  * @brief  Get the RTC interrupt pending.
  * @param  rtc_flag: specifies the flag to get.
  *         this parameter can be one of the following values:
  *             @arg RTC_FLAG_1S: RTC 1S interrupt pending bit.
  *             @arg RTC_FLAG_ALM: RTC alarm interrupt pending bit.
  * @retval The state of rtc_flag (SET or RESET).
  */
FLAG_STATE rtc_get_flag(uint32_t rtc_flag)
{
    if ((RTCCON & rtc_flag) != RESET) {
        return SET;
    } else {
        return RESET;
    }
}

/**
  * @brief  Clear the RTC interrupt pending.
  * @param  rtc_flag: specifies the flag to clear.
  *         this parameter can be one of the following values:
  *             @arg RTC_FLAG_1S: RTC 1S interrupt pending bit.
  *             @arg RTC_FLAG_ALM: RTC alarm interrupt pending bit.
  * @retval None
  */
void rtc_clear_flag(uint32_t rtc_flag)
{
    RTCCPND |= (uint32_t)rtc_flag;
}
