Skip to content

Conversation

HoZHel
Copy link
Contributor

@HoZHel HoZHel commented Aug 12, 2025

Provide PM support, specifically suspend-to-ram.

Add PM support to the Bluetooth HCI driver.

Optimize power consumption for the Nucleo-WB09KE board.

Provide radio timer driver for STM32WB0x SoCs to be used as the system timer when Bluetooth and/or PM are enabled.

Set the appropriate value for SYS_CLOCK_HW_CYCLES_PER_SEC and
SYS_CLOCK_TICKS_PER_SEC when radio timer is used as the system timer.

Enable UART wake-up line in STM32 driver.

Fix the improper use of CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC for some
STM32WB0 drivers due to the misunderstanding of its definition.

Update west to point to the recent changes for hal_stm32.

Supplementary PR #303.

@mathieuchopstm, thank you for your support in PM.

HoZHel added 7 commits August 5, 2025 16:27
Fix the improper use of CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC for some
STM32WB0 drivers due to the misunderstanding of its definition.

Signed-off-by: Ali Hozhabri <[email protected]>
Provide radio timer driver for STM32WB0x SoCs.

Signed-off-by: Ali Hozhabri <[email protected]>
Use radio timer as the system timer when Bluetooth is used.

Modify CMakeLists.txt to compile radio timer driver when
STM32_RADIO_TIMER is enabled.

Remove the common parts from hci_stm32wb0.c that are present
in the radio timer driver.

Set the appropriate value for SYS_CLOCK_HW_CYCLES_PER_SEC and
SYS_CLOCK_TICKS_PER_SEC.

Signed-off-by: Ali Hozhabri <[email protected]>
Provide PM support, specifically suspend-to-ram, for STM32WB0x.

Enable STM32_RADIO_TIMER Kconfig parameter when PM is set.

Signed-off-by: Ali Hozhabri <[email protected]>
Enable UART wake-up line in STM32 driver.

Signed-off-by: Ali Hozhabri <[email protected]>
Add PM support to the STM32WB0x Bluetooth HCI driver.

Implement PM event register to wake up the device for its BLE events.

Signed-off-by: Ali Hozhabri <[email protected]>
Optimize power consumption for the Nucleo-WB09KE board by
implementing correct pull-up/pull-down configurations when the device
enters lower power states.

Signed-off-by: Ali Hozhabri <[email protected]>
Comment on lines +11 to +13
config SYS_CLOCK_HW_CYCLES_PER_SEC
default 409600
depends on STM32_RADIO_TIMER
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

get this from a dts

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a software timer and there is no crystal running at this frequency that's why it is set in Kconfig. What do you think now?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hardware timer with software configurability? That can be represented in dts, it's going through a hardware block

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let me explain more:
SYS_CLOCK_HW_CYCLES_PER_SEC=409600 is the system time unit (STU). One STU is equal to 625/256 μs (about 2.4414 μs). It is independent to the hardware oscillator variation. Every timeout event is expressed in STU. Only before programming the real counter, the time expressed in STU is converted to the hardware timer counting unit internally from the radio timer driver.
Do you still think that it should be defined in a DTS file?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so then the radio timer driver is wrong? This value should be the hardware cycles per second, as the name implies, there shouldn't be some software translation in a radio driver that changes this into the actual value that the hardware uses, it should be using the hardware value directly

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we use the LSE (low-speed external 32.768 kHz), the SYS_CLOCK_HW_CYCLES_PER_SEC can be calculated and is well known. However, when using the LSI (low-speed internal), this value varies because the clock frequency is unknown and differs between devices within a certain range. In our Bluetooth protocol implementation, it is easier to use the STU, which is fixed and independent of both LSI and LSE. We manage internally this value according to the different HW configuration.

return 0;
}

SYS_INIT(board_pupd_init, PRE_KERNEL_2, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT);
Copy link
Contributor

@JarmouniA JarmouniA Aug 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use

void board_early_init_hook(void);
instead.
Also, this should be in the SoC hook.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why should it be in the SoC hook? Would you please explain more?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The operations performed appear to not be board specific.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No. These power pull-up/pull-down configurations are board specific.

