cancel
Showing results for 
Search instead for 
Did you mean: 

For STOP2, Is it necessary to disable unused peripherals?

ejb068
Associate II

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.

11 REPLIES 11
Sarra.S
ST Employee

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 

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.

ejb068
Associate II

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!

Sarra.S
ST Employee

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...

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.

ejb068
Associate II

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.

ejb068
Associate II

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.

Sarra.S
ST Employee

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.

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.

ejb068
Associate II

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.

Sarra.S
ST Employee

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;

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.

ejb068
Associate II

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!