Will stm32f4 start if VBAT is lo or floating, due to discharged/unfitted cell? - Page 1
Forum section: electronics / general

author: julian1
author_rank: Frequent Contributor
timestamp: June 18, 2023, 12:57:43 am
content: Input muxing at the mcu, switches the source to avoid drawing on the battery (for RTC, LSE, SRAM) when main power is available.But does VBAT still need to be pulled hi/sense threshold for the POR to sequence correctly, and for the MCU to start?The datasheet is a bit unclear,"If no external battery is used in the application, it is recommended to connect the VBAT pin toVDD with a 100 nF external decoupling ceramic capacitor in parallel."A similar question was asked here, but most answers assumed the ability to use a jumper.While the interest was to determine behavior if the battery was indicated, but not fitted or else discharged.https://stcommunity.st.com/t5/stm32-mcu-products/can-i-leave-vbat-unconnected/td-p/363846

author: wek
author_rank: Frequent Contributor
timestamp: June 18, 2023, 10:20:47 am
content: Do you reference to theVBAT-brownout erratum?The mcu - i.e. its VDD domain - will start regardless of VBAT state. However, if during execution in whatever is in startup it will stumble upon unexpected VBAT-domain (mainly RTC) state, well, it's not problem of hardware, but the code not written with such problems in mind.JW

author: julian1
author_rank: Frequent Contributor
timestamp: June 18, 2023, 10:03:21 pm
content: Thanks, that's good information. I only wanted to determine the simple-case - will the MCU start with no battery fitted - because I couldn't find a clear statement to that effect in datasheets/app notes.Although, it is still bad practice to leave a floating CMOS input.So a low-leakage parallel double-diode may help -Use a diode from VDD to VBAT, to avoid the floating input with no battery. And stop discharge from the battery to VDD, when VDD=0V if device is unpowered.And one diode from the cell-battery to VBAT to power the RTC/LSE circuit, and to prevent backflow into the battery, when VDD > battery charge.The disadvantage is the extra diode voltage-drop seen at VBAT, but that's ok. A pfet might substitute as a more idea diode.

