cancel
Showing results for 
Search instead for 
Did you mean: 

STM32U575 Wakeup from UART in stop mode 1

Alan01252
Associate II

Hi all,

I've been struggling so much to get wake from uart working on this board. 

It looks like it should be simple, I have this code which I am pretty sure should be everything needed, but it just doesn't wake up when I send data to the serial port.

Can anyone see what I might be missing?

#include <Arduino.h>
#include <stm32u5xx_hal.h>
#include <stm32u5xx_ll_usart.h>
#include <stm32u5xx_ll_bus.h>
#include "CustomPinsHub.h"
static constexpr uint32_t LED_PIN = LED1_GRN;
uint8_t aRxBuffer[10];

void SystemClock_Config(); // forward

HardwareSerial stlinkSerial(rx_pin2debug, tx_pin2debug);

void setup()
{
    stlinkSerial.begin(115200);
    HAL_PWREx_EnableUltraLowPowerMode();
    pinMode(LED1_GRN, OUTPUT);
    digitalWrite(LED1_GRN, LOW);
    stlinkSerial.println("→ Setup complete. LED is ON.");
    delay(500);
    UART_HandleTypeDef *huart = stlinkSerial.getHandle();
    UART_WakeUpTypeDef wudata{};
    wudata.WakeUpEvent = UART_WAKEUP_ON_READDATA_NONEMPTY;
    HAL_UARTEx_StopModeWakeUpSourceConfig(huart, wudata);
    __HAL_RCC_PWR_CLK_ENABLE();
    __HAL_UART_ENABLE_IT(huart, UART_IT_WUF);
    HAL_UARTEx_EnableStopMode(huart);
    HAL_UART_Receive_IT(huart, (uint8_t *)aRxBuffer, 10);
    stlinkSerial.println("Entering STOP-1, waiting for any RX data to wake me..");
    stlinkSerial.flush();
    delay(500);
    HAL_SuspendTick();
    HAL_PWREx_EnterSTOP1Mode(PWR_STOPENTRY_WFI);
    HAL_ResumeTick();
    SystemClock_Config();
    delay(500);
    stlinkSerial.println("✔ Woke up from STOP-1! Led off");
    delay(500);
    digitalWrite(LED_PIN, HIGH);
}

void loop()
{
    // nothing
}

 

19 REPLIES 19
Saket_Om
ST Employee

Hello @Alan01252 

Please refer to the example below: 

STM32CubeU5/Projects/NUCLEO-U575ZI-Q/Examples/UART/UART_WakeUpFromStopUsingFIFO at main · STMicroelectronics/STM32CubeU5 · GitHub

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.
Saket_Om

Thanks for the swift reply, but I amm very confused, I can't see anything I am missing in that example and what the code above.. Other than 

 

EXTI10_Wakeup_Enable

 

but that doesn't actually seem to have any implementation behind it?

Try to make UART receive work before implementing the stop and waking up mode.

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.
Saket_Om

Apologies, just to be clear, receive and transmit do work.

 

I can do a simple ping/pong when the chip is awake. What I can't do is a get the board to wake up from sleep :(

Im not expert to Arduino , but waking support require right clock tree setup for USART and work only on USART, that support it. 

MM1_0-1750185918215.png

default clock is PCLK but this in STOP not clock = no wake. Switch before stop USART used to clock , that run in STOP

Andrew Neil
Super User

Arduino questions should go here: https://www.stm32duino.com/

Or, perhaps, in that main Arduino forums: https://forum.arduino.cc/ 

 

A complex system that works is invariably found to have evolved from a simple system that worked.
A complex system designed from scratch never works and cannot be patched up to make it work.

Thanks guys.

 

This isn't really an Arduino question, I've just cheated slightly by using the HardwareSerial abstraction, but I'll remove that if it makes this thread clearer and just go-to pure HAL.

 

I have tried changing the clock via HAL but perhaps I've done something wrong there 


@Alan01252 wrote:

using the [Arduino] HardwareSerial abstraction, 


Maybe that's what's causing the problem?

A complex system that works is invariably found to have evolved from a simple system that worked.
A complex system designed from scratch never works and cannot be patched up to make it work.

I was hopeful that would be the case but alas.

I've now just modified the example code for my uart and no joy.

/* USER CODE BEGIN Header */
/**
 ******************************************************************************
 * @file    UART/UART_WakeUpFromStopUsingFIFO/Src/main.c
 * @author  MCD Application Team
 * @brief   This sample code shows how to use UART HAL API (UART instance)
 *          to wake up the MCU from STOP mode using the UART FIFO level.
 *          Two boards are used, one which enters STOP mode and the second
 *          one which sends the wake-up stimuli.
 ******************************************************************************
 * @attention
 *
 * Copyright (c) 2023 STMicroelectronics.
 * All rights reserved.
 *
 * This software is licensed under terms that can be found in the LICENSE file
 * in the root directory of this software component.
 * If no LICENSE file comes with this software, it is provided AS-IS.
 *
 ******************************************************************************
 */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include <CustomPinsHub.h>
#include <stm32u5xx_hal.h>
#include <stm32u5xx_hal_gpio.h>
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */

/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
#define HAL_TIMEOUT_VALUE 0xFFFFFFFF
#define countof(a) (sizeof(a) / sizeof(*(a)))
/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

UART_HandleTypeDef huart3;

/* USER CODE BEGIN PV */
uint8_t HeaderTxBuffer[] = "\r\nUSART3 WakeUp from stop mode using FIFO\r\n";
uint8_t Part1TxBuffer[] = "\r\n\t Part 1: RXFIFO threshold interrupt\r\n   Waiting for characters reception until RX FIFO threshold is reached\r\n   Please send 2 bytes\r\n";
uint8_t WakeupRXFTBuffer[] = "\r\n   Proper wakeup based on RXFIFO threshold interrupt detection.\r\n";
uint8_t Part2TxBuffer[] = "\r\n\t Part 2: RXFIFO full interrupt\r\n   Waiting for characters reception until RX FIFO is Full \r\n   Please send 8 bytes\r\n";
uint8_t WakeupRXFFBuffer[] = "\r\n   Proper wakeup based on RXFIFO full interrupt detection.\r\n";
uint8_t FooterTxBuffer[] = "\r\nExample finished successfully\r\n";

uint8_t RxBuffer[8];
/* USER CODE END PV */

static void SystemPower_Config(void);
static void MX_GPIO_Init(void);
static void MX_USART3_UART_Init(void);
/* USER CODE BEGIN PFP */
static void EXTI11_Wakeup_Enable(void);

void SystemClock_Config_fromSTOP(void);
/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

void HAL_MspInit(void)
{
    /* USER CODE BEGIN MspInit 0 */

    /* USER CODE END MspInit 0 */

    __HAL_RCC_PWR_CLK_ENABLE();

    /* System interrupt init*/

    /* USER CODE BEGIN MspInit 1 */

    /* USER CODE END MspInit 1 */
}

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();
    __HAL_RCC_HSI_ENABLE();

    /* USER CODE BEGIN Init */

    /* USER CODE END Init */

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

    /* Configure the System Power */
    SystemPower_Config();

    /* USER CODE BEGIN SysInit */
    /* Initialize BSP LED */
    /* USER CODE END SysInit */

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

    RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
    PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART3;
    PeriphClkInit.Usart3ClockSelection = RCC_USART3CLKSOURCE_HSI;
    HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit);

    MX_USART3_UART_Init();
    /* USER CODE BEGIN 2 */
    __HAL_RCC_WAKEUPSTOP_CLK_CONFIG(RCC_STOP_WAKEUPCLOCK_HSI);

    const char *test = "USART3 alive!\r\n";
    HAL_UART_Transmit(&huart3, (uint8_t *)test, strlen(test), HAL_MAX_DELAY);

    const char *echoBanner = "\r\n--- UART Echo Test ---\r\n"
                             "Type characters, they will be echoed back.\r\n"
                             "Send 'S' (0x53) to skip to STOP-mode test.\r\n";
    HAL_UART_Transmit(&huart3, (uint8_t *)echoBanner, strlen(echoBanner), HAL_MAX_DELAY);

    uint8_t ch;
    while (1)
    {
        if (HAL_UART_Receive(&huart3, &ch, 1, HAL_MAX_DELAY) == HAL_OK)
        {
            HAL_UART_Transmit(&huart3, &ch, 1, HAL_MAX_DELAY);
            if (ch == 'S') // user requests to move on
                break;
        }
    }

    UART_WakeUpTypeDef wakeup = {
        .WakeUpEvent = UART_WAKEUP_ON_READDATA_NONEMPTY};
    HAL_UARTEx_StopModeWakeUpSourceConfig(&huart3, wakeup);

    __HAL_RCC_HSISTOP_ENABLE();
    HAL_UART_Transmit(&huart3, (uint8_t *)&HeaderTxBuffer, countof(HeaderTxBuffer) - 1, HAL_TIMEOUT_VALUE);
    HAL_UARTEx_EnableStopMode(&huart3);
    EXTI11_Wakeup_Enable();
    HAL_UART_Transmit(&huart3, (uint8_t *)&Part1TxBuffer, countof(Part1TxBuffer) - 1, HAL_TIMEOUT_VALUE);
    HAL_UART_Receive_IT(&huart3, (uint8_t *)&RxBuffer, 2);
    HAL_SuspendTick();
    HAL_PWR_EnterSTOPMode(PWR_MAINREGULATOR_ON, PWR_STOPENTRY_WFI);
    HAL_ResumeTick();
    SystemClock_Config();
    while (HAL_UART_GetState(&huart3) != HAL_UART_STATE_READY)
    {
    }

    HAL_UARTEx_DisableStopMode(&huart3);
    HAL_UART_Transmit(&huart3, (uint8_t *)&WakeupRXFTBuffer, countof(WakeupRXFTBuffer) - 1, HAL_TIMEOUT_VALUE);
    if (HAL_UARTEx_SetRxFifoThreshold(&huart3, UART_RXFIFO_THRESHOLD_8_8) != HAL_OK)
    {
        Error_Handler();
    }

    HAL_UARTEx_EnableStopMode(&huart3);
    HAL_UART_Transmit(&huart3, (uint8_t *)&Part2TxBuffer, countof(Part2TxBuffer) - 1, HAL_TIMEOUT_VALUE);
    HAL_UART_Receive_IT(&huart3, (uint8_t *)&RxBuffer, 8);
    HAL_SuspendTick();
    HAL_PWR_EnterSTOPMode(PWR_MAINREGULATOR_ON, PWR_STOPENTRY_WFI);
    HAL_ResumeTick();
    SystemClock_Config();

    while (HAL_UART_GetState(&huart3) != HAL_UART_STATE_READY)
    {
    }

    HAL_UARTEx_DisableStopMode(&huart3);
    HAL_UART_Transmit(&huart3, (uint8_t *)&WakeupRXFFBuffer, countof(WakeupRXFFBuffer) - 1, HAL_TIMEOUT_VALUE);
    HAL_UART_Transmit(&huart3, (uint8_t *)&FooterTxBuffer, countof(FooterTxBuffer) - 1, HAL_TIMEOUT_VALUE);

    const char *testEnd = "USART3 alive again!\r\n";
    HAL_UART_Transmit(&huart3, (uint8_t *)testEnd, strlen(test), HAL_MAX_DELAY);

    while (1)
    {
        /* USER CODE END WHILE */

        /* USER CODE BEGIN 3 */
    }
}

/**

/**
 * @brief Power Configuration
 * @retval None
 */
static void SystemPower_Config(void)
{

    /*
     * Disable the internal Pull-Up in Dead Battery pins of UCPD peripheral
     */
    HAL_PWREx_DisableUCPDDeadBattery();
    /* USER CODE BEGIN PWR */
    /* USER CODE END PWR */
}

/**
 * @brief USART1 Initialization Function
 * @PAram None
 * @retval None
 */
