Skip to main content
Visitor II
November 15, 2023
Question

For STOP2, Is it necessary to disable unused peripherals?

  • November 15, 2023
  • 10 replies
  • 5912 views

Hi,

I'm using a NUCLEO-L452RE and wanted to check out current in different low power modes.

With only the basic pins configured, I can measure <7uA in Stop2. Not bad.

using: 

HAL_PWREx_EnterSTOP2Mode(PWR_STOPENTRY_WFI);

Problem I have is if I configure the 4 UART ports, an I2C port, etc... then go to stop mode 2, my current is between 200 and 1000uA, depending on what I have configured in the IOC file.

Since I'm going to stop mode 2, most of these devices can't be used. Is it really necessary to disable all unused peripherals before I enter stop mode 2? I probably assumed wrong that I could leave them configured assuming they'd not be powered in this low power state.

I've run some tests where I call:

HAL_UART_MspDeInit(&huart1);

HAL_UART_MspDeInit(&huart2);

HAL_UART_MspDeInit(&huart3);

before going to stop2, and I see major current improvements. Do I need to do this for all peripherals that can't be used in stop mode 2, then re-enable them on wake-up? 

I couldn't find a good example that specifically shows that this needs to be done, so I'm wondering if I'm missing something.

    This topic has been closed for replies.

    10 replies

    ST Employee
    November 16, 2023

    Hello @ejb068

    Several peripherals can be used in Stop 2 mode and can add consumption if they are enabled and clocked by LSI or LSE, or when they request the HSI16 clock: LCD, LPTIM1, I2C3, LPUART

    All the peripherals that cannot be enabled in Stop 2 mode must be either disabled by clearing the Enable bit in the peripheral itself or put under reset state by setting the corresponding bit.

    Please refer to RM Entering Stop 2 mode for more details 

    ejb068Author
    Visitor II
    November 16, 2023

    Hi Sarra,

     

    Thank you for that. 

    Do you have an example which shows this process of disabling and re-enabling a peripheral? Is there a list of all peripheral that should be disabled before entering stop mode 2? Sound like this would be an excellent topic for an application note:)

    I did look through to see for example that USART has a UE:USARTenable. There is however a procedure to to disable and enable this properly and I'd like to make sure I follow the correct procedure. Detailed description or example would be very helpful.

    The examples I found in the STM32CubeIDE are too simple and don't disable peripherals before entering stop mode. This is fine if you haven't enabled any peripherals but not a realistic use case.

    Thanks!

    ST Employee
    November 16, 2023

    Hello again @ejb068

    >> 4 UART ports, an I2C port, etc...

    Could you please first specify each peripheral used, their instances, and how they are clocked?

    I'm trying to discern the source of the 200 and 1000uA, it seems like a peripheral is fully functional in stop2, Which could be I2C3, LPUART1, LSE, or LSI, and also RTC...

    ejb068Author
    Visitor II
    November 16, 2023

    Hi Sarra,

    Here's an example of my main() using on a NUCLEO-L452RE (nothing connected) just pins configured. I'm using the button on the Nucleo configured as an interrupt to be able to wake the system for my example. Also is the current measurement which averages ~625uA in stop 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_USART2_UART_Init();
     MX_I2C1_Init();
     MX_USART1_UART_Init();
     MX_USART3_UART_Init();
     MX_QUADSPI_Init();
     /* USER CODE BEGIN 2 */
    
     /* USER CODE END 2 */
    
     /* Infinite loop */
     /* USER CODE BEGIN WHILE */
     while (1)
     {
     /* USER CODE END WHILE */
    
     /* USER CODE BEGIN 3 */
    
    	 //normal run mode
    	 HAL_GPIO_WritePin(GPIOA, LD4_Pin, GPIO_PIN_RESET);
    	 HAL_Delay(5000);
    
    	 //stop mode 2
    	 HAL_PWREx_EnterSTOP2Mode(PWR_STOPENTRY_WFI);
    	 SystemClock_Config();
    	 //flash LED
    	 HAL_GPIO_WritePin(GPIOA, LD4_Pin, GPIO_PIN_SET);
    	 HAL_Delay(100);
    	 HAL_GPIO_WritePin(GPIOA, LD4_Pin, GPIO_PIN_RESET);
     }
     /* USER CODE END 3 */
    }

    With peripherals enabled.png

    Now if I modify the code to disable the peripherals before stop mode 2, the current is much better at ~2.6uA. I re-enable them after wakeup.

    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_USART2_UART_Init();
     MX_I2C1_Init();
     MX_USART1_UART_Init();
     MX_USART3_UART_Init();
     MX_QUADSPI_Init();
     /* USER CODE BEGIN 2 */
    
     /* USER CODE END 2 */
    
     /* Infinite loop */
     /* USER CODE BEGIN WHILE */
     while (1)
     {
     /* USER CODE END WHILE */
    
     /* USER CODE BEGIN 3 */
    
    	 //normal run mode
    	 HAL_GPIO_WritePin(GPIOA, LD4_Pin, GPIO_PIN_RESET);
    	 HAL_Delay(5000);
    
    	 //stop mode 2
    	 HAL_UART_DeInit(&huart1);
    	 HAL_UART_DeInit(&huart2);
    	 HAL_UART_DeInit(&huart3);
    	 HAL_I2C_DeInit(&hi2c1);
    	 HAL_QSPI_DeInit(&hqspi);
    	 HAL_PWREx_EnterSTOP2Mode(PWR_STOPENTRY_WFI);
    	 SystemClock_Config();
    	 MX_USART2_UART_Init();
    	 MX_I2C1_Init();
    	 MX_USART1_UART_Init();
    	 MX_USART3_UART_Init();
    	 MX_QUADSPI_Init();
    	 //flash LED
    	 HAL_GPIO_WritePin(GPIOA, LD4_Pin, GPIO_PIN_SET);
    	 HAL_Delay(100);
    	 HAL_GPIO_WritePin(GPIOA, LD4_Pin, GPIO_PIN_RESET);
     }
     /* USER CODE END 3 */
    }

    With peripherals disabled before stop2.png

    The peripherals I'm disabling should not be available in stop mode 2 so disabling them should be automatic? Or what is the correct procedure? Wonder why they draw so much current when not even available.

    ejb068Author
    Visitor II
    November 16, 2023

    BTW, I will disable peripherals similar to this if needed, but want to understand if this is safe or what other considerations I may need to take into account.

    Also, I did check that it is not one specific peripheral causing the 600uA, they all contribute some.

    Look forward to your response and thanks for your help.

    ST Employee
    November 16, 2023

    Before entering Stop mode try putting all the used GPIOs in analog mode, try this configuration, and see if you have the same behavior or not.

    ejb068Author
    Visitor II
    November 16, 2023

    The GPIOs configured aren't causing the issue as the second example above leaves them as is and I can get to 2.6uA in stop2. I did make sure all GPIO input pins have a pull up or down as per application note

    AN4899 "STM32 microcontroller GPIO hardware settings and low-power consumption".

     

    The peripherals causing the current are:

    USART1, USART2, USART3, I2C1, QUADSPI, none of which are available in stop mode 2.

    ST Employee
    November 16, 2023

    Hello @ejb068

    It's not the peripherals causing the overcurrent in stop2, it's their GPIO pins. 

    You can still enable the peripherals and set all their GPIO as analog and the current should be as expected.

     

    Please remove all the DeInit and add this code between /* USER CODE BEGIN 2 */ and /* USER CODE BEGIN 2 */

     

     /* USER CODE BEGIN 2 */
     /* Set all GPIO in analog state to reduce power consumption, */
     __HAL_RCC_GPIOA_CLK_ENABLE();
     __HAL_RCC_GPIOB_CLK_ENABLE();
     __HAL_RCC_GPIOC_CLK_ENABLE();
     __HAL_RCC_GPIOD_CLK_ENABLE();
     
     GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
     GPIO_InitStruct.Pull = GPIO_NOPULL;
     GPIO_InitStruct.Pin = GPIO_PIN_ALL;
     
     HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
     HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
     HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
     HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
     
     __HAL_RCC_GPIOA_CLK_DISABLE();
     __HAL_RCC_GPIOB_CLK_DISABLE();
     __HAL_RCC_GPIOC_CLK_DISABLE();
     __HAL_RCC_GPIOD_CLK_DISABLE();
     
     MX_GPIO_Init();
    
     /* USER CODE BEGIN 2 */

     

    The current should be as expected. 

    Note: remove the GPIO port of your wakeup pin.  

    Edit : Declare GPIO_InitStruct and GPIO_PIN_ALL as following: 

     GPIO_InitTypeDef GPIO_InitStruct;
     uint16_t GPIO_PIN_ALL = GPIO_PIN_All;
    ejb068Author
    Visitor II
    November 20, 2023

    Hi Sarra,

     

    Any further advise? Is the correct procedure to enter stop mode 2 to set all un-needed pins to analog input before sleep, then set them back to their respective functions on wake-up? Or is there a better method?

    Thanks!

    ejb068Author
    Visitor II
    November 16, 2023

    Hi Sarra,

     

    I tried as you suggested and as expected it does bring the current down to 2.6uA. However, all my peripherals are defined and initialized just before the "/* USER CODE BEGIN 2 */" in the "/* Initialize all configured peripherals */" section. Doesn't this effectively reconfigure all the pins as GPIO analog input instead of the peripheral pin? For example, the IC2 peripheral configs the pin as GPIO_MODE_AF_OD (Alternate Function Open Drain Mode), then we set the pins to analog input. SO the I2C function wouldn't work.

    I'd need to set all pins as GPIO analog input before stop2 and then re-configure them back on wake-up?

    Let me know if I'm not understanding correctly.

    Thanks again!

    ejb068Author
    Visitor II
    November 24, 2023

    I don't have confirmation on the correct procedure to implement before and after stop 2 low power mode. I have found that if I don't disable the UART/I2C/QSPI peripherals before this low power mode, the current consumption is ~600uA vs ~2.6uA when I do disable them.

     

    I'm looking to determine if this is the correct procedure using the HAL interface. Please confirm or correct as needed.

     

    //stop mode 2

     //disable unused peripherals

      HAL_UART_MspDeInit(&huart1);

      HAL_UART_MspDeInit(&huart2);

      HAL_UART_MspDeInit(&huart3);

      HAL_UART_MspDeInit(&hlpuart1);

      HAL_I2C_MspDeInit(&hi2c1);

      HAL_QSPI_MspDeInit(&hqspi);

     //enter stop mode 2

      HAL_PWREx_EnterSTOP2Mode(PWR_STOPENTRY_WFI);

     //re-enable clocks

      SystemClock_Config();

     //re-enable peripherals

      HAL_UART_MspInit(&huart1);

      HAL_UART_MspInit(&huart2);

      HAL_UART_MspInit(&huart3);

      HAL_UART_MspInit(&hlpuart1);

      HAL_I2C_MspInit(&hi2c1);

      HAL_QSPI_MspInit(&hqspi);