author: peter-h
author_rank: Super Contributor
timestamp: June 19, 2023, 02:58:52 pm
content: This is an interesting point.What happens if one tries to access the RTC (e.g. during startup code) and Vbat is below spec. If one reads back garbage, that is OK, but could the CPU hang?My experience of factory-fresh boards with a 0.22F supercap not yet charged is that nothing weird happens, but then the unit has the 3.3V VCC provided so that powers the RTC anyway, surely?I am wondering whether any access to the low power domain should be preceeded by an ADC Vbat measurement?My RTC init code is below and AFAICT it is not doing the required RTC reset, but I am not sure. It is ex Cube MX stuff.Code:/** RTC initialise function.** Set up the RTC hardware and optionally the date/time.* It checks if the last NVRAM location holds a funny value RTC_STATUS_TIME_OK and if not, it loads the RTC* date/time as well, otherwise it just sets up the other registers. Note that this funny value will always* be there OK unless power on the backup RAM has totally died. This value doesn't say anything about the* clock date/time being valid.** This function is called at every power-up.**/uint32_t rtc_init(void){uint32_t status = 0;uint32_t result = 0;// Set handle structurehrtc.Instance = RTC;hrtc.Init.AsynchPrediv = RTC_ASYNC_PREDIV;hrtc.Init.SynchPrediv = RTC_SYNC_PREDIV;hrtc.Init.HourFormat = RTC_HOURFORMAT_24;hrtc.Init.OutPut = RTC_OUTPUT_DISABLE;hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_PUSHPULL;hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;// Enable PWR peripheral clock__HAL_RCC_PWR_CLK_ENABLE();// Allow access to BKP DomainHAL_PWR_EnableBkUpAccess();// Get RTC statusstatus = HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR19);// Check if RTC already initializedif (status == RTC_STATUS_TIME_OK){// Wait for RTC APB registers synchronisation (needed after start-up from Reset)HAL_RTC_WaitForSynchro(&hrtc);// Get date and timechar datetime;get_date_time(datetime);// Clear reset flags__HAL_RCC_CLEAR_RESET_FLAGS();// RTC already initialisedresult = 1;}else {// Start RTC clockRTC_Config();// Initialise RTC and set the Time and DateRTC_TimeTypeDef sTime = {0};RTC_DateTypeDef sDate = {0};// Load Saturday 25th March 2023 00:00:00sDate.WeekDay = RTC_WEEKDAY_SATURDAY;sDate.Month = RTC_MONTH_MARCH;sDate.Date = 25;sDate.Year = 23;HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BIN);sTime.Hours = 0;sTime.Minutes = 0;sTime.Seconds = 0;sTime.TimeFormat = RTC_HOURFORMAT_24;sTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;sTime.StoreOperation = RTC_STOREOPERATION_RESET;HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BIN);// Init RTCHAL_RTC_Init(&hrtc);// Save data to backup registerHAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR19, RTC_STATUS_TIME_OK);// RTC is now initialisedresult = 0;}return result;}It is the classic old RTC issue. There is no way to tell if the time is valid. One can do a sanity check on the registers (and re-init the RTC to some date if invalid) but that's about it. In the box I am doing we check for some magic value in one of the SRAM registers, and if this is not there, the RTC is initialised withCode:void RTC_Config(void){RCC_OscInitTypeDef RCC_OscInitStruct;RCC_PeriphCLKInitTypeDef PeriphClkInitStruct;/* We are updating RTC clock */PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_RTC;/* Do not use PLL */RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;/* LSE is used */RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE;RCC_OscInitStruct.LSEState = RCC_LSE_ON;PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSE;/* Config oscillator */HAL_RCC_OscConfig(&RCC_OscInitStruct);/* Select peripheral clock */HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);/* Enable RTC Clock */__HAL_RCC_RTC_ENABLE();}I wonder what is missing? I seehttp://efton.sk/STM32/gotcha/g62.htmlalso but have difficulty in working out the code for this. This is the original ex-MX RTC code:Code:/*** @brief Initializes the RTC peripheral* @param hrtc pointer to a RTC_HandleTypeDef structure that contains* the configuration information for RTC.* @retval HAL status*/HAL_StatusTypeDef HAL_RTC_Init(RTC_HandleTypeDef *hrtc){/* Check the RTC peripheral state */if(hrtc == NULL){return HAL_ERROR;}/* Check the parameters */assert_param(IS_RTC_HOUR_FORMAT(hrtc->Init.HourFormat));assert_param(IS_RTC_ASYNCH_PREDIV(hrtc->Init.AsynchPrediv));assert_param(IS_RTC_SYNCH_PREDIV(hrtc->Init.SynchPrediv));assert_param (IS_RTC_OUTPUT(hrtc->Init.OutPut));assert_param (IS_RTC_OUTPUT_POL(hrtc->Init.OutPutPolarity));assert_param(IS_RTC_OUTPUT_TYPE(hrtc->Init.OutPutType));if(hrtc->State == HAL_RTC_STATE_RESET){/* Allocate lock resource and initialize it */hrtc->Lock = HAL_UNLOCKED;/* Initialize RTC MSP */HAL_RTC_MspInit(hrtc);}/* Set RTC state */hrtc->State = HAL_RTC_STATE_BUSY;/* Disable the write protection for RTC registers */__HAL_RTC_WRITEPROTECTION_DISABLE(hrtc);/* Set Initialization mode */if(RTC_EnterInitMode(hrtc) != HAL_OK){/* Enable the write protection for RTC registers */__HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);/* Set RTC state */hrtc->State = HAL_RTC_STATE_ERROR;return HAL_ERROR;}else{/* Clear RTC_CR FMT, OSEL and POL Bits */hrtc->Instance->CR &= ((uint32_t)~(RTC_CR_FMT | RTC_CR_OSEL | RTC_CR_POL));/* Set RTC_CR register */hrtc->Instance->CR |= (uint32_t)(hrtc->Init.HourFormat | hrtc->Init.OutPut | hrtc->Init.OutPutPolarity);/* Configure the RTC PRER */hrtc->Instance->PRER = (uint32_t)(hrtc->Init.SynchPrediv);hrtc->Instance->PRER |= (uint32_t)(hrtc->Init.AsynchPrediv << 16U);/* Exit Initialization mode */hrtc->Instance->ISR &= (uint32_t)~RTC_ISR_INIT;/* If CR_BYPSHAD bit = 0, wait for synchro else this check is not needed */if((hrtc->Instance->CR & RTC_CR_BYPSHAD) == RESET){if(HAL_RTC_WaitForSynchro(hrtc) != HAL_OK){/* Enable the write protection for RTC registers */__HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);hrtc->State = HAL_RTC_STATE_ERROR;return HAL_ERROR;}}hrtc->Instance->TAFCR &= (uint32_t)~RTC_TAFCR_ALARMOUTTYPE;hrtc->Instance->TAFCR |= (uint32_t)(hrtc->Init.OutPutType);/* Enable the write protection for RTC registers */__HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);/* Set RTC state */hrtc->State = HAL_RTC_STATE_READY;return HAL_OK;}}One concern is that PA2 is also used for ETH so if the RTC init gets corrupted, ETH could stop working. It looks likesomeRTC config always need to be done, at every power-up.

author: julian1
author_rank: Frequent Contributor
timestamp: June 19, 2023, 07:27:34 pm
content: Quote from: peter-h on June 19, 2023, 02:58:52 pmThe ability to read VBAT with the ADC of f4 is a nice feature. A ST app/note or datasheet I saw also showed an additional circuit - with a nfet controlled by gpio used to put a small load on VBAT to try to increase confidence in the battery voltage reading.If the mcu comes out of long hibernation then the loading of the LSE/ circuity on the battery, is enough for a valid measurement. But in the case of a fast reset/or glitch, the battery has been in an unloaded state due to power muxing. So the suggestion was to first load the battery/VBAT by turning on a nfet/resistor using a GPIO pin, to avoid getting a floating/too high reading.Using a magic number in SRAM seems like a reasonable precaution to identify corruption due to battery concerns. But obviously still doesn't necessarily guarantee the state of other registers. There are probably lots of lurking corner cases if one looks hard.

author: peter-h
author_rank: Super Contributor
timestamp: June 19, 2023, 08:38:33 pm
content: I think RTC CR needs setting up whether or not the magic number is there.I think this code, currently used only if magic number if not found, needs to be run regardlessCode:/* Disable the write protection for RTC registers */__HAL_RTC_WRITEPROTECTION_DISABLE(hrtc);/* Clear RTC_CR FMT, OSEL and POL Bits */hrtc->Instance->CR &= ((uint32_t)~(RTC_CR_FMT | RTC_CR_OSEL | RTC_CR_POL));/* Set RTC_CR register */hrtc->Instance->CR |= (uint32_t)(hrtc->Init.HourFormat | hrtc->Init.OutPut | hrtc->Init.OutPutPolarity);/* Configure the RTC PRER */hrtc->Instance->PRER = (uint32_t)(hrtc->Init.SynchPrediv);hrtc->Instance->PRER |= (uint32_t)(hrtc->Init.AsynchPrediv << 16U);/* Exit Initialization mode */hrtc->Instance->ISR &= (uint32_t)~RTC_ISR_INIT;hrtc->Instance->TAFCR &= (uint32_t)~RTC_TAFCR_ALARMOUTTYPE;hrtc->Instance->TAFCR |= (uint32_t)(hrtc->Init.OutPutType);/* Enable the write protection for RTC registers */__HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);But I can't find where the PA2 etc function is set up. Someone who had trouble with this reported this pin outputting some square wave. That would bugger up ETH function, obviously.The basic problem is that the low power domain can have itsconfigcorrupted without the magic number being corrupted. So, to the extent that date/time is not messed with, the domain config should be initialised at each CPU power-up.Canweksee a problem with the above code?I struggle to see what measuring Vbat would solve, other than the situation where you are powering up a fresh board with a supercap (taking say 5 mins to charge up through 1k), you read the magic number corrupted (obviously) so you fully init the RTC, and then you power down the board, and after say 2 mins you power it up, find the magic number ok, skip the full init, but since the SRAM kept the data better than the config regs, you now have a board which will be duff, until the supercap is allowed to fully discharge.The problem arises because with 3.3V available, the RTC will run just fine.Also a 32F437 is no longer a drop-in for a 32F417 because (this being the only known change, except the 64k extra RAM on the 437) the Vbat ADC mapping differsReading thishttps://stcommunity.st.com/t5/stm32-mcu-products/once-in-a-while-stm32f446-is-unable-to-drive-pin-pa0-high-or-low/m-p/57761I cannot relate what he's doing with BDCR making sense.I suppose one could read Vbat at startup and if below the min value, trash the magic number in the RTC SRAM, forcing a full init.

