Skip to content

stm32wba: enabling Bluetooth resets system clock #91409

@stefanb2

Description

@stefanb2

Describe the bug

When configuring a board with a STM32WBAxx SoC to run at a system clock that is different than the default 16 MHz, then after a call to bt_enable() the system clock is reset to the default 16 MHz. But Zephyr kernel still thinks the system runs at the configured system clock, i.e. after that all OS timing calculations are off.

Regression

  • This is a regression.

Steps to reproduce

Changes I made to the Zephyr sample samples/bluetooth/peripheral_gatt_write.

Added file samples/bluetooth/peripheral_gatt_write/boards/nucleo_wba55cg.overlay:

/*
 * reconfigure clock tree
 *
 * NOTE: 10, 16, 20, 32, 40, 64, 80 or 100
 */
#define __SYSCLK_MHZ 100

&clk_hse { // HSE == 32 MHz oscillator
  /delete-property/ hse-div2;
};

&pll {
  status = "okay";
  clocks = <&clk_hse>;

  // VCO configuration
#if   (__SYSCLK_MHZ == 100)
  div-m  = < 8>;
  mul-n  = <50>;
  // -> fVCO = HSE * N / M = 32*50/8 = 200 MHz
#elif (__SYSCLK_MHZ == 16) || (__SYSCLK_MHZ == 32) || (__SYSCLK_MHZ == 64)
  div-m  = < 2>;
  mul-n  = < 8>;
  // -> fVCO = HSE * N / M = 32* 8/2 = 128 MHz
#else // 10, 20, 40 or 80 MHz
  div-m  = < 2>;
  mul-n  = <10>;
  // -> fVCO = HSE * N / M = 32*10/2 = 160 MHz
#endif

  // PLLCLK = fVCO / R
#if   (__SYSCLK_MHZ == 10)
  div-q  = <16>;
  div-r  = <16>;
#elif (__SYSCLK_MHZ == 16) || (__SYSCLK_MHZ == 20)
  div-q  = < 8>;
  div-r  = < 8>;
#elif (__SYSCLK_MHZ == 32) || (__SYSCLK_MHZ == 40)
  div-q  = < 4>;
  div-r  = < 4>;
#else // 64, 80 or 100 MHz
  div-q  = < 2>;
  div-r  = < 2>;
#endif
};

&rcc {
  clocks          = <&pll>;
  ahb-prescaler   = <1>;
  // output -> SYSCLK
  clock-frequency = <DT_FREQ_M(__SYSCLK_MHZ)>;
#if   (__SYSCLK_MHZ / 1) <= 32
  ahb5-prescaler  = <1>;
#elif (__SYSCLK_MHZ / 2) <= 32
  ahb5-prescaler  = <2>;
#else
  ahb5-prescaler  = <4>;
#endif
  apb1-prescaler  = <1>;
  apb2-prescaler  = <1>;
  apb7-prescaler  = <1>;
};

Changes to the application code:

