[STM32L452RE] How to reduce the 360 μA current consumption of I2C in deepSleep?

Working libraries, libraries being ported and related hardware
brixton
Posts: 24
Joined: Thu Mar 30, 2023 11:51 am
Answers: 1

[STM32L452RE] How to reduce the 360 μA current consumption of I2C in deepSleep?

Post by brixton »

Hello everyone :)

I'm currently using the Nucleo for the STM32L452RE. There are no peripherals attached to it. I measure current consumption in the following cases at at JP6, IDD.

If I activate Wire functions, I get roughly 360 μA in deepSleep mode :shock:

If I deactivate Wire functions, I get roughly 2.4 μA in deepSleep.

My questions are:
1. is that normal? (I repeat: no peripherals are attached, i.e. no I2C peripherals either).
2. Is there a way to make the I2C interface consume less power? To shut it down somewhat in deepSleep mode? I would expect the deepSleep library would already do that, but apparantly not so.

Code:

Code: Select all

#include "STM32LowPower.h"
#include <Wire.h>

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  
  /*------- Enable/disable the below piece of code--------- */
  // Wire.setSDA(PB9); 
  // Wire.setSCL(PB8); 
  // Wire.begin();
  /* -----Enable/disable the above piece of code ----*/


  // Configure low power
  LowPower.begin();

  
}

void loop() {
  digitalWrite(LED_BUILTIN, LOW);
  LowPower.deepSleep(30*1000);
  digitalWrite(LED_BUILTIN, HIGH);
  delay(5000); 
}

brixton
Posts: 24
Joined: Thu Mar 30, 2023 11:51 am
Answers: 1

Re: [STM32L452RE] How to reduce the 360 μA current consumption of I2C in deepSleep?

Post by brixton »

For SPI similar question,

With SPI active I get 93.4 μA in deepSleep, and 2.4 μA without.

Code: Select all

#include "STM32LowPower.h"
#include <SPI.h>  

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, HIGH);
  delay(5000); 
  
  /*------- Enable/disable the below piece of code--------- */
  //  SPI.begin();
  /* -----Enable/disable the above piece of code ----*/


  // Configure low power
  LowPower.begin();

  
}

void loop() {
  digitalWrite(LED_BUILTIN, LOW);
  LowPower.deepSleep(30*1000);
  digitalWrite(LED_BUILTIN, HIGH);
  delay(5000); 
}
User avatar
fpiSTM
Posts: 1723
Joined: Wed Dec 11, 2019 7:11 pm
Answers: 91
Location: Le Mans
Contact:

Re: [STM32L452RE] How to reduce the 360 μA current consumption of I2C in deepSleep?

Post by fpiSTM »

When you enable a peripheral the clock and power are enable so that is normal.
The lowpower library only put the mcu in the LP mode that's all. It can't be aware of what are enabled or not nor if it is required so no issue here. Up to the application to properly end the peripheral before entering in LP mode.
brixton
Posts: 24
Joined: Thu Mar 30, 2023 11:51 am
Answers: 1

Re: [STM32L452RE] How to reduce the 360 μA current consumption of I2C in deepSleep?

Post by brixton »

Hi @fpiSTM , thanks for the quick response!

Just to be clear, there are no peripherals attached to the Nucleo board. So no I2C device, and no SPI device. Just the Nucleo board, attached via USB to my PC.

So when you say
fpiSTM wrote: Wed Dec 06, 2023 1:50 pm Up to the application to properly end the peripheral before entering in LP mode.
I'm guessing with "peripheral" you mean the I2C / SPI interfaces, correct? And how am I supposed to do that? How do I end the I2C / SPI interface of the Nucleo? There is not a Wire.end() or SPI.end() function as far as I can see.

Any tips would be much appreciated!

Many thanks
User avatar
fpiSTM
Posts: 1723
Joined: Wed Dec 11, 2019 7:11 pm
Answers: 91
Location: Le Mans
Contact:

Re: [STM32L452RE] How to reduce the 360 μA current consumption of I2C in deepSleep?

Post by fpiSTM »

When I said peripheral I talk the I2C IP.
.end() exist for both instance....
brixton
Posts: 24
Joined: Thu Mar 30, 2023 11:51 am
Answers: 1

Re: [STM32L452RE] How to reduce the 360 μA current consumption of I2C in deepSleep?

Post by brixton »

fpiSTM wrote: Wed Dec 06, 2023 2:24 pm .end() exist for both instance....
ah silly me, I should have checked that better! I had read some old forum posts elsewhere that indicated that these functions did not exist, without actually checking for myself in the Arduino reference.

In any case, I have now implemented

Code: Select all

Wire.end()
and it does not reduce the current consumption unfortunately. Still stuck at roughly 360 μA.

Code: Select all

