📄 drvrtc.c
字号:
/*---------------------------------------------------------------------------------------------------------*/
/* */
/* Copyright(c) 2009 Nuvoton Technology Corp. All rights reserved. */
/* */
/*---------------------------------------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------------------------------------*/
/* Includes of system headers */
/*---------------------------------------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------------------------------------*/
/* Includes of local headers */
/*---------------------------------------------------------------------------------------------------------*/
#include <stdio.h>
#include "DrvRTC.h"
#include "DrvGPIO.h"
/*---------------------------------------------------------------------------------------------------------*/
/* Macro, type and constant definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define RTC_GLOBALS
//#define RTC_DEBUG
#ifdef RTC_DEBUG
#define RTCDEBUG printf
#else
#define RTCDEBUG(...)
#endif
/*---------------------------------------------------------------------------------------------------------*/
/* Global file scope (static) variables */
/*---------------------------------------------------------------------------------------------------------*/
static PFN_DRVRTC_CALLBACK *g_pfnRTCCallBack_Tick = NULL, *g_pfnRTCCallBack_Alarm = NULL;
static uint32_t volatile g_u32RTC_Count = 0;
static char g_chHourMode = 0;
static int32_t volatile g_bIsEnableTickInt = NULL;
static int8_t volatile g_bIsEnableAlarmInt = NULL;
static uint32_t volatile g_u32Reg, g_u32Reg1,g_u32hiYear,g_u32loYear,g_u32hiMonth,g_u32loMonth,g_u32hiDay,g_u32loDay;
static uint32_t volatile g_u32hiHour,g_u32loHour,g_u32hiMin,g_u32loMin,g_u32hiSec,g_u32loSec;
/*---------------------------------------------------------------------------------------------------------*/
/* Function: RTC_IRQHandler */
/* */
/* Parameter: */
/* None */
/* Returns: */
/* None */
/* Description: */
/* Install ISR to handle interrupt event */
/*---------------------------------------------------------------------------------------------------------*/
void RTC_IRQHandler(void)
{
if (RTC->RIIR.TIF == 0x1) /* tick interrupt occurred */
{
outpw(&RTC->RIIR, 0x2);
g_u32RTC_Count++; /* maintain RTC tick count */
if (g_pfnRTCCallBack_Tick != NULL) /* execute tick callback function */
{
g_pfnRTCCallBack_Tick();
}
}
if (RTC->RIIR.AIF == 0x1) /* alarm interrupt occurred */
{
outpw(&RTC->RIIR, 0x1);
if (g_pfnRTCCallBack_Alarm != NULL) /* execute alarm callback function */
{
g_pfnRTCCallBack_Alarm();
}
}
}
/*---------------------------------------------------------------------------------------------------------*/
/* Function: DrvRTC_SetFrequencyCompensation */
/* */
/* Parameter: */
/* i32FrequencyX100 -[in], the RTC osillator clock X100, ex:3277365 means 32773.65 */
/* Returns: */
/* E_SUCCESS Success. */
/* E_DRVRTC_ERR_FCR_VALUE Wrong Compenation VALUE */
/* DESCRIPTION */
/* */
/* Set Frequecy Compenation Data */
/*---------------------------------------------------------------------------------------------------------*/
int32_t DrvRTC_SetFrequencyCompensation(int32_t i32FrequencyX100)
{
int32_t i32RegInt,i32RegFra ;
/* Compute Interger and Fraction for RTC register*/
i32RegInt = (i32FrequencyX100/100) - DRVRTC_FCR_REFERENCE;
i32RegFra = (((i32FrequencyX100%100)) * 60) / 100;
/* Judge Interger part is reasonable */
if ( (i32RegInt < 0) | (i32RegInt > 15) )
{
return E_DRVRTC_ERR_FCR_VALUE ;
}
DrvRTC_WriteEnable();
outpw(&RTC->FCR, (uint32_t)((i32RegInt<<8) | i32RegFra));
return E_SUCCESS;
}
/*---------------------------------------------------------------------------------------------------------*/
/* Function: DrvRTC_WriteEnable */
/* */
/* Parameter: */
/* None */
/* Returns: */
/* E_SUCCESS Success. */
/* E_DRVRTC_ERR_FAILED FAILED */
/* DESCRIPTION */
/* Access Password to AER to make access other register enable */
/*---------------------------------------------------------------------------------------------------------*/
int32_t DrvRTC_WriteEnable(void)
{
int32_t i32i = 0;
int i32retry = 100;
/*----------------------------------------------------------------------------------------------------------*/
/* After 512 RTC clocks(about 15ms). Access enable wiil auto-clear. As soon as possible to do your setting. */
/*----------------------------------------------------------------------------------------------------------*/
RETRY:
i32i = 0;
RTC->AER.AER = 0xA965;
for (i32i=0 ; i32i<DRVRTC_WAIT_COUNT ; i32i++)
{
/*-------------------------------------------------------------------------------------------------*/
/* check RTC_AER[16] to find out RTC write enable */
/*-------------------------------------------------------------------------------------------------*/
RTC->AER.AER = 0xA965;
if (RTC->AER.ENF == 1)
break;
}
if (i32i == DRVRTC_WAIT_COUNT)
{
RTCDEBUG ("\nRTC: RTC_WriteEnable, set write enable FAILED!\n");
i32retry--;
if (!i32retry)
return E_DRVRTC_ERR_FAILED;
goto RETRY;
}
return E_SUCCESS;
}
/*---------------------------------------------------------------------------------------------------------*/
/* Function: DrvRTC_Init */
/* */
/* Parameter: */
/* None */
/* Returns: */
/* E_SUCCESS Success. */
/* E_DRVRTC_ERR_EIO Initial RTC FAILED. */
/* DESCRIPTION */
/* */
/* Initial RTC. It consists of clear callback function pointer, enable 32K clock and */
/* RTC clock and write initial key to let RTC start count */
/*---------------------------------------------------------------------------------------------------------*/
int32_t DrvRTC_Init(void)
{
int32_t i32i =0;
volatile int32_t i32delay=1000;
/*-----------------------------------------------------------------------------------------------------*/
/* Initial time data struct and some parameters. */
/*-----------------------------------------------------------------------------------------------------*/
g_pfnRTCCallBack_Alarm = NULL;
g_pfnRTCCallBack_Tick = NULL;
g_u32RTC_Count = 0;
if ((SYS->REGWRPROT & 0x01) == 0)
{
/* The protected Registers are locked */
return E_DRVRTC_ERR_EIO;
}
/* Enable 32K Clock */
SYSCLK->PWRCON.XTL32K_EN =1;
/* Waiting for 32K stable */
while(i32delay--);
/* Enable RTC Clock */
SYSCLK->APBCLK.RTC_EN =1;
/*-----------------------------------------------------------------------------------------------------*/
/* When RTC is power on, write 0xa5eb1357 to INIR to make RTC leaving reset state. */
/*-----------------------------------------------------------------------------------------------------*/
RTC->INIR = DRVRTC_INIT_KEY;
for (i32i=0 ; i32i<DRVRTC_WAIT_COUNT; i32i++)
{
if (RTC->INIR == 0x1) /* Check if RTC is at normal active state */
{
break;
}
}
if (i32i == DRVRTC_WAIT_COUNT)
{
RTCDEBUG("\nRTC: RTC_Init, initial RTC FAILED!\n");
return E_DRVRTC_ERR_EIO;
}
return E_SUCCESS;
}
/*---------------------------------------------------------------------------------------------------------*/
/* Function: DrvRTC_Open */
/* */
/* Parameter: S_DRVRTC_TIME_DATA_T *sPt Just Set Current_Timer */
/* */
/* Returns: */
/* E_SUCCESS Success. */
/* E_DRVRTC_ERR_EIO Initial RTC FAILED. */
/* */
/* DESCRIPTION */
/* Set Current time (Year/Month/Day, Hour/Minute/Sec and day of week) */
/*---------------------------------------------------------------------------------------------------------*/
int32_t DrvRTC_Open(S_DRVRTC_TIME_DATA_T *sPt)
{
uint32_t u32Reg;
volatile int32_t i32delay=1000;
RTC_TLR_T tlr = {0};
RTC_CLR_T clr = {0};
/*-----------------------------------------------------------------------------------------------------*/
/* DO BASIC JUDGEMENT TO Check RTC time data value is reasonable or not. */
/*-----------------------------------------------------------------------------------------------------*/
if ( ((sPt->u32Year - DRVRTC_YEAR2000) > 99)|
((sPt->u32cMonth == 0) || (sPt->u32cMonth > 12))|
((sPt->u32cDay == 0) || (sPt->u32cDay > 31)))
{
return E_DRVRTC_ERR_CALENDAR_VALUE;
}
if (sPt->u8cClockDisplay == DRVRTC_CLOCK_12)
{
if ( (sPt->u32cHour == 0) || (sPt->u32cHour > 12) )
{
return E_DRVRTC_ERR_TIMESACLE_VALUE ;
}
}
else if (sPt->u8cClockDisplay == DRVRTC_CLOCK_24)
{
if (sPt->u32cHour > 23)
{
return E_DRVRTC_ERR_TIMESACLE_VALUE ;
}
}
else
{
return E_DRVRTC_ERR_TIMESACLE_VALUE ;
}
if ((sPt->u32cMinute > 59) |
(sPt->u32cSecond > 59) |
(sPt->u32cSecond > 59))
{
return E_DRVRTC_ERR_TIME_VALUE ;
}
if (sPt->u32cDayOfWeek > 6)
{
return E_DRVRTC_ERR_DWR_VALUE ;
}
/*-----------------------------------------------------------------------------------------------------*/
/* Important, call RTC_WriteEnable() before write data into any register. */
/* User should be write data as soon as possible. */
/* Access enable wiil clear after 512 RTC clocks(about 15ms). */
/*-----------------------------------------------------------------------------------------------------*/
g_u32Reg = DrvRTC_WriteEnable();
if (g_u32Reg != 0)
{
return E_DRVRTC_ERR_FAILED;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -