cancel
Showing results for 
Search instead for 
Did you mean: 

Need help initializing RTC on STM32F407

jimmieh85
Associate
Posted on July 18, 2012 at 22:11

Hi I am trying to write date and time to the RTC which I later will read.

But something in my RTC configuration doesn’t work and reading the values in debug mode shows that the RTC registers that I try to set never get the new values.

Here is my code:

void Set_RTC()

{

/* Enable the PWR clock */

RCC_APB1ENR.PWREN = 1;

/* Allow access to RTC */

PWR_CR.DBP = 1;

/* LSE used as RTC source clock */

RCC_BDCR.LSEON = 1;    //External low-speed oscillator enable

 /* Wait till LSE is ready */

while(RCC_BDCR.LSERDY != 1)

{

}

/* Select the RTC Clock Source to LSE */

RCC_BDCR.F8 = 1;

RCC_BDCR.F9 = 0;

/* Wait for RTC APB registers synchronisation */

while(RTC_ISR.RSF != 1)

{

}

RCC_BDCR.RTCEN = 1;   //Enable RTC clock  <<<

RTC_WPR = 0xCA;   //unlock write protection

RTC_WPR = 0x53;   //unlock write protection

/* Configure the RTC prescaler */

RTC_PRER = 0x7f00ff;  //  set   SynchPrediv to FF and AsynchPrediv to 7F

//RCC_BDCR.RTCEN = 1;   //Enable RTC clock  <<<

RTC_ISR.INIT = 1;     //enter initialization mode <<<<<< THIS REGISTER NEVER GETS THE NEW VALUE

while(RTC_ISR.INITF != 1)   //poll INITF

{

}

/* Configure the RTC PRER */

 RTC_PRER = 0x7F;

 RTC_PRER |= 0xFF << 16;

 RTC_TR = 0x123500; //setting time to 12.35.00

 RTC_DR = 0x126718;  // set date to  2012-07-18

 RTC_CR.F6 = 0; // set FMT 24H format

 RTC_ISR.INIT = 0;     //exit initialization mode

  /* Enable the write protection for RTC registers */

  RTC_WPR = 0xFF;

}

I am using a STM32F407 @ 140Mz internal HSI oscillator.

What am I doing wrong?

42 REPLIES 42
adaehne9
Associate II
Posted on March 06, 2013 at 09:52

ok i get, i should read the frequency of the tamper pin with an oscilloskop or something, right? we will try it

Posted on March 06, 2013 at 18:28

I haven't managed to glean so far what compiler/tool chain you are using. If the problem changes if optimization is on vs off.

If the RTC register are not treated as volatile correctly I could see some optimization issues. You should examine the code generated and step through it.

I'm not sure LSI RDY indicates the clock is actually functioning. I could see issues here if the PWR/RTC or LSI were not clocking, or perhaps you had built code for the LSE path. I'm not sure what board issues would cause the LSI not to start. I've suggested you measure it so you can discount this failure mode. If it is a hardware issue you'd need to check the circuit design, power, etc.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
digital_dreamer
Associate II
Posted on December 14, 2013 at 05:12

Guys, you have to enable access to the RTC backup domain to make this work. Note that this access includes the RTC registers, not just the backup registers and RAM.

I also had this issue, as well. I needed to get the RTC calibration output for 1-Hz and could never enable the COE bit (Calibration Output Enable). However, I found I could turn it on during the RTC init stage, including the RTC_WaitForSynchro. Well, this stage requires the backup domain to be accessible. I couldn't access it later in my code, because it was disabled.

// Enables or disables access to the backup domain (RTC registers, RTC backup data registers and backup SRAM).
PWR_BackupAccessCmd(ENABLE);

This completes my wasting more than a day for me, which isn't too bad compared to other issues. It always seems to be the seemingly simple things that stump me. :p MAJ
subscriptions
Associate II
Posted on September 16, 2014 at 12:00

We had problems with

ERROR

== RTC_EnterInitMode(), where the init flag never became set.

It appeared to be caused because our backup battery failed, and then the RTC entered a weird mode.

To fix it, we issued a

RCC_BackupResetCmd(

ENABLE

);

Which allowed us to get going again.

signx
Associate II
Posted on November 27, 2014 at 12:01

I has the same problem with RTC_ISR_INITF flag. 

I found error in usb_bsp.c file.

  /* enable the PWR clock */

  RCC_APB1PeriphResetCmd(RCC_APB1Periph_PWR, ENABLE); 

  ----->>>

  RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);

cdb1702
Associate II
Posted on September 25, 2015 at 11:19

