|
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
// File name : rtc_drv.c
|
|
|
// Version : V0.1
|
|
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
#include "rtc_drv.h"
|
|
|
#include "cpm_reg.h"
|
|
|
#include "uart.h"
|
|
|
#include "pci_drv.h"
|
|
|
|
|
|
|
|
|
#define RTC_WCLK_MAX 10000000//10MHz
|
|
|
|
|
|
UINT32 g_rtc_int_sta = 0;
|
|
|
|
|
|
/*******************************************************************************
|
|
|
* Function Name : RTC_ISR
|
|
|
* Description : RTC中断处理
|
|
|
* Input : None
|
|
|
*
|
|
|
* Output : None
|
|
|
* Return : None
|
|
|
******************************************************************************/
|
|
|
//void PMU_RTC_IRQHandler(void)
|
|
|
//{
|
|
|
// UINT32 prc1r;
|
|
|
// UINT8 alarm_wakeup_flg = 1;
|
|
|
|
|
|
// prc1r = RTC->RTC_PRC1R;
|
|
|
|
|
|
// //printf("\r\nRTC INT[0x%08x]\r\n", prc1r);
|
|
|
// if (((prc1r&Ala_intf) == Ala_intf) && ((prc1r&Ala_IEN) == Ala_IEN))//alarm interrupt
|
|
|
// {
|
|
|
// RTC->RTC_PRC1R |= Ala_intf;
|
|
|
// g_rtc_int_sta |= Ala_intf;
|
|
|
// alarm_wakeup_flg = 0;
|
|
|
// printf("RTC Alarm\r\n");
|
|
|
// }
|
|
|
|
|
|
// if(((prc1r&Day_intf) == Day_intf) && ((prc1r&Day_IEN) == Day_IEN))//day interrupt
|
|
|
// {
|
|
|
// RTC->RTC_PRC1R |= Day_intf;
|
|
|
// g_rtc_int_sta |= Day_intf;
|
|
|
// alarm_wakeup_flg = 0;
|
|
|
// }
|
|
|
|
|
|
// if(((prc1r&Hou_intf) == Hou_intf) && ((prc1r&Hou_IEN) == Hou_IEN))//hour interrupt
|
|
|
// {
|
|
|
// RTC->RTC_PRC1R |= Hou_intf;
|
|
|
// g_rtc_int_sta |= Hou_intf;
|
|
|
// alarm_wakeup_flg = 0;
|
|
|
// }
|
|
|
|
|
|
// if(((prc1r&Min_intf) == Min_intf) && ((prc1r&Min_IEN) == Min_IEN))//minute interrupt
|
|
|
// {
|
|
|
// RTC->RTC_PRC1R |= Min_intf;
|
|
|
// g_rtc_int_sta |= Min_intf;
|
|
|
// alarm_wakeup_flg = 0;
|
|
|
// }
|
|
|
|
|
|
// if(((prc1r&Sec_intf) == Sec_intf) && ((prc1r&Sec_IEN) == Sec_IEN))//second interrupt
|
|
|
// {
|
|
|
// //tm tim;
|
|
|
|
|
|
// RTC->RTC_PRC1R |= Sec_intf;
|
|
|
// g_rtc_int_sta |= Sec_intf;
|
|
|
// //printf("RTC Second\r\n");
|
|
|
// //RTC_GetTime(&tim);
|
|
|
// //printf("RTC Second INT[%d]\r\n", tim.second);
|
|
|
// alarm_wakeup_flg = 0;
|
|
|
// }
|
|
|
|
|
|
// if (alarm_wakeup_flg)
|
|
|
// {
|
|
|
// printf("\r\nRTC alarm wakeup from sleep mode\r\n");
|
|
|
// RTC->RTC_PRKEYR = 0x5aa55aa5;//输入key
|
|
|
// RTC->RTC_PRC1R &= ~Ala_IEN;
|
|
|
// RTC->RTC_PRC1R &= ~Dir;//set dir = 0;
|
|
|
// }
|
|
|
//}
|
|
|
|
|
|
/*******************************************************************************
|
|
|
* Function Name : RTC_Init
|
|
|
* Description : RTC初始化
|
|
|
* Input : None
|
|
|
*
|
|
|
* Output : None
|
|
|
* Return : None
|
|
|
******************************************************************************/
|
|
|
void RTC_Init(UINT8 clk_sel)
|
|
|
{
|
|
|
UINT32 rtc_wclk_div = 0;
|
|
|
|
|
|
if(clk_sel == INTERNAL_CLK_SEL)
|
|
|
{
|
|
|
//write enable key
|
|
|
PCI->PCI_WRITEEN = 0x40000000;
|
|
|
PCI->PCI_WRITEEN = 0x80000000;
|
|
|
PCI->PCI_WRITEEN = 0xC0000000;
|
|
|
PCI->PCI_WRITEEN = 0xC000003F;//write enable
|
|
|
|
|
|
PCI->PCI_RTCIER = 0x00040001; //RTC Interface Enable
|
|
|
|
|
|
while((PCI->PCI_RTCIER&0x80000001)!=0x80000001); //RTC Interface Enable Delay Match
|
|
|
|
|
|
PCI->PCI_DETPCR |= 0x80770000; //RTC32K Clock Enable
|
|
|
|
|
|
PCI->PCI_IRCCR = 0x84;
|
|
|
|
|
|
RTC->RTC_PRENR = 0x0100; //disable PMU_RTC 5
|
|
|
RTC->RTC_PRENR = 0x0300;
|
|
|
}
|
|
|
|
|
|
rtc_wclk_div = g_sys_clk/RTC_WCLK_MAX;
|
|
|
|
|
|
if (rtc_wclk_div >= 1)
|
|
|
rtc_wclk_div--;
|
|
|
|
|
|
//Update RTC Counter(function case Dir=0)
|
|
|
NVIC_Init(3, 3, PMU_RTC_IRQn, 2);//开RTC中断
|
|
|
RTC->RTC_PRKEYR = 0x5aa55aa5;//输入key
|
|
|
RTC->RTC_PRC1R &= (~WCLK_DIV_MASK);
|
|
|
RTC->RTC_PRC1R |= (rtc_wclk_div<<3);//8分频
|
|
|
RTC->RTC_PRC1R &= ~Dir;//set dir = 0;
|
|
|
|
|
|
}
|
|
|
/*******************************************************************************
|
|
|
* Function Name : RTC_SetTime
|
|
|
* Description : 设置RTC初值
|
|
|
* Input : - t:tm结构体
|
|
|
* t->day:设置RTC的day值
|
|
|
* t->hour:设置RTC的hour值
|
|
|
* t->minute:设置RTC的minute值
|
|
|
* t->second:设置RTC的second值
|
|
|
*
|
|
|
* Output : None
|
|
|
* Return : None
|
|
|
******************************************************************************/
|
|
|
void RTC_SetTime(tm t)
|
|
|
{
|
|
|
|
|
|
RTC->RTC_PRT1R = t.day;
|
|
|
RTC->RTC_PRT2R = (t.hour<<16)|(t.minute<<8)|t.second;
|
|
|
|
|
|
RTC->RTC_PRC1R = (RTC->RTC_PRC1R & (~RTC_SEL_MASK)) | (RTC_SEL_MASK & RTC_RISING_EDGE_INT);
|
|
|
//RTC->RTC_PRC1R |= Sec_IEN;
|
|
|
|
|
|
// printf("t.day = %d\r\n", t.day);
|
|
|
// printf("t.hour = %d\r\n", t.hour);
|
|
|
// printf("t.minute = %d\r\n", t.minute);
|
|
|
// printf("t.second = %d\r\n", t.second);
|
|
|
}
|
|
|
|
|
|
/*******************************************************************************
|
|
|
* Function Name : RTC_SetAlarm
|
|
|
* Description : 设置RTC初值
|
|
|
* Input : - t:tm结构体,设置alarm计数器的值
|
|
|
* - AlarmMod:alarm的模式
|
|
|
* DAY_ALARM:day报警
|
|
|
* HOUR_ALARM:hour报警
|
|
|
* MINUTE_ALARM:minute报警
|
|
|
* SECOND_ALARM:second报警
|
|
|
* ALL_ALARM:day、hour、minute、second报警
|
|
|
*
|
|
|
* Output : None
|
|
|
* Return : None
|
|
|
******************************************************************************/
|
|
|
void RTC_SetAlarm(tm t, UINT8 AlarmMod)
|
|
|
{
|
|
|
switch(AlarmMod)
|
|
|
{
|
|
|
case DAY_ALARM:
|
|
|
RTC->RTC_PRA1R = AlaD_en|t.day;
|
|
|
break;
|
|
|
case HOUR_ALARM:
|
|
|
RTC->RTC_PRA2R = AlaH_en|(t.hour<<16);
|
|
|
break;
|
|
|
case MINUTE_ALARM:
|
|
|
RTC->RTC_PRA2R = AlaM_en|(t.minute<<8);
|
|
|
break;
|
|
|
case SECOND_ALARM:
|
|
|
RTC->RTC_PRA2R = AlaS_en|t.second;
|
|
|
break;
|
|
|
case ALL_ALARM:
|
|
|
{
|
|
|
RTC->RTC_PRA1R = AlaD_en|t.day;
|
|
|
RTC->RTC_PRA2R = AlaS_en|AlaM_en|AlaH_en|(t.hour<<16)|(t.minute<<8)|t.second;
|
|
|
// printf("t.day = %d\r\n", t.day);
|
|
|
// printf("t.hour = %d\r\n", t.hour);
|
|
|
// printf("t.minute = %d\r\n", t.minute);
|
|
|
// printf("t.second = %d\r\n", t.second);
|
|
|
break;
|
|
|
}
|
|
|
default:
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
RTC->RTC_PRC1R = (RTC->RTC_PRC1R & (~RTC_SEL_MASK)) | (RTC_SEL_MASK & RTC_FALLING_EDGE_INT);
|
|
|
//RTC->RTC_PRC1R = (RTC->RTC_PRC1R & (~RTC_SEL_MASK)) | (RTC_SEL_MASK & RTC_LOW_LEVEL_INT);
|
|
|
RTC->RTC_PRC1R |= Ala_IEN;
|
|
|
// printf("RTC->RTC_PRC1R = %08x\r\n", RTC->RTC_PRC1R);
|
|
|
}
|
|
|
|
|
|
/*******************************************************************************
|
|
|
* Function Name : RTC_GetTime
|
|
|
* Description : 读取RTC计数器值
|
|
|
* Input : None
|
|
|
*
|
|
|
* Output : - t:tm结构体指针
|
|
|
* t->day:读取的RTC的day值
|
|
|
* t->hour:读取的RTC的hour值
|
|
|
* t->minute:读取的RTC的minute值
|
|
|
* t->second:读取的RTC的second值
|
|
|
* Return : None
|
|
|
******************************************************************************/
|
|
|
void RTC_GetTime(tm *t)
|
|
|
{
|
|
|
UINT32 tim;
|
|
|
#if 0
|
|
|
/*
|
|
|
tim = RTC->RTC_PRT1R;//RTC_PRTCR
|
|
|
t->day = (UINT16)(tim&(0x7FFF));
|
|
|
|
|
|
tim = RTC->RTC_PRT2R;
|
|
|
|
|
|
t->second = (UINT8)(tim&0xff);
|
|
|
t->minute = (UINT8)(tim>>8);
|
|
|
t->hour = (UINT8)(tim>>16);
|
|
|
*/
|
|
|
#else
|
|
|
tim = RTC->RTC_PRTCR;
|
|
|
t->day = (UINT16)((tim>>17)&(0x7FFF));
|
|
|
t->second = (UINT8)((tim)&0x3f);
|
|
|
t->minute = (UINT8)((tim>>6)&0x3f);
|
|
|
t->hour = (UINT8)((tim>>12)&0x1f);
|
|
|
#endif
|
|
|
// printf("t->day = %d\r\n", t->day);
|
|
|
// printf("t->hour = %d\r\n", t->hour);
|
|
|
// printf("t->minute = %d\r\n", t->minute);
|
|
|
// printf("t->second = %d\r\n", t->second);
|
|
|
}
|