cancel
Showing results for 
Search instead for 
Did you mean: 

Clock Gating (I2C HSI kernel clock) prevents Standby

BCowp.1
Associate II

Hi,
I have a situation which I would like to understand better:

I have an STM32U595ZJT6Q with I2C2 configured to use HSI16 (not PCLK1) as its kernel clock. I put the STM32 into Standby to save power.

Recently I implemented Clock Gating to save power when not in Standby.

I call 

__HAL_RCC_I2C2_CLK_DISABLE();

...to gate/pause the I2C kernel clock when I'm not using it.

I call: 

__HAL_RCC_I2C2_CLK_ENABLE();

...to un-gate/resume the I2C kernel clock when I wish to use it.

This seems to work fine and I do save a significant amount of power.

However! When I attempt to put the STM32 into Standby, something that previously worked fine, the MCU does NOT drop to Standby power level and the ST-Link debugger disconnects. The latter happens even when I have called:

HAL_DBGMCU_EnableDBGStandbyMode();

 This leads me to believe that the MCU has entered some kind of unpleasant hardfault state, but without actually calling any fault handlers. I don't think (unless I am checking it wrong) the NVIC has any pending interrupts that would prevent Standby.

I can avoid this occurrence by either:

  • Not clock gating
  • Using PCLK1, instead of the HSI16, as my I2C2 kernel clock

I have two questions:

  1. What do we think happened to my STM32 when I attempted to go to Standby?
    Having it enter an undefined state without apparent warning (eg. without calling a handler) is a bit concerning when I'm trying to build something that must go to Standby reliably.
    How do I debug/diagnose this behaviour?
  2. What is going on with I2C2 to apparently cause such behaviour?
    Am I doing Clock Gating wrong? Am I meant to wait for some bit to set/unset before disabling the kernel clock?

In essence, how do I arm myself with the tools to prevent his happening again with other peripherals? I would also like the flexibility to use other clock sources as kernel clocks and implement clock gating without fear of Standby not working.

Notes:
This issue occurs only if I2C2 is clock gated (disabled) when I attempt to go to Standby. Re-enabling the clock just before going to Standby appears to fix the issue make the issue go away.

It feels like a race hazard is occurring. If I insert nops before the call to gate/disable the clock, the issue appears to resolve itself. So I can imagine that I'm gating the clock whilst the peripheral is in the middle of a register update. If so, that begs the questions: How do I detect this (ie do I need to wait on a bit before gating the clock)? And why does that cause the MCU the silently refuse to go to Standby? 

 

 

1 REPLY 1
Sarra.S
ST Employee

Hello @BCowp.1

Are you performing the clock gating in run mode?

Could you provide some minimal code to reproduce this behavior on our side?

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.