1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153 |
- /**************************************************************************//**
- * @file RTC.c
- * @brief N9H30 RTC driver source file
- *
- * @note
- * SPDX-License-Identifier: Apache-2.0
- * Copyright (C) 2018 Nuvoton Technology Corp. All rights reserved.
- *****************************************************************************/
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include "N9H30.h"
- #include "nu_sys.h"
- #include "nu_rtc.h"
- /** @addtogroup N9H30_Device_Driver N9H30 Device Driver
- @{
- */
- /** @addtogroup N9H30_RTC_Driver RTC Driver
- @{
- */
- /** @addtogroup N9H30_RTC_EXPORTED_FUNCTIONS RTC Exported Functions
- @{
- */
- /// @cond HIDDEN_SYMBOLS
- static CHAR g_chHourMode = 0;
- static BOOL volatile g_bIsEnableTickInt = FALSE;
- static BOOL volatile g_bIsEnableAlarmInt = FALSE;
- static UINT32 volatile g_u32Reg, g_u32Reg1, g_u32hiYear, g_u32loYear, g_u32hiMonth, g_u32loMonth, g_u32hiDay, g_u32loDay;
- static UINT32 volatile g_u32hiHour, g_u32loHour, g_u32hiMin, g_u32loMin, g_u32hiSec, g_u32loSec;
- UINT32 volatile i, Wait;
- VOID RTC_Check(void)
- {
- i = 0;
- Wait = inp32(REG_RTC_INTSTS) & RTC_INTSTS_REGWRBUSY_Msk;
- while (Wait == RTC_INTSTS_REGWRBUSY_Msk)
- {
- Wait = inp32(REG_RTC_INTSTS) & RTC_INTSTS_REGWRBUSY_Msk;
- i++;
- if (i > RTC_WAIT_COUNT)
- {
- break;
- }
- }
- }
- /// @endcond HIDDEN_SYMBOLS
- /**
- * @brief Set 32k Frequency Compensation Data
- *
- * @param[in] i32FrequencyX100 Specify the RTC clock X100, ex: 3277365 means 32773.65.
- *
- * @return E_RTC_ERR_FCR_VALUE Wrong Compensation VALUE
- * E_RTC_SUCCESS Success
- *
- * @details This API is used to compensate the 32 kHz frequency by current LXT frequency for RTC application.
- */
- UINT32 RTC_DoFrequencyCompensation(INT32 i32FrequencyX100)
- {
- INT32 i32RegInt, i32RegFra;
- UINT32 u32Reg;
- /* Compute integer and fraction for RTC FCR register */
- i32RegInt = (i32FrequencyX100 / 100) - RTC_FCR_REFERENCE;
- i32RegFra = (((i32FrequencyX100 % 100)) * 60) / 100;
- /* Judge Integer part is reasonable */
- if ((i32RegInt < 0) | (i32RegInt > 15))
- {
- return E_RTC_ERR_FCR_VALUE;
- }
- u32Reg = (uint32_t)((i32RegInt << 8) | i32RegFra);
- RTC_WriteEnable(1);
- outp32(REG_RTC_FREQADJ, u32Reg);
- RTC_Check();
- return E_RTC_SUCCESS;
- }
- /**
- * @brief RTC access register enable
- *
- * @param[in] bEnable 1: Enable access register
- * 0: Disable access register
- *
- * @retval E_RTC_ERR_EIO Time-out error
- * @retval E_RTC_SUCCESS Success
- *
- */
- UINT32 RTC_WriteEnable(BOOL bEnable)
- {
- INT32 volatile i32i;
- RTC_Check();
- if (bEnable)
- {
- outp32(REG_RTC_RWEN, RTC_WRITE_KEY);
- RTC_Check();
- for (i32i = 0 ; i32i < RTC_WAIT_COUNT ; i32i++)
- {
- /*-------------------------------------------------------------------------------------------------*/
- /* check RTC_RWEN[16] to find out RTC write enable */
- /*-------------------------------------------------------------------------------------------------*/
- if (inp32(REG_RTC_RWEN) & 0x10000)
- {
- break;
- }
- }
- if (i32i == RTC_WAIT_COUNT)
- {
- //sysprintf ("\nRTC: 3, set write enable FAILED!\n");
- return E_RTC_ERR_EIO;
- }
- }
- else
- {
- for (i32i = 0 ; i32i < RTC_WAIT_COUNT ; i32i++)
- {
- if (inp32(REG_RTC_RWEN) == 0)
- {
- break;
- }
- }
- }
- return E_RTC_SUCCESS;
- }
- /**
- * @brief Initial RTC and install ISR
- * @retval E_RTC_ERR_EIO Initial RTC time-out
- * @retval E_RTC_SUCCESS Success
- *
- */
- UINT32 RTC_Init(void)
- {
- INT32 i32i;
- /*-----------------------------------------------------------------------------------------------------*/
- /* When RTC is power on, write 0xa5eb1357 to RTC_INIR to reset all logic. */
- /*-----------------------------------------------------------------------------------------------------*/
- outp32(REG_RTC_INIT, RTC_INIT_KEY);
- RTC_Check();
- for (i32i = 0 ; i32i < RTC_WAIT_COUNT ; i32i++)
- {
- if (inp32(REG_RTC_INIT) & 0x01)
- {
- /* Check RTC_INIR[0] to find out RTC reset signal */
- break;
- }
- }
- if (i32i == RTC_WAIT_COUNT)
- {
- return E_RTC_ERR_EIO;
- }
- /*-----------------------------------------------------------------------------------------------------*/
- /* Install RTC ISR */
- /*-----------------------------------------------------------------------------------------------------*/
- outp32(REG_RTC_RWEN, RTC_WRITE_KEY);
- RTC_Check();
- for (i32i = 0 ; i32i < RTC_WAIT_COUNT ; i32i++)
- {
- /*-------------------------------------------------------------------------------------------------*/
- /* check RTC_RWEN[16] to find out RTC write enable */
- /*-------------------------------------------------------------------------------------------------*/
- if (inp32(REG_RTC_RWEN) & 0x10000)
- {
- break;
- }
- }
- if (i32i == RTC_WAIT_COUNT)
- {
- return E_RTC_ERR_EIO;
- }
- return E_RTC_SUCCESS;
- }
- /**
- * @brief Set Current Timer
- *
- * @param[in] *sPt Specify the time property and current time. It includes:
- * - u8cClockDisplay: \ref RTC_CLOCK_12 / \ref RTC_CLOCK_24
- * - u8cAmPm: \ref RTC_AM / \ref RTC_PM
- * - u32cSecond: Second value
- * - u32cMinute: Minute value
- * - u32cHour: Hour value
- * - u32cDayOfWeek: Day of week
- * - u32cDay: Day value
- * - u32cMonth: Month value
- * - u32Year: Year value
- * - u32AlarmMaskSecond: Mask second alarm
- * - u32AlarmMaskMinute: Mask minute alarm
- * - u32AlarmMaskHour: Mask hour alarm
- * - *pfnAlarmCallBack: Call back function
- *
- * @retval E_RTC_ERR_EIO Initial RTC time-out
- * @retval E_RTC_SUCCESS Success
- *
- */
- UINT32 RTC_Open(S_RTC_TIME_DATA_T *sPt)
- {
- UINT32 volatile u32Reg;
- /*-----------------------------------------------------------------------------------------------------*/
- /* DO BASIC JUDGEMENT TO Check RTC time data value is reasonable or not. */
- /*-----------------------------------------------------------------------------------------------------*/
- if (((sPt->u32Year - RTC_YEAR2000) > 99) |
- ((sPt->u32cMonth == 0) || (sPt->u32cMonth > 12)) |
- ((sPt->u32cDay == 0) || (sPt->u32cDay > 31)))
- {
- return E_RTC_ERR_CALENDAR_VALUE;
- }
- if (sPt->u8cClockDisplay == RTC_CLOCK_12)
- {
- if ((sPt->u32cHour == 0) || (sPt->u32cHour > 12))
- {
- return E_RTC_ERR_TIMESACLE_VALUE ;
- }
- }
- else if (sPt->u8cClockDisplay == RTC_CLOCK_24)
- {
- if (sPt->u32cHour > 23)
- {
- return E_RTC_ERR_TIMESACLE_VALUE ;
- }
- }
- else
- {
- return E_RTC_ERR_TIMESACLE_VALUE ;
- }
- if ((sPt->u32cMinute > 59) |
- (sPt->u32cSecond > 59) |
- (sPt->u32cSecond > 59))
- {
- return E_RTC_ERR_TIME_VALUE ;
- }
- if (sPt->u32cDayOfWeek > 6)
- {
- return E_RTC_ERR_DWR_VALUE ;
- }
- /*-----------------------------------------------------------------------------------------------------*/
- /* Second, set RTC time data. */
- /*-----------------------------------------------------------------------------------------------------*/
- if (sPt->u8cClockDisplay == RTC_CLOCK_12)
- {
- g_chHourMode = RTC_CLOCK_12;
- RTC_WriteEnable(1);
- outp32(REG_RTC_TIMEFMT, RTC_CLOCK_12);
- RTC_Check();
- /*-------------------------------------------------------------------------------------------------*/
- /* important, range of 12-hour PM mode is 21 upto 32 */
- /*-------------------------------------------------------------------------------------------------*/
- if (sPt->u8cAmPm == RTC_PM)
- sPt->u32cHour += 20;
- }
- else /* RTC_CLOCK_24 */
- {
- g_chHourMode = RTC_CLOCK_24;
- RTC_WriteEnable(1);
- outp32(REG_RTC_TIMEFMT, RTC_CLOCK_24);
- RTC_Check();
- }
- g_u32hiHour = sPt->u32cHour / 10;
- g_u32loHour = sPt->u32cHour % 10;
- g_u32hiMin = sPt->u32cMinute / 10;
- g_u32loMin = sPt->u32cMinute % 10;
- g_u32hiSec = sPt->u32cSecond / 10;
- g_u32loSec = sPt->u32cSecond % 10;
- u32Reg = (g_u32hiHour << 20);
- u32Reg |= (g_u32loHour << 16);
- u32Reg |= (g_u32hiMin << 12);
- u32Reg |= (g_u32loMin << 8);
- u32Reg |= (g_u32hiSec << 4);
- u32Reg |= g_u32loSec;
- g_u32Reg = u32Reg;
- RTC_WriteEnable(1);
- outp32(REG_RTC_TIME, (UINT32)g_u32Reg);
- RTC_Check();
- if (sPt->u8cClockDisplay == RTC_CLOCK_12)
- {
- if (sPt->u8cAmPm == RTC_PM)
- sPt->u32cHour -= 20;
- }
- g_u32hiYear = (sPt->u32Year - RTC_YEAR2000) / 10;
- g_u32loYear = (sPt->u32Year - RTC_YEAR2000) % 10;
- g_u32hiMonth = sPt->u32cMonth / 10;
- g_u32loMonth = sPt->u32cMonth % 10;
- g_u32hiDay = sPt->u32cDay / 10;
- g_u32loDay = sPt->u32cDay % 10;
- u32Reg = (g_u32hiYear << 20);
- u32Reg |= (g_u32loYear << 16);
- u32Reg |= (g_u32hiMonth << 12);
- u32Reg |= (g_u32loMonth << 8);
- u32Reg |= (g_u32hiDay << 4);
- u32Reg |= g_u32loDay;
- g_u32Reg = u32Reg;
- RTC_WriteEnable(1);
- outp32(REG_RTC_CAL, (UINT32)g_u32Reg);
- RTC_Check();
- RTC_WriteEnable(1);
- outp32(REG_RTC_WEEKDAY, (UINT32)sPt->u32cDayOfWeek);
- RTC_Check();
- return E_RTC_SUCCESS;
- }
- /**
- * @brief Read current date/time or alarm date/time from RTC
- *
- * @param[in] eTime \ref RTC_CURRENT_TIME / \ref RTC_ALARM_TIME
- * @param[out] *sPt Specify the time property and current time. It includes:
- * - u8cClockDisplay: \ref RTC_CLOCK_12 / \ref RTC_CLOCK_24
- * - u8cAmPm: \ref RTC_AM / \ref RTC_PM
- * - u32cSecond: Second value
- * - u32cMinute: Minute value
- * - u32cHour: Hour value
- * - u32cDayOfWeek: Day of week
- * - u32cDay: Day value
- * - u32cMonth: Month value
- * - u32Year: Year value
- * - u32AlarmMaskSecond: Mask second alarm
- * - u32AlarmMaskMinute: Mask minute alarm
- * - u32AlarmMaskHour: Mask hour alarm
- * - *pfnAlarmCallBack: Call back function
- *
- * @retval E_RTC_ERR_ENOTTY Wrong select time
- * @retval E_RTC_SUCCESS Success
- *
- */
- UINT32 RTC_Read(E_RTC_TIME_SELECT eTime, S_RTC_TIME_DATA_T *sPt)
- {
- UINT32 u32Tmp;
- sPt->u8cClockDisplay = inp32(REG_RTC_TIMEFMT); /* 12/24-hour */
- sPt->u32cDayOfWeek = inp32(REG_RTC_WEEKDAY); /* Day of week */
- switch (eTime)
- {
- case RTC_CURRENT_TIME:
- {
- g_u32Reg = inp32(REG_RTC_CAL);
- g_u32Reg1 = inp32(REG_RTC_TIME);
- break;
- }
- case RTC_ALARM_TIME:
- {
- g_u32Reg = inp32(REG_RTC_CALM);
- g_u32Reg1 = inp32(REG_RTC_TALM);
- break;
- }
- default:
- {
- return E_RTC_ERR_ENOTTY;
- }
- }
- g_u32hiYear = (g_u32Reg & 0xF00000) >> 20;
- g_u32loYear = (g_u32Reg & 0xF0000) >> 16;
- g_u32hiMonth = (g_u32Reg & 0x1000) >> 12;
- g_u32loMonth = (g_u32Reg & 0xF00) >> 8;
- g_u32hiDay = (g_u32Reg & 0x30) >> 4;
- g_u32loDay = g_u32Reg & 0xF;
- u32Tmp = (g_u32hiYear * 10);
- u32Tmp += g_u32loYear;
- sPt->u32Year = u32Tmp + RTC_YEAR2000;
- u32Tmp = (g_u32hiMonth * 10);
- sPt->u32cMonth = u32Tmp + g_u32loMonth;
- u32Tmp = (g_u32hiDay * 10);
- sPt->u32cDay = u32Tmp + g_u32loDay;
- g_u32hiHour = (g_u32Reg1 & 0x300000) >> 20;
- g_u32loHour = (g_u32Reg1 & 0xF0000) >> 16;
- g_u32hiMin = (g_u32Reg1 & 0x7000) >> 12;
- g_u32loMin = (g_u32Reg1 & 0xF00) >> 8;
- g_u32hiSec = (g_u32Reg1 & 0x70) >> 4;
- g_u32loSec = g_u32Reg1 & 0xF;
- if (sPt->u8cClockDisplay == RTC_CLOCK_12)
- {
- u32Tmp = (g_u32hiHour * 10);
- u32Tmp += g_u32loHour;
- sPt->u32cHour = u32Tmp; /* AM: 1~12. PM: 21~32. */
- if (eTime == RTC_CURRENT_TIME)
- {
- if (sPt->u32cHour >= 21)
- {
- sPt->u8cAmPm = RTC_PM;
- sPt->u32cHour -= 20;
- }
- else
- {
- sPt->u8cAmPm = RTC_AM;
- }
- }
- else
- {
- if (sPt->u32cHour < 12)
- {
- if (sPt->u32cHour == 0)
- sPt->u32cHour = 12;
- sPt->u8cAmPm = RTC_AM;
- }
- else
- {
- sPt->u32cHour -= 12;
- sPt->u8cAmPm = RTC_PM;
- }
- }
- u32Tmp = (g_u32hiMin * 10);
- u32Tmp += g_u32loMin;
- sPt->u32cMinute = u32Tmp;
- u32Tmp = (g_u32hiSec * 10);
- u32Tmp += g_u32loSec;
- sPt->u32cSecond = u32Tmp;
- }
- else
- {
- /* RTC_CLOCK_24 */
- u32Tmp = (g_u32hiHour * 10);
- u32Tmp += g_u32loHour;
- sPt->u32cHour = u32Tmp;
- u32Tmp = (g_u32hiMin * 10);
- u32Tmp += g_u32loMin;
- sPt->u32cMinute = u32Tmp;
- u32Tmp = (g_u32hiSec * 10);
- u32Tmp += g_u32loSec;
- sPt->u32cSecond = u32Tmp;
- }
- return E_RTC_SUCCESS;
- }
- /**
- * @brief Write current date/time or alarm date/time from RTC
- *
- * @param[in] eTime \ref RTC_CURRENT_TIME / \ref RTC_ALARM_TIME
- * @param[in] *sPt Specify the time property and current time. It includes:
- * - u8cClockDisplay: \ref RTC_CLOCK_12 / \ref RTC_CLOCK_24
- * - u8cAmPm: \ref RTC_AM / \ref RTC_PM
- * - u32cSecond: Second value
- * - u32cMinute: Minute value
- * - u32cHour: Hour value
- * - u32cDayOfWeek: Day of week
- * - u32cDay: Day value
- * - u32cMonth: Month value
- * - u32Year: Year value
- * - u32AlarmMaskSecond: Mask second alarm
- * - u32AlarmMaskMinute: Mask minute alarm
- * - u32AlarmMaskHour: Mask hour alarm
- * - *pfnAlarmCallBack: Call back function
- *
- * @retval E_RTC_ERR_ENOTTY Wrong select time
- * @retval E_RTC_ERR_CALENDAR_VALUE Wrong calender value
- * @retval E_RTC_ERR_TIME_VALUE Wrong time value
- * @retval E_RTC_ERR_DWR_VALUE Wrong day of week value
- * @retval E_RTC_SUCCESS Success
- *
- */
- UINT32 RTC_Write(E_RTC_TIME_SELECT eTime, S_RTC_TIME_DATA_T *sPt)
- {
- UINT32 u32Reg;
- /*-----------------------------------------------------------------------------------------------------*/
- /* Check RTC time data value is reasonable or not. */
- /*-----------------------------------------------------------------------------------------------------*/
- if (((sPt->u32Year - RTC_YEAR2000) > 99) |
- ((sPt->u32cMonth == 0) || (sPt->u32cMonth > 12)) |
- ((sPt->u32cDay == 0) || (sPt->u32cDay > 31)))
- {
- return E_RTC_ERR_CALENDAR_VALUE;
- }
- if ((sPt->u32Year - RTC_YEAR2000) > 99)
- {
- return E_RTC_ERR_CALENDAR_VALUE;
- }
- if ((sPt->u32cMonth == 0) || (sPt->u32cMonth > 12))
- {
- return E_RTC_ERR_CALENDAR_VALUE;
- }
- if ((sPt->u32cDay == 0) || (sPt->u32cDay > 31))
- {
- return E_RTC_ERR_CALENDAR_VALUE;
- }
- if (sPt->u8cClockDisplay == RTC_CLOCK_12)
- {
- if ((sPt->u32cHour == 0) || (sPt->u32cHour > 12))
- {
- return E_RTC_ERR_TIME_VALUE;
- }
- }
- else if (sPt->u8cClockDisplay == RTC_CLOCK_24)
- {
- if (sPt->u32cHour > 23)
- {
- return E_RTC_ERR_TIME_VALUE;
- }
- }
- else
- {
- return E_RTC_ERR_TIME_VALUE;
- }
- if (sPt->u32cMinute > 59)
- {
- return E_RTC_ERR_TIME_VALUE;
- }
- if (sPt->u32cSecond > 59)
- {
- return E_RTC_ERR_TIME_VALUE;
- }
- if (sPt->u32cDayOfWeek > 6)
- {
- return E_RTC_ERR_DWR_VALUE;
- }
- switch (eTime)
- {
- case RTC_CURRENT_TIME:
- {
- /*---------------------------------------------------------------------------------------------*/
- /* Second, set RTC time data. */
- /*---------------------------------------------------------------------------------------------*/
- if (sPt->u8cClockDisplay == RTC_CLOCK_12)
- {
- g_chHourMode = RTC_CLOCK_12;
- RTC_WriteEnable(1);
- outp32(REG_RTC_TIMEFMT, RTC_CLOCK_12);
- RTC_Check();
- /*-----------------------------------------------------------------------------------------*/
- /* important, range of 12-hour PM mode is 21 upto 32 */
- /*-----------------------------------------------------------------------------------------*/
- if (sPt->u8cAmPm == RTC_PM)
- {
- sPt->u32cHour += 20;
- }
- }
- else /* RTC_CLOCK_24 */
- {
- g_chHourMode = RTC_CLOCK_24;
- RTC_WriteEnable(1);
- outp32(REG_RTC_TIMEFMT, RTC_CLOCK_24);
- RTC_Check();
- }
- g_u32hiHour = sPt->u32cHour / 10;
- g_u32loHour = sPt->u32cHour % 10;
- g_u32hiMin = sPt->u32cMinute / 10;
- g_u32loMin = sPt->u32cMinute % 10;
- g_u32hiSec = sPt->u32cSecond / 10;
- g_u32loSec = sPt->u32cSecond % 10;
- u32Reg = (g_u32hiHour << 20);
- u32Reg |= (g_u32loHour << 16);
- u32Reg |= (g_u32hiMin << 12);
- u32Reg |= (g_u32loMin << 8);
- u32Reg |= (g_u32hiSec << 4);
- u32Reg |= g_u32loSec;
- g_u32Reg = u32Reg;
- RTC_WriteEnable(1);
- outp32(REG_RTC_TIME, (UINT32)g_u32Reg);
- RTC_Check();
- g_u32hiYear = (sPt->u32Year - RTC_YEAR2000) / 10;
- g_u32loYear = (sPt->u32Year - RTC_YEAR2000) % 10;
- g_u32hiMonth = sPt->u32cMonth / 10;
- g_u32loMonth = sPt->u32cMonth % 10;
- g_u32hiDay = sPt->u32cDay / 10;
- g_u32loDay = sPt->u32cDay % 10;
- u32Reg = (g_u32hiYear << 20);
- u32Reg |= (g_u32loYear << 16);
- u32Reg |= (g_u32hiMonth << 12);
- u32Reg |= (g_u32loMonth << 8);
- u32Reg |= (g_u32hiDay << 4);
- u32Reg |= g_u32loDay;
- g_u32Reg = u32Reg;
- RTC_WriteEnable(1);
- outp32(REG_RTC_CAL, (UINT32)g_u32Reg);
- RTC_Check();
- RTC_WriteEnable(1);
- outp32(REG_RTC_WEEKDAY, (UINT32) sPt->u32cDayOfWeek);
- RTC_Check();
- if (sPt->u8cClockDisplay == RTC_CLOCK_12)
- {
- if (sPt->u8cAmPm == RTC_PM)
- {
- sPt->u32cHour -= 20;
- }
- }
- return E_RTC_SUCCESS;
- }
- case RTC_ALARM_TIME:
- {
- RTC_WriteEnable(1);
- outp32(REG_RTC_PWRCTL, inp32(REG_RTC_PWRCTL) & ~RTC_PWRCTL_ALARM_EN_Msk);
- RTC_Check();
- /*---------------------------------------------------------------------------------------------*/
- /* Second, set alarm time data. */
- /*---------------------------------------------------------------------------------------------*/
- g_u32hiYear = (sPt->u32Year - RTC_YEAR2000) / 10;
- g_u32loYear = (sPt->u32Year - RTC_YEAR2000) % 10;
- g_u32hiMonth = sPt->u32cMonth / 10;
- g_u32loMonth = sPt->u32cMonth % 10;
- g_u32hiDay = sPt->u32cDay / 10;
- g_u32loDay = sPt->u32cDay % 10;
- //u32Reg = ((sPt->u32AlarmMaskDayOfWeek & 0x1) << 31);
- u32Reg = ((sPt->u32cDayOfWeek & 0x7) << 24);
- //u32Reg|= ((sPt->u32AlarmMaskYear & 0x1) << 30);
- u32Reg |= (g_u32hiYear << 20);
- u32Reg |= (g_u32loYear << 16);
- //u32Reg|= ((sPt->u32AlarmMaskMonth & 0x1) << 29);
- u32Reg |= (g_u32hiMonth << 12);
- u32Reg |= (g_u32loMonth << 8);
- //u32Reg|= ((sPt->u32AlarmMaskDay & 0x1) << 28);
- u32Reg |= (g_u32hiDay << 4);
- u32Reg |= g_u32loDay;
- g_u32Reg = u32Reg;
- RTC_WriteEnable(1);
- outp32(REG_RTC_CALM, (UINT32)g_u32Reg);
- RTC_Check();
- if (g_chHourMode == RTC_CLOCK_12)
- {
- if (sPt->u8cAmPm == RTC_PM) /* important, range of 12-hour PM mode is 21 upto 32 */
- {
- sPt->u32cHour += 20;
- }
- }
- g_u32hiHour = sPt->u32cHour / 10;
- g_u32loHour = sPt->u32cHour % 10;
- g_u32hiMin = sPt->u32cMinute / 10;
- g_u32loMin = sPt->u32cMinute % 10;
- g_u32hiSec = sPt->u32cSecond / 10;
- g_u32loSec = sPt->u32cSecond % 10;
- u32Reg = ((sPt->u32AlarmMaskHour & 0x1) << 30);
- u32Reg |= (g_u32hiHour << 20);
- u32Reg |= (g_u32loHour << 16);
- u32Reg |= ((sPt->u32AlarmMaskMinute & 0x1) << 29);
- u32Reg |= (g_u32hiMin << 12);
- u32Reg |= (g_u32loMin << 8);
- u32Reg |= ((sPt->u32AlarmMaskSecond & 0x1) << 28);
- u32Reg |= (g_u32hiSec << 4);
- u32Reg |= g_u32loSec;
- g_u32Reg = u32Reg;
- RTC_WriteEnable(1);
- outp32(REG_RTC_TALM, (UINT32)g_u32Reg);
- RTC_Check();
- if (sPt->u8cClockDisplay == RTC_CLOCK_12)
- {
- if (sPt->u8cAmPm == RTC_PM)
- {
- sPt->u32cHour -= 20;
- }
- }
- /*---------------------------------------------------------------------------------------------*/
- /* Finally, enable alarm interrupt. */
- /*---------------------------------------------------------------------------------------------*/
- RTC_Ioctl(0, RTC_IOC_ENABLE_INT, RTC_ALARM_INT, 0);
- RTC_WriteEnable(1);
- outp32(REG_RTC_PWRCTL, inp32(REG_RTC_PWRCTL) | RTC_PWRCTL_ALARM_EN_Msk);
- RTC_Check();
- return E_RTC_SUCCESS;
- }
- default:
- {
- return E_RTC_ERR_ENOTTY;
- }
- }
- }
- /**
- * @brief Support some commands for application.
- *
- * @param[in] i32Num Interface number. always set 0
- * @param[in] eCmd Command
- * @param[in] u32Arg0 Arguments for the command
- * @param[in] u32Arg1 Arguments for the command.
- *
- * @retval E_RTC_ERR_ENOTTY Wrong command or argument
- * @retval E_RTC_ERR_ENODEV Interface number incorrect
- * @retval E_RTC_SUCCESS Success
- *
- */
- UINT32 RTC_Ioctl(INT32 i32Num, E_RTC_CMD eCmd, UINT32 u32Arg0, UINT32 u32Arg1)
- {
- INT32 i32Ret;
- UINT32 u32Reg;
- RTC_TICK_T *ptick;
- UINT32 u32Tmp;
- if (i32Num != 0)
- return E_RTC_ERR_ENODEV;
- switch (eCmd)
- {
- case RTC_IOC_IDENTIFY_LEAP_YEAR:
- {
- u32Reg = inp32(REG_RTC_LEAPYEAR);
- if (u32Reg & 0x01)
- {
- *(PUINT32)u32Arg0 = RTC_LEAP_YEAR;
- }
- else
- {
- *(PUINT32)u32Arg0 = 0;
- }
- break;
- }
- case RTC_IOC_SET_TICK_MODE:
- {
- ptick = (RTC_TICK_T *) u32Arg0;
- if (g_bIsEnableTickInt == TRUE)
- {
- RTC_Ioctl(0, RTC_IOC_DISABLE_INT, RTC_TICK_INT, 0);
- g_bIsEnableTickInt = TRUE;
- }
- if (ptick->ucMode > RTC_TICK_1_128_SEC) /*Tick mode 0 to 7 */
- {
- return E_RTC_ERR_ENOTTY ;
- }
- RTC_WriteEnable(1);
- outp32(REG_RTC_TICK, ptick->ucMode);
- RTC_Check();
- /*---------------------------------------------------------------------------------------------*/
- /* Reset tick interrupt status if program enable tick interrupt before. */
- /*---------------------------------------------------------------------------------------------*/
- if (g_bIsEnableTickInt == TRUE)
- {
- RTC_Ioctl(0, RTC_IOC_ENABLE_INT, RTC_TICK_INT, 0);
- return E_RTC_SUCCESS;
- }
- break;
- }
- case RTC_IOC_GET_TICK:
- {
- break;
- }
- case RTC_IOC_RESTORE_TICK:
- {
- break;
- }
- case RTC_IOC_ENABLE_INT:
- {
- switch ((RTC_INT_SOURCE)u32Arg0)
- {
- case RTC_TICK_INT:
- {
- g_bIsEnableTickInt = TRUE;
- u32Tmp = inp32(REG_RTC_INTEN) | RTC_TICK_INT;
- break;
- }
- case RTC_ALARM_INT:
- {
- g_bIsEnableAlarmInt = TRUE;
- RTC_WriteEnable(1);
- u32Tmp = inp32(REG_RTC_PWRCTL) | RTC_PWRCTL_ALARM_EN_Msk;
- outp32(REG_RTC_PWRCTL, u32Tmp);
- outp32(REG_RTC_INTEN, inp32(REG_RTC_INTEN) | RTC_INTEN_ALMIEN_Msk);
- RTC_Check();
- u32Tmp = inp32(REG_RTC_INTEN) | RTC_ALARM_INT;
- break;
- }
- case RTC_RELATIVE_ALARM_INT:
- {
- g_bIsEnableAlarmInt = TRUE;
- RTC_WriteEnable(1);
- u32Tmp = inp32(REG_RTC_PWRCTL) | RTC_PWRCTL_REL_ALARM_EN_Msk;
- outp32(REG_RTC_PWRCTL, u32Tmp);
- RTC_Check();
- u32Tmp = inp32(REG_RTC_INTEN) | RTC_RELATIVE_ALARM_INT;
- break;
- }
- case RTC_PSWI_INT:
- {
- g_bIsEnableAlarmInt = TRUE;
- u32Tmp = inp32(REG_RTC_INTEN) | RTC_PSWI_INT;
- break;
- }
- default:
- {
- return E_RTC_ERR_ENOTTY;
- }
- }
- RTC_WriteEnable(1);
- outp32(REG_RTC_INTEN, u32Tmp);
- RTC_Check();
- break;
- }
- case RTC_IOC_DISABLE_INT:
- {
- switch ((RTC_INT_SOURCE)u32Arg0)
- {
- case RTC_TICK_INT:
- {
- g_bIsEnableTickInt = FALSE;
- RTC_WriteEnable(1);
- u32Tmp = inp32(REG_RTC_INTEN) & (~RTC_TICK_INT);
- outp32(REG_RTC_INTEN, u32Tmp);
- outp32(REG_RTC_INTSTS, RTC_TICK_INT);
- RTC_Check();
- break;
- }
- case RTC_ALARM_INT:
- {
- g_bIsEnableAlarmInt = FALSE;
- RTC_WriteEnable(1);
- u32Tmp = inp32(REG_RTC_INTEN) & (~RTC_ALARM_INT);
- outp32(REG_RTC_INTEN, u32Tmp);
- RTC_Check();
- RTC_WriteEnable(1);
- u32Tmp = inp32(REG_RTC_PWRCTL) & ~RTC_PWRCTL_ALARM_EN_Msk;
- outp32(REG_RTC_PWRCTL, u32Tmp);
- RTC_Check();
- outp32(REG_RTC_INTSTS, RTC_ALARM_INT);
- break;
- }
- case RTC_RELATIVE_ALARM_INT:
- {
- g_bIsEnableAlarmInt = FALSE;
- RTC_WriteEnable(1);
- u32Tmp = inp32(REG_RTC_INTEN) & (~RTC_RELATIVE_ALARM_INT);
- outp32(REG_RTC_INTEN, u32Tmp);
- RTC_Check();
- RTC_WriteEnable(1);
- u32Tmp = inp32(REG_RTC_PWRCTL) & ~RTC_PWRCTL_REL_ALARM_EN_Msk;
- outp32(REG_RTC_PWRCTL, u32Tmp);
- RTC_Check();
- outp32(REG_RTC_INTSTS, RTC_RELATIVE_ALARM_INT);
- break;
- }
- case RTC_PSWI_INT:
- {
- g_bIsEnableAlarmInt = FALSE;
- RTC_WriteEnable(1);
- u32Tmp = inp32(REG_RTC_INTEN) & (~RTC_PSWI_INT);
- outp32(REG_RTC_INTEN, u32Tmp);
- RTC_Check();
- outp32(REG_RTC_INTSTS, RTC_PSWI_INT);
- break;
- }
- case RTC_ALL_INT:
- {
- g_bIsEnableTickInt = FALSE;
- g_bIsEnableAlarmInt = FALSE;
- RTC_WriteEnable(1);
- outp32(REG_RTC_INTEN, 0);
- outp32(REG_RTC_INTSTS, RTC_ALL_INT);
- RTC_Check();
- break;
- }
- default:
- {
- return E_RTC_ERR_ENOTTY;
- }
- }
- break;
- }
- case RTC_IOC_SET_FREQUENCY:
- {
- i32Ret = RTC_DoFrequencyCompensation(u32Arg0) ;
- if (i32Ret != 0)
- {
- return E_RTC_ERR_ENOTTY;
- }
- break;
- }
- case RTC_IOC_SET_POWER_ON:
- {
- RTC_WriteEnable(1);
- u32Tmp = inp32(REG_RTC_PWRCTL) | 0x01;
- outp32(REG_RTC_PWRCTL, u32Tmp);
- RTC_Check();
- while ((inp32(REG_RTC_PWRCTL) & 0x01) != 0x1);
- break;
- }
- case RTC_IOC_SET_POWER_OFF:
- {
- RTC_WriteEnable(1);
- outp32(REG_RTC_PWRCTL, (inp32(REG_RTC_PWRCTL) & ~0x01) | 2);
- RTC_Check();
- while (1);
- //break;
- }
- case RTC_IOC_SET_POWER_OFF_PERIOD:
- {
- if (u32Arg0 < 4) u32Arg0 = 4;
- u32Arg0 = u32Arg0 - 4;
- RTC_WriteEnable(1);
- outp32(REG_RTC_PWRCTL, (inp32(REG_RTC_PWRCTL) & ~0xF000) | ((u32Arg0 & 0xF) << 12));
- RTC_Check();
- break;
- }
- case RTC_IOC_ENABLE_HW_POWEROFF:
- {
- RTC_WriteEnable(1);
- outp32(REG_RTC_PWRCTL, (inp32(REG_RTC_PWRCTL) | 0x04));
- RTC_Check();
- break;
- }
- case RTC_IOC_DISABLE_HW_POWEROFF:
- {
- RTC_WriteEnable(1);
- outp32(REG_RTC_PWRCTL, (inp32(REG_RTC_PWRCTL) & ~0x04));
- RTC_Check();
- break;
- }
- case RTC_IOC_SET_PSWI_CALLBACK:
- {
- RTC_Ioctl(0, RTC_IOC_ENABLE_INT, RTC_PSWI_INT, 0);
- break;
- }
- case RTC_IOC_GET_POWERKEY_STATUS:
- {
- RTC_WriteEnable(1);
- if (inp32(REG_RTC_PWRCTL) & 0x80)
- *(PUINT32)u32Arg0 = 1;
- else
- *(PUINT32)u32Arg0 = 0;
- break;
- }
- case RTC_IOC_SET_RELEATIVE_ALARM:
- {
- g_bIsEnableAlarmInt = TRUE;
- RTC_WriteEnable(1);
- outp32(REG_RTC_PWRCTL, (inp32(REG_RTC_PWRCTL) & ~0xFFF0010));
- RTC_Check();
- RTC_WriteEnable(1);
- u32Tmp = (inp32(REG_RTC_PWRCTL) & ~0xFFF0000) | ((u32Arg0 & 0xFFF) << 16) | RTC_PWRCTL_REL_ALARM_EN_Msk;
- outp32(REG_RTC_PWRCTL, u32Tmp);
- RTC_Check();
- g_bIsEnableAlarmInt = TRUE;
- RTC_WriteEnable(1);
- u32Tmp = inp32(REG_RTC_INTEN) | RTC_RELATIVE_ALARM_INT;
- outp32(REG_RTC_INTEN, u32Tmp);
- RTC_Check();
- break;
- }
- default:
- {
- return E_RTC_ERR_ENOTTY;
- }
- }
- return E_RTC_SUCCESS;
- }
- /**
- * @brief Disable AIC channel of RTC and both tick and alarm interrupt.
- *
- * @param[in] None
- *
- * @retval E_RTC_SUCCESS Success
- *
- */
- UINT32 RTC_Close(void)
- {
- g_bIsEnableTickInt = FALSE;
- sysDisableInterrupt(RTC_IRQn);
- RTC_Ioctl(0, RTC_IOC_DISABLE_INT, RTC_ALL_INT, 0);
- return E_RTC_SUCCESS;
- }
- /**
- * @brief Enable RTC clock.
- *
- * @param[in] bEnable 1: Enable \n
- * 2: Disable
- *
- * @return None
- *
- */
- void RTC_EnableClock(BOOL bEnable)
- {
- if (bEnable)
- outp32(REG_CLK_PCLKEN0, inp32(REG_CLK_PCLKEN0) | (1 << 2));
- else
- outp32(REG_CLK_PCLKEN0, inp32(REG_CLK_PCLKEN0) & ~(1 << 2));
- }
- /*@}*/ /* end of group N9H30_RTC_EXPORTED_FUNCTIONS */
- /*@}*/ /* end of group N9H30_RTC_Driver */
- /*@}*/ /* end of group N9H30_Device_Driver */
- /*** (C) COPYRIGHT 2018 Nuvoton Technology Corp. ***/
|