cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F103 Multiple wakeup sources detection. Unable to read RTC_CRL[ALRF] flag after reset from STBY

Cgelectronics
Associate II

Hello,

In this thread, I would like to clarify a point regarding how to read the RTC_CLR[ALRF] flag. I am using the STM32F103C8T6 microcontroller and the STM32Cube Firmware (HAL) version 1.8.5. This flag indicates that the alarm has been activated.

My intention is to determine the reason for the system reset, as I have configured two ways to exit the STANDBY mode before enabling it:

1. Through the wakeup pin.
2. Through the activation of the alarm.

To achieve this, I am trying to read the RTC_CRL[ALRF] bit after returning from STANDBY mode and executing the functions HAL_Init(); and SystemClock_Config(); The result I obtain is somewhat curious. When the debugger is connected (Stlink V2), the flag is correctly activated after the system reset. However, when I disconnect the debugger and perform logging through UART, the bit never gets activated, even though it is the alarm that causes the system reset.

Cgelectronics_2-1695502691819.png

I have created my own function to read the register following the instructions I´ve found on the reference manual and on AN2629, and it must be executed before the function MX_RTC_Init(); generated automatically by the STMCUBE IDE. This is because MX_RTC_Init includes the HAL_RTC_Init function, which clears the ALRF flag during RTC initialization.

Cgelectronics_0-1695500851362.png

Cgelectronics_1-1695501377490.png

#define RTC_REG (0x40002800)
RTC_TypeDef *Rtc = (RTC_TypeDef *) RTC_REG;
static char message_buffer[30];

static uint8_t ALRF_Get_Flag (uint8_t *alrf){
	uint32_t tickstart = 0U;
	uint8_t ret_val = HAL_OK;

	/* Clear RSF flag */
	CLEAR_BIT(Rtc->CRL, RTC_FLAG_RSF);

	tickstart = HAL_GetTick();

	/* Wait the registers to be synchronised */
	while (READ_BIT(Rtc->CRL, RTC_CRL_RSF) != (RTC_CRL_RSF))
	{
		if ((HAL_GetTick() - tickstart) >  2000)
		{
			ret_val = HAL_TIMEOUT;
		}
	}

	*alrf = (uint8_t)(READ_BIT(Rtc->CRL, RTC_CRL_ALRF) == (RTC_CRL_ALRF)? 1:0);

	return ret_val;
}

int main(void)
{
	/* USER CODE BEGIN 1 */
	uint8_t flag_check;
	/* USER CODE END 1 */

	/* MCU Configuration--------------------------------------------------------*/

	/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
	HAL_Init();

	/* USER CODE BEGIN Init */

	/* USER CODE END Init */

	/* Configure the system clock */
	SystemClock_Config();

	/* USER CODE BEGIN SysInit */
	/* Configure the system Power */
	SystemPower_Config();
	/* USER CODE END SysInit */

	/* Initialize all configured peripherals */
	MX_GPIO_Init();
	MX_I2C2_Init();
	MX_USART1_UART_Init();

	ALRF_Get_Flag(&flag_check);
	if(flag_check == 1){
		(void)snprintf (message_buffer, (size_t)50, "RTC_WKPU - RTC_CLR[ALRF]: %d\r\n", flag_check);
		HAL_UART_Transmit(&huart1, (uint8_t *)message_buffer, strlen (message_buffer), HAL_MAX_DELAY);
	}else{
		(void)snprintf (message_buffer, (size_t)50, "PIN WKPU - RTC_CLR[ALRF]: %d\r\n", flag_check);
		HAL_UART_Transmit(&huart1, (uint8_t *)message_buffer, strlen (message_buffer), HAL_MAX_DELAY);
	}
/*...*/
}

My solution to this problem is as follows:
After a system reset following a return from STANDBY mode due to a rising edge on pin PA0 or the activation of the RTC alarm, we can read the PWR_FLAG_SB flag using the macro: __HAL_PWR_GET_FLAG(PWR_FLAG_SB). This way, I can confirm that a reset has occurred. To determine the cause of the reset, I read the current time and compare it with the time I had set for the alarm (previously saved in backup registers or flash memory). If both times are equal, the reset reason is the RTC; otherwise, it's the PA0 pin. This solution works, but in my opinion, it may not be the best one.

My questions are as follows:

1. Does anyone in this community or who works at ST Microelectronics know if it is possible to read the RTC_CRL[ALRF] flag the way I am attempting to do it?

2. Is there a way to achieve this using only the HAL firmware STM32Cube FWF1 V1.8.5?

3. Why do I only see the flag active when I am in DEBUG mode and not when the software is running normally?

If anyone finds this post interesting and knows the solution to my questions, I would appreciate it if you could leave a comment.

Thank you in advance!

1 ACCEPTED SOLUTION

Accepted Solutions

Hello @Piranha

Thanks for your answer, I would like to complete my response since my comment does not sufficiently clarify the solution to this thread. Here is the necessary information:

The ALRF bit is part of RTC_CR register, not ALR - this can be seen e.g. in the figure just above, the paragraph from the reference manual i´ve posted. And this register is not part of the backup domain.


When debugging during this time, then the MCU is not really in standby - the debug enable bit is active. This means that the core is still clocked along with all the registers and thus they are not reset. In normal conditions, debug does not provide power / clock to the core and peripherals.

View solution in original post

7 REPLIES 7
Issamos
Lead II

Hello @Cgelectronics 

I think you can read the ALRF flag directly using the __HAL_RTC_ALARM_GET_FLAG(hrtc, RTC_FLAG_ALRAF). 

Best regards.

II

Hello @Issamos , what you say is correct, but using that function to read the flag does not influence the result; I have already tested it, and the result is the same. Also is needed to wait for the RSF (Register Synchronized Flag) bit after waking up from standby mode. After a reset caused by the scheduled RTC alarm, if I have the debugger connected, it reads the ALRF flag correctly. However, if I disconnect the debugger and check the value of the variable again (I print the flag's value through the serial port), I see that the ALRF flag is 0 after the system has restarted due to the RTC alarm activation. I will continue investigating this issue and will share the results in this post.

I will try to:

  1. Review the power supply of the STM32F103C8T6 Mcu, i´m not sure but maybe there is an issue on the PCB traces.
  2. Veryfy what is inside the HAL_RTC_Init to check the posibility to read the ALRF flag inside, Perhaps this option was not considered in this HAL version, and there is no way to check the wakeup source without changing the HAL software.

Hello @Piranha,

First of all, thanks for your answer.

You´ve shared one link that contains one interesting option that i did not test regardind the debug status during low power modes.

 

#ifdef NDEBUG
	DBGMCU->CR = 0; // Disable debug, trace and IWDG in low-power modes
#endif

 

Also this option can be disabled on the debug configurations of the STM32CUBE IDE 1.13.2. I´m not sure if a new compilation flag is generated/removed by enabling/disabling this option.

Cgelectronics_0-1696022081393.png

I will investigate it and share with you my results. 

Cgelectronics
Associate II

 After many attempts and tests, I have opened a ticket with ST, and this is the answer to this topic:

"It turns out that the ALRF flag (and indeed the whole register) is not kept through system reset - which occurs at wake up. Although this is not explicitly documented. The only similar flag that is kept is WUF in PWR_CSR register but this is combines wakeup from button and RTC alarm so not helpful in your case.
The solution is then the one you already applied - compare the current time to a predefined one from Flash/backup registers."

Piranha
Chief II

As can be seen even in your screenshot, the RM0008 section 18.3.2 "Resetting RTC registers" documents the reset factor very clearly:
All system registers are asynchronously reset by a System Reset or Power Reset, except for RTC_PRL, RTC_ALR, RTC_CNT, and RTC_DIV.

There is no RTC_CRL register in the list of exceptions, therefore it is reset and it is documented. But, of course, ST's support stuff also cannot see it...

Hello @Piranha

Thanks for your answer, I would like to complete my response since my comment does not sufficiently clarify the solution to this thread. Here is the necessary information:

The ALRF bit is part of RTC_CR register, not ALR - this can be seen e.g. in the figure just above, the paragraph from the reference manual i´ve posted. And this register is not part of the backup domain.


When debugging during this time, then the MCU is not really in standby - the debug enable bit is active. This means that the core is still clocked along with all the registers and thus they are not reset. In normal conditions, debug does not provide power / clock to the core and peripherals.