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