stm32/i2c: use one static per instance instead of an array.
This commit is contained in:
parent
8d46d31824
commit
e6299549a0
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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>,
|
||||
}
|
||||
|
@ -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(());
|
||||
|
Loading…
Reference in New Issue
Block a user