diff --git a/boards/st/nucleo_wba55cg/nucleo_wba55cg.dts b/boards/st/nucleo_wba55cg/nucleo_wba55cg.dts index 0c4c91cbedb3..51f93e214676 100644 --- a/boards/st/nucleo_wba55cg/nucleo_wba55cg.dts +++ b/boards/st/nucleo_wba55cg/nucleo_wba55cg.dts @@ -100,7 +100,6 @@ &clk_hse { status = "okay"; - hse-div2; }; &clk_hsi { @@ -109,9 +108,9 @@ &rcc { clocks = <&clk_hse>; - clock-frequency = ; + clock-frequency = ; ahb-prescaler = <1>; - ahb5-prescaler = <2>; + ahb5-prescaler = <1>; apb1-prescaler = <1>; apb2-prescaler = <2>; apb7-prescaler = <1>; diff --git a/boards/st/nucleo_wba65ri/nucleo_wba65ri.dts b/boards/st/nucleo_wba65ri/nucleo_wba65ri.dts index a44e2f3ef571..0f1b30347b1b 100644 --- a/boards/st/nucleo_wba65ri/nucleo_wba65ri.dts +++ b/boards/st/nucleo_wba65ri/nucleo_wba65ri.dts @@ -79,12 +79,15 @@ }; }; +&clk_lsi { + status = "okay"; +}; + &clk_lse { status = "okay"; }; &clk_hse { - hse-div2; status = "okay"; }; @@ -94,9 +97,9 @@ &rcc { clocks = <&clk_hse>; - clock-frequency = ; + clock-frequency = ; ahb-prescaler = <1>; - ahb5-prescaler = <2>; + ahb5-prescaler = <1>; apb1-prescaler = <1>; apb2-prescaler = <2>; apb7-prescaler = <1>; diff --git a/drivers/bluetooth/hci/hci_stm32wba.c b/drivers/bluetooth/hci/hci_stm32wba.c index 646bdedd8836..a0425f57623d 100644 --- a/drivers/bluetooth/hci/hci_stm32wba.c +++ b/drivers/bluetooth/hci/hci_stm32wba.c @@ -13,6 +13,12 @@ #include #include #include +#ifdef CONFIG_PM_DEVICE +#include +#include +#include +#include "linklayer_plat.h" +#endif #include #include @@ -454,6 +460,52 @@ static int bt_hci_stm32wba_setup(const struct device *dev, } #endif /* CONFIG_BT_HCI_SETUP */ +#ifdef CONFIG_PM_DEVICE +static int radio_pm_action(const struct device *dev, enum pm_device_action action) +{ + switch (action) { + case PM_DEVICE_ACTION_RESUME: + LL_AHB5_GRP1_EnableClock(LL_AHB5_GRP1_PERIPH_RADIO); +#if defined(CONFIG_PM_S2RAM) + if (LL_PWR_IsActiveFlag_SB() == 1U) { + /* Put the radio in active state */ + link_layer_register_isr(); + } +#endif + LINKLAYER_PLAT_NotifyWFIExit(); + ll_sys_dp_slp_exit(); + break; + case PM_DEVICE_ACTION_SUSPEND: +#if defined(CONFIG_PM_S2RAM) + uint32_t radio_remaining_time = 0; + enum pm_state state = pm_state_next_get(_current_cpu->id)->state; + if (state == PM_STATE_SUSPEND_TO_RAM) { + /* */ + uint32_t cmd_status = + ll_intf_le_get_remaining_time_for_next_event(&radio_remaining_time); + UNUSED(cmd_status); + assert_param(cmd_status == SUCCESS); + + if (radio_remaining_time == LL_DP_SLP_NO_WAKEUP) { + /* No next radio event scheduled */ + (void)ll_sys_dp_slp_enter(LL_DP_SLP_NO_WAKEUP); + } else /* if (radio_remaining_time > RADIO_DEEPSLEEP_WAKEUP_TIME_US) */ { + /* No event in a "near" futur */ + (void)ll_sys_dp_slp_enter(radio_remaining_time - + CFG_LPM_STDBY_WAKEUP_TIME); + } + } +#endif + LINKLAYER_PLAT_NotifyWFIEnter(); + break; + default: + return -ENOTSUP; + } + + return 0; +} +#endif /* CONFIG_PM_DEVICE */ + static DEVICE_API(bt_hci, drv) = { #if defined(CONFIG_BT_HCI_SETUP) .setup = bt_hci_stm32wba_setup, @@ -462,11 +514,22 @@ static DEVICE_API(bt_hci, drv) = { .send = bt_hci_stm32wba_send, }; + +#if defined (CONFIG_PM_DEVICE) +#define HCI_DEVICE_INIT(inst) \ + static struct hci_data hci_data_##inst = {}; \ + PM_DEVICE_DT_INST_DEFINE(inst, radio_pm_action); \ + DEVICE_DT_INST_DEFINE(inst, NULL, PM_DEVICE_DT_INST_GET(inst), &hci_data_##inst, NULL, \ + POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, &drv) + +/* Only one instance supported */ +HCI_DEVICE_INIT(0) +#else #define HCI_DEVICE_INIT(inst) \ - static struct hci_data hci_data_##inst = { \ - }; \ + static struct hci_data hci_data_##inst = {}; \ DEVICE_DT_INST_DEFINE(inst, NULL, NULL, &hci_data_##inst, NULL, \ POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, &drv) /* Only one instance supported */ HCI_DEVICE_INIT(0) +#endif diff --git a/samples/bluetooth/peripheral_hr/boards/nucleo_wba55cg.overlay b/samples/bluetooth/peripheral_hr/boards/nucleo_wba55cg.overlay new file mode 100644 index 000000000000..dbb7ee158248 --- /dev/null +++ b/samples/bluetooth/peripheral_hr/boards/nucleo_wba55cg.overlay @@ -0,0 +1,29 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2023 STMicroelectronics + */ + +/ { + /* Change min residency time to ease power consumption measurement */ + cpus { + cpu0: cpu@0 { + cpu-power-states = <&stop0 &stop1 &standby>; + }; + + power-states { + standby: state2 { + compatible = "zephyr,power-state"; + power-state-name = "suspend-to-ram"; + substate-id = <1>; + min-residency-us = <10000>; + exit-latency-us = <1000>; + }; + }; + }; + +}; + +&lptim1 { + status = "okay"; +}; diff --git a/samples/bluetooth/peripheral_hr/boards/nucleo_wba65ri.overlay b/samples/bluetooth/peripheral_hr/boards/nucleo_wba65ri.overlay new file mode 100644 index 000000000000..44237c28c34e --- /dev/null +++ b/samples/bluetooth/peripheral_hr/boards/nucleo_wba65ri.overlay @@ -0,0 +1,28 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2023 STMicroelectronics + */ + +/ { + /* Change min residency time to ease power consumption measurement */ + cpus { + cpu0: cpu@0 { + cpu-power-states = <&stop0 &stop1 &standby>; + }; + + power-states { + standby: state2 { + compatible = "zephyr,power-state"; + power-state-name = "suspend-to-ram"; + substate-id = <1>; + min-residency-us = <10000>; + exit-latency-us = <1000>; + }; + }; + }; +}; + +&lptim1 { + status = "okay"; +}; diff --git a/samples/bluetooth/peripheral_hr/prj.conf b/samples/bluetooth/peripheral_hr/prj.conf index c24dc7c59673..eb848ef7dec7 100644 --- a/samples/bluetooth/peripheral_hr/prj.conf +++ b/samples/bluetooth/peripheral_hr/prj.conf @@ -8,3 +8,9 @@ CONFIG_BT_BAS=y CONFIG_BT_HRS=y CONFIG_BT_DEVICE_NAME="Zephyr Heartrate Sensor" CONFIG_BT_DEVICE_APPEARANCE=833 + +CONFIG_PM=y +CONFIG_PM_DEVICE=y +CONFIG_PM_DEVICE_RUNTIME=y +CONFIG_PM_DEVICE_SYSTEM_MANAGED=y +CONFIG_PM_S2RAM=y diff --git a/soc/st/stm32/stm32wbax/hci_if/linklayer_plat_adapt.c b/soc/st/stm32/stm32wbax/hci_if/linklayer_plat_adapt.c index 19f3697de8b5..6d2556bd121e 100644 --- a/soc/st/stm32/stm32wbax/hci_if/linklayer_plat_adapt.c +++ b/soc/st/stm32/stm32wbax/hci_if/linklayer_plat_adapt.c @@ -10,7 +10,8 @@ #include -#include "scm.h" +#include "app_conf.h" +#include "bsp.h" #define LOG_LEVEL CONFIG_SOC_LOG_LEVEL LOG_MODULE_REGISTER(linklayer_plat_adapt); @@ -245,8 +246,6 @@ void LINKLAYER_PLAT_StartRadioEvt(void) __HAL_RCC_RADIO_CLK_SLEEP_ENABLE(); NVIC_SetPriority((IRQn_Type)RADIO_INTR_NUM, RADIO_INTR_PRIO_HIGH_Z); - - scm_notifyradiostate(SCM_RADIO_ACTIVE); } void LINKLAYER_PLAT_StopRadioEvt(void) @@ -254,8 +253,6 @@ void LINKLAYER_PLAT_StopRadioEvt(void) __HAL_RCC_RADIO_CLK_SLEEP_DISABLE(); NVIC_SetPriority((IRQn_Type)RADIO_INTR_NUM, RADIO_INTR_PRIO_LOW_Z); - - scm_notifyradiostate(SCM_RADIO_NOT_ACTIVE); } /* Link Layer notification for RCO calibration start */ diff --git a/soc/st/stm32/stm32wbax/power.c b/soc/st/stm32/stm32wbax/power.c index 43fcd67b6124..e035efe4892b 100644 --- a/soc/st/stm32/stm32wbax/power.c +++ b/soc/st/stm32/stm32wbax/power.c @@ -10,6 +10,10 @@ #include #include #include +#include +#include + +#include #include #include @@ -19,7 +23,8 @@ #include #ifdef CONFIG_BT_STM32WBA -#include "scm.h" +#include "linklayer_plat.h" +#include "ll_sys.h" #endif #include @@ -28,59 +33,71 @@ LOG_MODULE_DECLARE(soc, CONFIG_SOC_LOG_LEVEL); void stm32_power_init(void); -static void set_mode_stop(uint8_t substate_id) -{ - - LL_PWR_ClearFlag_STOP(); - LL_RCC_ClearResetFlags(); - - /* Erratum 2.2.15: - * Disabling ICACHE is required before entering stop mode - */ - sys_cache_instr_disable(); - -#ifdef CONFIG_BT_STM32WBA - scm_setwaitstates(LP); -#endif - /* Set SLEEPDEEP bit of Cortex System Control Register */ - LL_LPM_EnableDeepSleep(); +#define HSE_ON ((READ_BIT(RCC->CR, RCC_CR_HSEON) == RCC_CR_HSEON) ? 1UL : 0UL) - while (LL_PWR_IsActiveFlag_ACTVOS() == 0) { - } +#if defined(CONFIG_PM_S2RAM) +struct fpu_ctx_full fpu_state; +SCB_Type backup_scb; - switch (substate_id) { - case 1: /* enter STOP0 mode */ - LL_PWR_SetPowerMode(LL_PWR_MODE_STOP0); - break; - case 2: /* enter STOP1 mode */ - LL_PWR_SetPowerMode(LL_PWR_MODE_STOP1); - break; - default: - LOG_DBG("Unsupported power state substate-id %u", substate_id); - break; - } +static void scb_suspend(SCB_Type *backup) +{ + backup->ICSR = SCB->ICSR; + backup->VTOR = SCB->VTOR; + backup->AIRCR = SCB->AIRCR; + backup->SCR = SCB->SCR; + backup->CCR = SCB->CCR; + memcpy((uint32_t *) backup->SHPR, (uint32_t *)SCB->SHPR, sizeof(SCB->SHPR)); + backup->SHCSR = SCB->SHCSR; + backup->CFSR = SCB->CFSR; + backup->HFSR = SCB->HFSR; + backup->DFSR = SCB->DFSR; + backup->MMFAR = SCB->MMFAR; + backup->BFAR = SCB->BFAR; + backup->AFSR = SCB->AFSR; + backup->CPACR = SCB->CPACR; +} +static void scb_resume(SCB_Type *backup) +{ + SCB->ICSR = backup->ICSR; + SCB->VTOR = backup->VTOR; + SCB->AIRCR = backup->AIRCR; + SCB->SCR = backup->SCR; + SCB->CCR = backup->CCR; + memcpy((uint32_t *)SCB->SHPR, (uint32_t *)backup->SHPR, sizeof(SCB->SHPR)); + SCB->SHCSR = backup->SHCSR; + SCB->CFSR = backup->CFSR; + SCB->HFSR = backup->HFSR; + SCB->DFSR = backup->DFSR; + SCB->MMFAR = backup->MMFAR; + SCB->BFAR = backup->BFAR; + SCB->AFSR = backup->AFSR; + SCB->CPACR = backup->CPACR; } -#if defined(CONFIG_PM_S2RAM) static int suspend_to_ram(void) { + uint32_t basepri; + LL_LPM_EnableDeepSleep(); while (LL_PWR_IsActiveFlag_ACTVOS() == 0) { } - /* Select mode entry : WFE or WFI and enter the CPU selected mode */ - k_cpu_idle(); + /* MCU enters in low-power modes */ + basepri = __get_BASEPRI(); + __set_BASEPRI(0); + __ISB(); + __DSB(); + __WFI(); + + /* MCU exits from low power mode and set back the basepri */ + __set_BASEPRI(basepri); return 0; } -static void set_mode_suspend_to_ram(void) +static void set_mode_suspend_to_ram_enter(void) { - /* Enable SRAM full retention */ - LL_PWR_SetSRAM1SBRetention(LL_PWR_SRAM1_SB_FULL_RETENTION); - LL_PWR_SetSRAM2SBRetention(LL_PWR_SRAM2_SB_FULL_RETENTION); - /* Enable RTC wakeup * This configures an internal pin that generates an event to wakeup the system */ @@ -97,88 +114,150 @@ static void set_mode_suspend_to_ram(void) /* Select standby mode */ LL_PWR_SetPowerMode(LL_PWR_MODE_STANDBY); + /* Save FPU state and configuration */ + z_arm_save_fp_context(&fpu_state); + scb_suspend(&backup_scb); /* Save context and enter Standby mode */ arch_pm_s2ram_suspend(suspend_to_ram); +} + +static void set_mode_suspend_to_ram_exit(void) +{ +#if defined(CONFIG_ARM_MPU) + z_arm_mpu_init(); + /* Configure static memory map. This will program MPU regions, + * to set up access permissions for fixed memory sections, such + * as Application Memory or No-Cacheable SRAM area. + * + * This function is invoked once, upon system initialization. + */ + z_arm_configure_static_mpu_regions(); +#endif /* CONFIG_ARM_MPU */ + z_arm_fault_init(); + scb_resume(&backup_scb); + z_arm_restore_fp_context(&fpu_state); + + __HAL_RCC_PWR_CLK_ENABLE(); + __HAL_RCC_RAMCFG_CLK_ENABLE(); - /* Execution is restored at this point after wake up */ /* Restore system clock as soon as we exit standby mode */ stm32_clock_control_standby_exit(); + + if (LL_PWR_IsActiveFlag_SB() || !HSE_ON) + { + stm32_clock_control_init(NULL); + } else { + /* Apply waitsates for HSE32 configuration */ + __HAL_FLASH_SET_LATENCY(FLASH_LATENCY_0); + while (__HAL_FLASH_GET_LATENCY() != FLASH_LATENCY_0); + MODIFY_REG(RAMCFG_SRAM1->CR, RAMCFG_CR_WSC, RAMCFG_WAITSTATE_0); + MODIFY_REG(RAMCFG_SRAM2->CR, RAMCFG_CR_WSC, RAMCFG_WAITSTATE_0); + } + + /* Resume configuration */ + stm32wba_init(); + stm32_power_init(); } #endif -/* Invoke Low Power/System Off specific Tasks */ -void pm_state_set(enum pm_state state, uint8_t substate_id) +static void set_mode_stop_enter(uint8_t substate_id) { - switch (state) { - case PM_STATE_SUSPEND_TO_IDLE: - set_mode_stop(substate_id); + uint32_t basepri; + + LL_PWR_ClearFlag_STOP(); + LL_RCC_ClearResetFlags(); + + /* Erratum 2.2.15: + * Disabling ICACHE is required before entering stop mode + */ + sys_cache_instr_disable(); - /* Select mode entry : WFE or WFI and enter the CPU selected mode */ - k_cpu_idle(); + __HAL_FLASH_SET_LATENCY(FLASH_LATENCY_3); + while (__HAL_FLASH_GET_LATENCY() != FLASH_LATENCY_3); + MODIFY_REG(RAMCFG_SRAM1->CR, RAMCFG_CR_WSC, RAMCFG_WAITSTATE_1); + MODIFY_REG(RAMCFG_SRAM2->CR, RAMCFG_CR_WSC, RAMCFG_WAITSTATE_1); + + /* Set SLEEPDEEP bit of Cortex System Control Register */ + LL_LPM_EnableDeepSleep(); + + while (LL_PWR_IsActiveFlag_ACTVOS() == 0) { + } + switch (substate_id) { + case 1: /* enter STOP0 mode */ + LL_PWR_SetPowerMode(LL_PWR_MODE_STOP0); break; -#if defined(CONFIG_PM_S2RAM) - case PM_STATE_SUSPEND_TO_RAM: - set_mode_suspend_to_ram(); + case 2: /* enter STOP1 mode */ + LL_PWR_SetPowerMode(LL_PWR_MODE_STOP1); break; -#endif default: - LOG_DBG("Unsupported power state %u", state); - return; + LOG_DBG("Unsupported power state substate-id %u", substate_id); + break; } + + /* MCU enters in low-power modes we cannot use k_cpu_idle() since it reset basepri to zero allowing any interrupt to fire */ + basepri = __get_BASEPRI(); + __set_BASEPRI(0); + __ISB(); + __DSB(); + __WFI(); + + /* Set MCU exits from low power mode and set back the basepri */ + __set_BASEPRI(basepri); } -/* Handle SOC specific activity after Low Power Mode Exit */ -void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) +static void set_mode_stop_exit(uint8_t substate_id) { -#ifdef CONFIG_BT_STM32WBA - if (LL_PWR_IsActiveFlag_STOP() == 1U) { - scm_setup(); - } else { - scm_setwaitstates(RUN); + if (LL_PWR_IsActiveFlag_STOP() || !HSE_ON) + { + /* Reconfigure the clock */ + stm32_clock_control_init(NULL); + } else { + /* Apply waitsates for HSE32 configuration */ + __HAL_FLASH_SET_LATENCY(FLASH_LATENCY_0); + while (__HAL_FLASH_GET_LATENCY() != FLASH_LATENCY_0); + MODIFY_REG(RAMCFG_SRAM1->CR, RAMCFG_CR_WSC, RAMCFG_WAITSTATE_0); + MODIFY_REG(RAMCFG_SRAM2->CR, RAMCFG_CR_WSC, RAMCFG_WAITSTATE_0); } -#endif + /* Erratum 2.2.15: + * Enable ICACHE when exiting stop mode + */ + sys_cache_instr_enable(); + + LL_LPM_DisableSleepOnExit(); + LL_LPM_EnableSleep(); +} + +/* Invoke Low Power/System Off specific Tasks */ +void pm_state_set(enum pm_state state, uint8_t substate_id) +{ switch (state) { case PM_STATE_SUSPEND_TO_IDLE: - if (substate_id <= 2) { - /* Erratum 2.2.15: - * Enable ICACHE when exiting stop mode - */ - sys_cache_instr_enable(); - - LL_LPM_DisableSleepOnExit(); - LL_LPM_EnableSleep(); - } else { - LOG_DBG("Unsupported power substate-id %u", - substate_id); - } + __disable_irq(); + set_mode_stop_enter(substate_id); + /* Resume here */ + set_mode_stop_exit(substate_id); + __enable_irq(); break; - case PM_STATE_SUSPEND_TO_RAM: #if defined(CONFIG_PM_S2RAM) - stm32wba_init(); - stm32_power_init(); - - LL_LPM_DisableSleepOnExit(); - LL_LPM_EnableSleep(); -#else - LOG_DBG("Suspend to RAM needs CONFIG_PM_S2RAM to be enabled"); -#endif + case PM_STATE_SUSPEND_TO_RAM: + __disable_irq(); + set_mode_suspend_to_ram_enter(); + /* Resume here */ + set_mode_suspend_to_ram_exit(); + __enable_irq(); break; - case PM_STATE_STANDBY: - __fallthrough; - case PM_STATE_SUSPEND_TO_DISK: - __fallthrough; +#endif default: LOG_DBG("Unsupported power state %u", state); - break; + return; } +} - /* When BLE is enabled, clock restoration is performed by SCM */ -#if !defined(CONFIG_BT_STM32WBA) - stm32_clock_control_init(NULL); -#endif - +/* Handle SOC specific activity after Low Power Mode Exit */ +void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) +{ /* * System is now in active mode. * Reenable interrupts which were disabled @@ -191,10 +270,6 @@ void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) void stm32_power_init(void) { -#ifdef CONFIG_BT_STM32WBA - scm_init(); -#endif - LL_AHB4_GRP1_EnableClock(LL_AHB4_GRP1_PERIPH_PWR); #ifdef CONFIG_DEBUG @@ -205,6 +280,13 @@ void stm32_power_init(void) LL_DBGMCU_DisableDBGStandbyMode(); #endif + /* Enable SRAM full retention */ + LL_PWR_SetSRAM1SBRetention(LL_PWR_SRAM1_SB_FULL_RETENTION); + LL_PWR_SetSRAM2SBRetention(LL_PWR_SRAM2_SB_FULL_RETENTION); + + /* Enable Radio RAM full retention */ + LL_PWR_SetRadioSBRetention(LL_PWR_RADIO_SB_FULL_RETENTION); + /* Enabling Ultra Low power mode */ LL_PWR_EnableUltraLowPowerMode(); diff --git a/subsys/pm/pm.c b/subsys/pm/pm.c index 261fc01ca81d..d49c3ca1f6b5 100644 --- a/subsys/pm/pm.c +++ b/subsys/pm/pm.c @@ -19,6 +19,9 @@ #include "pm_stats.h" #include "device_system_managed.h" +#ifdef CONFIG_BT_STM32WBA +#include "ll_sys.h" +#endif #include LOG_MODULE_REGISTER(pm, CONFIG_PM_LOG_LEVEL); @@ -148,6 +151,9 @@ bool pm_system_suspend(int32_t kernel_ticks) k_spinlock_key_t key; int32_t ticks, events_ticks; uint32_t exit_latency_ticks; +#ifdef CONFIG_BT_STM32WBA + int32_t old_ticks; +#endif SYS_PORT_TRACING_FUNC_ENTER(pm, system_suspend, kernel_ticks); @@ -163,6 +169,17 @@ bool pm_system_suspend(int32_t kernel_ticks) events_ticks = pm_policy_next_event_ticks(); ticks = ticks_expiring_sooner(kernel_ticks, events_ticks); +#ifdef CONFIG_BT_STM32WBA + { + uint32_t radio_remaining_time, cmd_status; + int32_t radio_ticks; + cmd_status = + ll_intf_le_get_remaining_time_for_next_event(&radio_remaining_time); + radio_ticks = (radio_remaining_time == LL_DP_SLP_NO_WAKEUP) ? K_TICKS_FOREVER : k_us_to_ticks_floor32(radio_remaining_time); + old_ticks = ticks; + ticks = ticks_expiring_sooner(radio_ticks, ticks); + } +#endif key = k_spin_lock(&pm_forced_state_lock); if (z_cpus_pm_forced_state[id] != NULL) { z_cpus_pm_state[id] = z_cpus_pm_forced_state[id]; @@ -194,6 +211,10 @@ bool pm_system_suspend(int32_t kernel_ticks) } #endif +#ifdef CONFIG_BT_STM32WBA + ticks = old_ticks; +#endif + exit_latency_ticks = EXIT_LATENCY_US_TO_TICKS(z_cpus_pm_state[id]->exit_latency_us); if ((exit_latency_ticks > 0) && (ticks != K_TICKS_FOREVER)) { /* diff --git a/west.yml b/west.yml index 8851147b8c33..81540b101094 100644 --- a/west.yml +++ b/west.yml @@ -245,7 +245,7 @@ manifest: groups: - hal - name: hal_stm32 - revision: 126cbbee19208b7aaca5ad8b287cf104e8bc837a + revision: pull/294/head path: modules/hal/stm32 groups: - hal