--- a/samples/bluetooth/peripheral_gatt_write/src/peripheral_gatt_write.c
+++ b/samples/bluetooth/peripheral_gatt_write/src/peripheral_gatt_write.c
@@ -53,12 +55,22 @@ uint32_t peripheral_gatt_write(uint32_t count)
 {
        int err;
 
+       printk(
+               "before enabling BT: running on board " CONFIG_BOARD " with CPU frequency: %d MHz\n",
+               SystemCoreClock / MHZ(1)
+       );
+
        err = bt_enable(NULL);
        if (err) {
                printk("Bluetooth init failed (err %d)\n", err);
                return 0U;
        }
 
+       printk(
+               "after enabling BT:  running on board " CONFIG_BOARD " with CPU frequency: %d MHz\n",
+               SystemCoreClock / MHZ(1)
+       );
+
        printk("Bluetooth initialized\n");
 
        bt_gatt_cb_register(&gatt_callbacks);

Relevant log output

*** Booting Zephyr OS build 436fabeb0a40 ***
before enabling BT: running on board nucleo_wba55cg with CPU frequency: 100 MHz
[00:00:00.006,000] <wrn> bt_hci_core: Num of Controller's ACL packets != ACL bt_conn_tx contexts (8 != 3)
[00:00:00.007,000] <inf> bt_hci_core: HCI transport: BT IPM
[00:00:00.007,000] <inf> bt_hci_core: Identity: 00:80:E1:XX:XX:XX (public)
[00:00:00.007,000] <inf> bt_hci_core: HCI: version 5.4 (0x0d) revision 0x8014, manufacturer 0x0030
[00:00:00.007,000] <inf> bt_hci_core: LMP: version 5.4 (0x0d) subver 0x6014
after enabling BT:  running on board nucleo_wba55cg with CPU frequency: 16 MHz
Bluetooth initialized
Advertising successfully started

Impact

Major – Severely degrades functionality; workaround is difficult or unavailable.

Environment

  • OS: Linux (Fedora 42)
  • tested with boards nucleo_wba55cg and nucleo_wba65ri.
  • tested with Zephyr branches: v4.1.0, v4.1-branch & main. main is at the time of this writing
436fabeb0 (grafted, HEAD, manifest-rev) doc: build: signing: Correct typo – 'singing' to 'signing'

Tested with Zephyr SDK 0.17:

$ west build --pristine always --board nucleo_wba55cg zephyr/samples/bluetooth/peripheral_gatt_write
-- west build: making build dir ...workspace/build pristine
-- west build: generating a build system
Loading Zephyr default modules (Zephyr base).
-- Application: ...workspace/zephyr/samples/bluetooth/peripheral_gatt_write
-- CMake version: 3.31.6
...
-- Board: nucleo_wba55cg, qualifiers: stm32wba55xx
-- ZEPHYR_TOOLCHAIN_VARIANT not set, trying to locate Zephyr SDK
-- Found host-tools: zephyr 0.17.0 (/path/to/toolchains/zephyr-sdk/zephyr-sdk-0.17.0)
-- Found toolchain: zephyr 0.17.0 (/path/to/toolchains/zephyr-sdk/zephyr-sdk-0.17.0)
...
-- Found BOARD.dts: ...workspace/zephyr/boards/st/nucleo_wba55cg/nucleo_wba55cg.dts
-- Found devicetree overlay: ...workspace/zephyr/samples/bluetooth/peripheral_gatt_write/boards/nucleo_wba55cg.overlay
...
Generating files from ...workspace/build/zephyr/zephyr.elf for board: nucleo_wba55cg

$ west flash
-- west flash: rebuilding
ninja: no work to do.
-- west flash: using runner stm32cubeprogrammer
      -------------------------------------------------------------------
                        STM32CubeProgrammer v2.19.0                  
      -------------------------------------------------------------------
...
Start operation achieved successfully

Tested with an external toolchain:

$ west build --pristine always --board nucleo_wba55cg zephyr/samples/bluetooth/peripheral_gatt_write -- -DZEPHYR_TOOLCHAIN_VARIANT=gnuarmemb -DGNUARMEMB_TOOLCHAIN_PATH=/path/to/toolchains/arm-gnu-toolchain-14.2.rel1-x86_64-arm-none-eabi/
-- west build: making build dir ...workspace/build pristine
-- west build: generating a build system
Loading Zephyr default modules (Zephyr base).
-- Application: ...workspace/zephyr/samples/bluetooth/peripheral_gatt_write
-- CMake version: 3.31.6
...
-- Board: nucleo_wba55cg, qualifiers: stm32wba55xx
-- Found toolchain: gnuarmemb (/path/to/toolchains/arm-gnu-toolchain-14.2.rel1-x86_64-arm-none-eabi/)
...
-- Found BOARD.dts: ...workspace/zephyr/boards/st/nucleo_wba55cg/nucleo_wba55cg.dts
-- Found devicetree overlay: ...workspace/zephyr/samples/bluetooth/peripheral_gatt_write/boards/nucleo_wba55cg.overlay
...
Generating files from ...workspace/build/zephyr/zephyr.elf for board: nucleo_wba55cg

$ west flash
-- west flash: rebuilding
ninja: no work to do.
-- west flash: using runner stm32cubeprogrammer
      -------------------------------------------------------------------
                        STM32CubeProgrammer v2.19.0                  
      -------------------------------------------------------------------
...
Start operation achieved successfully

Additional Context

I see two possible root causes for this issue:

  • because of technical reasons the stm32wba BT stack (blob) only works with a system clock @ 16 MHz. The BT initialization therefore switches the system clock to 16 MHz, but forgets to update all clock control bits required for correct Zephyr behavior.
  • there are no technical reasons for the stm32wbaxx BT stack (blobs) to switch the system clock to 16 MHz, but it incorrectly does so.

Metadata

Metadata

Assignees

Labels

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions