diff options
| author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2022-10-18 08:29:43 +0000 |
|---|---|---|
| committer | GitHub <[email protected]> | 2022-10-18 08:29:43 +0000 |
| commit | 18453ee64c7d1b397aa96cb322cedee6166b4602 (patch) | |
| tree | d4e8492ba812ab18d953a630557fc0e25f0007bd | |
| parent | b7d09442650d765562b25f9f27d654c2ef5e014a (diff) | |
| parent | 02a3cdb507d535908bc0668a31526c05b5d01005 (diff) | |
Merge #1012
1012: rp i2c: have separate wakers for each i2c unit r=Dirbaio a=jsgf
If they both share one waker, there's the possibility that some wakeups could get lost.
Co-authored-by: Jeremy Fitzhardinge <[email protected]>
| -rw-r--r-- | embassy-rp/src/i2c.rs | 15 |
1 files changed, 11 insertions, 4 deletions
diff --git a/embassy-rp/src/i2c.rs b/embassy-rp/src/i2c.rs index 68cfc653e..d6742f6a6 100644 --- a/embassy-rp/src/i2c.rs +++ b/embassy-rp/src/i2c.rs | |||
| @@ -70,8 +70,6 @@ impl<'d, T: Instance> I2c<'d, T, Blocking> { | |||
| 70 | } | 70 | } |
| 71 | } | 71 | } |
| 72 | 72 | ||
| 73 | static I2C_WAKER: AtomicWaker = AtomicWaker::new(); | ||
| 74 | |||
| 75 | impl<'d, T: Instance> I2c<'d, T, Async> { | 73 | impl<'d, T: Instance> I2c<'d, T, Async> { |
| 76 | pub fn new_async( | 74 | pub fn new_async( |
| 77 | peri: impl Peripheral<P = T> + 'd, | 75 | peri: impl Peripheral<P = T> + 'd, |
| @@ -109,7 +107,7 @@ impl<'d, T: Instance> I2c<'d, T, Async> { | |||
| 109 | let r = f(self); | 107 | let r = f(self); |
| 110 | 108 | ||
| 111 | if r.is_pending() { | 109 | if r.is_pending() { |
| 112 | I2C_WAKER.register(cx.waker()); | 110 | T::waker().register(cx.waker()); |
| 113 | g(self); | 111 | g(self); |
| 114 | } | 112 | } |
| 115 | r | 113 | r |
| @@ -122,7 +120,7 @@ impl<'d, T: Instance> I2c<'d, T, Async> { | |||
| 122 | let i2c = T::regs(); | 120 | let i2c = T::regs(); |
| 123 | i2c.ic_intr_mask().write_value(pac::i2c::regs::IcIntrMask::default()); | 121 | i2c.ic_intr_mask().write_value(pac::i2c::regs::IcIntrMask::default()); |
| 124 | 122 | ||
| 125 | I2C_WAKER.wake(); | 123 | T::waker().wake(); |
| 126 | } | 124 | } |
| 127 | 125 | ||
| 128 | async fn read_async_internal(&mut self, buffer: &mut [u8], restart: bool, send_stop: bool) -> Result<(), Error> { | 126 | async fn read_async_internal(&mut self, buffer: &mut [u8], restart: bool, send_stop: bool) -> Result<(), Error> { |
| @@ -809,6 +807,7 @@ fn i2c_reserved_addr(addr: u16) -> bool { | |||
| 809 | 807 | ||
| 810 | mod sealed { | 808 | mod sealed { |
| 811 | use embassy_cortex_m::interrupt::Interrupt; | 809 | use embassy_cortex_m::interrupt::Interrupt; |
| 810 | use embassy_sync::waitqueue::AtomicWaker; | ||
| 812 | 811 | ||
| 813 | pub trait Instance { | 812 | pub trait Instance { |
| 814 | const TX_DREQ: u8; | 813 | const TX_DREQ: u8; |
| @@ -818,6 +817,7 @@ mod sealed { | |||
| 818 | 817 | ||
| 819 | fn regs() -> crate::pac::i2c::I2c; | 818 | fn regs() -> crate::pac::i2c::I2c; |
| 820 | fn reset() -> crate::pac::resets::regs::Peripherals; | 819 | fn reset() -> crate::pac::resets::regs::Peripherals; |
| 820 | fn waker() -> &'static AtomicWaker; | ||
| 821 | } | 821 | } |
| 822 | 822 | ||
| 823 | pub trait Mode {} | 823 | pub trait Mode {} |
| @@ -862,6 +862,13 @@ macro_rules! impl_instance { | |||
| 862 | ret.$reset(true); | 862 | ret.$reset(true); |
| 863 | ret | 863 | ret |
| 864 | } | 864 | } |
| 865 | |||
| 866 | #[inline] | ||
| 867 | fn waker() -> &'static AtomicWaker { | ||
| 868 | static WAKER: AtomicWaker = AtomicWaker::new(); | ||
| 869 | |||
| 870 | &WAKER | ||
| 871 | } | ||
| 865 | } | 872 | } |
| 866 | impl Instance for peripherals::$type {} | 873 | impl Instance for peripherals::$type {} |
| 867 | }; | 874 | }; |