static void MX_USART3_UART_Init(void)
{
    RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
    PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART3;
    PeriphClkInit.Usart3ClockSelection = RCC_USART1CLKSOURCE_HSI;

    __HAL_RCC_USART3_FORCE_RESET();
    __HAL_RCC_USART3_RELEASE_RESET();
    __HAL_RCC_USART3_CLK_ENABLE();

    /* USER CODE BEGIN USART3_Init 0 */

    /* USER CODE END USART3_Init 0 */

    /* USER CODE BEGIN USART3_Init 1 */

    /* USER CODE END USART3_Init 1 */
    huart3.Instance = USART3;
    huart3.Init.BaudRate = 115200;
    huart3.Init.WordLength = UART_WORDLENGTH_8B;
    huart3.Init.StopBits = UART_STOPBITS_1;
    huart3.Init.Parity = UART_PARITY_NONE;
    huart3.Init.Mode = UART_MODE_TX_RX;
    huart3.Init.HwFlowCtl = UART_HWCONTROL_NONE;
    huart3.Init.OverSampling = UART_OVERSAMPLING_16;
    huart3.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
    huart3.Init.ClockPrescaler = UART_PRESCALER_DIV1;
    huart3.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
    if (HAL_UART_Init(&huart3) != HAL_OK)
    {
        Error_Handler();
    }
    if (HAL_UARTEx_SetTxFifoThreshold(&huart3, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK)
    {
        Error_Handler();
    }
    if (HAL_UARTEx_SetRxFifoThreshold(&huart3, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK)
    {
        Error_Handler();
    }
    if (HAL_UARTEx_DisableFifoMode(&huart3) != HAL_OK)
    {
        Error_Handler();
    }
    /* USER CODE BEGIN USART3_Init 2 */

    /* USER CODE END USART3_Init 2 */
}

/**
 * @brief GPIO Initialization Function
 * @PAram None
 * @retval None
 */
static void MX_GPIO_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};
    /* USER CODE BEGIN MX_GPIO_Init_1 */
    /* USER CODE END MX_GPIO_Init_1 */

    /* GPIO Ports Clock Enable */
    __HAL_RCC_GPIOC_CLK_ENABLE();
    __HAL_RCC_GPIOH_CLK_ENABLE();
    __HAL_RCC_GPIOA_CLK_ENABLE();
    __HAL_RCC_GPIOB_CLK_ENABLE();
    __HAL_RCC_GPIOD_CLK_ENABLE();

    GPIO_InitStruct.Pin = GPIO_PIN_10 | GPIO_PIN_11;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF7_USART3;
    HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

    /* USER CODE BEGIN MX_GPIO_Init_2 */
    /* USER CODE END MX_GPIO_Init_2 */
    HAL_NVIC_SetPriority(USART3_IRQn, UART_IRQ_PRIO, UART_IRQ_SUBPRIO);
    HAL_NVIC_EnableIRQ(USART3_IRQn);
}

/* USER CODE BEGIN 4 */
static void EXTI11_Wakeup_Enable(void)
{
    EXTI_HandleTypeDef hexti;
    EXTI_ConfigTypeDef exticonfig;
    exticonfig.Line = EXTI_LINE_11;
    exticonfig.Mode = EXTI_MODE_INTERRUPT;
    HAL_EXTI_SetConfigLine(&hexti, &exticonfig);
}

Example logs here, it's so weird. I must be missing *something* vital

--- UART Echo Test ---
Type characters, they will be echoed back.
Send 'S' (0x53) to skip to STOP-mode test.
---- Sent utf8 encoded message: "asdadad\n" ----
asdadad
---- Sent utf8 encoded message: "asdaad\n" ----
asdaad
---- Sent utf8 encoded message: "S\n" ----
S
USART3 WakeUp from stop mode using FIFO

         Part 1: RXFIFO threshold interrupt
   Waiting for characters reception until RX FIFO threshold is reached
   Please send 2 bytes
---- Sent utf8 encoded message: "asdasdasd\n" ----