/*---------------------------------------------------------------------------------------------------------*/ 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; }
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; UNLOCKREG(); /* Enable 32K Clock */ SYSCLK->PWRCON.XTL32K_EN =1; /* Waiting for 32K stable */ while(i32delay--); /* Enable RTC Clock */ SYSCLK->APBCLK.RTC_EN =1; LOCKREG(); /*-----------------------------------------------------------------------------------------------------*/ /* When RTC is power on, write 0xa5eb1357 to RTC_INIR to reset all logic. */ /*-----------------------------------------------------------------------------------------------------*/ RTC->INIR = DRVRTC_INIT_KEY; for (i32i = 0 ; i32i < DRVRTC_WAIT_COUNT ; i32i++) { if(RTC->INIR == 0x1) /* Check RTC_INIR[0] to find out RTC reset signal */ { break; } } if (i32i == DRVRTC_WAIT_COUNT) { RTCDEBUG("\nRTC: RTC_Init, initial RTC FAILED!\n"); return E_DRVRTC_ERR_EIO; } return E_SUCCESS; }
/*---------------------------------------------------------------------------------------------------------*/ int32_t DrvRTC_WriteEnable (void) { int32_t i32i = 0; int i32retry = 100; /*-------------------------------------------------------------------------------------------------*/ /* After 200ms, 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; }
/* Write current date/time or alarm date/time from RTC */ //*--------------------------------------------------------------------------------------------------------*/ int32_t DrvRTC_Write(E_DRVRTC_TIME_SELECT eTime, S_DRVRTC_TIME_DATA_T *sPt) { uint32_t u32Reg; /*-----------------------------------------------------------------------------------------------------*/ /* 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))) { RTCDEBUG ("\nRTC: Year value is incorrect\n"); return E_DRVRTC_ERR_CALENDAR_VALUE; } if ( (sPt->u32Year - DRVRTC_YEAR2000) > 99 ) { RTCDEBUG ("\nRTC: Year value is incorrect\n"); return E_DRVRTC_ERR_CALENDAR_VALUE; } if ( (sPt->u32cMonth == 0) || (sPt->u32cMonth > 12) ) { RTCDEBUG ("\nRTC: Month value is incorrect\n"); return E_DRVRTC_ERR_CALENDAR_VALUE; } if ( (sPt->u32cDay == 0) || (sPt->u32cDay > 31) ) { RTCDEBUG ("\nRTC: Day value is incorrect\n"); return E_DRVRTC_ERR_CALENDAR_VALUE; } if (sPt->u8cClockDisplay == DRVRTC_CLOCK_12) { if ( (sPt->u32cHour == 0) || (sPt->u32cHour > 12) ) { RTCDEBUG ("\nRTC: Hour value is incorrect\n"); return E_DRVRTC_ERR_TIMESACLE_VALUE; } } else if (sPt->u8cClockDisplay == DRVRTC_CLOCK_24) { if (sPt->u32cHour > 23) { RTCDEBUG ("\nRTC: Hour value is incorrect\n"); return E_DRVRTC_ERR_TIMESACLE_VALUE; } } else { RTCDEBUG ("\nRTC: Clock mode is incorrect\n"); return E_DRVRTC_ERR_TIMESACLE_VALUE; } if (sPt->u32cMinute > 59) { RTCDEBUG ("\nRTC: Minute value is incorrect\n"); return E_DRVRTC_ERR_TIME_VALUE; } if (sPt->u32cSecond > 59) { RTCDEBUG ("\nRTC: Second value is incorrect\n"); return E_DRVRTC_ERR_TIME_VALUE; } if (sPt->u32cDayOfWeek > 6) { RTCDEBUG ("\nRTC: Day of week value is incorrect\n"); return E_DRVRTC_ERR_DWR_VALUE; } /*-----------------------------------------------------------------------------------------------------*/ /* Important, call RTC_Open() before write data into any register. */ /*-----------------------------------------------------------------------------------------------------*/ g_u32Reg = DrvRTC_WriteEnable(); if (g_u32Reg != 0) { return E_DRVRTC_ERR_FAILED; } switch (eTime) { case DRVRTC_CURRENT_TIME: g_pfnRTCCallBack_Tick = NULL; /*---------------------------------------------------------------------------------------------*/ /* Second, set RTC time data. */ /*---------------------------------------------------------------------------------------------*/ if (sPt->u8cClockDisplay == DRVRTC_CLOCK_12) { g_chHourMode = DRVRTC_CLOCK_12; DrvRTC_WriteEnable(); RTC->TSSR.HR24 = DRVRTC_CLOCK_12; RTCDEBUG ("RTC: 12-hour\n"); /*-----------------------------------------------------------------------------------------*/ /* important, range of 12-hour PM mode is 21 upto 32 */ /*-----------------------------------------------------------------------------------------*/ if (sPt->u8cAmPm == DRVRTC_PM) sPt->u32cHour += 20; } else /* RTC_CLOCK_24 */ { g_chHourMode = DRVRTC_CLOCK_24; DrvRTC_WriteEnable(); RTC->TSSR.HR24 = DRVRTC_CLOCK_24; RTCDEBUG ("RTC: 24-hour\n"); } /*---------------------------------------------------------------------------------------------*/ /* Second, set RTC time data. */ /*---------------------------------------------------------------------------------------------*/ u32Reg = ((sPt->u32Year - DRVRTC_YEAR2000) / 10) << 20; u32Reg |= (((sPt->u32Year - DRVRTC_YEAR2000) % 10) << 16); u32Reg |= ((sPt->u32cMonth / 10) << 12); u32Reg |= ((sPt->u32cMonth % 10) << 8); u32Reg |= ((sPt->u32cDay / 10) << 4); u32Reg |= (sPt->u32cDay % 10); g_u32Reg = u32Reg; DrvRTC_WriteEnable(); outpw(&RTC->CLR, (uint32_t)g_u32Reg); RTCDEBUG ("RTC: REG_RTC_CLR[0x%08x]\n", inpw(&RTC->CLR)); u32Reg = ((sPt->u32cHour / 10) << 20); u32Reg |= ((sPt->u32cHour % 10) << 16); u32Reg |= ((sPt->u32cMinute / 10) << 12); u32Reg |= ((sPt->u32cMinute % 10) << 8); u32Reg |= ((sPt->u32cSecond / 10) << 4); u32Reg |= (sPt->u32cSecond % 10); g_u32Reg = u32Reg; DrvRTC_WriteEnable(); outpw(&RTC->TLR, (uint32_t)g_u32Reg); outpw(&RTC->DWR, sPt->u32cDayOfWeek); RTCDEBUG ("RTC: REG_RTC_TLR[0x%08x]\n", inpw(&RTC->TLR)); return E_SUCCESS; case DRVRTC_ALARM_TIME: g_pfnRTCCallBack_Alarm = NULL; /* Initial call back function.*/ /*---------------------------------------------------------------------------------------------*/ /* Set Calender alarm time data. */ /*---------------------------------------------------------------------------------------------*/ u32Reg = ((sPt->u32Year - DRVRTC_YEAR2000) / 10) << 20; u32Reg |= (((sPt->u32Year - DRVRTC_YEAR2000) % 10) << 16); u32Reg |= ((sPt->u32cMonth / 10) << 12); u32Reg |= ((sPt->u32cMonth % 10) << 8); u32Reg |= ((sPt->u32cDay / 10) << 4); u32Reg |= (sPt->u32cDay % 10); g_u32Reg = u32Reg; DrvRTC_WriteEnable(); outpw(&RTC->CAR, (uint32_t)g_u32Reg); RTCDEBUG ("RTC: REG_RTC_CAR[0x%08x]\n", inpw(&RTC->CAR)); if (g_chHourMode == DRVRTC_CLOCK_12) { if (sPt->u8cAmPm == DRVRTC_PM) /* important, range of 12-hour PM mode is 21 upto 32 */ sPt->u32cHour += 20; } /*---------------------------------------------------------------------------------------------*/ /* Set Time alarm time data. */ /*---------------------------------------------------------------------------------------------*/ u32Reg = ((sPt->u32cHour / 10) << 20); u32Reg |= ((sPt->u32cHour % 10) << 16); u32Reg |= ((sPt->u32cMinute / 10) << 12); u32Reg |= ((sPt->u32cMinute % 10) << 8); u32Reg |= ((sPt->u32cSecond / 10) << 4); u32Reg |= (sPt->u32cSecond % 10); g_u32Reg = u32Reg; DrvRTC_WriteEnable(); outpw(&RTC->TAR, (uint32_t)g_u32Reg); RTCDEBUG ("RTC: REG_RTC_TAR[0x%08x]\n", inpw(&RTC->TAR)); return E_SUCCESS; default: { return E_DRVRTC_ERR_ENOTTY; } } }
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 200ms */ /*-----------------------------------------------------------------------------------------------------*/ g_u32Reg = DrvRTC_WriteEnable(); if (g_u32Reg != 0) { return E_DRVRTC_ERR_FAILED; } /*-----------------------------------------------------------------------------------------------------*/ /* Second, set RTC 24/12 hour setting */ /*-----------------------------------------------------------------------------------------------------*/ if (sPt->u8cClockDisplay == DRVRTC_CLOCK_12) { DrvRTC_WriteEnable(); RTC->TSSR.HR24 = DRVRTC_CLOCK_12; /*-------------------------------------------------------------------------------------------------*/ /* important, range of 12-hour PM mode is 21 upto 32 */ /*-------------------------------------------------------------------------------------------------*/ if (sPt->u8cAmPm == DRVRTC_PM) sPt->u32cHour += 20; } else /* RTC_CLOCK_24 */ { DrvRTC_WriteEnable(); RTC->TSSR.HR24 = DRVRTC_CLOCK_24; RTCDEBUG ("RTC: 24-hour\n"); } /*-----------------------------------------------------------------------------------------------------*/ /* Set RTC Calender Loading */ /*-----------------------------------------------------------------------------------------------------*/ u32Reg = ((sPt->u32Year - DRVRTC_YEAR2000) / 10) << 20; u32Reg |= (((sPt->u32Year - DRVRTC_YEAR2000) % 10) << 16); u32Reg |= ((sPt->u32cMonth / 10) << 12); u32Reg |= ((sPt->u32cMonth % 10) << 8); u32Reg |= ((sPt->u32cDay / 10) << 4); u32Reg |= (sPt->u32cDay % 10); g_u32Reg = u32Reg; DrvRTC_WriteEnable(); RTC->TSSR.HR24 = DRVRTC_CLOCK_24; outpw(&RTC->CLR, (uint32_t)g_u32Reg); /*-----------------------------------------------------------------------------------------------------*/ /* Set RTC Time Loading */ /*-----------------------------------------------------------------------------------------------------*/ u32Reg = ((sPt->u32cHour / 10) << 20); u32Reg |= ((sPt->u32cHour % 10) << 16); u32Reg |= ((sPt->u32cMinute / 10) << 12); u32Reg |= ((sPt->u32cMinute % 10) << 8); u32Reg |= ((sPt->u32cSecond / 10) << 4); u32Reg |= (sPt->u32cSecond % 10); g_u32Reg = u32Reg; DrvRTC_WriteEnable(); outpw(&RTC->TLR, (uint32_t)g_u32Reg); outpw(&RTC->DWR, sPt->u32cDayOfWeek); RTC->TTR.TWKE = sPt->u8IsEnableWakeUp; /* Waiting for RTC settings stable */ while(i32delay--); return E_SUCCESS; }