cancel
Showing results for 
Search instead for 
Did you mean: 

STM32WB Errata "CPU2 hard fault when changing C2HPRE clock divider in RCC_EXTCFGR on CPU1"

Tim.N
Associate III

Hello!

The errata states this as a workaround for this errata:

Description
When CPU1 switches the system clock frequency, the C2HPRE divider may need to be updated according to
CPU2 frequency requirements. Changing the C2HPRE divider by CPU1 when CPU2 is running can cause a
wrong instruction fetch on CPU2, which may lead to a hard fault.
Workaround
To avoid this situation, once CPU2 is started, the C2HPRE divider must not be updated by CPU1. CPU1 must call
the SHCI_C2_SetSystemClock system command to request CPU2 to manage the switch of the system clock. The
C2HPRE divider is then set in a specific procedure to avoid wrong instruction fetching by CPU2

Does this apply if C2BOOT is cleared after the BLE stack had been running for some time and PWR_EXTSCR.C2DS is cleared?  Normally C2BOOT is set once at startup, but if it was more dynamically managed and CPU2 isn't currently running via the following checks:

  1. PWR_CR4.C2BOOT is 0
    1. CPU2 cannot start autonomously with this set to 0, but will continue to run (if running at the time) when this is cleared as far as I understand.
  2. PWR_EXTSCR.C2DS is 0
    1. This proves that CPU2 is currently not running.

Would it be okay to touch C2HPRE while those two bits are 0, even if the BLE stack had been active in the current bootup previously (but isn't currently active with any scheduled RADIO events)?

Thanks,
Tim

6 REPLIES 6
Tim.N
Associate III

Note that I'm still keen on knowing if this can be done or not.  I'd like to avoid using the SHCI_C2_SetSystemClock(...) call if CPU2 is currently in STOP and cannot wakeup if I clear C2BOOT between usages of CPU2.  The call adds a significant power draw to our idle draw since without it we can jump to 64MHz fairly quickly in comparison.  We have some sensor data processing tasks that run on a relatively frequent basis and running at the higher frequency saves on overall system power.

When the system state is:

  • HSE turned off, HSI16 turned on
  • PLL currently enabled to create 64MHz off of the HSI16
  • System clock currently on HSI16

The SHCI_C2_SetSystemClock(...) call takes around 230us to switch over to the PLL and it leaves HSE enabled afterward.  If HSE was already on with the same scenario, it takes 85us to switch to the PLL.  (This was measured by polling on CPU1 for when the system clock switched over to the PLL asynchronously and using a LPTIM against the HSI16 clock to do the measurement itself.)

I'm guessing when you ask it to transition to the PLL that it has an interim state of switching the system clock to the HSE when it wakes up, which is unfortunate.  The HSE clock takes an order of magnitude longer to start than the HSI16 clock + PLL to reach 64MHz.

For getting CPU1 to 64MHz out of STOP we have the following for a total of ~18us when not using the SHCI_C2_SetSystemClock(...) API:

  1. Set wakeup out of STOP to HSI16
  2. HSI16 turn on:: typical 3us
  3. PLL lock time: typical 15us

As a result, SHCI_C2_SetSystemClock(...), this ends up being an order of magnitude longer.

Remy ISSALYS
ST Employee

Hello,

Indeed, if you ensure that CPU2 is not running by checking PWR_CR4.C2BOOT and PWR_EXTSCR.C2DS values and there are any scheduled RADIO events, you can switch the system clock frequency without calling SHCI_C2_SetSystemClock system command. 

You can find additional information on PLL management in AN5289 part 6.

When CPU2 wakes up from STOP, it checks the system clock if it's HSI16, it switches to HSE to be at 32 MHz. 

Best Regards

Hi Remy -

I did read through those, but both the errata and AN5289 do not cover the case where C2BOOT is cleared after having started CPU2, and didn't talk about whether or not inspecting the C2DS bit in conjunction with clearing C2BOOT would be sufficient enough to avoid the errata.

The language in the errata states "once CPU2 is started", which wouldn't include clearing C2BOOT after startup.  The language in AN5289 part 6 states that "case 1: Before CPU2 is started", which also wouldn't include clearing C2BOOT after startup.  (Also, I don't know why case 1 would utilize any of the hardware semaphores if it was before CPU2 was started...)

One further question - can I tell from a register bit if the radio has a scheduled wakeup from CPU2?  E.g. there's this note in the TRM indicating that the radio can then wakeup CPU2 independently of C2BOOT:

When the system remains in Run mode (due to the Radio system) the CPU2 wakes up from
CSTOP mode independently from the C2BOOT setting.

I'd be nice for the idle exit routine in CPU1 to be dependent on hardware state rather than recording state in software for deciding if it has to take the higher power consumption path of invoking SHCI_C2_SetSystemClock(...).  Otherwise, I'll keep track in software if the BLE code currently has BLE operations enabled (or not).

Thanks for the response!

- Tim

Tim.N
Associate III

I did some testing, and at least for the BLE scanning case, the RADIO does not wake up CPU2 independently of C2BOOT.  I wrote some code that prints out whenever C2DS and CRPF in PWR_EXTSCR change along with allowing me to clear C2BOOT on selectable edges for C2DS and CRPF.  In general I see (for the BLE scanning case) the following for a loop:

  • C2DS cleared (CPU2 running)
  • CRPF set (RADIO on)
  • CRPF cleared (RADIO off)
  • C2DS set (CPU2 in STOP)
  • Delay

No matter when I clear C2BOOT in that loop, CPU2 never wakes up from the RADIO.  Does CPU2 ever wake up autonomously from the radio in the BLE scanning case?  It seems not from my experiments here.  Based on this, I'm going to do the following in the CPU1 STOP wakeup code:

  1. Clear C2BOOT
  2. If C2DS is set (e.g. CPU2 is in STOP), directly adjust system clock and dividers.  Once adjusted, set C2BOOT.
  3. If C2DS is cleared (e.g. CPU2 is running), set C2BOOT, and invoke SHCI_C2_SetSystemClock(..)
Remy ISSALYS
ST Employee

Hello,

On CPU1 side, there is no register bit to know if the radio has a scheduled wakeup. The software architecture doesn't allow to synchronize the activity running on CPU1 side and the RF activity. As mentioned in the UM, there is a case where the radio can wakeup the CPU2 independently of C2BOOT. If it's not the case in your application, your procedure is correct. I will check this point regarding scanning. Do you try to perform the same test during a connection?

Best Regards

Tim.N
Associate III

Hi Remy -

We don't perform BLE connections on our platform so I didn't test that use case; we only ever do BLE advertisement scans.  I suspect that maybe the BLE connection path is a bit different since there are harder real-time requirements to meet the expected connection window intervals within an active BLE connection. 

Thanks for checking for the scanning case whether or not there is an independent wakeup on CPU2.

- Tim