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? 

 

 

0 REPLIES 0