summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Fitzhardinge <jeremy@goop.org>2022-10-16 18:00:23 -0700
committerJeremy Fitzhardinge <jeremy@goop.org>2022-10-16 18:00:23 -0700
commite4c2b2aa9a61e5135d2e129705c9bdc3b4cb73ae (patch)
tree6e1036a519ee5facbbd973e5708c61eff14766cf
parentb7d09442650d765562b25f9f27d654c2ef5e014a (diff)
downloadembassy-e4c2b2aa9a61e5135d2e129705c9bdc3b4cb73ae.zip
rp i2c: have separate wakers for each i2c unit
If they both share one waker, there's the possibility that some wakeups could get lost.
-rw-r--r--embassy-rp/src/i2c.rs14
1 files changed, 8 insertions, 6 deletions
diff --git a/embassy-rp/src/i2c.rs b/embassy-rp/src/i2c.rs
index 68cfc653..b9e4382c 100644
--- a/embassy-rp/src/i2c.rs
+++ b/embassy-rp/src/i2c.rs
@@ -70,7 +70,7 @@ impl<'d, T: Instance> I2c<'d, T, Blocking> {
}
}
-static I2C_WAKER: AtomicWaker = AtomicWaker::new();
+static I2C_WAKER: [AtomicWaker; 2] = [AtomicWaker::new(), AtomicWaker::new()];
impl<'d, T: Instance> I2c<'d, T, Async> {
pub fn new_async(
@@ -109,7 +109,7 @@ impl<'d, T: Instance> I2c<'d, T, Async> {
let r = f(self);
if r.is_pending() {
- I2C_WAKER.register(cx.waker());
+ I2C_WAKER[T::IDX].register(cx.waker());
g(self);
}
r
@@ -122,7 +122,7 @@ impl<'d, T: Instance> I2c<'d, T, Async> {
let i2c = T::regs();
i2c.ic_intr_mask().write_value(pac::i2c::regs::IcIntrMask::default());
- I2C_WAKER.wake();
+ I2C_WAKER[T::IDX].wake();
}
async fn read_async_internal(&mut self, buffer: &mut [u8], restart: bool, send_stop: bool) -> Result<(), Error> {
@@ -813,6 +813,7 @@ mod sealed {
pub trait Instance {
const TX_DREQ: u8;
const RX_DREQ: u8;
+ const IDX: usize;
type Interrupt: Interrupt;
@@ -844,10 +845,11 @@ impl_mode!(Async);
pub trait Instance: sealed::Instance {}
macro_rules! impl_instance {
- ($type:ident, $irq:ident, $reset:ident, $tx_dreq:expr, $rx_dreq:expr) => {
+ ($type:ident, $idx:expr, $irq:ident, $reset:ident, $tx_dreq:expr, $rx_dreq:expr) => {
impl sealed::Instance for peripherals::$type {
const TX_DREQ: u8 = $tx_dreq;
const RX_DREQ: u8 = $rx_dreq;
+ const IDX: usize = $idx;
type Interrupt = crate::interrupt::$irq;
@@ -867,8 +869,8 @@ macro_rules! impl_instance {
};
}
-impl_instance!(I2C0, I2C0_IRQ, set_i2c0, 32, 33);
-impl_instance!(I2C1, I2C1_IRQ, set_i2c1, 34, 35);
+impl_instance!(I2C0, 0, I2C0_IRQ, set_i2c0, 32, 33);
+impl_instance!(I2C1, 1, I2C1_IRQ, set_i2c1, 34, 35);
pub trait SdaPin<T: Instance>: sealed::SdaPin<T> + crate::gpio::Pin {}
pub trait SclPin<T: Instance>: sealed::SclPin<T> + crate::gpio::Pin {}