author: peter-h
author_rank: Super Contributor
timestamp: June 20, 2023, 10:18:28 am
content: I am the 10000th person to work out how to read Vbat with ADC1, given that the yellow bit is duffYou have to set channel 18 explicitly.In fact the ST "HAL" code gets you to set ch 18 and if it sees 18 it sets VBATE=1.

author: peter-h
author_rank: Super Contributor
timestamp: June 20, 2023, 03:17:50 pm
content: Another day down the rabbit hole... done the Vbat measurement and force low power domain reset if below 1.8V (the DS says 1.65V min).That should take care of the case where the target is powered up clean, the magic number is written (because it wasn't there), the supercap charges to say 1.2V, then the target is turned off, then back on after not too long, during which the low power domain config gets corrupted and the RTC has stopped, and the magic number is found OK (because the SRAM held it at 1.2V), but the domain is never re-initialised.Recovery could be "interesting". With a 0.22F supercap you will be ok if powered down for about 10 days (experimentally, RTC stopped after about 5 days; slightly better than spec, based on actual current measurement) but your customer will be jumping up and down well before the 10 days is up.And with a battery you could have even more fun.Hard to believe nobody has found this issue before.But I know, from selling other products with RTCs, that actually very few people use the RTC. It's a bit like an ADSL router; 99.9% of users never care about the time displayed when you go into its config.My modified version:Code:HAL_StatusTypeDef HAL_RTC_Init(RTC_HandleTypeDef *hrtc){uint32_t tmpreg1 = 0U;// Exit if hrtc structure is NULL (should never happen)if(hrtc == NULL){return HAL_ERROR;}/* Disable the write protection for RTC registers */__HAL_RTC_WRITEPROTECTION_DISABLE(hrtc);// Reset the low power domain with RCC_BDCR.BDRST bit. This is from the HAL code HAL_RCCEx_PeriphCLKConfig().// Get just RTCSEL bits into tmpreg1tmpreg1 = (RCC->BDCR & RCC_BDCR_RTCSEL);tmpreg1 = (RCC->BDCR & ~(RCC_BDCR_RTCSEL));// Reset command__HAL_RCC_BACKUPRESET_FORCE();__HAL_RCC_BACKUPRESET_RELEASE();// Restore the original RTCSEL bits in BDCRRCC->BDCR = tmpreg1;/* Clear RTC_CR FMT, OSEL and POL Bits */hrtc->Instance->CR &= ((uint32_t)~(RTC_CR_FMT | RTC_CR_OSEL | RTC_CR_POL));/* Set RTC_CR register */hrtc->Instance->CR |= (uint32_t)(hrtc->Init.HourFormat | hrtc->Init.OutPut | hrtc->Init.OutPutPolarity);/* Configure the RTC PRER */hrtc->Instance->PRER = (uint32_t)(hrtc->Init.SynchPrediv);hrtc->Instance->PRER |= (uint32_t)(hrtc->Init.AsynchPrediv << 16U);/* Exit Initialization mode */hrtc->Instance->ISR &= (uint32_t)~RTC_ISR_INIT;/* If CR_BYPSHAD bit = 0, wait for synchro else this check is not needed */if((hrtc->Instance->CR & RTC_CR_BYPSHAD) == RESET){if(HAL_RTC_WaitForSynchro(hrtc) != HAL_OK){/* Enable the write protection for RTC registers */__HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);hrtc->State = HAL_RTC_STATE_ERROR;return HAL_ERROR;}}hrtc->Instance->TAFCR &= (uint32_t)~RTC_TAFCR_ALARMOUTTYPE;hrtc->Instance->TAFCR |= (uint32_t)(hrtc->Init.OutPutType);/* Enable the write protection for RTC registers */__HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);return HAL_OK;}

author: julian1
author_rank: Frequent Contributor
timestamp: June 20, 2023, 08:05:54 pm
content: QuoteDoes this go to the general point; That if the RTC is only low-priority/ or a nice-to-have feature, then it would be good if the product design allowed the end-user/distributor a choice as to whether to fit a battery or not. Or perhaps cost/price is a real consideration.But without a battery fitted -- VBAT is left floating, and the ADC measurement cannot be trusted, to distinguish a low-charge state, that can be used to clear/reset all backup-domain registers due to the possibility of corruption.- it contradicts ST guidance, that VBAT should be pulled hi if unused.- it goes against best-practice not to leave a cmos input floating - although the pin is probably not directly cmos.Maybe some of this could be solved by loading (temporarily before reading the ADC) the VBAT using gpio PC13 which itself is powered by the battery domain, and will maintain state when the mcu is unpowered. But it adds to complexity.

author: peter-h
author_rank: Super Contributor
timestamp: June 20, 2023, 09:26:56 pm
content: QuoteI may be misunderstanding you but loading already happens, because if you set VBATE=1(and also set channel=18)you connect a resistor divider to Vbat. So if there is nothing connected to Vbat, you will read ~zero. The divider is /2 on 32F417 and /4 on 32F437. I have today found experimentally that Vbat is exactly 3.3V minus the ~0.6V drop on a BAS116 (low leakage diode), which would not be 0.6V if the loading was not there.QuoteYes; I have in the passt made the RTC a factory option.The biggest problem is lousy options for the "battery".I am using a 0.22F supercap, which is expensive enough, ~$1 IIRC. Unlikeallbatteries, it never wears out (batteries generally go short-circuit, thus buggering your product even if powered 24/7) but lasts only a few days. OTOH I have RTC setting from NTP or GPS.Re batteries, I have used a very rare Sanyo 2016 lithium rechargeable cell, made for a short time in the early 1990s. It would run for probably some months - or a few years using a proper RTC like a DS1302 which draws much less than an STM CPU. But this means the shelf like of your product may be just a few years.I also used a common lithium 2032 cell, and a quality one of those will run with a 32F4 for a few years. Or 20+ years with a DS1302 - the shelf life of the battery itself, down to 50% capacity.The other problem with batteries is that the boards need to be handled carefully; a brief short to something will run it down fast.Hence the supercap was chosen...IMHO it is a crap design by STM to not incorporate some feature which is guaranteed to indicate an intervening Vbat dip, with a margin like say 0.3V.I think I may now get what you meant: you want a product which can be sold with a missing battery, with no software changes. Not sure how it could be done simply.

author: julian1
author_rank: Frequent Contributor
timestamp: June 20, 2023, 10:15:19 pm
content: Thanks, that's helpful. In particular, I wasn't aware of the divider that could bias the input, to help identify if the battery is fitted.I haven't tried using a battery yet, and didn't want to cut the trace of a working board to experiment. From the software side, I have used the clock oscillator, and read VBAT, with the ADC alongside reading TEMP.

author: peter-h
author_rank: Super Contributor
timestamp: June 21, 2023, 11:21:26 am
content: The divider is from Vbat to GND.So measuring Vbat should indicate if a battery is present.The problem is with rechargeables - a supercap or a lithium. Normally you will have a circuit like thisand the charging path (via D18) will produce the same voltage on Vbat, about 2.7V, whether the supercap is fitted or not.A lithium battery has a cell voltage of about 3.6V so can't be charged from 3.3V, so you have to get into stuff like checking the above-VCC tolerance of the Vbat pin, because it might have say 5V on it with no battery, but youcanthen detect no-battery because it will measure 5V.

author: wek
author_rank: Frequent Contributor
timestamp: June 26, 2023, 09:45:08 am
content: Just for amusement: today I dug out my prototype of our first product with STM32F407. CR2032 holds OK, at 3.01V. This cell has been inserted when I started working with the RTC, looked up in code archive and it was October 2012, so around 10.5 years. It powers both RTC and BKPSRAM and has seen dozens of measurements (i.e. loads by the 50k divider) daily (upon each restart) during the 3-year development period. Since then it has been mostly sitting on a shelf, so there are no more loads from the measurement but also there are no periods of relief when the VBAT domain would be powered from VDD. I guess it has seen more drain than if it would be used daily for 20 years.The CR2032 is connected directly to VBAT, there is nothing else connected there. I have developed the habit of shorting terminals briefly when removing the cell, as I am removing it only to test BKPSRAM/RTC failures. I don't remember ever having any problem from powering up a board without battery. I guess the few pF of parasitic capacitance of VBAT+empty cell holder charged from VDD during tRSTTEMPO will discharge quickly enough to prevent the erratum-described problem to occur in real life (back-of-the-envelope: 30pF*3.3V/100nA=1ms). With well-behaved power supply, that is (I've seen power supplies pathologically oscillating at powerup/powerdown, with all sorts of "funny" consequences). I don't have a high-impedance scope probe to investigate this in depth and am not interested enough at the moment to build one, maybe in future.JW

author: peter-h
author_rank: Super Contributor
timestamp: June 26, 2023, 02:17:01 pm
content: QuoteThat sounds about right, for the CR2032 in my product, which has a DS1302 drawing around 200nA.One issue is that a lot of batteries are crap / counterfeit / etc. Many years ago I was working on a project which used a Renata (a pricey Swiss make) 2016 cell. We had alotof dud ones. I think the Japanese ones were good.This and other factors is what drives the use of supercaps, but they will merely cause this issue to happen with a higher probability - because any product you make will contain a Vbat source which after a few days has a good probability of being discharged enough to corrupt the RTC and related backup domain config, but not discharged enough to corrupt the magic number.I chose a supercap in this product even though it goes "flat" after just a few days (with a 32F4) because even if one had a power source which lasts 100 years, the RTC will still need periodic setting, because a 32768Hz RTC will never be better than a few mins per year. This CPU has RTC calibration but that takes care of just the 1st order; to get better you need to do multipoing cal over temperature. My RTC gets fixed up via NTP or via GPS.

author: wek
author_rank: Frequent Contributor
timestamp: June 26, 2023, 04:36:15 pm
content: Is time important? Standalone or networked/GPS-dependent? How OK is to lose it? Do you need backup data? Are they changing often? Is the device attended? Is there a mechanism (usually, human) to check the battery and change it in time? Can the battery be exchanged by user without consequences (e.g. HV-inside)? Is there enough space for the battery/supercap? What's the expected longevity of product? Can accumulators be used and a whole new can of worms handled? Can occasional corruption of whatever tolerated? Can external watchdog/reset be employed? Can the increased power consumption due to these tolerated? Can the whole mcu be powered up one time at the bottom of supercap's charge to make some sort of mark? Is there any other magical solution? Can we use free energy(TM) instead? These all are design choices based on available information and experience, and they are consequences we have to cope with. That's all, all the usual stuff.JWPS. Varta. We moved company 10.2021 and I did not touch this box since, and I doubt I touched it for couple of months prior, so that's at least 2 years; it was always indoors so +-5deg.C; clock now lags 5 minutes almost exactly. The oscillator is knowingly designed with non-optimal capacitors (time is entirely not important in this product, was just a gimmick, as we already needed battery because of the BKPSRAM; and we already had 22pF in the BOM so called it good enough) and it is compensated cca 80ppm using the built-in mechanism.

author: peter-h
author_rank: Super Contributor
timestamp: June 27, 2023, 11:13:16 am
content: Well, yes, sure. It depends on whether you want the RTC to work properly, or aren't too bothered. I've been selling two products for 25 years, with an RTC, and I am pretty damn sure that the RTC was used by just one customer, who bought maybe 1-2% of the units.I am not implementing the calibration because it is quite a bit of work. Sample code is provided with the ex-MX "HAL" stuff but it is really hard to understand. I reckon it would take me a week or two to work it out. And without xtal temp measurement you are fixing up only the 1st order error; doing it properly needs a multipoint cal over temperature which is a huge hassle for a feature which- vast majority won't need- those who do need it will probably use the ETH interface so they can use NTP- those who want to avoid NTP (for security etc) can buy the GPS optionFor me the extra cost of the RTC is just the supercap. It's funny; if one has time setting, one could produce a working product (if one has the above time setting options) with some electrolytic cap

author: wek
author_rank: Frequent Contributor
timestamp: June 27, 2023, 12:41:29 pm
content: Quote from: peter-h on June 27, 2023, 11:13:16 amI wrote software for one STM32-based product with RTC without the electrolytic or any other extra VBAT source, and even without the 32.768kHz crystal. Functionality of this device depends on GSM (which is source of time here) anyway, and for the same reason there's a xxMHz crystal on HSE, so what.JW

author: peter-h
author_rank: Super Contributor
timestamp: June 27, 2023, 12:43:56 pm
content: Good point; you could emulate an RTC with just a 1ms (or even 1 sec) interrupt.

author: wek
author_rank: Frequent Contributor
timestamp: June 27, 2023, 02:18:04 pm
content: Quote from: peter-h on June 27, 2023, 12:43:56 pmThat too; but in that particular case I just used the option of STM32 RTC to be clocked from HSE/32, and adjusted RTC prescalers accordingly.JW

author: peter-h
author_rank: Super Contributor
timestamp: June 27, 2023, 05:23:36 pm
content: That's very clever!I've been working on that backup domain reset stuff today. The way ST did it is really complicated e.g. they implement the reset only if any of the bits in that register are different from their reset values. Why??The other oddity is that in the RTC config, after they set the DBP bit (the one which disables backup domain write protection) they wait for it to show the correct value, with a 2ms timeout. But in other code they don't wait; they just disable write protect and write (the date/time) right away.