K82 : how to identify if RTC initialised already ?

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

K82 : how to identify if RTC initialised already ?

1,802 Views
EugeneHiihtaja
Senior Contributor I

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

9 Replies

1,582 Views
EugeneHiihtaja
Senior Contributor I

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

0 Kudos

1,582 Views
mjbcswitzerland
Specialist V

Eugene

The flag is cleared when the timer counter is disabled and something is written to RTC_TSR.

pastedImage_1.png

The TIF flag is also explained in the user's manual:

pastedImage_2.png

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

0 Kudos

1,582 Views
EugeneHiihtaja
Senior Contributor I

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

0 Kudos

1,582 Views
mjbcswitzerland
Specialist V

Eugene

        if ((RTC_SR & RTC_SR_TIF) != 0) {                                // if time invalid

Regards

Mark

0 Kudos

1,582 Views
EugeneHiihtaja
Senior Contributor I

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

0 Kudos

1,582 Views
mjbcswitzerland
Specialist V

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

http://www.utasker.com/kinetis/FRDM-K82F.html

0 Kudos

1,582 Views
kerryzhou
NXP TechSupport
NXP TechSupport

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.

pastedImage_1.png

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!
-----------------------------------------------------------------------------------------------------------------------

1,582 Views
EugeneHiihtaja
Senior Contributor I

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

1,582 Views
kerryzhou
NXP TechSupport
NXP TechSupport

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!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos