2017-12-05 03:39 PM
Hi,
I was wondering if there is a way to save a few flags or CPU condition before I put the CPU either to SandBy or Stop Mode?
Are there any memory locations that I can write to, then retrieve after woken up from either StandBy or Stop mode?
Thanks,
-Andy
2017-12-05 04:56 PM
RTC backup registers?
EEPROM Emulation?
2017-12-05 06:18 PM
Thank you. I think RTC backup registers are my best option.
2017-12-06 11:02 AM
I've run in a bit of a potential problem. In order to use the RTC backup register, I have to execute this function
at the beginning of the program to select the RTC clock source:
HAL_RCCEx_PeriphCLKConfig();
But based on the STM documentation, if this function is executed, all the RTC backup registers are reset to their default
state, which does present a problem.
After the the uProcessor has woken up from StandBy Mode, I assume I have to initialize all my clock, INCLUDING
the RTC clock which means I have to execute this function: HAL_RCCEx_PeriphCLKConfig(). But if I execute
this function, then all the value in the RTC registers are lost.
So could you provide some feeback how to resolve this issue?
Thanks.
2017-12-06 01:50 PM
Just enable the clocks in the PWR domain, and unlock the PWR/RTC.
/* Enable the PWR clock */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);/* Allow access to Backup Domain */
PWR_BackupAccessCmd(ENABLE);Some of the parts also have 4KB of BKPRAM
In the SPL this is done to get the RTC working, and not stomp on everything if starting via STANDBY
STM32F0xx_StdPeriph_Lib_V1.5.0\Projects\STM32F0xx_StdPeriph_Examples\PWR\PWR_Standby\main.c
static void RTC_Config(void)
{ RTC_InitTypeDef RTC_InitStructure; RTC_TimeTypeDef RTC_TimeStructure; uint32_t LSIFreq = 0;/* Enable the PWR clock */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);/* Allow access to Backup Domain */
PWR_BackupAccessCmd(ENABLE);/* Disable wake-up source(ALARM) to guarantee free access to WUT level-OR input */
RTC_ITConfig(RTC_IT_ALRA, DISABLE);/* Clear Wakeup flag */
PWR_ClearFlag(PWR_FLAG_WU);/* Enable wake-up source(ALARM) to guarantee free access to WUT level-OR input */
RTC_ITConfig(RTC_IT_ALRA, ENABLE);/* Enable the LSI OSC */
RCC_LSICmd(ENABLE);/* Wait till LSI is ready */
while (RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET) {}/* Check if the StandBy flag is set */
if (PWR_GetFlagStatus(PWR_FLAG_SB) != RESET) { /* Clear StandBy flag */ PWR_ClearFlag(PWR_FLAG_SB);/* Check if the StandBy flag is cleared */
if (PWR_GetFlagStatus(PWR_FLAG_SB) != RESET) { while(1); }RTC_WaitForSynchro();
/* No need to configure the RTC as the RTC config(clock source, enable,
prescaler,...) are kept after wake-up from STANDBY */ } else { /* RTC Configuration ******************************************************/ /* Reset Backup Domain */ RCC_BackupResetCmd(ENABLE); RCC_BackupResetCmd(DISABLE);/* Select the RTC Clock Source */
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);/* Enable the RTC Clock */
RCC_RTCCLKCmd(ENABLE);/* Wait for RTC APB registers synchronisation */
RTC_WaitForSynchro();/* Get the LSI frequency: TIM14 is used to measure the LSI frequency */
LSIFreq = GetLSIFrequency();RTC_InitStructure.RTC_HourFormat = RTC_HourFormat_24;
RTC_InitStructure.RTC_AsynchPrediv = 99; RTC_InitStructure.RTC_SynchPrediv = (LSIFreq/100) - 1;RTC_Init(&RTC_InitStructure);
/* Set the time to 01h 00mn 00s AM */
RTC_TimeStructure.RTC_H12 = RTC_H12_AM; RTC_TimeStructure.RTC_Hours = 0x01; RTC_TimeStructure.RTC_Minutes = 0x00; RTC_TimeStructure.RTC_Seconds = 0x00;RTC_SetTime(RTC_Format_BIN, &RTC_TimeStructure);
}}2017-12-11 03:19 PM
Hi Clive,
Thanks for the info very much. Here is what I plan to do, could you comment if this is correct?
I am trying to preserve the HAL structure as much as possible and do not change too much. Thanks.
The function used to setup RTC is : HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit)
Within this function, it checks to see if the RTC clock is selected:
if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RTC) == (RCC_PERIPHCLK_RTC))
{
}
If RCC_PERIPHCLK_RTC is not part of the RCC_PeriphCLKInitTypeDef, then it will not initialize the RTC clock.
So, in the main(), I would check if the uController was from a reset state,
then go ahead and initialize the RTC.
if (__HAL_RCC_GET_FLAG(RCC_FLAG_IWDGRST) == RESET)
PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_LSI;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
But if the uController was from a StandBy wake up mode, then just enable the Power clock and allow access to RTC:
if (__HAL_RCC_GET_FLAG(RCC_FLAG_IWDGRST) != RESET)
{
/* Enable Power Clock*/
__HAL_RCC_PWR_CLK_ENABLE();
/* Allow access to Backup */
HAL_PWR_EnableBkUpAccess();
}
2017-12-11 05:50 PM
I've used this method and it works for Read but gives me an error when I tried to write to RTC backup registers.
I use this function to write to the registers:
void HAL_RTCEx_BKUPWrite(RTC_HandleTypeDef *hrtc, uint32_t BackupRegister, uint32_t Data)
{
uint32_t tmp = 0U;
/* Check the parameters */
assert_param(IS_RTC_BKP(BackupRegister));
tmp = (uint32_t)&(hrtc->Instance->BKP0R);
tmp += (BackupRegister * 4U);
/* Write the specified register */
*(__IO uint32_t *)tmp = (uint32_t)Data;
}
The last line *(__IO uint32_t *)tmp = (uint32_t)Data gives me a Hard_Fault error which ends up calling this function:
/**
* @brief This function handles Hard fault interrupt.
*/
void HardFault_Handler(void)
{
while (1)
{
}
}
Do you know what could be the reason?
Thanks.