#include "STM32LowPower.h"
#include <Wire.h>

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  
  /*------- Enable/disable the below piece of code--------- */
  Wire.setSDA(PB9); 
  Wire.setSCL(PB8); 
  Wire.begin();
  Wire.end(); 
  /* -----Enable/disable the above piece of code ----*/


  // Configure low power
  LowPower.begin();

  
}

void loop() {
  digitalWrite(LED_BUILTIN, LOW);
  LowPower.deepSleep(30*1000);
  digitalWrite(LED_BUILTIN, HIGH);
  delay(5000); 
}

I had a look at what the function does in https://github.com/stm32duino/Arduino_C ... e.cpp#L117

If I trace that down I see the following functions. I'd have to dig down deep to understand what is going on at the HAL level. Do you have any ideas @fpiSTM ?

Code: Select all

void TwoWire::end(void)
{
  i2c_deinit(&_i2c);
  if (txBuffer != nullptr) {
    free(txBuffer);
    txBuffer = nullptr;
  }
  txBufferAllocated = 0;
  if (rxBuffer != nullptr) {
    free(rxBuffer);
    rxBuffer = nullptr;
  }
  rxBufferAllocated = 0;
}

https://github.com/stm32duino/Arduino_C ... twi.c#L800

Code: Select all

void i2c_deinit(i2c_t *obj)
{
  HAL_NVIC_DisableIRQ(obj->irq);
#if !defined(STM32C0xx) && !defined(STM32F0xx) && !defined(STM32G0xx) && !defined(STM32L0xx)
  HAL_NVIC_DisableIRQ(obj->irqER);
#endif /* !STM32C0xx && !STM32F0xx && !STM32G0xx && !STM32L0xx */
  HAL_I2C_DeInit(&(obj->handle));
}

Many thanks!
User avatar
fpiSTM
Posts: 1723
Joined: Wed Dec 11, 2019 7:11 pm
Answers: 91
Location: Le Mans
Contact:

Re: [STM32L452RE] How to reduce the 360 μA current consumption of I2C in deepSleep?

Post by fpiSTM »

I've made a PR few minutes ago to disable the clock. If you can test it and told me if it help.
https://github.com/stm32duino/Arduino_C ... /pull/2223

SPI is correct and already disable the clock.
brixton
Posts: 24
Joined: Thu Mar 30, 2023 11:51 am
Answers: 1

Re: [STM32L452RE] How to reduce the 360 μA current consumption of I2C in deepSleep?

Post by brixton »

Hi @fpiSTM , thanks for making the PR so quick! I haven't been able to test it yet for the I2C, but I can confirm that using SPI.end() for SPI reduces the power consumption back down to 2.0 μA.

Code: Select all

#include "STM32LowPower.h"
#include <SPI.h>  

void setup() {
  // pinMode(LED_BUILTIN, OUTPUT);
  // digitalWrite(LED_BUILTIN, HIGH);
  delay(5000); 
  
  /*------- Enable/disable the below piece of code--------- */
   SPI.begin();
   SPI.end(); 

  /* -----Enable/disable the above piece of code ----*/

  // Configure low power
  LowPower.begin();
  
}

void loop() {
  // digitalWrite(LED_BUILTIN, LOW);
  LowPower.deepSleep(30*1000);
  // digitalWrite(LED_BUILTIN, HIGH);
  delay(5000); 
}

brixton
Posts: 24
Joined: Thu Mar 30, 2023 11:51 am
Answers: 1

Re: [STM32L452RE] How to reduce the 360 μA current consumption of I2C in deepSleep?

Post by brixton »

Hi @fpiSTM

Unfortunately Wire.end() does not change the situation. Current consumption is still around 360 μA. Can you confirm that the update works on your end?
I'm using the STM32 board package via the Arduino board manager, so I just copy pasted your commit into the file in
"C:\Users\XXX\AppData\Local\Arduino15\packages\STMicroelectronics\hardware\stm32\2.7.1\libraries\Wire\src\utility\twi.c"

Many thanks,

Code: Select all

#include "STM32LowPower.h"
#include <Wire.h>

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  
  /*------- Enable/disable the below piece of code--------- */
  Wire.setSDA(PB9); 
  Wire.setSCL(PB8); 
  Wire.begin();
  Wire.end(); 
  /* -----Enable/disable the above piece of code ----*/


  // Configure low power
  LowPower.begin();

  
}

void loop() {
  digitalWrite(LED_BUILTIN, LOW);
  LowPower.deepSleep(30*1000);
  digitalWrite(LED_BUILTIN, HIGH);
  delay(5000); 
}

User avatar
fpiSTM
Posts: 1723
Joined: Wed Dec 11, 2019 7:11 pm
Answers: 91
Location: Le Mans
Contact:

Re: [STM32L452RE] How to reduce the 360 μA current consumption of I2C in deepSleep?

Post by fpiSTM »

I did not test, just do this fix after code review. The I2C is disable by the HAL I2C deinit then the clock are disable, nothing more we can do.
So the issue is elsewhere but no idea.
Post Reply

Return to “Libraries & Hardware”