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 February 20, 2013 at 12:08

hey!

I got the same problem with changing the RTC_ISR register. It seems that although I unlock the write protection the write protection ist still active. Did you solve that problem or does anybody know why I can't change the values of this register?

Posted on February 20, 2013 at 12:24

In the original post, this

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

clears all other bits in the RCC_BDCR register, including the RTCSEL bits (setting the selector to ''no clock'') and LSEON bit (stopping the oscillator).

[EDIT] This is of course nonsense and I don't know why did I write this back then... :| JW [EDIT]

The new poster should post [relevant portions of] his code for us to chew on it, too.

JW

adaehne9
Associate II
Posted on March 05, 2013 at 15:30

this is the code of my initialization, it is just copied from the example time stamp:

    

      if (RTC_ReadBackupRegister(RTC_BKP_DR0) != 0x32F2)

      {

        /* RTC configuration  */

        RTC_Config();

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

        RTC_InitStructure.RTC_AsynchPrediv = AsynchPrediv;

        RTC_InitStructure.RTC_SynchPrediv = SynchPrediv;

        RTC_InitStructure.RTC_HourFormat = RTC_HourFormat_24;

        /* Check on RTC init */

        if (RTC_Init(&RTC_InitStructure) == ERROR)

        {

          sprintf(buf, ''\n\r        /!\\***** RTC Prescaler Config failed ********/!\\ \n\r'');

          DbgPutString(buf);

        }

      }

void RTC_Config(void)

{

  /* Enable the PWR clock */

  RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);

  /* Allow access to RTC */

  PWR_BackupAccessCmd(ENABLE);

#if defined (RTC_CLOCK_SOURCE_LSI)  /* LSI used as RTC source clock*/

/* The RTC Clock may varies due to LSI frequency dispersion. */

  /* Enable the LSI OSC */

  RCC_LSICmd(ENABLE);

  /* Wait till LSI is ready */

  while(RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET)

  {

  }

  /* Select the RTC Clock Source */

  RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);

  SynchPrediv = 0xFF;

  AsynchPrediv = 0x7F;

#elif defined (RTC_CLOCK_SOURCE_LSE) /* LSE used as RTC source clock */

  /* Enable the LSE OSC */

  RCC_LSEConfig(RCC_LSE_ON);

  /* Wait till LSE is ready */

  while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)

  {

  }

  /* Select the RTC Clock Source */

  RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);

  SynchPrediv = 0xFF;

  AsynchPrediv = 0x7F;

#else

  #error Please select the RTC Clock source inside the main.c file

#endif /* RTC_CLOCK_SOURCE_LSI */

  /* Enable the RTC Clock */

  RCC_RTCCLKCmd(ENABLE);

  /* Wait for RTC APB registers synchronisation */

  RTC_WaitForSynchro();

  /* Enable The TimeStamp */

  RTC_TimeStampCmd(RTC_TimeStampEdge_Falling, ENABLE);

}

ErrorStatus RTC_Init(RTC_InitTypeDef* RTC_InitStruct)

{

  ErrorStatus status = ERROR;

 

  /* Check the parameters */

  assert_param(IS_RTC_HOUR_FORMAT(RTC_InitStruct->RTC_HourFormat));

  assert_param(IS_RTC_ASYNCH_PREDIV(RTC_InitStruct->RTC_AsynchPrediv));

  assert_param(IS_RTC_SYNCH_PREDIV(RTC_InitStruct->RTC_SynchPrediv));

  /* Disable the write protection for RTC registers */

  RTC->WPR = 0xCA;

  RTC->WPR = 0x53;

  /* Set Initialization mode */

  if (RTC_EnterInitMode() == ERROR)

  {

    status = ERROR;

  }

  else

  {

    /* Clear RTC CR FMT Bit */

    RTC->CR &= ((uint32_t)~(RTC_CR_FMT));

    /* Set RTC_CR register */

    RTC->CR |=  ((uint32_t)(RTC_InitStruct->RTC_HourFormat));

 

    /* Configure the RTC PRER */

    RTC->PRER = (uint32_t)(RTC_InitStruct->RTC_SynchPrediv);

    RTC->PRER |= (uint32_t)(RTC_InitStruct->RTC_AsynchPrediv << 16);

    /* Exit Initialization mode */

    RTC_ExitInitMode();

    status = SUCCESS;    

  }

  /* Enable the write protection for RTC registers */

  RTC->WPR = 0xFF;

 

  return status;

}

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;

    DbgPutString(''\r\n ISR: '');

    DbgPutU32(RTC->ISR);

    /* 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);  

}

I can't see what's wrong, because it is exactly the same source code from the example. I found out that the RTC->ISR register did not change although the write protection was disabled.  I would be very thankful if somebody could help me.

Posted on March 05, 2013 at 16:19

And this is on what board, and with which clock?

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

i use the LSI-clock but it's not on a eval board.

we use the stm32f405
Posted on March 05, 2013 at 18:03

Some of that looks to be library code. I'd have to waste a lot of energy framing this into a project.

So how exactly is this failing, how are you diagnosing that? Is it getting to RTC_EnterInitMode(), getting stuck in that? Are some parts just not executing?

Code flow doesn't look unreasonable, do you need to enable the time stamp? Are you using it?

RTC_TimeStampCmd(RTC_TimeStampEdge_Falling, ENABLE);
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
adaehne9
Associate II
Posted on March 06, 2013 at 01:35

yes, this code is from the examples and library code. but  i can't figure out where the mistake is. 

it's failing in the 

RTC_EnterInitMode 

function. it's not able to change the rtc->isr register. That register is alsway on its default values (7). in cause of that i got the output  

 /!\\***** RTC Prescaler Config failed ********/!\\ \n\r'');

the other register before this are changeable and have the suggested values of the data sheet.

it seems that the write protection is still enabled. is there a way to check this? Although  the write-protection should be disabled by writing  

  RTC->WPR = 0xCA;

  RTC->WPR = 0x53;

to the register.

I wanted to use the timestamp for logging some data.
Posted on March 06, 2013 at 07:38

Merging it into another project, and trying the LSI on an STM32F4-Discovery board, and building under Keil.

Seems to run successfully to completion, register returning 0xC7

At this point I guess I'd be concerned by the compiler and the board. I'd want to be very sure the LSI had started, and ticking at the right frequency. You should be able to get it out the TAMPER pin if I recall.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
adaehne9
Associate II
Posted on March 06, 2013 at 09:25

in your project the RTC->ISR register gets the value 0xC7?

Do you mean I should read the TAMPFREQ register to get the frequency of the LSI?