From 466dcc2a150c1d0b87a78506b3def8ea46a96b09 Mon Sep 17 00:00:00 2001 From: Robin Mueller <31589589+robamu@users.noreply.github.com> Date: Mon, 19 May 2025 10:49:41 +0200 Subject: [PATCH] allow stealing the RMT channel creator + Drop bugfix (#3496) --- esp-hal/CHANGELOG.md | 2 ++ esp-hal/src/rmt.rs | 69 ++++++++++++++++++++------------------------ 2 files changed, 33 insertions(+), 38 deletions(-) diff --git a/esp-hal/CHANGELOG.md b/esp-hal/CHANGELOG.md index d48c73958..719585ef4 100644 --- a/esp-hal/CHANGELOG.md +++ b/esp-hal/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added +- RMT channel creator `steal` function (#3496) - Support for RMT extended memory (#3182) - Support for `rand_core` 0.9 (#3211) - `ESP_HAL_CONFIG_STACK_GUARD_OFFSET` and `ESP_HAL_CONFIG_STACK_GUARD_VALUE` to configure Rust's [Stack smashing protection](https://doc.rust-lang.org/rustc/exploit-mitigations.html#stack-smashing-protection) (#3203) @@ -65,6 +66,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed +- RMT channel drop implementation bugfix where the channel was not released properly (#3496) - RMT now uses correct max filter threshold of 255 instead of 127 (#3192) - Full-duplex SPI works when mixed with half-duplex SPI (#3176) - `Uart::flush_async` should no longer return prematurely (#3186) diff --git a/esp-hal/src/rmt.rs b/esp-hal/src/rmt.rs index 1a5d393fd..6836b12ca 100644 --- a/esp-hal/src/rmt.rs +++ b/esp-hal/src/rmt.rs @@ -401,7 +401,7 @@ impl Default for RxChannelConfig { } } -pub use impl_for_chip::{ChannelCreator, Rmt}; +pub use impl_for_chip::Rmt; impl<'d, Dm> Rmt<'d, Dm> where @@ -781,10 +781,35 @@ macro_rules! impl_rx_channel_creator { }; } +/// RMT Channel Creator +pub struct ChannelCreator +where + Dm: crate::DriverMode, +{ + phantom: PhantomData, + _guard: GenericPeripheralGuard<{ crate::system::Peripheral::Rmt as u8 }>, +} + +impl ChannelCreator { + /// Unsafely steal a channel creator instance. + /// + /// # Safety + /// + /// Circumvents HAL ownership and safety guarantees and allows creating + /// multiple handles to the same peripheral structure. + pub unsafe fn steal() -> ChannelCreator { + ChannelCreator { + phantom: PhantomData, + _guard: GenericPeripheralGuard::new(), + } + } +} + #[cfg(not(any(esp32, esp32s2, esp32s3)))] mod impl_for_chip { use core::marker::PhantomData; + use super::ChannelCreator; use crate::system::GenericPeripheralGuard; /// RMT Instance @@ -832,15 +857,6 @@ mod impl_for_chip { } } - /// RMT Channel Creator - pub struct ChannelCreator - where - Dm: crate::DriverMode, - { - phantom: PhantomData, - _guard: GenericPeripheralGuard<{ crate::system::Peripheral::Rmt as u8 }>, - } - impl_tx_channel_creator!(0); impl_tx_channel_creator!(1); @@ -858,6 +874,7 @@ mod impl_for_chip { mod impl_for_chip { use core::marker::PhantomData; + use super::ChannelCreator; use crate::{peripherals::RMT, system::GenericPeripheralGuard}; /// RMT Instance @@ -929,15 +946,6 @@ mod impl_for_chip { } } - /// RMT Channel Creator - pub struct ChannelCreator - where - Dm: crate::DriverMode, - { - phantom: PhantomData, - _guard: GenericPeripheralGuard<{ crate::system::Peripheral::Rmt as u8 }>, - } - impl_tx_channel_creator!(0); impl_tx_channel_creator!(1); impl_tx_channel_creator!(2); @@ -979,6 +987,7 @@ mod impl_for_chip { mod impl_for_chip { use core::marker::PhantomData; + use super::ChannelCreator; use crate::{peripherals::RMT, system::GenericPeripheralGuard}; /// RMT Instance @@ -1026,15 +1035,6 @@ mod impl_for_chip { } } - /// RMT Channel Creator - pub struct ChannelCreator - where - Dm: crate::DriverMode, - { - phantom: PhantomData, - _guard: GenericPeripheralGuard<{ crate::system::Peripheral::Rmt as u8 }>, - } - impl_tx_channel_creator!(0); impl_tx_channel_creator!(1); impl_tx_channel_creator!(2); @@ -1060,6 +1060,7 @@ mod impl_for_chip { mod impl_for_chip { use core::marker::PhantomData; + use super::ChannelCreator; use crate::{peripherals::RMT, system::GenericPeripheralGuard}; /// RMT Instance @@ -1131,15 +1132,6 @@ mod impl_for_chip { } } - /// RMT Channel Creator - pub struct ChannelCreator - where - Dm: crate::DriverMode, - { - phantom: PhantomData, - _guard: GenericPeripheralGuard<{ crate::system::Peripheral::Rmt as u8 }>, - } - impl_tx_channel_creator!(0); impl_tx_channel_creator!(1); impl_tx_channel_creator!(2); @@ -1177,11 +1169,12 @@ where Dm: crate::DriverMode, { fn drop(&mut self) { + let memsize = chip_specific::channel_mem_size(CHANNEL); + // This isn't really necessary, but be extra sure that this channel can't // interfere with others. chip_specific::set_channel_mem_size(CHANNEL, 0); - let memsize = chip_specific::channel_mem_size(CHANNEL); for s in STATE[usize::from(CHANNEL)..usize::from(CHANNEL + memsize)] .iter() .rev()