2021-09-03 11:40 AM
2021-09-05 08:22 AM
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?
2021-09-03 12:40 PM
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
2021-09-04 06:14 AM
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) {};
2021-09-04 09:05 AM
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
2021-09-05 08:22 AM
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?
2021-09-05 09:21 AM
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