static struct k_work_delayable hal_radio_timer_work, ble_stack_work;
static struct k_work_delayable ble_stack_work;

#if CONFIG_PM_DEVICE
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
#if CONFIG_PM_DEVICE
#ifdef CONFIG_PM_DEVICE

apply everywhere for Kconfig symbols

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Which style do you suggest? #ifdef or #if defined()?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Which style do you suggest? #ifdef or #if defined()?

either is fine.

#elif defined(IS_UART_WAKEUP_FROMSTOP_INSTANCE)
if (wakeup_line != STM32_WAKEUP_LINE_NONE) {
/* Enable EXTI line associated to UART wake-up event */
LL_EXTI_EnableIT_0_31(BIT(wakeup_line));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use the STM32 EXTI API in include/zephyr/drivers/interrupt_controller/intc_exti_stm32.h

* Things that need to be preserved across Deepstop, but
* have no associated driver to backup and restore them.
*/
#define SRAM DT_CHOSEN(zephyr_sram)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
#define SRAM DT_CHOSEN(zephyr_sram)
#define STM32WB0_SRAM DT_CHOSEN(zephyr_sram)


#define RCC_CSR (DT_REG_ADDR(DT_NODELABEL(rcc)) + 0x94)
#define PWR_BASE DT_REG_ADDR(DT_NODELABEL(pwrc))
#define PWR_SR1 0x10
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
#define PWR_SR1 0x10
#define STM32WB0_PWR_SR1 0x10


#if CONFIG_PM_DEVICE
/* ST Proprietary extended event */
#define HCI_EXT_EVT 0x82
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
#define HCI_EXT_EVT 0x82
#define STM32_HCI_EXT_EVT 0x82

/* ST Proprietary extended event */
#define HCI_EXT_EVT 0x82
#define ACI_HAL_END_OF_RADIO_ACTIVITY_VSEVT_CODE 0x0004
#define STATE_ALL_BITMASK 0xFFFF
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
#define STATE_ALL_BITMASK 0xFFFF
#define STM32_STATE_ALL_BITMASK 0xFFFF

#define HCI_EXT_EVT 0x82
#define ACI_HAL_END_OF_RADIO_ACTIVITY_VSEVT_CODE 0x0004
#define STATE_ALL_BITMASK 0xFFFF
#define STATE_IDLE 0x00
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
#define STATE_IDLE 0x00
#define STM32_STATE_IDLE 0x00


/* Construct net_buf from event data */
buf = get_rx(buffer_out);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the NULL check should be 1st, and it should result in a panic or reset or something if it's not excepted.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand the purpose of "the NULL check should be 1st," Can you explain more?
For the second part, you mean to put something like __ASSERT_NO_MSG(buf);?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What I meant is

	if (buf == NULL) {
                LOG_ERR("Buf is null");
                Panic/return error if pointer should never be Null
        }
	/* Handle the received HCI data */
	LOG_DBG("New event %p len %u type %u", buf, buf->len, buf->data[0]);
	hci->recv(dev, buf);

Copy link
Contributor Author

@HoZHel HoZHel Aug 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At the moment, the null check is implemented in the else. Since the function is void, it's not returning any error, and also the situation is not critical to panic. So, LOG_ERR is enough.

Update west.yml to point to the recent changes for hal_stm32.

Signed-off-by: Ali Hozhabri <[email protected]>
@HoZHel HoZHel force-pushed the PM_with_radio_timer branch from 7e53340 to be88807 Compare August 13, 2025 08:05
Copy link

The following west manifest projects have changed revision in this Pull Request:

Name Old Revision New Revision Diff
hal_stm32 zephyrproject-rtos/hal_stm32@126cbbe zephyrproject-rtos/hal_stm32#303 zephyrproject-rtos/hal_stm32#303/files

DNM label due to: 1 project with PR revision

Note: This message is automatically posted and updated by the Manifest GitHub Action.

@github-actions github-actions bot added manifest manifest-hal_stm32 DNM (manifest) This PR should not be merged (controlled by action-manifest) labels Aug 13, 2025
Copy link

@mathieuchopstm mathieuchopstm self-requested a review August 19, 2025 11:23
@HoZHel HoZHel requested a review from erwango August 22, 2025 09:05
Copy link
Member

@erwango erwango left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Quick skimming

Comment on lines +13 to +39
static int board_pupd_init(void)
{
LL_PWR_EnableGPIOPullUp(LL_PWR_GPIO_A,
LL_PWR_GPIO_BIT_0|
LL_PWR_GPIO_BIT_1|
LL_PWR_GPIO_BIT_2|
LL_PWR_GPIO_BIT_3);

LL_PWR_EnableGPIOPullDown(LL_PWR_GPIO_A,
LL_PWR_GPIO_BIT_8|
LL_PWR_GPIO_BIT_9|
LL_PWR_GPIO_BIT_10|
LL_PWR_GPIO_BIT_11);

LL_PWR_EnableGPIOPullDown(LL_PWR_GPIO_B,
LL_PWR_GPIO_BIT_0|
LL_PWR_GPIO_BIT_3|
LL_PWR_GPIO_BIT_6|
LL_PWR_GPIO_BIT_7);

LL_PWR_EnableGPIOPullUp(LL_PWR_GPIO_B,
LL_PWR_GPIO_BIT_1|
LL_PWR_GPIO_BIT_2|
LL_PWR_GPIO_BIT_4|
LL_PWR_GPIO_BIT_5|
LL_PWR_GPIO_BIT_14|
LL_PWR_GPIO_BIT_15);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There should be a way to use fts and gpio hog to do this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFAIK, gpio hog is used to automatically set a GPIO pin at boot, but in this file these pull-up/pull-down configs are related to PWR register and they will be applied when the SoC enters suspend-to-ram state. In other words, they are not used in active state.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, we do keep PWRC_CR1.APC at default value and configure GPIO pull-up/pull-down via PWR on WB0 series:

static inline void ll_gpio_set_pin_pull(GPIO_TypeDef *GPIOx, uint32_t Pin, uint32_t Pull)
{
#if defined(CONFIG_SOC_SERIES_STM32WB0X)
/* On STM32WB0, the PWRC PU/PD control registers should be used instead
* of the GPIO controller registers, so we cannot use LL_GPIO_SetPinPull.
*/
const uint32_t gpio = (GPIOx == GPIOA) ? LL_PWR_GPIO_A : LL_PWR_GPIO_B;
if (Pull == LL_GPIO_PULL_UP) {
LL_PWR_EnableGPIOPullUp(gpio, Pin);
LL_PWR_DisableGPIOPullDown(gpio, Pin);
} else if (Pull == LL_GPIO_PULL_DOWN) {
LL_PWR_EnableGPIOPullDown(gpio, Pin);
LL_PWR_DisableGPIOPullUp(gpio, Pin);
} else if (Pull == LL_GPIO_PULL_NO) {
LL_PWR_DisableGPIOPullUp(gpio, Pin);
LL_PWR_DisableGPIOPullDown(gpio, Pin);
}
#else
LL_GPIO_SetPinPull(GPIOx, Pin, Pull);
#endif /* CONFIG_SOC_SERIES_STM32WB0X */
}

so this configuration would be applied all the time, as far as I understand. (and most importantly: lost if the application changes the pins' configuration!)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right. So, I should implement these pull-up/pull-down configs in the board's DTS file?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. You should use a GPIO hog as suggested by @erwango.
See example here:

&gpioe {
status = "okay";
/* Enable 2.7V Analog LDO */
ldo-enable-gpios {
gpio-hog;
gpios = <15 GPIO_ACTIVE_HIGH>;
output-high;
};
};

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As far as I noticed, it sets the pin state at boot time, and it's not related to pull-up/pull-down configs. It doesn't support bias-pull-up and bias-pull-down properties.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have you tried using gpios = <xx GPIO_PULL_UP> / gpios = <xx GPIO_PULL_DOWN>? From my understanding of the hog driver, it should work.

Comment on lines +26 to +28
imply PM_DEVICE if PM
imply PM_S2RAM
imply PM_S2RAM_CUSTOM_MARKING
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use of imply make it possible that activation if not done if dependency is not met, w/o any error reported.
When using select an error will be generated if dependencies of selected symbol is not met and hence expected configuration cannot be met.
Is that done on purpose ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean why select ... if ... is not used instead?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think using select ... if PM for all should work.
I may have used imply to avoid repeating the if PM.

Comment on lines +100 to +101
#define STM32_HCLK_FREQUENCY DT_PROP(DT_NODELABEL(rcc), clock_frequency)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should be able to put that definition in a header somewhere - or in fact, it may already be! - instead of re-defining it in every driver.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think about defining it in include/zephyr/dt-bindings/clock/stm32_common_clocks.h

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This header is for DT bindings only, it should just contain (un)packing macros for DT->driver exchanges.

I think placing the definition in <soc.h> (soc/st/stm32/stm32wb0x/soc.h) would be acceptable. The header might also be already by drivers too.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this case, it's only for WB0x. What about other STM32 products?

Copy link
Contributor

@mathieuchopstm mathieuchopstm Aug 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe it could go in here? I was suggesting <soc.h> because I was a bit worried WB0 that including this file on WB0 would blow up, but now I realize it's actually used and my fears are unjustified 😅

Name should be changed if we place it in the general file, maybe to something like STM32_MAIN_SYSTEM_FREQ (because it corresponds to AXI frequency on some SoCs).

Note that the definition will be unused on all other STM32 until we clean-up the SYS_CLOCK_HW_CYCLES_PER_SEC mess, which will be done in another PR, hence why having something WB0-specific for now is fine (IMO)

Comment on lines +563 to +564
PM_DEVICE_DT_INST_DEFINE(0, ble_pm_action);

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move this to the HCI_DEVICE_INIT() macro:

Suggested change
PM_DEVICE_DT_INST_DEFINE(0, ble_pm_action);

+

#define HCI_DEVICE_INIT(inst) \
+       PM_DEVICE_DT_INST_DEFINE(inst, ble_pm_action);
	static struct hci_data hci_data_##inst = { \
	}; \

#define HCI_DEVICE_INIT(inst) \
static struct hci_data hci_data_##inst = { \
}; \
DEVICE_DT_INST_DEFINE(inst, NULL, NULL, &hci_data_##inst, NULL, \
DEVICE_DT_INST_DEFINE(inst, NULL, PM_DEVICE_DT_INST_GET(0), &hci_data_##inst, NULL, \
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
DEVICE_DT_INST_DEFINE(inst, NULL, PM_DEVICE_DT_INST_GET(0), &hci_data_##inst, NULL, \
DEVICE_DT_INST_DEFINE(inst, NULL, PM_DEVICE_DT_INST_GET(inst), &hci_data_##inst, NULL, \



BUILD_ASSERT(DT_NODE_HAS_STATUS(DT_NODELABEL(clk_lsi), disabled),
"At the moment, LSI is not supported");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit:

Suggested change
"At the moment, LSI is not supported");
"LSI not supported yet");

+ we should check if the slow-clock property on rcc is clk_lsi instead... but that's fine.

Comment on lines +26 to +28
imply PM_DEVICE if PM
imply PM_S2RAM
imply PM_S2RAM_CUSTOM_MARKING
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think using select ... if PM for all should work.
I may have used imply to avoid repeating the if PM.

@@ -8,6 +8,18 @@ if SOC_SERIES_STM32WB0X
config NUM_IRQS
default 32

config SYS_CLOCK_HW_CYCLES_PER_SEC
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think putting these directives in a if STM32_RADIO_TIMER block would yield the same result.

/* Wait to be sure that the Radio Timer is active */
while (LL_RADIO_TIMER_GetAbsoluteTime(WAKEUP) < 0x10) {
}
HAL_RADIO_TIMER_Init(&VTIMER_InitStruct);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit:

Suggested change
HAL_RADIO_TIMER_Init(&VTIMER_InitStruct);
/* Note: Device IRQs are enabled by this function */
HAL_RADIO_TIMER_Init(&VTIMER_InitStruct);

/* Read RCC and PWRC base from Device Tree */
#include <zephyr/devicetree.h>

#define RCC_CSR (DT_REG_ADDR(DT_NODELABEL(rcc)) + 0x94)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there are private definitions to a file, it kinda doesn't matter...

Comment on lines +42 to +82
/*
* Check for Deepstop exit on wakeup event:
* - RCC_CSR is zero
* - PWRC.EXTSRR has bit DEEPSTOPF set
* (Redundant => unchecked)
* - Either PWRC_SR1 or PWRC_SR3 is non-zero
*
* Note that we don't have to clear any register since
* they are automatically updated on reset/wake-up.
*
* IMPLEMENTATIONS DETAILS:
* r1 must not be modified and the stack must not be
* used by this function as of writing, due to the
* current implementation of arch_pm_s2ram_resume.
* As such, we can only use r0, r2 and r3 here.
*
* N.B.: r12 is also volatile for the ARM ABI, but it
* cannot be used for most operations on ARMv6-M due
* to 16-bit Thumb limitations, so we might as well
* avoid using it entirely.
*/
ldr r0, =RCC_CSR
ldr r2, [r0]
cmp r2, #0
bne not_deepstop_wakeup

ldr r0, =PWR_BASE
ldr r2, [r0, #PWR_SR1]
ldr r3, [r0, #PWR_SR3]
orrs r2, r2, r3
beq not_deepstop_wakeup

/**
* All conditions met: this is a wakeup from Deepstop.
*/
movs r0, #1
bx lr

not_deepstop_wakeup:
movs r0, #0
bx lr
Copy link
Contributor

@mathieuchopstm mathieuchopstm Aug 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/*
* Check for Deepstop exit on wakeup event:
* - RCC_CSR is zero
* - PWRC.EXTSRR has bit DEEPSTOPF set
* (Redundant => unchecked)
* - Either PWRC_SR1 or PWRC_SR3 is non-zero
*
* Note that we don't have to clear any register since
* they are automatically updated on reset/wake-up.
*
* IMPLEMENTATIONS DETAILS:
* r1 must not be modified and the stack must not be
* used by this function as of writing, due to the
* current implementation of arch_pm_s2ram_resume.
* As such, we can only use r0, r2 and r3 here.
*
* N.B.: r12 is also volatile for the ARM ABI, but it
* cannot be used for most operations on ARMv6-M due
* to 16-bit Thumb limitations, so we might as well
* avoid using it entirely.
*/
ldr r0, =RCC_CSR
ldr r2, [r0]
cmp r2, #0
bne not_deepstop_wakeup
ldr r0, =PWR_BASE
ldr r2, [r0, #PWR_SR1]
ldr r3, [r0, #PWR_SR3]
orrs r2, r2, r3
beq not_deepstop_wakeup
/**
* All conditions met: this is a wakeup from Deepstop.
*/
movs r0, #1
bx lr
not_deepstop_wakeup:
movs r0, #0
bx lr
/*
* Check for Deepstop exit on wakeup event:
* - RCC_CSR is zero
* - PWRC.EXTSRR has bit DEEPSTOPF set
* (optional; RCC_CSR check suffices)
* - Either PWRC_SR1 or PWRC_SR3 is non-zero
*
* Note that we don't have to clear any register since
* they are automatically updated on reset/wake-up.
*/
ldr r0, =RCC_CSR
ldr r0, [r0]
cmp r0, #0
bne not_deepstop_wakeup
ldr r0, =PWR_BASE
ldr r1, [r0, #PWR_SR1]
ldr r0, [r0, #PWR_SR3]
orrs r0, r0, r1
beq not_deepstop_wakeup
/* All conditions met: this is a wakeup from Deepstop. */
movs r0, #1
bx lr
not_deepstop_wakeup:
movs r0, #0
bx lr

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
DNM (manifest) This PR should not be merged (controlled by action-manifest) manifest manifest-hal_stm32
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants