cancel
Showing results for 
Search instead for 
Did you mean: 

RTC LSE Bypass - I wrote code that RTC works with HSE as clock in, but the same code using LSEBYP w/ external 32KHz oscillator can't get past LSERDY not INITF. Any docs found so far mentions LSEBYP but none indicates how it all works together.

GLero.1
Associate II
 
1 ACCEPTED SOLUTION

Accepted Solutions
GLero.1
Associate II

Thanks for this info. This should be very useful.

The define ...RTCEN you provided is close to what I was looking for, but I originally could only find defines of "...RTCEN" that were 0x1 not 0x1<<15. This would make coding extreeemely cumbersome so I defined my own. I will have to revisit that since you've shown me they do exist. However, a second reason I defined my own is I don't like to type "_" plus the value RTCEN must be used in RCC->BDCR. As I already know the constant is used in that register, why do I want to type "RCC_BCDR_" every time I use "RTCEN"? So I defined my own that are the short version of the bit name. And I wanted the constant to explicitly say what I am doing, hence RTCENon and RTCENoff.

That I was only setting the _S was a mistake. When I was writing my first response, I found several issues with my code that I have corrected, that one in particular had a visible affect. That was why the RTC was running very fast.

Using an actual complete BCD number instead of the separated BCD digits is extremely useful information. I have read the references and coded the assignments several times never made the connection, and probably never would have made the connection. So much easier.

Thanks again for the info.

A silly question however, I am a newbie to the community, how do I mark it as "best" to close it out?

View solution in original post

5 REPLIES 5

Which STM32?

Read out and check/post relevant RCC (at least RCC_BDCR) and RTC registers content.

Some STM32 allow to routing LSE to MCO output, that then enables to check if LSE is correctly running.

JW

GLero.1
Associate II

I was in the process of composing this when I realized my oscillator was connected to pin 4, not 3. The 32KHz is at 32K out MCO1. Things initialize correct at this point except the clock is running very fast, as if the pre-divide is not dividing. The HSE code was working fine, however. And now I see my PREDIV_A was actually being put into PREDIV_S (you can see in the code below). Fixed and now everything is working correct. Thanks for the time.

----------

I am working with a STM32F730R8T6, hse is at 24MHz, pll is at 216MHz, lse is 32768Hz oscillator (is getting to pin 3)

RCC->AHB1ENR = ((RCC->AHB1ENR & (BKPSRAMENmsk)) | (BKPSRAMENon)); // Enable the Backup SRAM clock

RCC->APB1ENR = ((RCC->APB1ENR & (PWRENmsk)) | (PWRENon)); // Enable the Power Interface

RCC->APB1ENR = ((RCC->APB1ENR & (RTCAPBENmsk)) | (RTCAPBENon)); // Enable the RTC APB clock

RCC->CFGR = ((RCC->CFGR & (MCO1msk & MCO1PREmsk)) | (MCO1hse | MCO1PREdiv4));

RCC->BDCR |= ( RTCENon ); // Enable RTC

GPIOA->MODER = 0xA8000000 | GPIO8MODEalt;

GPIOA->OTYPER = GPIO8OTYPEpushpull;

GPIOA->OSPEEDR = GPIO8OSPEEDveryhigh;

GPIOA->PUPDR = 0x64000000 | GPIO8PUPDnone;

GPIOA->AFRH = GPIOA8AFmco1;

GPIOC->MODER = GPIO14MODEalt;

GPIOC->OTYPER = GPIO14OTYPEopendrain;

GPIOC->OSPEEDR = GPIO14OSPEEDhigh;

GPIOC->PUPDR = 0x00000100 | GPIO14PUPDnone;

PWR->CR1 = ((PWR->CR1 & (DBPmsk)) | (DBPnotprotected)); // Unlock the backup domain registers

RCC->BDCR = ((RCC->BDCR & (BDRSTmsk)) | (BDRSTon)); // Put Backup Domain into reset mode

RCC->BDCR = ((RCC->BDCR & (BDRSTmsk)) | (BDRSToff)); // Take Backup Domain out off reset mode

// RCC->CFGR = ((RCC->CFGR & (RTCPREmsk)) | (RTCPREval)); // Set 1MHz pre-scaler for RTC using HSE

// RCC->BDCR = ((RCC->BDCR & (RTCSELmsk)) | (RTCSELhse)); // Select HSE as the RTC clock input

RCC->BDCR = ((RCC->BDCR & (LSEBYPmsk)) | (LSEBYPon)); // Bypass the LSE to use ext. oscillator

RCC->BDCR = ((RCC->BDCR & (LSEONmsk)) | (LSEONon)); // Turn on the LSE

while ((RCC->BDCR & (LSERDYbit)) == 0) {}; // Wait for the LSE to be ready <<<<<<<<<< HANGS HERE

RCC->BDCR = ((RCC->BDCR & (RTCSELmsk)) | (RTCSELlse)); // Select LSE as the RTC clock input

RCC->BDCR = ((RCC->BDCR & (RTCENmsk)) | (RTCENon) ); // Enable RTC

RTC->WPR = 0xCA; RTC->WPR = 0x53;

RTC->ISR = ((RTC->ISR & (INITmsk)) | (INITon));

while ((RTC->ISR & INITFbit) == 0) {}; // Wait for INIT mode <<<<<<<<<<<<<< OR HANGS HERE

// RTC->PRER = (99<<PREDIV_Apos);

// RTC->PRER = ((RTC->PRER & PREDIV_Smsk) | (9999<<PREDIV_Spos));

RTC->PRER = (127<<PREDIV_Spos);

RTC->PRER = ((RTC->PRER & RTCDIV_Smsk) | (255<<PREDIV_Spos));

// To be removed after RTC system is maintained by backup battery

RTC->TR = ((0<<HTpos) | (6<<HUpos) | (0<<MNTpos) | (1<<MNUpos) | (0<<STpos) | (0<<SUpos) | (PMam24));

RTC->DR = ((2<<YTpos) | (1<<YUpos) | (WDUsaturday<<WDUpos) | (0<<MTpos) | (8<<MUpos) | (2<<DTpos) | (8<<DUpos));

//---------

RTC->ISR = ((RTC->ISR & (INITmsk)) | (INIToff));

// while ((RTC->ISR & INITFbit) == 1) {};

Thanks for coming back with the solution. Please select your post as "Best" so that the thread is marked as resolved.

Note, that RTC_PRER requires always two writes as per description of this register in RM. That's indeed what your code actually does, although you change only the synchronous prescaler, I'm not sure if you do that intentionally.

[STYLE thus matter of personal preference]

You appear to have defined lots of symbols with register-related constants. Are you aware of the fact that the CMSIS-mandated device header - from which you already use e.g. definition of the RTC registers - do contain most of these symbols too? I know not all of them - especially values of multi-bit fields (and if they do, it's in a non-systemic manner), but anyway, I believe it pays off to use them where they are available:

RCC->BDCR |= ( RTCENon ); // Enable RTC

vs.

RCC->BDCR |= RCC_BDCR_RTCEN;

This particular case:

RTC->TR = ((0<<HTpos) | (6<<HUpos) | (0<<MNTpos) | (1<<MNUpos) | (0<<STpos) | (0<<SUpos) | (PMam24));

is IMO better to be written as

RTC->TR = 0x060100 + (0 * RTC_TR_PM);

given fields are BDC, in this way the time is "naturally readable", e.g. one minute to midnight in 24h notation is 0x235900.

[/STYLE]

JW

GLero.1
Associate II

Thanks for this info. This should be very useful.

The define ...RTCEN you provided is close to what I was looking for, but I originally could only find defines of "...RTCEN" that were 0x1 not 0x1<<15. This would make coding extreeemely cumbersome so I defined my own. I will have to revisit that since you've shown me they do exist. However, a second reason I defined my own is I don't like to type "_" plus the value RTCEN must be used in RCC->BDCR. As I already know the constant is used in that register, why do I want to type "RCC_BCDR_" every time I use "RTCEN"? So I defined my own that are the short version of the bit name. And I wanted the constant to explicitly say what I am doing, hence RTCENon and RTCENoff.

That I was only setting the _S was a mistake. When I was writing my first response, I found several issues with my code that I have corrected, that one in particular had a visible affect. That was why the RTC was running very fast.

Using an actual complete BCD number instead of the separated BCD digits is extremely useful information. I have read the references and coded the assignments several times never made the connection, and probably never would have made the connection. So much easier.

Thanks again for the info.

A silly question however, I am a newbie to the community, how do I mark it as "best" to close it out?

You should see "Select as Best" at the bottom of each post (I don't see them as only those who started the thread see them), just click on the one in your second post.

JW