diff --git a/embassy-stm32/src/i2c/mod.rs b/embassy-stm32/src/i2c/mod.rs index aad1c137..7fc4f044 100644 --- a/embassy-stm32/src/i2c/mod.rs +++ b/embassy-stm32/src/i2c/mod.rs @@ -21,9 +21,10 @@ pub enum Error { } pub(crate) mod sealed { + use super::*; pub trait Instance: crate::rcc::RccPeripheral { fn regs() -> crate::pac::i2c::I2c; - fn state_number() -> usize; + fn state() -> &'static State; } } @@ -36,24 +37,6 @@ pin_trait!(SdaPin, Instance); dma_trait!(RxDma, Instance); dma_trait!(TxDma, Instance); -macro_rules! i2c_state { - (I2C1) => { - 0 - }; - (I2C2) => { - 1 - }; - (I2C3) => { - 2 - }; - (I2C4) => { - 3 - }; - (I2C5) => { - 4 - }; -} - crate::pac::interrupts!( ($inst:ident, i2c, $block:ident, EV, $irq:ident) => { impl sealed::Instance for peripherals::$inst { @@ -61,8 +44,9 @@ crate::pac::interrupts!( crate::pac::$inst } - fn state_number() -> usize { - i2c_state!($inst) + fn state() -> &'static State { + static STATE: State = State::new(); + &STATE } } diff --git a/embassy-stm32/src/i2c/v1.rs b/embassy-stm32/src/i2c/v1.rs index 2bd0dcdf..f280187e 100644 --- a/embassy-stm32/src/i2c/v1.rs +++ b/embassy-stm32/src/i2c/v1.rs @@ -7,6 +7,14 @@ use crate::i2c::{Error, Instance, SclPin, SdaPin}; use crate::pac::i2c; use crate::time::Hertz; +pub struct State {} + +impl State { + pub(crate) const fn new() -> Self { + Self {} + } +} + pub struct I2c<'d, T: Instance> { phantom: PhantomData<&'d mut T>, } diff --git a/embassy-stm32/src/i2c/v2.rs b/embassy-stm32/src/i2c/v2.rs index a1ba5bc7..2c46237d 100644 --- a/embassy-stm32/src/i2c/v2.rs +++ b/embassy-stm32/src/i2c/v2.rs @@ -13,31 +13,23 @@ use futures::future::poll_fn; use crate::dma::NoDma; use crate::gpio::sealed::AFType; use crate::i2c::{Error, Instance, SclPin, SdaPin}; -use crate::pac; use crate::pac::i2c; use crate::time::Hertz; -const I2C_COUNT: usize = pac::peripheral_count!(i2c); - pub struct State { - waker: [AtomicWaker; I2C_COUNT], - chunks_transferred: [AtomicUsize; I2C_COUNT], + waker: AtomicWaker, + chunks_transferred: AtomicUsize, } impl State { - const fn new() -> Self { - const AW: AtomicWaker = AtomicWaker::new(); - const CT: AtomicUsize = AtomicUsize::new(0); - + pub(crate) const fn new() -> Self { Self { - waker: [AW; I2C_COUNT], - chunks_transferred: [CT; I2C_COUNT], + waker: AtomicWaker::new(), + chunks_transferred: AtomicUsize::new(0), } } } -static STATE: State = State::new(); - pub struct I2c<'d, T: Instance, TXDMA = NoDma, RXDMA = NoDma> { phantom: PhantomData<&'d mut T>, tx_dma: TXDMA, @@ -108,9 +100,9 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { let isr = regs.isr().read(); if isr.tcr() || isr.tc() { - let n = T::state_number(); - STATE.chunks_transferred[n].fetch_add(1, Ordering::Relaxed); - STATE.waker[n].wake(); + let state = T::state(); + state.chunks_transferred.fetch_add(1, Ordering::Relaxed); + state.waker.wake(); } // The flag can only be cleared by writting to nbytes, we won't do that here, so disable // the interrupt @@ -411,8 +403,8 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { crate::dma::write(ch, request, bytes, dst) }; - let state_number = T::state_number(); - STATE.chunks_transferred[state_number].store(0, Ordering::Relaxed); + let state = T::state(); + state.chunks_transferred.store(0, Ordering::Relaxed); let mut remaining_len = total_len; let _on_drop = OnDrop::new(|| { @@ -445,8 +437,8 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { } poll_fn(|cx| { - STATE.waker[state_number].register(cx.waker()); - let chunks_transferred = STATE.chunks_transferred[state_number].load(Ordering::Relaxed); + state.waker.register(cx.waker()); + let chunks_transferred = state.chunks_transferred.load(Ordering::Relaxed); if chunks_transferred == total_chunks { return Poll::Ready(()); @@ -504,8 +496,8 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { crate::dma::read(ch, request, src, buffer) }; - let state_number = T::state_number(); - STATE.chunks_transferred[state_number].store(0, Ordering::Relaxed); + let state = T::state(); + state.chunks_transferred.store(0, Ordering::Relaxed); let mut remaining_len = total_len; let _on_drop = OnDrop::new(|| { @@ -530,8 +522,8 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { } poll_fn(|cx| { - STATE.waker[state_number].register(cx.waker()); - let chunks_transferred = STATE.chunks_transferred[state_number].load(Ordering::Relaxed); + state.waker.register(cx.waker()); + let chunks_transferred = state.chunks_transferred.load(Ordering::Relaxed); if chunks_transferred == total_chunks { return Poll::Ready(());