I wanted to know if this problem with the initialization of the RTC has been solved because too I am in the same situation

Thanks

Carlo De Bonis

Posted on September 25, 2015 at 11:43

Carlo,

start your own thread, stating in detail your problem and the circumstances.

JW
cdb1702
Associate II
Posted on September 25, 2015 at 12:39

Hello JW,

I send you the the list of the function I used

void RTC_Config(void)

{

unsigned char ErrorStatus;

  /* Enable the PWR clock */

  RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);

  /* Allow access to RTC */

  PWR_BackupAccessCmd(ENABLE);

  /* Reset RTC Domain */

  RCC_BackupResetCmd(ENABLE);

RCC_BackupResetCmd(DISABLE);

  /* Enable the LSE OSC */

  RCC_LSEConfig(RCC_LSE_ON);

/*------------------------------------------------------------------------------

The LSERDY flag in the RCC Backup domain control register (RCC_BDCR) indicates 

if the LSE crystal is stable or not. At startup, the LSE crystal output clock 

signal is not released until this bit is set by hardware

------------------------------------------------------------------------------*/

  /* Wait till LSE is ready */  

  while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)

  {

  }

  /* Select the RTC Clock Source */

  RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);

  /* Configure the RTC data register and RTC prescaler */

  RTC_InitStructure.RTC_AsynchPrediv = 0x7F;

  RTC_InitStructure.RTC_SynchPrediv  = 0xFF;

  RTC_InitStructure.RTC_HourFormat   = RTC_HourFormat_24;

  ErrorStatus=RTC_Init(&RTC_InitStructure);

  

  /* Set the time to 01h 02mn 00s AM */

  RTC_TimeStruct.RTC_H12     = RTC_H12_AM;

  RTC_TimeStruct.RTC_Hours   = 0x01;

  RTC_TimeStruct.RTC_Minutes = 0x02;

  RTC_TimeStruct.RTC_Seconds = 0x00;  

  ErrorStatus=RTC_SetTime(RTC_Format_BCD, &RTC_TimeStruct);

}

Notes

Point 1

  while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)

  {

  }

THE  WHILE  IS PASSED BECAUSE THE 32KHZ OSCILLATION IS PRESENT

Point 2

ErrorStatus=RTC_Init(&RTC_InitStructure);

RTC_Init  returns

 ErrorStatus=ERROR

Point 3

 ErrorStatus=RTC_SetTime(RTC_Format_BCD, &RTC_TimeStruct);

RTC_SetTime returns 

ErrorStatus=ERROR

Point 4

 

My board  uses STM32F437IIT6 , 176 pin LQFP

The 32 kHZ oscillation is present because I have tested with an oscilloscope

All the library functions come from  file

stm32f4xx_rtc.c

  * @author  MCD Application Team

  * @version V1.1.0

  * @date    11-January-2013

Thanks in advance

Carlo

Posted on September 25, 2015 at 13:04

I don't see problem in this but I don't use SPL.

Try to do the same through direct register writes in the debugger.

JW

cdb1702
Associate II
Posted on September 25, 2015 at 14:10

The problem is in this function

/**

  * @brief  Enters the RTC Initialization mode.

  * @note   The RTC Initialization mode is write protected, use the 

  *         RTC_WriteProtectionCmd(DISABLE) before calling this function.    

  * @param  None

  * @retval An ErrorStatus enumeration value:

  *          - SUCCESS: RTC is in Init mode

  *          - ERROR: RTC is not in Init mode  

  */

ErrorStatus RTC_EnterInitMode(void)

{

  __IO uint32_t initcounter = 0x00;

  ErrorStatus status = ERROR;

  uint32_t initstatus = 0x00;

  /* Check if the Initialization mode is set */

  if ((RTC->ISR & RTC_ISR_INITF) == (uint32_t)RESET)

  {

    /* Set the Initialization mode */

RTC->ISR = (uint32_t)RTC_INIT_MASK;

    /* Wait till RTC is in INIT state and if Time out is reached exit */

    do

    {

      initstatus = RTC->ISR & RTC_ISR_INITF;

      initcounter++;  

    } while((initcounter != INITMODE_TIMEOUT) && (initstatus == 0x00));

    

    if ((RTC->ISR & RTC_ISR_INITF) != RESET)

    {

      status = SUCCESS;

    }

    else

    {

      status = ERROR;

    }        

  }

  else

  {

    status = SUCCESS;  

  } 

    

  return (status);  

}

/* Wait till RTC is in INIT statet */

RTC does not go to INIT state and the return status is ERROR