Author Topic: Will stm32f4 start if VBAT is lo or floating, due to discharged/unfitted cell?  (Read 4364 times)

0 Members and 1 Guest are viewing this topic.

Offline julian1Topic starter

  • Frequent Contributor
  • **
  • Posts: 781
  • Country: au
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 to
  VDD 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
 

Offline wek

  • Frequent Contributor
  • **
  • Posts: 560
  • Country: sk
Do you reference to the VBAT-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
« Last Edit: June 18, 2023, 10:23:46 am by wek »
 
The following users thanked this post: boB

Offline julian1Topic starter

  • Frequent Contributor
  • **
  • Posts: 781
  • Country: au
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.
 

Offline peter-h

  • Super Contributor
  • ***
  • Posts: 4591
  • Country: gb
  • Doing electronics since the 1960s...
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: [Select]
/*
 * 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 structure
hrtc.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 Domain
HAL_PWR_EnableBkUpAccess();

// Get RTC status
status = HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR19);

// Check if RTC already initialized
if (status == RTC_STATUS_TIME_OK)
{

// Wait for RTC APB registers synchronisation (needed after start-up from Reset)
HAL_RTC_WaitForSynchro(&hrtc);

// Get date and time
char datetime[32];
get_date_time(datetime);

// Clear reset flags
__HAL_RCC_CLEAR_RESET_FLAGS();

// RTC already initialised
result = 1;
}
else {
// Start RTC clock
RTC_Config();

// Initialise RTC and set the Time and Date
RTC_TimeTypeDef sTime = {0};
RTC_DateTypeDef sDate = {0};

// Load Saturday 25th March 2023 00:00:00

sDate.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 RTC
HAL_RTC_Init(&hrtc);

// Save data to backup register
HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR19, RTC_STATUS_TIME_OK);

// RTC is now initialised
result = 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 with

Code: [Select]
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 see http://efton.sk/STM32/gotcha/g62.html also but have difficulty in working out the code for this. This is the original ex-MX RTC code:

Code: [Select]
/**
  * @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 like some RTC config always need to be done, at every power-up.
« Last Edit: June 19, 2023, 03:45:11 pm by peter-h »
Z80 Z180 Z280 Z8 S8 8031 8051 H8/300 H8/500 80x86 90S1200 32F417
 

Offline julian1Topic starter

  • Frequent Contributor
  • **
  • Posts: 781
  • Country: au

I am wondering whether any access to the low power domain should be preceeded by an ADC Vbat measurement?

The 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.
« Last Edit: June 19, 2023, 07:29:07 pm by julian1 »
 

Offline peter-h

  • Super Contributor
  • ***
  • Posts: 4591
  • Country: gb
  • Doing electronics since the 1960s...
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 regardless

Code: [Select]
/* 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 its config corrupted 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.

Can wek see 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 differs :)

Reading this
https://stcommunity.st.com/t5/stm32-mcu-products/once-in-a-while-stm32f446-is-unable-to-drive-pin-pa0-high-or-low/m-p/57761
I 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.
« Last Edit: June 19, 2023, 09:14:58 pm by peter-h »
Z80 Z180 Z280 Z8 S8 8031 8051 H8/300 H8/500 80x86 90S1200 32F417
 

Offline peter-h

  • Super Contributor
  • ***
  • Posts: 4591
  • Country: gb
  • Doing electronics since the 1960s...
I am the 10000th person to work out how to read Vbat with ADC1, given that the yellow bit is duff



You 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.
Z80 Z180 Z280 Z8 S8 8031 8051 H8/300 H8/500 80x86 90S1200 32F417
 

Offline peter-h

  • Super Contributor
  • ***
  • Posts: 4591
  • Country: gb
  • Doing electronics since the 1960s...
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: [Select]

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 tmpreg1
tmpreg1 = (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 BDCR
RCC->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;
}
Z80 Z180 Z280 Z8 S8 8031 8051 H8/300 H8/500 80x86 90S1200 32F417
 

Offline julian1Topic starter

  • Frequent Contributor
  • **
  • Posts: 781
  • Country: au
Quote
But I know, from selling other products with RTCs, that actually very few people use the RTC.

Does 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.
 

Offline peter-h

  • Super Contributor
  • ***
  • Posts: 4591
  • Country: gb
  • Doing electronics since the 1960s...
Quote
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.

I 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.

Quote
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.

Yes; 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. Unlike all batteries, 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.
« Last Edit: June 20, 2023, 09:43:49 pm by peter-h »
Z80 Z180 Z280 Z8 S8 8031 8051 H8/300 H8/500 80x86 90S1200 32F417
 

Offline julian1Topic starter

  • Frequent Contributor
  • **
  • Posts: 781
  • Country: au
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.
« Last Edit: June 20, 2023, 10:54:09 pm by julian1 »
 

Offline peter-h

  • Super Contributor
  • ***
  • Posts: 4591
  • Country: gb
  • Doing electronics since the 1960s...
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 this



and 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 you can then detect no-battery because it will measure 5V.
Z80 Z180 Z280 Z8 S8 8031 8051 H8/300 H8/500 80x86 90S1200 32F417
 

Offline wek

  • Frequent Contributor
  • **
  • Posts: 560
  • Country: sk
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
« Last Edit: June 26, 2023, 09:50:06 am by wek »
 

Offline peter-h

  • Super Contributor
  • ***
  • Posts: 4591
  • Country: gb
  • Doing electronics since the 1960s...
Quote
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.

That 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 a lot of 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.
« Last Edit: June 26, 2023, 02:20:50 pm by peter-h »
Z80 Z180 Z280 Z8 S8 8031 8051 H8/300 H8/500 80x86 90S1200 32F417
 

Offline wek

  • Frequent Contributor
  • **
  • Posts: 560
  • Country: sk
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.

JW

PS. 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.
 

Offline peter-h

  • Super Contributor
  • ***
  • Posts: 4591
  • Country: gb
  • Doing electronics since the 1960s...
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 option :)

For 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 :)
Z80 Z180 Z280 Z8 S8 8031 8051 H8/300 H8/500 80x86 90S1200 32F417
 

Offline wek

  • Frequent Contributor
  • **
  • Posts: 560
  • Country: sk
For 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 :)
I 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
« Last Edit: June 27, 2023, 12:43:17 pm by wek »
 

Offline peter-h

  • Super Contributor
  • ***
  • Posts: 4591
  • Country: gb
  • Doing electronics since the 1960s...
Good point; you could emulate an RTC with just a 1ms (or even 1 sec) interrupt.
Z80 Z180 Z280 Z8 S8 8031 8051 H8/300 H8/500 80x86 90S1200 32F417
 

Offline wek

  • Frequent Contributor
  • **
  • Posts: 560
  • Country: sk
Good point; you could emulate an RTC with just a 1ms (or even 1 sec) interrupt.
That 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
 

Offline peter-h

  • Super Contributor
  • ***
  • Posts: 4591
  • Country: gb
  • Doing electronics since the 1960s...
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.
Z80 Z180 Z280 Z8 S8 8031 8051 H8/300 H8/500 80x86 90S1200 32F417
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf