cancel
Showing results for 
Search instead for 
Did you mean: 

STM32L476RC RTC run, wakeup and standby mode problems

SLesh.1
Associate III

Hi here,

I have made a prototype with STM32L476RG on Nucleo-board - MCU are doing some task and go to standby mode with wakeup from RTC (1 Hz counter). The code was migrated into my own board with STM32L476RC - RTC doesn't work correctly - MCU goes to Standby, but never wakeup.

I have made the simplest one project for test - only RTC and UART3 for debuging. It works very strange. Source was generated by CubeMX 1.4.0.

HAL_RTC_GetTime(&hrtc, &currentTime, RTC_FORMAT_BCD) returns the same time. But if I do hard reset (f.e. flash new firmware) it gets new time (I'm not set time in the app) - RTC runs! But wakeup doesn't work. RTC works in both case from LSI.

static void MX_RTC_Init(void)
{
 
  /* USER CODE BEGIN RTC_Init 0 */
 
  /* USER CODE END RTC_Init 0 */
 
  /* USER CODE BEGIN RTC_Init 1 */
 
  /* USER CODE END RTC_Init 1 */
  /** Initialize RTC Only
  */
  hrtc.Instance = RTC;
  hrtc.Init.HourFormat = RTC_HOURFORMAT_24;
  hrtc.Init.AsynchPrediv = 127;
  hrtc.Init.SynchPrediv = 255;
  hrtc.Init.OutPut = RTC_OUTPUT_DISABLE;
  hrtc.Init.OutPutRemap = RTC_OUTPUT_REMAP_NONE;
  hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
  hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
  if (HAL_RTC_Init(&hrtc) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN RTC_Init 2 */
 
  /* USER CODE END RTC_Init 2 */
 
}
 
 
int main(void)
{
  /* USER CODE BEGIN 1 */
 
  /* 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 */
 
  /* USER CODE END SysInit */
 
  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_RTC_Init();
  MX_USART3_UART_Init();
  /* USER CODE BEGIN 2 */
 
  /* USER CODE END 2 */
 
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
		RTC_TimeTypeDef currentTime;
 
		char message[22];
		if (HAL_RTC_GetTime(&hrtc, &currentTime, RTC_FORMAT_BCD) == HAL_OK) {
 
			sprintf(message,"%.2x:%.2x:%.2x", currentTime.Hours, currentTime.Minutes, currentTime.Seconds );
			debug_print_message(message);
		}
		else
			debug_error();
 
		HAL_Delay(2000);
 
		if (HAL_RTC_GetTime(&hrtc, &currentTime, RTC_FORMAT_BCD) == HAL_OK) {
 
			sprintf(message,"%.2x:%.2x:%.2x", currentTime.Hours, currentTime.Minutes, currentTime.Seconds );
			debug_print_message(message);
		}
		else
				debug_error();
 
		HAL_Delay(2000);
 
    /* USER CODE END WHILE */
 
    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

UART output:

12:21:52

12:21:52

After re-flash:

12:25:09

12:25:09

The original code with wakeUp that works on STM32L476RG Nucleo board:

/**
/* Battery saving mode
*/
void sleepMode(uint32_t timeout) { // timeout in seconds
 
	HAL_PWR_DisableWakeUpPin(PWR_WAKEUP_PIN1); //
	HAL_PWR_DisableWakeUpPin(PWR_WAKEUP_PIN2); //
	HAL_PWR_DisableWakeUpPin(PWR_WAKEUP_PIN3); //
	HAL_PWR_DisableWakeUpPin(PWR_WAKEUP_PIN4); //
	HAL_PWR_DisableWakeUpPin(PWR_WAKEUP_PIN5); // Disable all used wake up sources
 
	HAL_RTCEx_DeactivateWakeUpTimer(&hrtc); // disable wake up RTC interrupt
 
	__HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU); //
	__HAL_PWR_CLEAR_FLAG(PWR_FLAG_WUFI); // clear wake up flags
 
	// check timeout
	if (timeout < 0x10001) { // less 18 hours
 
		if (HAL_RTCEx_SetWakeUpTimer_IT(&hrtc, timeout - 1, RTC_WAKEUPCLOCK_CK_SPRE_16BITS) != HAL_OK) {
 
			Error_Handler();
		}
	}
	else if ((timeout >= 0x10001 ) & (timeout <= 0x1FFFF )) { // more then 18 hours
 
		if (HAL_RTCEx_SetWakeUpTimer_IT(&hrtc, timeout - 1, RTC_WAKEUPCLOCK_CK_SPRE_17BITS) != HAL_OK) {
 
			Error_Handler();
		}
	}
	else { // invalid value - set maximum - 36 hours
 
		if (HAL_RTCEx_SetWakeUpTimer_IT(&hrtc, 0x1FFFF, RTC_WAKEUPCLOCK_CK_SPRE_17BITS) != HAL_OK) {
 
			Error_Handler();
		}
	}
 
	HAL_PWR_EnterSTANDBYMode(); // go to standby mode
}

Init the system when it runs:

void system_init(void) {
 
	__HAL_RCC_PWR_CLK_ENABLE();
 
	if(__HAL_PWR_GET_FLAG(PWR_FLAG_SB) != RESET) { // check wake up
 
		__HAL_PWR_CLEAR_FLAG(PWR_FLAG_SB); // clear standby flag
 
#if DEBUG
		HAL_UART_Transmit(&huart3, "wakeup\r\n", 8, 100);
#endif
 
	}
	else { // the first start
		RTC_AlarmConfig(); // set default RTC settings // TODO ...
 
#if DEBUG
		HAL_UART_Transmit(&huart3, "run\r\n", 5, 100);
#endif
 
	}
 
	HAL_RTCEx_DeactivateWakeUpTimer(&hrtc); // disable wake up interrupts
 
	__HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU); // clear wake up flags
	__HAL_PWR_CLEAR_FLAG(PWR_FLAG_WUFI); // clear wake up flags\
 
 
#if DEBUG
	RTC_TimeTypeDef currentTime;
	char message[22];
	if (HAL_RTC_GetTime(&hrtc, &currentTime, RTC_FORMAT_BCD) == HAL_OK) {
 
		sprintf(message,"%.2x:%.2x:%.2x", currentTime.Hours, currentTime.Minutes, currentTime.Seconds );
		debug_print_message(message);
	}
	else
		debug_error();
 
	HAL_Delay(2000);
 
	if (HAL_RTC_GetTime(&hrtc, &currentTime, RTC_FORMAT_BCD) == HAL_OK) {
 
		sprintf(message,"%.2x:%.2x:%.2x", currentTime.Hours, currentTime.Minutes, currentTime.Seconds );
		debug_print_message(message);
	}
	else
			debug_error();
#endif
 
}

1 ACCEPTED SOLUTION

Accepted Solutions

The wake-up *timer* itself is not visible to the user. What you write and read is the register holding the autoreload value, (RTC_WUTR).

I don't use and don't understand Cube. For the problem with the wake-up you may want to read the relevant portions of RTC, EXTI and PWR chapters. Maybe start with checking the wake-up timer settings by reading out the RTC registers content, and check if the wakeup flag gets set periodically while the processor is still running.

JW

View solution in original post

5 REPLIES 5

> HAL_RTC_GetTime(&hrtc, &currentTime, RTC_FORMAT_BCD) returns the same time.

You need to read date, too.

JW

SLesh.1
Associate III

Ok, thank you! That is clear.

But wakeup doesn't work. It looks that wakeup counter don't run. The code:

	if (HAL_RTCEx_SetWakeUpTimer_IT(&hrtc, 5, RTC_WAKEUPCLOCK_CK_SPRE_16BITS) != HAL_OK) {
 
		Error_Handler();
	}
 
	uint32_t wkp = HAL_RTCEx_GetWakeUpTimer(&hrtc);
	sprintf(message,"wkp: %d", wkp );
	debug_print_message(message);
 
	HAL_Delay(2000);
 
	wkp = HAL_RTCEx_GetWakeUpTimer(&hrtc);
	sprintf(message,"wkp: %d", wkp );
	debug_print_message(message);
 
	HAL_PWR_EnterSTANDBYMode(); // go to standby mode

UART output:

wakeup

08:56:32

08:56:33

wkp: 5

wkp: 5

Have I to read something else or is it stopped?

The wake-up *timer* itself is not visible to the user. What you write and read is the register holding the autoreload value, (RTC_WUTR).

I don't use and don't understand Cube. For the problem with the wake-up you may want to read the relevant portions of RTC, EXTI and PWR chapters. Maybe start with checking the wake-up timer settings by reading out the RTC registers content, and check if the wakeup flag gets set periodically while the processor is still running.

JW

SLesh.1
Associate III

@Community member​ thank you! wakeup interrupts works. I replace

HAL_PWR_EnterSTANDBYMode();

by

HAL_Delay(10000);

and add

void HAL_RTCEx_WakeUpTimerEventCallback(RTC_HandleTypeDef *hrtc)
{
  /* Prevent unused argument(s) compilation warning */
	HAL_UART_Transmit(&huart3, "rtc wkp\r\n", 9, 100);
 
  /* NOTE : This function should not be modified, when the callback is needed,
            the HAL_RTCEx_WakeUpTimerEventCallback could be implemented in the user file
   */
}

It is happening.

But flag

if (__HAL_RTC_WAKEUPTIMER_GET_IT_SOURCE(&hrtc, RTC_IT_WUT) == 1U) {
 
	debug_print_message("WKP IT = 1U");
}
else {
 
	debug_print_message("WKP IT = 0U");
}

After-

HAL_RTCEx_SetWakeUpTimer_IT(&hrtc, 5, RTC_WAKEUPCLOCK_CK_SPRE_16BITS);

is 1U.

It is enabled. But it doesn't work

SLesh.1
Associate III

Solved.

I'm stupid... Sorry, guys. Difference is in boot0 pin. I'm thinking that is has internal pulldown. But no.