2020-07-30 11:50 PM
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, ¤tTime, 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, ¤tTime, 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, ¤tTime, 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, ¤tTime, 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, ¤tTime, RTC_FORMAT_BCD) == HAL_OK) {
sprintf(message,"%.2x:%.2x:%.2x", currentTime.Hours, currentTime.Minutes, currentTime.Seconds );
debug_print_message(message);
}
else
debug_error();
#endif
}
Solved! Go to Solution.
2020-07-31 11:20 AM
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
2020-07-31 12:51 AM
> HAL_RTC_GetTime(&hrtc, ¤tTime, RTC_FORMAT_BCD) returns the same time.
You need to read date, too.
JW
2020-07-31 10:33 AM
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?
2020-07-31 11:20 AM
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
2020-07-31 11:03 PM
@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
2020-08-01 02:27 AM
Solved.
I'm stupid... Sorry, guys. Difference is in boot0 pin. I'm thinking that is has internal pulldown. But no.