| PDL for FM0+ Version1.0 Peripheral Driverl Library for FM0+

- Main Page
- Modules
- Data Structures
- Files

- File List
- Globals

C:/pdl_v10/library/driver/rtc/rtc.c
Go to the documentation of this file.

    00001 /*******************************************************************************
    00002 * Copyright (C) 2013 Spansion LLC. All Rights Reserved.
    00003 *
    00004 * This software is owned and published by:
    00005 * Spansion LLC, 915 DeGuigne Dr. Sunnyvale, CA  94088-3453 ("Spansion").
    00006 *
    00007 * BY DOWNLOADING, INSTALLING OR USING THIS SOFTWARE, YOU AGREE TO BE BOUND
    00008 * BY ALL THE TERMS AND CONDITIONS OF THIS AGREEMENT.
    00009 *
    00010 * This software contains source code for use with Spansion
    00011 * components. This software is licensed by Spansion to be adapted only
    00012 * for use in systems utilizing Spansion components. Spansion shall not be
    00013 * responsible for misuse or illegal use of this software for devices not
    00014 * supported herein.  Spansion is providing this software "AS IS" and will
    00015 * not be responsible for issues arising from incorrect user implementation
    00016 * of the software.
    00017 *
    00018 * SPANSION MAKES NO WARRANTY, EXPRESS OR IMPLIED, ARISING BY LAW OR OTHERWISE,
    00019 * REGARDING THE SOFTWARE (INCLUDING ANY ACOOMPANYING WRITTEN MATERIALS),
    00020 * ITS PERFORMANCE OR SUITABILITY FOR YOUR INTENDED USE, INCLUDING,
    00021 * WITHOUT LIMITATION, THE IMPLIED WARRANTY OF MERCHANTABILITY, THE IMPLIED
    00022 * WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE OR USE, AND THE IMPLIED
    00023 * WARRANTY OF NONINFRINGEMENT.
    00024 * SPANSION SHALL HAVE NO LIABILITY (WHETHER IN CONTRACT, WARRANTY, TORT,
    00025 * NEGLIGENCE OR OTHERWISE) FOR ANY DAMAGES WHATSOEVER (INCLUDING, WITHOUT
    00026 * LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION,
    00027 * LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY LOSS) ARISING FROM USE OR
    00028 * INABILITY TO USE THE SOFTWARE, INCLUDING, WITHOUT LIMITATION, ANY DIRECT,
    00029 * INDIRECT, INCIDENTAL, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOSS OF DATA,
    00030 * SAVINGS OR PROFITS,
    00031 * EVEN IF SPANSION HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
    00032 * YOU ASSUME ALL RESPONSIBILITIES FOR SELECTION OF THE SOFTWARE TO ACHIEVE YOUR
    00033 * INTENDED RESULTS, AND FOR THE INSTALLATION OF, USE OF, AND RESULTS OBTAINED
    00034 * FROM, THE SOFTWARE.
    00035 *
    00036 * This software may be replicated in part or whole for the licensed use,
    00037 * with the restriction that this Disclaimer and Copyright notice must be
    00038 * included with each copy of this software, whether used in part or whole,
    00039 * at all times.
    00040 */
    00041 /******************************************************************************/
    00054 /******************************************************************************/
    00055 /* Include files                                                              */
    00056 /******************************************************************************/
    00057 #include "rtc.h"
    00058
    00059 #if (defined(PDL_PERIPHERAL_RTC_ACTIVE))
    00060
    00066
    00067 /******************************************************************************/
    00068 /* Local pre-processor symbols/macros ('#define')                             */
    00069 /******************************************************************************/
    00070 /* Timeout count */
    00071 #define RTC_TIMEOUT              (SystemCoreClock/10)
    00072 /* Error code for mktime */
    00073 #define RTC_ERR                 (-1)
    00074 /* convert DEC to BCD */
    00075 #define DecToBcd(x)           ((((x)/10)<<4) + ((x)%10))
    00076 /* convert BCD to DEC */
    00077 #define BcdToDec(x)           ((((x)>>4)*10) + ((x)&0x0F))
    00078
    00079 /******************************************************************************/
    00080 /* Global variable definitions (declared in header file with 'extern')        */
    00081 /******************************************************************************/
    00082
    00083 /******************************************************************************/
    00084 /* Local type definitions ('typedef')                                         */
    00085 /******************************************************************************/
    00086
    00087 /******************************************************************************/
    00088 /* Local function prototypes ('static')                                       */
    00089 /******************************************************************************/
    00090 static void RtcToTm( stc_rtc_time_t* pstcRtcTime,
    00091                             struct tm*      pstcTime);
    00092 static void RtcDisableNvic(void);
    00093 static void RtcRestoreNvic(void);
    00094
    00095 #if (PDL_INTERRUPT_ENABLE_RTC == PDL_ON)
    00096 static void RtcInitIrq(void);
    00097 static void RtcDeInitIrq(void);
    00098 #endif
    00099
    00100 /******************************************************************************/
    00101 /* Local variable definitions ('static')                                      */
    00102 /******************************************************************************/
    00103 #if (PDL_INTERRUPT_ENABLE_RTC == PDL_ON)
    00104 static stc_rtc_intern_data_t stcRtcInternData;
    00105 #endif
    00106 static uint32_t u32NvicData;
    00107
    00108 /******************************************************************************/
    00109 /* Function implementation - global ('extern') and local ('static')           */
    00110 /******************************************************************************/
    00111
    00116 static void RtcDisableNvic(void)
    00117 {
    00118     u32NvicData = NVIC->ISER[(uint32_t)((int32_t)OSC_PLL_WC_RTC_IRQn) >> 5];
    00119     NVIC->ICER[((uint32_t)(OSC_PLL_WC_RTC_IRQn) >> 5)] = (1 << ((uint32_t)(OSC_PLL_WC_RTC_IRQn) & 0x1F));
    00120 }
    00121
    00126 static void RtcRestoreNvic(void)
    00127 {
    00128     NVIC->ISER[(uint32_t)((int32_t)OSC_PLL_WC_RTC_IRQn) >> 5] = u32NvicData;
    00129 }
    00130
    00131
    00140 static void RtcToTm( stc_rtc_time_t* pstcRtcTime,
    00141                             struct tm*      pstcTime)
    00142 {
    00143     pstcTime->tm_year  = (int)(pstcRtcTime->u16Year - 1900);
    00144     pstcTime->tm_mon   = (int)(pstcRtcTime->u8Month - 1);
    00145     pstcTime->tm_mday  = (int)(pstcRtcTime->u8Day);
    00146     pstcTime->tm_sec   = (int)(pstcRtcTime->u8Second);
    00147     pstcTime->tm_min   = (int)(pstcRtcTime->u8Minute);
    00148     pstcTime->tm_hour  = (int)(pstcRtcTime->u8Hour);
    00149     pstcTime->tm_isdst = 0;
    00150 } /* RtcToTm */
    00151
    00152 #if (PDL_INTERRUPT_ENABLE_RTC == PDL_ON)
    00153
    00159 static void RtcInitIrq(void)
    00160 {
    00161     NVIC_ClearPendingIRQ(OSC_PLL_WC_RTC_IRQn);
    00162     NVIC_EnableIRQ(OSC_PLL_WC_RTC_IRQn);
    00163     NVIC_SetPriority(OSC_PLL_WC_RTC_IRQn, PDL_IRQ_LEVEL_CLK_WC_RTC);
    00164
    00165 } /* RtcInitIrq */
    00166
    00173 static void RtcDeInitIrq(void)
    00174 {
    00175     NVIC_ClearPendingIRQ(OSC_PLL_WC_RTC_IRQn);
    00176     NVIC_DisableIRQ(OSC_PLL_WC_RTC_IRQn);
    00177     NVIC_SetPriority(OSC_PLL_WC_RTC_IRQn, PDL_DEFAULT_INTERRUPT_LEVEL);
    00178 } /* RtcDeInitIrq */
    00179
    00184 void Rtc_IrqHandler(void)
    00185 {
    00186     stc_rtc_wtcr1_field_t stcWtcr1;
    00187     stc_rtc_time_t stcTime;
    00188     boolean_t bAlarmMatch = TRUE;
    00189
    00190     stcWtcr1 = FM0P_RTC->WTCR1_f;
    00191
    00192     /* Timer writing error Interrupt? */
    00193     if (TRUE == stcWtcr1.INTERI)
    00194     {
    00195         /* Clear INTERI Flag */
    00196         stcWtcr1.INTERI = FALSE;
    00197
    00198         if (NULL != stcRtcInternData.pfnTimeWrtErrCallback)
    00199         {
    00200             /* Callback */
    00201             stcRtcInternData.pfnTimeWrtErrCallback();
    00202         }
    00203     }
    00204
    00205     /* Alarm Completion? */
    00206     if (TRUE == stcWtcr1.INTALI)
    00207     {
    00208         /* Clear INTALI Flag */
    00209         stcWtcr1.INTALI = FALSE;
    00210
    00211         Rtc_ReadDateTime(&stcTime);
    00212
    00213         if(FM0P_RTC->WTCR1_f.MIEN)
    00214         {
    00215             if(FM0P_RTC->ALMIR != DecToBcd(stcTime.u8Minute)) bAlarmMatch = FALSE;
    00216         }
    00217         if(FM0P_RTC->WTCR1_f.HEN)
    00218         {
    00219             if(FM0P_RTC->ALHR != DecToBcd(stcTime.u8Hour)) bAlarmMatch = FALSE;
    00220         }
    00221         if(FM0P_RTC->WTCR1_f.DEN)
    00222         {
    00223             if(FM0P_RTC->ALDR != DecToBcd(stcTime.u8Day)) bAlarmMatch = FALSE;
    00224         }
    00225         if(FM0P_RTC->WTCR1_f.MOEN)
    00226         {
    00227             if(FM0P_RTC->ALMOR != DecToBcd(stcTime.u8Month)) bAlarmMatch = FALSE;
    00228         }
    00229         if(FM0P_RTC->WTCR1_f.YEN)
    00230         {
    00231             if(FM0P_RTC->ALYR != DecToBcd(stcTime.u16Year - 2000)) bAlarmMatch = FALSE;
    00232         }
    00233
    00234         if(bAlarmMatch == TRUE)
    00235         {
    00236             if (NULL != stcRtcInternData.pfnAlarmCallback)
    00237             {
    00238                 /* Callback */
    00239                 stcRtcInternData.pfnAlarmCallback();
    00240             }
    00241         }
    00242     }
    00243
    00244     /* Timer Interrupt? */
    00245     if (TRUE == stcWtcr1.INTTMI)
    00246     {
    00247         /* Clear INTTMI Flag */
    00248         stcWtcr1.INTTMI = FALSE;
    00249
    00250         if (NULL != stcRtcInternData.pfnTimerCallback)
    00251         {
    00252             /* Callback */
    00253             stcRtcInternData.pfnTimerCallback();
    00254         }
    00255     }
    00256
    00257     /* 0.5-Second Interrupt? */
    00258     if (TRUE == stcWtcr1.INTSSI)
    00259     {
    00260         /* Clear INTSSI Flag */
    00261         stcWtcr1.INTSSI = FALSE;
    00262
    00263         if (NULL != stcRtcInternData.pfnHalfSecondCallback)
    00264         {
    00265             /* Callback */
    00266             stcRtcInternData.pfnHalfSecondCallback();
    00267         }
    00268     }
    00269
    00270     /* One Second Interrupt? */
    00271     if (TRUE == stcWtcr1.INTSI)
    00272     {
    00273         /* Clear INTSI Flag */
    00274         stcWtcr1.INTSI = FALSE;
    00275
    00276         if (NULL != stcRtcInternData.pfnOneSecondCallback)
    00277         {
    00278             /* Callback */
    00279             stcRtcInternData.pfnOneSecondCallback();
    00280         }
    00281     }
    00282
    00283     /* One Minute Interrupt? */
    00284     if (TRUE == stcWtcr1.INTMI)
    00285     {
    00286         /* Clear INTMI Flag */
    00287         stcWtcr1.INTMI = FALSE;
    00288
    00289         if (NULL != stcRtcInternData.pfnOneMinuteCallback)
    00290         {
    00291             /* Callback */
    00292             stcRtcInternData.pfnOneMinuteCallback();
    00293         }
    00294     }
    00295
    00296     /* One Hour Interrupt? */
    00297     if (TRUE == stcWtcr1.INTHI)
    00298     {
    00299         /* Clear INTHI Flag */
    00300         stcWtcr1.INTHI = FALSE;
    00301
    00302         if (NULL != stcRtcInternData.pfnOneHourCallback)
    00303         {
    00304             /* Callback */
    00305             stcRtcInternData.pfnOneHourCallback();
    00306         }
    00307     }
    00308
    00309     FM0P_RTC->WTCR1_f = stcWtcr1;
    00310 } /* RtcIrqHandler */
    00311
    00325 en_result_t Rtc_EnableInt(stc_rtc_int_sel_t* pstcIntSel, stc_rtc_int_cb_t* pstcIntCb)
    00326 {
    00327     stc_rtc_wtcr1_field_t stcWtcr1 ;
    00328
    00329     stcWtcr1 = FM0P_RTC->WTCR1_f;
    00330     /* Check for valid pointer */
    00331     if ((NULL == pstcIntSel) || (NULL == pstcIntCb))
    00332     {
    00333         return ErrorInvalidParameter;
    00334     }
    00335     /* Enable timer rewrite error interrupt */
    00336     if (TRUE == pstcIntSel->TimeRewriteErrorInt)
    00337     {
    00338         stcWtcr1.INTERIE = TRUE;
    00339         stcRtcInternData.pfnTimeWrtErrCallback = pstcIntCb->pfnTimeWrtErrCallback;
    00340     }
    00341
    00342     /* Enable alarm coincidence interrupt */
    00343     if (TRUE == pstcIntSel->AlarmInt)
    00344     {
    00345         stcWtcr1.INTALIE = TRUE;
    00346         stcRtcInternData.pfnAlarmCallback = pstcIntCb->pfnAlarmCallback;
    00347     }
    00348
    00349     /* Enable timer underflow detection interrupt */
    00350     if (TRUE == pstcIntSel->TimerInt)
    00351     {
    00352         stcWtcr1.INTTMIE = TRUE;
    00353         stcRtcInternData.pfnTimerCallback = pstcIntCb->pfnTimerCallback;
    00354     }
    00355
    00356     /* Enable every hour interrupt */
    00357     if (TRUE == pstcIntSel->OneHourInt)
    00358     {
    00359         stcWtcr1.INTHIE = TRUE;
    00360         stcRtcInternData.pfnOneHourCallback = pstcIntCb->pfnOneHourCallback;
    00361     }
    00362
    00363     /* Enable every minute interrupt */
    00364     if (TRUE == pstcIntSel->OneMinuteInt)
    00365     {
    00366         stcWtcr1.INTMIE = TRUE;
    00367         stcRtcInternData.pfnOneMinuteCallback = pstcIntCb->pfnOneMinuteCallback;
    00368     }
    00369
    00370     /* Enable every second interrupt */
    00371     if (TRUE == pstcIntSel->OneSecondInt)
    00372     {
    00373         stcWtcr1.INTSIE = TRUE;
    00374         stcRtcInternData.pfnOneSecondCallback = pstcIntCb->pfnOneSecondCallback;
    00375     }
    00376
    00377     /* Enable every 0.5 second interrupt */
    00378     if (TRUE == pstcIntSel->HalfSecondInt)
    00379     {
    00380         stcWtcr1.INTSSIE = TRUE;
    00381         stcRtcInternData.pfnHalfSecondCallback = pstcIntCb->pfnHalfSecondCallback;
    00382     }
    00383
    00384     FM0P_RTC->WTCR1_f = stcWtcr1;  /* Update WTCR13 */
    00385
    00386     RtcInitIrq();
    00387
    00388     return (Ok);
    00389 } /* Rtc_EnableDisableInterrupts */
    00390
    00401 en_result_t Rtc_DisableInt(stc_rtc_int_sel_t* pstcIntSel)
    00402 {
    00403     stc_rtc_wtcr1_field_t stcWtcr1 ;
    00404     stcWtcr1 = FM0P_RTC->WTCR1_f;
    00405
    00406     /* Check for valid pointer */
    00407     if (NULL == pstcIntSel)
    00408     {
    00409         return ErrorInvalidParameter;
    00410     }
    00411
    00412     /* Enable timer rewrite error interrupt */
    00413     if (TRUE == pstcIntSel->TimeRewriteErrorInt)
    00414     {
    00415         stcWtcr1.INTERIE = FALSE;
    00416     }
    00417
    00418     /* Enable alarm coincidence interrupt */
    00419     if (TRUE == pstcIntSel->AlarmInt)
    00420     {
    00421         stcWtcr1.INTALIE = FALSE;
    00422     }
    00423
    00424     /* Enable timer underflow detection interrupt */
    00425     if (TRUE == pstcIntSel->TimerInt)
    00426     {
    00427         stcWtcr1.INTTMIE = FALSE;
    00428     }
    00429
    00430     /* Enable every hour interrupt */
    00431     if (TRUE == pstcIntSel->OneHourInt)
    00432     {
    00433         stcWtcr1.INTHIE = FALSE;
    00434     }
    00435
    00436     /* Enable every minute interrupt */
    00437     if (TRUE == pstcIntSel->OneMinuteInt)
    00438     {
    00439         stcWtcr1.INTMIE = FALSE;;
    00440     }
    00441
    00442     /* Enable every second interrupt */
    00443     if (TRUE == pstcIntSel->OneSecondInt)
    00444     {
    00445         stcWtcr1.INTSIE = FALSE;
    00446     }
    00447
    00448     /* Enable every 0.5 second interrupt */
    00449     if (TRUE == pstcIntSel->HalfSecondInt)
    00450     {
    00451         stcWtcr1.INTSSIE = FALSE;
    00452     }
    00453
    00454     FM0P_RTC->WTCR1_f = stcWtcr1;  /* Update WTCR13 */
    00455
    00456     if((FM0P_RTC->WTCR1 & 0xFF000000u) != 0u)
    00457     {
    00458         return Ok;
    00459     }
    00460
    00461     if(FM0P_WC->WCCR_f.WCIE != 0)
    00462     {
    00463         return Ok;
    00464     }
    00465
    00466     /* Only when RTC and WC interrupt are all disabled, disable IRQ */
    00467     RtcDeInitIrq();
    00468
    00469     return Ok;
    00470 } /* Rtc_DisableInt */
    00471
    00472 #endif
    00473
    00488 en_result_t Rtc_Init(stc_rtc_config_t*       pstcConfig)
    00489 {
    00490     uint32_t u32Timeout = RTC_TIMEOUT;
    00491
    00492     if(pstcConfig == NULL)
    00493     {
    00494         return ErrorInvalidParameter;
    00495     }
    00496
    00497     /* For initialization: Force all bits of WTCR1 and WTCR2 (inclusive ST bit) */
    00498     /*   to '0'  */
    00499     FM0P_RTC->WTCR1 = 0;
    00500     FM0P_RTC->WTCR2 = 0;
    00501
    00502     /* Select source clock for RTC */
    00503     switch (pstcConfig->enClkSel)
    00504     {
    00505         case RtcUseSubClk:
    00506             /* Select sub clock as source clock */
    00507             FM0P_RTC->WTCLKS_f.WTCLKS = 0u;
    00508             /* Wait until sub clock stable */
    00509             while(1)
    00510             {
    00511                 if(FM0P_RTC->WTCLKM_f.WTCLKM == 0x02u)
    00512                 {
    00513                     break;
    00514                 }
    00515                 else
    00516                 {
    00517                     u32Timeout--;
    00518                     if(u32Timeout == 0)
    00519                     {
    00520                         return ErrorTimeout;
    00521                     }
    00522                 }
    00523             }
    00524
    00525             FM0P_RTC->WTBR = (__CLKSO/4) - 1; /* set 0.5s as sub-second interval */
    00526             break;
    00527         case RtcuseMainClk:
    00528             /* Select main clock as source clock */
    00529             FM0P_RTC->WTCLKS_f.WTCLKS = 1u;
    00530             /* Wait until main clock stable */
    00531             while(1)
    00532             {
    00533                 if(FM0P_RTC->WTCLKM_f.WTCLKM == 0x03u)
    00534                 {
    00535                     break;
    00536                 }
    00537                 else
    00538                 {
    00539                     u32Timeout--;
    00540                     if(u32Timeout == 0)
    00541                     {
    00542                         return ErrorTimeout;
    00543                     }
    00544                 }
    00545             }
    00546             FM0P_RTC->WTBR = (__CLKMO/4) - 1; /* set 0.5s as sub-second interval */
    00547             break;
    00548         default:
    00549             return ErrorInvalidParameter;
    00550     }
    00551
    00552     if(pstcConfig->bEnSuboutDivider == TRUE)
    00553     {
    00554         /* Disable divider */
    00555         FM0P_RTC->WTDIVEN_f.WTDIVEN = 0;
    00556
    00557         /* Set Divider ratio */
    00558         switch (pstcConfig->enDividerRatio)
    00559         {
    00560             case RtcDivRatio1:
    00561             case RtcDivRatio2:
    00562             case RtcDivRatio4:
    00563             case RtcDivRatio8:
    00564             case RtcDivRatio16:
    00565             case RtcDivRatio32:
    00566             case RtcDivRatio64:
    00567             case RtcDivRatio128:
    00568             case RtcDivRatio256:
    00569             case RtcDivRatio512:
    00570             case RtcDivRatio1024:
    00571             case RtcDivRatio2048:
    00572             case RtcDivRatio4096:
    00573             case RtcDivRatio8192:
    00574             case RtcDivRatio16384:
    00575             case RtcDivRatio32768:
    00576                 FM0P_RTC->WTDIV = pstcConfig->enDividerRatio;
    00577                 break;
    00578             default:
    00579                 return  ErrorInvalidParameter;
    00580         }
    00581
    00582         /*  Enable divider */
    00583         u32Timeout = RTC_TIMEOUT;
    00584         FM0P_RTC->WTDIVEN_f.WTDIVEN = 1;
    00585         while(TRUE != FM0P_RTC->WTDIVEN_f.WTDIVRDY)
    00586         {
    00587             u32Timeout--;
    00588             if(u32Timeout == 0)
    00589             {
    00590                 return ErrorInvalidParameter;
    00591             }
    00592         }
    00593     }
    00594
    00595     /* Initial frequency correction module */
    00596     if(pstcConfig->bInitFreqCorr == TRUE)
    00597     {
    00598         if(pstcConfig->stcFreqCorrConfig.u16FreqCorrValue > RTC_MAX_FREQ_CORR_VALUE)
    00599         {
    00600             return ErrorInvalidParameter;
    00601         }
    00602         FM0P_RTC->WTCAL = pstcConfig->stcFreqCorrConfig.u16FreqCorrValue;
    00603
    00604         if(pstcConfig->stcFreqCorrConfig.u16FreqCorrCycle > RTC_MAX_FREQ_CORR_CYCLE_SET_VALUE)
    00605         {
    00606             return ErrorInvalidParameter;
    00607         }
    00608         FM0P_RTC->WTCALPRD = pstcConfig->stcFreqCorrConfig.u16FreqCorrCycle;
    00609     }
    00610
    00611     /* Configure RTCCO output */
    00612     if (pstcConfig->enRtccoSel == RtccoOutput2Hz)
    00613     {
    00614         FM0P_RTC->WTCOSEL_f.WTCOSEL = 0;
    00615     }
    00616     else
    00617     {
    00618         FM0P_RTC->WTCOSEL_f.WTCOSEL = 1;
    00619     }
    00620
    00621     /* Initialize time and date */
    00622     if(pstcConfig->bInitTimeDate == TRUE)
    00623     {
    00624         FM0P_RTC->WTSR  = DecToBcd(pstcConfig->stcTimeDate.u8Second);
    00625         FM0P_RTC->WTMIR = DecToBcd(pstcConfig->stcTimeDate.u8Minute);
    00626         FM0P_RTC->WTHR  = DecToBcd(pstcConfig->stcTimeDate.u8Hour);
    00627         FM0P_RTC->WTDR  = DecToBcd(pstcConfig->stcTimeDate.u8Day);
    00628         FM0P_RTC->WTMOR = DecToBcd(pstcConfig->stcTimeDate.u8Month);
    00629         FM0P_RTC->WTYR  = DecToBcd(pstcConfig->stcTimeDate.u16Year - 2000);
    00630         FM0P_RTC->WTDW  = DecToBcd(pstcConfig->stcTimeDate.u8DayOfWeek);
    00631     }
    00632
    00633     /* Initialize Alarm */
    00634     if(pstcConfig->bInitAlarm == TRUE)
    00635     {
    00636         FM0P_RTC->ALMIR = DecToBcd(pstcConfig->stcAlarm.u8Minute);
    00637         FM0P_RTC->ALHR  = DecToBcd(pstcConfig->stcAlarm.u8Hour);
    00638         FM0P_RTC->ALDR  = DecToBcd(pstcConfig->stcAlarm.u8Day);
    00639         FM0P_RTC->ALMOR = DecToBcd(pstcConfig->stcAlarm.u8Month);
    00640         FM0P_RTC->ALYR  = DecToBcd(pstcConfig->stcAlarm.u16Year - 2000);
    00641     }
    00642
    00643     if(pstcConfig->bInitTimer == TRUE)
    00644     {
    00645         switch (pstcConfig->stcTimer.enMode)
    00646         {
    00647             case RtcTimerOneshot:
    00648                 FM0P_RTC->WTCR2_f.TMEN = 0u;
    00649                 break;
    00650             case RtcTimerPeriod:
    00651                 FM0P_RTC->WTCR2_f.TMEN = 1u;
    00652                 break;
    00653             default:
    00654                 return ErrorInvalidParameter;
    00655         }
    00656
    00657         if(pstcConfig->stcTimer.u32TimerCycle > RTC_MAX_TIMER_SET_VALUE)
    00658         {
    00659             return ErrorInvalidParameter;
    00660         }
    00661
    00662         FM0P_RTC->WTTR = (pstcConfig->stcTimer.u32TimerCycle*2) - 1;
    00663
    00664     }
    00665
    00666     return (Ok);
    00667 } /* Rtc_Init */
    00668
    00678 en_result_t Rtc_DeInit(void)
    00679 {
    00680     /* Set all registers of RTC instance to '0' */
    00681     FM0P_RTC->WTCAL    = 0;
    00682     FM0P_RTC->WTCALEN  = 0;
    00683     FM0P_RTC->WTDIV    = 0;
    00684     FM0P_RTC->WTDIVEN  = 0;
    00685     FM0P_RTC->WTCALPRD = 0;
    00686     FM0P_RTC->WTCOSEL  = 0;
    00687     FM0P_RTC->WTSR     = 0;
    00688     FM0P_RTC->WTMIR    = 0;
    00689     FM0P_RTC->WTHR     = 0;
    00690     FM0P_RTC->WTDR     = 0;
    00691     FM0P_RTC->WTDW     = 0;
    00692     FM0P_RTC->WTMOR    = 0;
    00693     FM0P_RTC->WTYR     = 0;
    00694     FM0P_RTC->ALMIR    = 0;
    00695     FM0P_RTC->ALHR     = 0;
    00696     FM0P_RTC->ALDR     = 0;
    00697     FM0P_RTC->ALMOR    = 0;
    00698     FM0P_RTC->ALYR     = 0;
    00699
    00700     return (Ok);
    00701 } /* Rtc_DeInit */
    00702
    00703
    00726 en_result_t Rtc_EnableFunc(en_rtc_func_t enFunc)
    00727 {
    00728     switch (enFunc)
    00729     {
    00730         case RtcCount:
    00731             FM0P_RTC->WTCR1_f.ST = 1u;
    00732             break;
    00733         case RtcTimer:
    00734             FM0P_RTC->WTCR2_f.TMST = 1u;
    00735             break;
    00736         case RtcFreqCorr:
    00737             FM0P_RTC->WTCALEN_f.WTCALEN = 1u;
    00738             break;
    00739         case RtcAlarmYearEn:
    00740             FM0P_RTC->WTCR1_f.YEN = 1u;
    00741             break;
    00742         case RtcAlarmMonthEn:
    00743             FM0P_RTC->WTCR1_f.MOEN = 1u;
    00744             break;
    00745         case RtcAlarmDayEn:
    00746             FM0P_RTC->WTCR1_f.DEN = 1u;
    00747             break;
    00748         case RtcAlarmHourEn:
    00749             FM0P_RTC->WTCR1_f.HEN = 1u;
    00750             break;
    00751         case RtcAlarmMinEn:
    00752             FM0P_RTC->WTCR1_f.MIEN = 1u;
    00753             break;
    00754         default:
    00755             return ErrorInvalidParameter;
    00756     }
    00757
    00758     return Ok;
    00759 }
    00760
    00783 en_result_t Rtc_DisableFunc(en_rtc_func_t enFunc)
    00784 {
    00785     switch (enFunc)
    00786     {
    00787         case RtcCount:
    00788             FM0P_RTC->WTCR1_f.ST = 0u;
    00789             break;
    00790         case RtcTimer:
    00791             FM0P_RTC->WTCR2_f.TMST = 0u;
    00792             break;
    00793         case RtcFreqCorr:
    00794             FM0P_RTC->WTCALEN_f.WTCALEN = 0u;
    00795             break;
    00796         case RtcAlarmYearEn:
    00797             FM0P_RTC->WTCR1_f.YEN = 0u;
    00798             break;
    00799         case RtcAlarmMonthEn:
    00800             FM0P_RTC->WTCR1_f.MOEN = 0u;
    00801             break;
    00802         case RtcAlarmDayEn:
    00803             FM0P_RTC->WTCR1_f.DEN = 0u;
    00804             break;
    00805         case RtcAlarmHourEn:
    00806             FM0P_RTC->WTCR1_f.HEN = 0u;
    00807             break;
    00808         case RtcAlarmMinEn:
    00809             FM0P_RTC->WTCR1_f.MIEN = 0u;
    00810             break;
    00811         default:
    00812             return ErrorInvalidParameter;
    00813     }
    00814
    00815     return Ok;
    00816 }
    00817
    00855 boolean_t Rtc_GetStatus(en_rtc_status_t enStatus)
    00856 {
    00857     boolean_t bRet = FALSE;
    00858
    00859     switch(enStatus)
    00860     {
    00861         case RtcRewriteError:
    00862             (FM0P_RTC->WTCR1_f.INTERI == 1) ? (bRet = TRUE) : (bRet = FALSE);
    00863             break;
    00864         case RtcAlarmElementMatch:
    00865             (FM0P_RTC->WTCR1_f.INTALI == 1) ? (bRet = TRUE) : (bRet = FALSE);
    00866             break;
    00867         case RtcTimerUnderFlow:
    00868             (FM0P_RTC->WTCR1_f.INTTMI == 1) ? (bRet = TRUE) : (bRet = FALSE);
    00869             break;
    00870         case RtcOneHourFlag:
    00871             (FM0P_RTC->WTCR1_f.INTHI == 1) ? (bRet = TRUE) : (bRet = FALSE);
    00872             break;
    00873         case RtcOneMiniteFlag:
    00874             (FM0P_RTC->WTCR1_f.INTMI == 1) ? (bRet = TRUE) : (bRet = FALSE);
    00875             break;
    00876         case RtcOneSecondFlag:
    00877             (FM0P_RTC->WTCR1_f.INTSI == 1) ? (bRet = TRUE) : (bRet = FALSE);
    00878             break;
    00879         case RtcHalfSecondFlag:
    00880             (FM0P_RTC->WTCR1_f.INTSSI == 1) ? (bRet = TRUE) : (bRet = FALSE);
    00881             break;
    00882         case RtcRunStatus:
    00883             (FM0P_RTC->WTCR1_f.RUN == 1) ? (bRet = TRUE) : (bRet = FALSE);
    00884             break;
    00885         case RtcTimerStatus:
    00886             (FM0P_RTC->WTCR2_f.TMRUN == 1) ? (bRet = TRUE) : (bRet = FALSE);
    00887             break;
    00888         default:
    00889             break;
    00890     }
    00891
    00892     return bRet;
    00893 }
    00894
    00918 en_result_t Rtc_ClrStatus(en_rtc_status_t enStatus)
    00919 {
    00920     switch(enStatus)
    00921     {
    00922         case RtcRewriteError:
    00923             FM0P_RTC->WTCR1_f.INTERI = 0;
    00924             break;
    00925         case RtcAlarmElementMatch:
    00926             FM0P_RTC->WTCR1_f.INTALI = 0;
    00927             break;
    00928         case RtcTimerUnderFlow:
    00929             FM0P_RTC->WTCR1_f.INTTMI = 0;
    00930             break;
    00931         case RtcOneHourFlag:
    00932             FM0P_RTC->WTCR1_f.INTHI = 0;
    00933             break;
    00934         case RtcOneMiniteFlag:
    00935             FM0P_RTC->WTCR1_f.INTMI = 0;
    00936             break;
    00937         case RtcOneSecondFlag:
    00938             FM0P_RTC->WTCR1_f.INTSI = 0;
    00939             break;
    00940         case RtcHalfSecondFlag:
    00941             FM0P_RTC->WTCR1_f.INTSSI = 0;
    00942             break;
    00943         case RtcRunStatus:
    00944         case RtcTimerStatus:
    00945             break;
    00946         default:
    00947             return ErrorInvalidParameter;
    00948     }
    00949
    00950     return Ok;
    00951 }
    00952
    00957 void Rtc_Reset(void)
    00958 {
    00959     FM0P_RTC->WTCR1_f.SRST = 1;
    00960 }
    00961
    00978 en_result_t Rtc_SetDateTime(stc_rtc_time_t* pstcTimeDate, boolean_t bContinue)
    00979 {
    00980     uint32_t u32TimeOut;
    00981
    00982      /* Don't set time and date with this function before RTC starts */
    00983     if(FM0P_RTC->WTCR1_f.RUN == 1)
    00984     {
    00985         return ErrorInvalidMode;
    00986     }
    00987
    00988     if(pstcTimeDate == NULL)
    00989     {
    00990         return ErrorInvalidParameter;
    00991     }
    00992
    00993     if(FM0P_RTC->WTCR1_f.BUSY == 1)
    00994     {
    00995         /*  Wait until rewrite idle */
    00996         u32TimeOut = RTC_TIMEOUT;
    00997         while(1)
    00998         {
    00999             if(bContinue == TRUE)
    01000             {
    01001                 if((FM0P_RTC->WTCR1_f.BUSY == 0) && (FM0P_RTC->WTCR1_f.SCST == 0))
    01002                 {
    01003                     break;
    01004                 }
    01005             }
    01006             else
    01007             {
    01008                 if((FM0P_RTC->WTCR1_f.BUSY == 0) && (FM0P_RTC->WTCR1_f.SCRST == 0))
    01009                 {
    01010                     break;
    01011                 }
    01012             }
    01013             u32TimeOut--;
    01014             if(u32TimeOut == 0)
    01015             {
    01016                 return ErrorTimeout;
    01017             }
    01018         }
    01019     }
    01020
    01021     RtcDisableNvic();
    01022
    01023     if(bContinue == TRUE)
    01024     {
    01025         /* Stop 1 second output */
    01026         FM0P_RTC->WTCR1_f.SCST = 1;
    01027     }
    01028     else
    01029     {
    01030         /* Reset 1 second counter */
    01031         FM0P_RTC->WTCR1_f.SCRST = 1;
    01032     }
    01033
    01034     /* Set time and date */
    01035     FM0P_RTC->WTSR  = DecToBcd(pstcTimeDate->u8Second);
    01036     FM0P_RTC->WTMIR = DecToBcd(pstcTimeDate->u8Minute);
    01037     FM0P_RTC->WTHR  = DecToBcd(pstcTimeDate->u8Hour);
    01038     FM0P_RTC->WTDR  = DecToBcd(pstcTimeDate->u8Day);
    01039     FM0P_RTC->WTMOR = DecToBcd(pstcTimeDate->u8Month);
    01040     FM0P_RTC->WTYR  = DecToBcd(pstcTimeDate->u16Year - 2000);
    01041     FM0P_RTC->WTDW  = DecToBcd(pstcTimeDate->u8DayOfWeek);
    01042
    01043     if(bContinue == TRUE)
    01044     {
    01045         /* Refresh the time and date */
    01046         FM0P_RTC->WTCR1_f.SCST = 0;
    01047     }
    01048     else
    01049     {
    01050         /* Refresh the time and date  */
    01051         FM0P_RTC->WTCR1_f.SCRST = 0;
    01052     }
    01053
    01054     RtcRestoreNvic();
    01055
    01056     /* Wait until the transfer from time and date registers to counters end */
    01057     u32TimeOut = RTC_TIMEOUT;
    01058     while(1)
    01059     {
    01060         if(bContinue == TRUE)
    01061         {
    01062             if((FM0P_RTC->WTCR1_f.BUSY == 0) && (FM0P_RTC->WTCR1_f.SCST == 0))
    01063             {
    01064                 break;
    01065             }
    01066         }
    01067         else
    01068         {
    01069             if((FM0P_RTC->WTCR1_f.BUSY == 0) && (FM0P_RTC->WTCR1_f.SCRST == 0))
    01070             {
    01071                 break;
    01072             }
    01073         }
    01074         u32TimeOut--;
    01075         if(u32TimeOut == 0)
    01076         {
    01077             return ErrorTimeout;
    01078         }
    01079     }
    01080
    01081     return Ok;
    01082 }
    01083
    01096 en_result_t Rtc_ReadDateTime(stc_rtc_time_t* pstcTimeDate)
    01097 {
    01098     uint32_t u32TimeOut;
    01099     uint8_t  u8DayOfWeek, u8BcdSec, u8BcdMin, u8BcdHour, u8Day, u8Month, u16Year = 0;
    01100
    01101     if(pstcTimeDate == NULL)
    01102     {
    01103         return ErrorInvalidParameter;
    01104     }
    01105
    01106     RtcDisableNvic();
    01107
    01108     if(FM0P_RTC->WTCR2_f.CREAD == 1) /* read is in process? */
    01109     {
    01110         ;  /* Already been read */
    01111     }
    01112     else
    01113     {
    01114         /* Start read */
    01115         FM0P_RTC->WTCR2_f.CREAD = 1;
    01116
    01117     }
    01118
    01119     /* Wait until read finish */
    01120     u32TimeOut = RTC_TIMEOUT;
    01121     while(1)
    01122     {
    01123         if(FM0P_RTC->WTCR2_f.CREAD == 0)
    01124         {
    01125             break;
    01126         }
    01127         u32TimeOut --;
    01128         if(u32TimeOut == 0)
    01129         {
    01130             RtcRestoreNvic();
    01131             return ErrorTimeout;
    01132         }
    01133
    01134     }
    01135
    01136     /* Read time and date */
    01137     u8BcdSec  = FM0P_RTC->WTSR;
    01138     u8BcdMin  = FM0P_RTC->WTMIR;
    01139     u8BcdHour = FM0P_RTC->WTHR;
    01140     u8Day     = FM0P_RTC->WTDR;
    01141     u8Month   = FM0P_RTC->WTMOR;
    01142     u16Year    = FM0P_RTC->WTYR;
    01143     u8DayOfWeek = FM0P_RTC->WTDW;
    01144
    01145     pstcTimeDate->u8Second = BcdToDec(u8BcdSec);
    01146     pstcTimeDate->u8Minute = BcdToDec(u8BcdMin);
    01147     pstcTimeDate->u8Hour   = BcdToDec(u8BcdHour);
    01148     pstcTimeDate->u8Day    = BcdToDec(u8Day);
    01149     pstcTimeDate->u8Month  = BcdToDec(u8Month);
    01150     pstcTimeDate->u16Year  = BcdToDec(u16Year) + 2000;
    01151     pstcTimeDate->u8DayOfWeek = BcdToDec(u8DayOfWeek);
    01152
    01153     RtcRestoreNvic();
    01154
    01155     return Ok;
    01156 }
    01157
    01168 en_result_t Rtc_SetAlarmDateTime(stc_rtc_alarm_t* pstcAlarm)
    01169 {
    01170     if(pstcAlarm == NULL)
    01171     {
    01172         return ErrorInvalidParameter;
    01173     }
    01174
    01175     FM0P_RTC->ALMIR = DecToBcd(pstcAlarm->u8Minute);
    01176     FM0P_RTC->ALHR  = DecToBcd(pstcAlarm->u8Hour);
    01177     FM0P_RTC->ALDR  = DecToBcd(pstcAlarm->u8Day);
    01178     FM0P_RTC->ALMOR = DecToBcd(pstcAlarm->u8Month);
    01179     FM0P_RTC->ALYR  = DecToBcd(pstcAlarm->u16Year - 2000);
    01180
    01181     return Ok;
    01182 }
    01183
    01194 en_result_t Rtc_GetAlarmDateTime(stc_rtc_alarm_t* pstcAlarm)
    01195 {
    01196     uint8_t  u8BcdMin, u8BcdHour, u8Day, u8Month, u8Year;
    01197     if(pstcAlarm == NULL)
    01198     {
    01199         return ErrorInvalidParameter;
    01200     }
    01201
    01202     u8BcdMin  = FM0P_RTC->ALMIR;
    01203     u8BcdHour = FM0P_RTC->ALHR;
    01204     u8Day     = FM0P_RTC->ALDR;
    01205     u8Month   = FM0P_RTC->ALMOR;
    01206     u8Year    = FM0P_RTC->ALYR;
    01207
    01208     pstcAlarm->u8Minute = BcdToDec(u8BcdMin);
    01209     pstcAlarm->u8Hour   = BcdToDec(u8BcdHour);
    01210     pstcAlarm->u8Day    = BcdToDec(u8Day);
    01211     pstcAlarm->u8Month  = BcdToDec(u8Month);
    01212     pstcAlarm->u16Year   = BcdToDec(u8Year) + 2000;
    01213
    01214     return Ok;
    01215 }
    01216
    01230 en_result_t Rtc_SetDayOfWeek(stc_rtc_time_t* pstcRtcTime)
    01231 {
    01232     en_result_t enResult;
    01233     struct tm stcTime;
    01234
    01235     enResult = ErrorInvalidParameter;
    01236
    01237     /* Check for NULL pointer */
    01238     if (NULL != pstcRtcTime)
    01239     {
    01240         enResult = Ok;
    01241         /* Convert RTC time structure to time.h tm structure */
    01242         RtcToTm(pstcRtcTime, &stcTime);
    01243
    01244         /* Calculated raw time (UNIX time) is error */
    01245         if ((time_t)RTC_ERR == mktime(&stcTime))
    01246         {
    01247             enResult = ErrorInvalidParameter;
    01248         }
    01249
    01250         if (Ok == enResult)
    01251         {
    01252             /* Set calculated the day of week */
    01253             pstcRtcTime->u8DayOfWeek = (uint8_t)(stcTime.tm_wday);
    01254         }
    01255     }
    01256
    01257     return (enResult);
    01258 } /* Rtc_SetDayOfWeek */
    01259
    01272 en_result_t Rtc_SetTimerCycle(uint32_t u32TimerCycle)
    01273 {
    01274     if(u32TimerCycle > RTC_MAX_TIMER_SET_VALUE)
    01275     {
    01276         return ErrorInvalidParameter;
    01277     }
    01278
    01279     FM0P_RTC->WTTR = (u32TimerCycle*2) - 1;
    01280
    01281     return Ok;
    01282 }
    01283
    01294 en_result_t Rtc_SetFreqCorrValue(uint16_t u16Value)
    01295 {
    01296     if(u16Value > RTC_MAX_FREQ_CORR_VALUE)
    01297     {
    01298         return ErrorInvalidParameter;
    01299     }
    01300
    01301     FM0P_RTC->WTCAL = u16Value;
    01302
    01303     return Ok;
    01304 }
    01305
    01307
    01308 #endif /* #if (defined(PDL_PERIPHERAL_RTC_ACTIVE)) */
    01309 /******************************************************************************/
    01310 /* EOF (not truncated)                                                        */
    01311 /******************************************************************************/