embassy-rs / embassy

Modern embedded framework, using Rust and async.
https://embassy.dev
Apache License 2.0
5.32k stars 733 forks source link

STM32U5 - Selectively disable peripheral clocks during "operational sleep". #3373

Open brentmellor opened 1 week ago

brentmellor commented 1 week ago

I am developing a system at work that will spend the majority of it's time with most things disabled while a few peripherals collect and store data via DMA. Once buffers are full or USB is connected, the system brings the system clock up to full speed and uses a bunch of peripherals and timers.

I haven't seen the ability to disable and re-enable peripheral clocks in the Embassy STM32 HAL drivers. Am I missing something (this is the first time I've worked on an Embassy/Rust project) or is that not an available feature? Using the normal HAL I would have disabled all of the unnecessary peripheral clocks during the low power time as I cannot put the whole system into stop mode.

Dirbaio commented 1 week ago

Peripheral drivers disable their clock in RCC when you drop them. For example: https://github.com/embassy-rs/embassy/blob/main/embassy-stm32/src/i2c/mod.rs#L220

This means to save power you can dynamically initialize the driver, use it for a bit to transfer data, then drop it.

To be able to create the driver again, you can create it with borrowed peripherals. This way when you drop the driver the borrows are released and the peripherals are available for use again. See here for an example: https://github.com/embassy-rs/embassy/blob/main/examples/nrf52840/src/bin/twim_lowpower.rs#L35 (it's for nRF, but the same works for STM32)

brentmellor commented 1 week ago

Thanks, that helps!

brentmellor commented 1 week ago

Do you have recommendations for dropping these driver "objects" in an embassy project where it needs to be statically created and accessed across multiple asynchronous tasks with channels?