/*
 * SystemProc.c
 *
 *  Created on: Jul 31, 2014
 *      Author: QTC
 */
#include "common.h"
#include "rtc.h"

rtc_counter_value_t calendar;

/***********************************************************************************************************************
* Function Name: RTC_Start
* @brief  This function enables the real-time clock.
* @param  None
* @return None
***********************************************************************************************************************/
void RTC_Start(void)
{
    INTC_ClearPendingIRQ(RTC_IRQn); /* clear INTRTC interrupt flag */
    NVIC_ClearPendingIRQ(RTC_IRQn); /* clear INTRTC interrupt flag */
    INTC_EnableIRQ(RTC_IRQn);       /* enable INTRTC interrupt */

    RTC->RTCC0  |= 0x80;    /* starts counter operation */

    /* confirm the RTC is running */
    RTC->RTCC1 |= RTC_RTCC1_RWAIT_Msk;              /* stops SEC to YEAR counters. Mode to read or write counter value */           
    while((RTC->RTCC1 & RTC_RTCC1_RWST_Msk) == 0);  /* wait RWST = 1 */
    RTC->RTCC1 &= ~RTC_RTCC1_RWAIT_Msk;             /* sets counter operation */
    while((RTC->RTCC1 & RTC_RTCC1_RWST_Msk) != 0);  /* wait RWST = 0 */
}
/***********************************************************************************************************************
* Function Name: RTC_Set_CounterValue
* @brief  This function set the counter value of the real-time clock.
* @param  counter_val
*             - the pointer of the expected real-time clock value(BCD code)
* @return None
***********************************************************************************************************************/
void RTC_Set_CounterValue(rtc_counter_value_t *counter_val)
{

    RTC->RTCC1 |= RTC_RTCC1_RWAIT_Msk;              /* stops SEC to YEAR counters. Mode to read or write counter value */           
    while((RTC->RTCC1 & RTC_RTCC1_RWST_Msk) == 0);  /* wait RWST = 1 */
    
    RTC->SEC   = counter_val->sec;
    RTC->MIN   = counter_val->min;
    RTC->HOUR  = counter_val->hour;
    RTC->DAY   = counter_val->day;
    RTC->WEEK  = counter_val->week;
    RTC->MONTH = counter_val->month;
    RTC->YEAR  = counter_val->year;

    RTC->RTCC1 &= ~RTC_RTCC1_RWAIT_Msk;             /* sets counter operation */
    while((RTC->RTCC1 & RTC_RTCC1_RWST_Msk) != 0);  /* wait RWST = 0 */
}
/***********************************************************************************************************************
* Function Name: RTC_Get_CounterValue
* @brief  This function get the counter value of the real-time clock.
* @param  counter_val
*             - the pointer of the current real-time clock value(BCD code)
* @return None
***********************************************************************************************************************/
void RTC_Get_CounterValue(rtc_counter_value_t *counter_val)
{
    RTC->RTCC1 |= RTC_RTCC1_RWAIT_Msk;              /* stops SEC to YEAR counters. Mode to read or write counter value */           
    while((RTC->RTCC1 & RTC_RTCC1_RWST_Msk) == 0);  /* wait RWST = 1 */
    
    counter_val->sec   = RTC->SEC;    
    counter_val->min   = RTC->MIN;   
    counter_val->hour  = RTC->HOUR;   
    counter_val->day   = RTC->DAY;    
    counter_val->week  = RTC->WEEK;   
    counter_val->month = RTC->MONTH;  
    counter_val->year  = RTC->YEAR;   

    RTC->RTCC1 &= ~RTC_RTCC1_RWAIT_Msk;             /* sets counter operation */
    while((RTC->RTCC1 & RTC_RTCC1_RWST_Msk) != 0);  /* wait RWST = 0 */
}
/***********************************************************************************************************************
* Function Name: RTC_Init
* @brief  This function initializes the real-time clock module.
* @param  rtccks - select the operaton clock of RTC
* @return None
***********************************************************************************************************************/
void RTC_Init(rtc_cks_t rtccks)
{

    rtc_counter_value_t calendar;
    CGC->PER0  |= CGC_PER0_RTCEN_Msk;     /* enables input clock supply */
    if(rtccks == RTC_FSUB) {
        MISC->RTCCL  = 0x00;  /* fRTC = fSUB */
    }
    if(rtccks == RTC_FIL) {
        MISC->RTCCL  = 0x01;  /* fRTC = fIL */
        CGC->OSMC  |= 1<<4;   /* WUTMMCK0 = 1 */
    }
    if(rtccks == RTC_48MHZ) {
        MISC->RTCCL  = 0x82;  /* fRTC = fHOCO/1464 */
    }
    if(rtccks == RTC_32MHZ) {
        MISC->RTCCL  = 0xC2;  /* fRTC = fHOCO/976 */
    }
    if(rtccks == RTC_16MHZ) {
        MISC->RTCCL  = 0x03;  /* fRTC = fMX/488 */
    }
    if(rtccks == RTC_8MHZ) {
        MISC->RTCCL  = 0x43;  /* fRTC = fMX/244 */
    }
    RTC->RTCC0  = 0;     /* stops counter operation */
    RTC->RTCC0 |= 0x08;    /* 24-hour system */
    
    //RTC->SUBCUD = 0x0018; /*13 hours fast 3 seconds*/
		//RTC->SUBCUD = 0x0023; /*24 hours fast 8 seconds    20220812*/
		RTC->SUBCUD = 0x0023; /**/
    
    RTC_Start();

    calendar.year = 0x22;
    calendar.month = 0x01;
    calendar.day = 0x01;
    calendar.hour = 0x00;
    calendar.min = 0x00;
    calendar.sec = 0x00;
    RTC_Set_CounterValue((rtc_counter_value_t *)&calendar);    
}


/*-------------------------------------------------------------------------
* Function Name  : bsp_rtc_isr_Handler
* Description    : 
* Input          : None
* Output         : None
* Return         : None
* onther         : 
--------------------------------------------------------------------------*/

void RTC_Service(void)
{
    RTC_Get_CounterValue((rtc_counter_value_t *)&calendar);
}

void Get_RTC_Time(rtc_counter_value_t* pCalendar)
{
    pCalendar->sec = calendar.sec;
    pCalendar->min = calendar.min;
    pCalendar->hour = calendar.hour;
    pCalendar->day = calendar.day;
    pCalendar->week = calendar.week;
    pCalendar->month = calendar.month;
    pCalendar->year = calendar.year;
}

