K82 : how to identify if RTC initialised already ?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello !
In SDK examples, RTC is always initialized with some date/time after reboot.
But on practice, default time should be set only if RTC is not initialized yet or lost time and etc.
What is correct initialization sequence for enable all what is need and set default time if RTC dosn't have correct time yet ?
After some experiments, I can see that kRTC_AlarmFlag is set if RTC dosn't have any initialisation values yet.
Could you suggest right sequence what should be executed every time when MCU has SW or HW reset ?
Now I have someting like this:
/* Init RTC */
rtc_config_t rtcConfig;
/*
* rtcConfig.wakeupSelect = false;
* rtcConfig.updateMode = false;
* rtcConfig.supervisorAccess = false;
* rtcConfig.compensationInterval = 0;
* rtcConfig.compensationTime = 0;
*/
RTC_GetDefaultConfig(&rtcConfig);
RTC_Init(RTC, &rtcConfig);
/* Select RTC clock source, RTC 32KHz oscillator. */
RTC_SetClockSource(RTC);
/* Start the RTC time counter */
RTC_StartTimer(RTC);
/* Get RTC status. If it set already. */
uint32_t status = RTC_GetStatusFlags(RTC);
if (status & kRTC_AlarmFlag /*kRTC_TimeInvalidFlag*/)
{
RTC_ClearStatusFlags(RTC, kRTC_AlarmFlag);
rtc_datetime_t date;
/* Set a start date time and start RT */
date.year = 2018U;
date.month = 8U;
date.day = 6U;
date.hour = 19U;
date.minute = 0;
date.second = 0;
/* RTC time counter has to be stopped before setting the date & time in the TSR register. */
RTC_StopTimer(RTC);
/ * Set RTC time to default */
RTC_SetDatetime(RTC, &date);
/* Start the RTC time counter */
RTC_StartTimer(RTC);
}
Regards,
Eugene
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Mark !
So this is flag kRTC_TimeInvalidFlag in RTC status register.
Should it be cleaned explicitly when everything is configured or it vanish automatically ?
Regards,
Eugene
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Eugene
The flag is cleared when the timer counter is disabled and something is written to RTC_TSR.
The TIF flag is also explained in the user's manual:
however don't get fooled by the note about it being set on a software reset since this actually means the "RTC software reset" command (via RTC_CR) and not a general processor reset.
Regards
Mark
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Mark !
Thank you !
But what exact trick is recommended by NXP for identify if RTC running after reboot already and no need to reinitialise all
parameters again ?
Regards,
Eugene
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Eugene
if ((RTC_SR & RTC_SR_TIF) != 0) { // if time invalid
Regards
Mark
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Kerry !
I can see picture is more complicate. Config tool ( I'm using latest MCUEXpresso and SDK ) generate the next function for RTC clock initialization.
And this sequence have effect for my RTC initialization what is executed later on.
/*FUNCTION**********************************************************************
*
* Function Name : CLOCK_CONFIG_SetRtcClock
* Description : This function is used to configuring RTC clock including
* enabling RTC oscillator.
* Param capLoad : RTC oscillator capacity load
* Param enableOutPeriph : Enable (1U)/Disable (0U) clock to peripherals
*
*END**************************************************************************/
static void CLOCK_CONFIG_SetRtcClock(uint32_t capLoad, uint8_t enableOutPeriph)
{
/* RTC clock gate enable */
CLOCK_EnableClock(kCLOCK_Rtc0);
if ((RTC->CR & RTC_CR_OSCE_MASK) == 0u) { /* Only if the Rtc oscillator is not already enabled */
/* Set the specified capacitor configuration for the RTC oscillator */
RTC_SetOscCapLoad(RTC, capLoad);
/* Enable the RTC 32KHz oscillator */
RTC->CR |= RTC_CR_OSCE_MASK;
}
/* Output to other peripherals */
if (enableOutPeriph) {
RTC->CR &= ~RTC_CR_CLKO_MASK;
}
else {
RTC->CR |= RTC_CR_CLKO_MASK;
}
/* Set the XTAL32/RTC_CLKIN frequency based on board setting. */
CLOCK_SetXtal32Freq(BOARD_XTAL32K_CLK_HZ);
/* Set RTC_TSR if there is fault value in RTC */
if (RTC->SR & RTC_SR_TIF_MASK) {
RTC -> TSR = RTC -> TSR;
}
/* RTC clock gate disable */
CLOCK_DisableClock(kCLOCK_Rtc0);
}
And first power on reset , show 0 status and default time what is in registers
-- RTC ( status 0x0 ) -> 1970-01-01 00:00:00
-- Power-on Reset
And after SW reset ( NVIC_SystemReset() ) status is set to 0x4 what means kRTC_AlarmFlag ( ? )
And I configure RTC according SDK example.
-- RTC ( status 0x4 ) -> 2018-08-08 19:00:00
-- Software Reset
It means I should just do the next sequence.
1. Enable RTC clock
CLOCK_EnableClock(kCLOCK_Rtc0);
2. Read Year register and if it 1970 ( or less than 2018)
Execute full initialization sequence , like in SDK example.
3. Clean RTC status if Alarm is set there.
Is any glue why it is set over SW reset ?
What do you think about this sequence ?
Unfortunately it is not part of SDK and we should design it.
Regards,
Eugene
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Eugene
You can also use the RTC method from the uTasker open source project which is a complete implementation rather than examples as a starting point. You just need to use the relevant content from its kinetis_RTC.h file and the time_keeper.c file which then implements a complete Gregorian calendar method with various alarms, time zone and daylight saving time features: http://www.utasker.com/docs/uTasker/uTasker_Time.pdf
Try the K82 simulator too since it emulates the RTC in the chip and allows full testing without need for HW, with more advanced debugging capabilities.
Regards
Mark
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Eugene,
Do you just want to check whether RTC is initialized?
If yes, you just need to compare the register with the reset value.
Actually, if the RTC is configured, and want the RTC to run, you need to enable the RTC_CR_OSCE.
static inline void RTC_SetClockSource(RTC_Type *base)
{
/* Enable the RTC 32KHz oscillator */
base->CR |= RTC_CR_OSCE_MASK;
}
About the detail initialize flow, you can refer to the SDK RTC project in sdk folder:
FRDM-K82F\boards\frdmk82f\driver_examples\rtc
Wish it helps you!
If you still have question about it, please kindly let me know.
Have a great day,
Kerry
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Kerry !
So initialisation flow after HW/SW reboot can be like this:
- enable RTC clock source
- read few RTC registers or one for example RTC control register
- if control register has default value -> reinitialize RTC according SDK example ( full flow )
- clean all flags in status register if any
- RTC is continue to run as usually.
But what about Time Invalid flag ?
"
Time Invalid Flag
The time invalid flag is set on VBAT POR or software reset. The TSR and TPR do not increment and read
as zero when this bit is set. This bit is cleared by writing the TSR register when the time counter is
disabled.
"
It should indicate software reset and etc.
Regards,
Eugene
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Eugene,
After reset, the TIF in default is 1, it means the time is invalid.
If you want to enable the time valid, you must write 1 to this bit.
After you initialize the RTC, you also need to start timer, then the RTC will run:
RTC_StartTimer(RTC);
The flow, please refer to the SDK rtc project:
RTC_Init();
RTC_SetClockSource(RTC);
RTC_StopTimer(RTC);
RTC_SetDatetime(RTC, &date);
RTC_StartTimer(RTC);
If you want to use interrupt, you also need to enable the interrupt bit, and the NVIC RTC IRQ.
Wish it helps you!
Have a great day,
Kerry
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------