aboutsummaryrefslogtreecommitdiff
path: root/embassy-rp/src
diff options
context:
space:
mode:
authorMathias <[email protected]>2022-10-24 12:14:26 +0200
committerMathias <[email protected]>2022-10-24 12:14:26 +0200
commit8d809c96ecf2fabf77f0fb72f2a59acd18306bf2 (patch)
treeda3e28e491bbaadbc448b9a021291e2164b7531e /embassy-rp/src
parent7152031229da19005e5b0d52c8c72d359d3e0daa (diff)
parentce1cba761c2942b7faa27f4098487c6468784729 (diff)
Merge branch 'master' of https://github.com/embassy-rs/embassy into embassy-rp/flash
Diffstat (limited to 'embassy-rp/src')
-rw-r--r--embassy-rp/src/gpio.rs54
-rw-r--r--embassy-rp/src/i2c.rs425
-rw-r--r--embassy-rp/src/rtc/mod.rs2
-rw-r--r--embassy-rp/src/spi.rs8
-rw-r--r--embassy-rp/src/uart/mod.rs12
-rw-r--r--embassy-rp/src/usb.rs16
6 files changed, 453 insertions, 64 deletions
diff --git a/embassy-rp/src/gpio.rs b/embassy-rp/src/gpio.rs
index 9b9a08110..f79f592b4 100644
--- a/embassy-rp/src/gpio.rs
+++ b/embassy-rp/src/gpio.rs
@@ -599,12 +599,12 @@ pub(crate) mod sealed {
599 fn pin_bank(&self) -> u8; 599 fn pin_bank(&self) -> u8;
600 600
601 #[inline] 601 #[inline]
602 fn pin(&self) -> u8 { 602 fn _pin(&self) -> u8 {
603 self.pin_bank() & 0x1f 603 self.pin_bank() & 0x1f
604 } 604 }
605 605
606 #[inline] 606 #[inline]
607 fn bank(&self) -> Bank { 607 fn _bank(&self) -> Bank {
608 if self.pin_bank() & 0x20 == 0 { 608 if self.pin_bank() & 0x20 == 0 {
609 Bank::Bank0 609 Bank::Bank0
610 } else { 610 } else {
@@ -613,35 +613,35 @@ pub(crate) mod sealed {
613 } 613 }
614 614
615 fn io(&self) -> pac::io::Gpio { 615 fn io(&self) -> pac::io::Gpio {
616 let block = match self.bank() { 616 let block = match self._bank() {
617 Bank::Bank0 => crate::pac::IO_BANK0, 617 Bank::Bank0 => crate::pac::IO_BANK0,
618 Bank::Qspi => crate::pac::IO_QSPI, 618 Bank::Qspi => crate::pac::IO_QSPI,
619 }; 619 };
620 block.gpio(self.pin() as _) 620 block.gpio(self._pin() as _)
621 } 621 }
622 622
623 fn pad_ctrl(&self) -> Reg<pac::pads::regs::GpioCtrl, RW> { 623 fn pad_ctrl(&self) -> Reg<pac::pads::regs::GpioCtrl, RW> {
624 let block = match self.bank() { 624 let block = match self._bank() {
625 Bank::Bank0 => crate::pac::PADS_BANK0, 625 Bank::Bank0 => crate::pac::PADS_BANK0,
626 Bank::Qspi => crate::pac::PADS_QSPI, 626 Bank::Qspi => crate::pac::PADS_QSPI,
627 }; 627 };
628 block.gpio(self.pin() as _) 628 block.gpio(self._pin() as _)
629 } 629 }
630 630
631 fn sio_out(&self) -> pac::sio::Gpio { 631 fn sio_out(&self) -> pac::sio::Gpio {
632 SIO.gpio_out(self.bank() as _) 632 SIO.gpio_out(self._bank() as _)
633 } 633 }
634 634
635 fn sio_oe(&self) -> pac::sio::Gpio { 635 fn sio_oe(&self) -> pac::sio::Gpio {
636 SIO.gpio_oe(self.bank() as _) 636 SIO.gpio_oe(self._bank() as _)
637 } 637 }
638 638
639 fn sio_in(&self) -> Reg<u32, RW> { 639 fn sio_in(&self) -> Reg<u32, RW> {
640 SIO.gpio_in(self.bank() as _) 640 SIO.gpio_in(self._bank() as _)
641 } 641 }
642 642
643 fn int_proc(&self) -> pac::io::Int { 643 fn int_proc(&self) -> pac::io::Int {
644 let io_block = match self.bank() { 644 let io_block = match self._bank() {
645 Bank::Bank0 => crate::pac::IO_BANK0, 645 Bank::Bank0 => crate::pac::IO_BANK0,
646 Bank::Qspi => crate::pac::IO_QSPI, 646 Bank::Qspi => crate::pac::IO_QSPI,
647 }; 647 };
@@ -658,6 +658,18 @@ pub trait Pin: Peripheral<P = Self> + Into<AnyPin> + sealed::Pin + Sized + 'stat
658 pin_bank: self.pin_bank(), 658 pin_bank: self.pin_bank(),
659 } 659 }
660 } 660 }
661
662 /// Returns the pin number within a bank
663 #[inline]
664 fn pin(&self) -> u8 {
665 self._pin()
666 }
667
668 /// Returns the bank of this pin
669 #[inline]
670 fn bank(&self) -> Bank {
671 self._bank()
672 }
661} 673}
662 674
663pub struct AnyPin { 675pub struct AnyPin {
@@ -867,7 +879,7 @@ mod eh1 {
867 type Error = Infallible; 879 type Error = Infallible;
868 } 880 }
869 881
870 impl<'d, T: Pin> embedded_hal_1::digital::blocking::InputPin for Input<'d, T> { 882 impl<'d, T: Pin> embedded_hal_1::digital::InputPin for Input<'d, T> {
871 fn is_high(&self) -> Result<bool, Self::Error> { 883 fn is_high(&self) -> Result<bool, Self::Error> {
872 Ok(self.is_high()) 884 Ok(self.is_high())
873 } 885 }
@@ -881,7 +893,7 @@ mod eh1 {
881 type Error = Infallible; 893 type Error = Infallible;
882 } 894 }
883 895
884 impl<'d, T: Pin> embedded_hal_1::digital::blocking::OutputPin for Output<'d, T> { 896 impl<'d, T: Pin> embedded_hal_1::digital::OutputPin for Output<'d, T> {
885 fn set_high(&mut self) -> Result<(), Self::Error> { 897 fn set_high(&mut self) -> Result<(), Self::Error> {
886 Ok(self.set_high()) 898 Ok(self.set_high())
887 } 899 }
@@ -891,7 +903,7 @@ mod eh1 {
891 } 903 }
892 } 904 }
893 905
894 impl<'d, T: Pin> embedded_hal_1::digital::blocking::StatefulOutputPin for Output<'d, T> { 906 impl<'d, T: Pin> embedded_hal_1::digital::StatefulOutputPin for Output<'d, T> {
895 fn is_set_high(&self) -> Result<bool, Self::Error> { 907 fn is_set_high(&self) -> Result<bool, Self::Error> {
896 Ok(self.is_set_high()) 908 Ok(self.is_set_high())
897 } 909 }
@@ -901,7 +913,7 @@ mod eh1 {
901 } 913 }
902 } 914 }
903 915
904 impl<'d, T: Pin> embedded_hal_1::digital::blocking::ToggleableOutputPin for Output<'d, T> { 916 impl<'d, T: Pin> embedded_hal_1::digital::ToggleableOutputPin for Output<'d, T> {
905 fn toggle(&mut self) -> Result<(), Self::Error> { 917 fn toggle(&mut self) -> Result<(), Self::Error> {
906 Ok(self.toggle()) 918 Ok(self.toggle())
907 } 919 }
@@ -911,7 +923,7 @@ mod eh1 {
911 type Error = Infallible; 923 type Error = Infallible;
912 } 924 }
913 925
914 impl<'d, T: Pin> embedded_hal_1::digital::blocking::OutputPin for OutputOpenDrain<'d, T> { 926 impl<'d, T: Pin> embedded_hal_1::digital::OutputPin for OutputOpenDrain<'d, T> {
915 fn set_high(&mut self) -> Result<(), Self::Error> { 927 fn set_high(&mut self) -> Result<(), Self::Error> {
916 Ok(self.set_high()) 928 Ok(self.set_high())
917 } 929 }
@@ -921,7 +933,7 @@ mod eh1 {
921 } 933 }
922 } 934 }
923 935
924 impl<'d, T: Pin> embedded_hal_1::digital::blocking::StatefulOutputPin for OutputOpenDrain<'d, T> { 936 impl<'d, T: Pin> embedded_hal_1::digital::StatefulOutputPin for OutputOpenDrain<'d, T> {
925 fn is_set_high(&self) -> Result<bool, Self::Error> { 937 fn is_set_high(&self) -> Result<bool, Self::Error> {
926 Ok(self.is_set_high()) 938 Ok(self.is_set_high())
927 } 939 }
@@ -931,7 +943,7 @@ mod eh1 {
931 } 943 }
932 } 944 }
933 945
934 impl<'d, T: Pin> embedded_hal_1::digital::blocking::ToggleableOutputPin for OutputOpenDrain<'d, T> { 946 impl<'d, T: Pin> embedded_hal_1::digital::ToggleableOutputPin for OutputOpenDrain<'d, T> {
935 fn toggle(&mut self) -> Result<(), Self::Error> { 947 fn toggle(&mut self) -> Result<(), Self::Error> {
936 Ok(self.toggle()) 948 Ok(self.toggle())
937 } 949 }
@@ -941,7 +953,7 @@ mod eh1 {
941 type Error = Infallible; 953 type Error = Infallible;
942 } 954 }
943 955
944 impl<'d, T: Pin> embedded_hal_1::digital::blocking::InputPin for Flex<'d, T> { 956 impl<'d, T: Pin> embedded_hal_1::digital::InputPin for Flex<'d, T> {
945 fn is_high(&self) -> Result<bool, Self::Error> { 957 fn is_high(&self) -> Result<bool, Self::Error> {
946 Ok(self.is_high()) 958 Ok(self.is_high())
947 } 959 }
@@ -951,7 +963,7 @@ mod eh1 {
951 } 963 }
952 } 964 }
953 965
954 impl<'d, T: Pin> embedded_hal_1::digital::blocking::OutputPin for Flex<'d, T> { 966 impl<'d, T: Pin> embedded_hal_1::digital::OutputPin for Flex<'d, T> {
955 fn set_high(&mut self) -> Result<(), Self::Error> { 967 fn set_high(&mut self) -> Result<(), Self::Error> {
956 Ok(self.set_high()) 968 Ok(self.set_high())
957 } 969 }
@@ -961,7 +973,7 @@ mod eh1 {
961 } 973 }
962 } 974 }
963 975
964 impl<'d, T: Pin> embedded_hal_1::digital::blocking::StatefulOutputPin for Flex<'d, T> { 976 impl<'d, T: Pin> embedded_hal_1::digital::StatefulOutputPin for Flex<'d, T> {
965 fn is_set_high(&self) -> Result<bool, Self::Error> { 977 fn is_set_high(&self) -> Result<bool, Self::Error> {
966 Ok(self.is_set_high()) 978 Ok(self.is_set_high())
967 } 979 }
@@ -971,7 +983,7 @@ mod eh1 {
971 } 983 }
972 } 984 }
973 985
974 impl<'d, T: Pin> embedded_hal_1::digital::blocking::ToggleableOutputPin for Flex<'d, T> { 986 impl<'d, T: Pin> embedded_hal_1::digital::ToggleableOutputPin for Flex<'d, T> {
975 fn toggle(&mut self) -> Result<(), Self::Error> { 987 fn toggle(&mut self) -> Result<(), Self::Error> {
976 Ok(self.toggle()) 988 Ok(self.toggle())
977 } 989 }
diff --git a/embassy-rp/src/i2c.rs b/embassy-rp/src/i2c.rs
index 9596d661d..d6742f6a6 100644
--- a/embassy-rp/src/i2c.rs
+++ b/embassy-rp/src/i2c.rs
@@ -1,9 +1,12 @@
1use core::future;
1use core::marker::PhantomData; 2use core::marker::PhantomData;
3use core::task::Poll;
2 4
5use embassy_cortex_m::interrupt::InterruptExt;
3use embassy_hal_common::{into_ref, PeripheralRef}; 6use embassy_hal_common::{into_ref, PeripheralRef};
7use embassy_sync::waitqueue::AtomicWaker;
4use pac::i2c; 8use pac::i2c;
5 9
6use crate::dma::AnyChannel;
7use crate::gpio::sealed::Pin; 10use crate::gpio::sealed::Pin;
8use crate::gpio::AnyPin; 11use crate::gpio::AnyPin;
9use crate::{pac, peripherals, Peripheral}; 12use crate::{pac, peripherals, Peripheral};
@@ -52,31 +55,276 @@ impl Default for Config {
52const FIFO_SIZE: u8 = 16; 55const FIFO_SIZE: u8 = 16;
53 56
54pub struct I2c<'d, T: Instance, M: Mode> { 57pub struct I2c<'d, T: Instance, M: Mode> {
55 _tx_dma: Option<PeripheralRef<'d, AnyChannel>>,
56 _rx_dma: Option<PeripheralRef<'d, AnyChannel>>,
57 _dma_buf: [u16; 256],
58 phantom: PhantomData<(&'d mut T, M)>, 58 phantom: PhantomData<(&'d mut T, M)>,
59} 59}
60 60
61impl<'d, T: Instance> I2c<'d, T, Blocking> { 61impl<'d, T: Instance> I2c<'d, T, Blocking> {
62 pub fn new_blocking( 62 pub fn new_blocking(
63 _peri: impl Peripheral<P = T> + 'd, 63 peri: impl Peripheral<P = T> + 'd,
64 scl: impl Peripheral<P = impl SclPin<T>> + 'd, 64 scl: impl Peripheral<P = impl SclPin<T>> + 'd,
65 sda: impl Peripheral<P = impl SdaPin<T>> + 'd, 65 sda: impl Peripheral<P = impl SdaPin<T>> + 'd,
66 config: Config, 66 config: Config,
67 ) -> Self { 67 ) -> Self {
68 into_ref!(scl, sda); 68 into_ref!(scl, sda);
69 Self::new_inner(_peri, scl.map_into(), sda.map_into(), None, None, config) 69 Self::new_inner(peri, scl.map_into(), sda.map_into(), config)
70 }
71}
72
73impl<'d, T: Instance> I2c<'d, T, Async> {
74 pub fn new_async(
75 peri: impl Peripheral<P = T> + 'd,
76 scl: impl Peripheral<P = impl SclPin<T>> + 'd,
77 sda: impl Peripheral<P = impl SdaPin<T>> + 'd,
78 irq: impl Peripheral<P = T::Interrupt> + 'd,
79 config: Config,
80 ) -> Self {
81 into_ref!(scl, sda, irq);
82
83 let i2c = Self::new_inner(peri, scl.map_into(), sda.map_into(), config);
84
85 irq.set_handler(Self::on_interrupt);
86 unsafe {
87 let i2c = T::regs();
88
89 // mask everything initially
90 i2c.ic_intr_mask().write_value(i2c::regs::IcIntrMask(0));
91 }
92 irq.unpend();
93 debug_assert!(!irq.is_pending());
94 irq.enable();
95
96 i2c
97 }
98
99 /// Calls `f` to check if we are ready or not.
100 /// If not, `g` is called once the waker is set (to eg enable the required interrupts).
101 async fn wait_on<F, U, G>(&mut self, mut f: F, mut g: G) -> U
102 where
103 F: FnMut(&mut Self) -> Poll<U>,
104 G: FnMut(&mut Self),
105 {
106 future::poll_fn(|cx| {
107 let r = f(self);
108
109 if r.is_pending() {
110 T::waker().register(cx.waker());
111 g(self);
112 }
113 r
114 })
115 .await
116 }
117
118 // Mask interrupts and wake any task waiting for this interrupt
119 unsafe fn on_interrupt(_: *mut ()) {
120 let i2c = T::regs();
121 i2c.ic_intr_mask().write_value(pac::i2c::regs::IcIntrMask::default());
122
123 T::waker().wake();
124 }
125
126 async fn read_async_internal(&mut self, buffer: &mut [u8], restart: bool, send_stop: bool) -> Result<(), Error> {
127 if buffer.is_empty() {
128 return Err(Error::InvalidReadBufferLength);
129 }
130
131 let p = T::regs();
132
133 let mut remaining = buffer.len();
134 let mut remaining_queue = buffer.len();
135
136 let mut abort_reason = Ok(());
137
138 while remaining > 0 {
139 // Waggle SCK - basically the same as write
140 let tx_fifo_space = Self::tx_fifo_capacity();
141 let mut batch = 0;
142
143 debug_assert!(remaining_queue > 0);
144
145 for _ in 0..remaining_queue.min(tx_fifo_space as usize) {
146 remaining_queue -= 1;
147 let last = remaining_queue == 0;
148 batch += 1;
149
150 unsafe {
151 p.ic_data_cmd().write(|w| {
152 w.set_restart(restart && remaining_queue == buffer.len() - 1);
153 w.set_stop(last && send_stop);
154 w.set_cmd(true);
155 });
156 }
157 }
158
159 // We've either run out of txfifo or just plain finished setting up
160 // the clocks for the message - either way we need to wait for rx
161 // data.
162
163 debug_assert!(batch > 0);
164 let res = self
165 .wait_on(
166 |me| {
167 let rxfifo = Self::rx_fifo_len();
168 if let Err(abort_reason) = me.read_and_clear_abort_reason() {
169 Poll::Ready(Err(abort_reason))
170 } else if rxfifo >= batch {
171 Poll::Ready(Ok(rxfifo))
172 } else {
173 Poll::Pending
174 }
175 },
176 |_me| unsafe {
177 // Set the read threshold to the number of bytes we're
178 // expecting so we don't get spurious interrupts.
179 p.ic_rx_tl().write(|w| w.set_rx_tl(batch - 1));
180
181 p.ic_intr_mask().modify(|w| {
182 w.set_m_rx_full(true);
183 w.set_m_tx_abrt(true);
184 });
185 },
186 )
187 .await;
188
189 match res {
190 Err(reason) => {
191 abort_reason = Err(reason);
192 break;
193 }
194 Ok(rxfifo) => {
195 // Fetch things from rx fifo. We're assuming we're the only
196 // rxfifo reader, so nothing else can take things from it.
197 let rxbytes = (rxfifo as usize).min(remaining);
198 let received = buffer.len() - remaining;
199 for b in &mut buffer[received..received + rxbytes] {
200 *b = unsafe { p.ic_data_cmd().read().dat() };
201 }
202 remaining -= rxbytes;
203 }
204 };
205 }
206
207 self.wait_stop_det(abort_reason, send_stop).await
208 }
209
210 async fn write_async_internal(
211 &mut self,
212 bytes: impl IntoIterator<Item = u8>,
213 send_stop: bool,
214 ) -> Result<(), Error> {
215 let p = T::regs();
216
217 let mut bytes = bytes.into_iter().peekable();
218
219 let res = 'xmit: loop {
220 let tx_fifo_space = Self::tx_fifo_capacity();
221
222 for _ in 0..tx_fifo_space {
223 if let Some(byte) = bytes.next() {
224 let last = bytes.peek().is_none();
225
226 unsafe {
227 p.ic_data_cmd().write(|w| {
228 w.set_stop(last && send_stop);
229 w.set_cmd(false);
230 w.set_dat(byte);
231 });
232 }
233 } else {
234 break 'xmit Ok(());
235 }
236 }
237
238 let res = self
239 .wait_on(
240 |me| {
241 if let abort_reason @ Err(_) = me.read_and_clear_abort_reason() {
242 Poll::Ready(abort_reason)
243 } else if !Self::tx_fifo_full() {
244 // resume if there's any space free in the tx fifo
245 Poll::Ready(Ok(()))
246 } else {
247 Poll::Pending
248 }
249 },
250 |_me| unsafe {
251 // Set tx "free" threshold a little high so that we get
252 // woken before the fifo completely drains to minimize
253 // transfer stalls.
254 p.ic_tx_tl().write(|w| w.set_tx_tl(1));
255
256 p.ic_intr_mask().modify(|w| {
257 w.set_m_tx_empty(true);
258 w.set_m_tx_abrt(true);
259 })
260 },
261 )
262 .await;
263 if res.is_err() {
264 break res;
265 }
266 };
267
268 self.wait_stop_det(res, send_stop).await
269 }
270
271 /// Helper to wait for a stop bit, for both tx and rx. If we had an abort,
272 /// then we'll get a hardware-generated stop, otherwise wait for a stop if
273 /// we're expecting it.
274 ///
275 /// Also handles an abort which arises while processing the tx fifo.
276 async fn wait_stop_det(&mut self, had_abort: Result<(), Error>, do_stop: bool) -> Result<(), Error> {
277 if had_abort.is_err() || do_stop {
278 let p = T::regs();
279
280 let had_abort2 = self
281 .wait_on(
282 |me| unsafe {
283 // We could see an abort while processing fifo backlog,
284 // so handle it here.
285 let abort = me.read_and_clear_abort_reason();
286 if had_abort.is_ok() && abort.is_err() {
287 Poll::Ready(abort)
288 } else if p.ic_raw_intr_stat().read().stop_det() {
289 Poll::Ready(Ok(()))
290 } else {
291 Poll::Pending
292 }
293 },
294 |_me| unsafe {
295 p.ic_intr_mask().modify(|w| {
296 w.set_m_stop_det(true);
297 w.set_m_tx_abrt(true);
298 });
299 },
300 )
301 .await;
302 unsafe {
303 p.ic_clr_stop_det().read();
304 }
305
306 had_abort.and(had_abort2)
307 } else {
308 had_abort
309 }
310 }
311
312 pub async fn read_async(&mut self, addr: u16, buffer: &mut [u8]) -> Result<(), Error> {
313 Self::setup(addr)?;
314 self.read_async_internal(buffer, false, true).await
315 }
316
317 pub async fn write_async(&mut self, addr: u16, bytes: impl IntoIterator<Item = u8>) -> Result<(), Error> {
318 Self::setup(addr)?;
319 self.write_async_internal(bytes, true).await
70 } 320 }
71} 321}
72 322
73impl<'d, T: Instance, M: Mode> I2c<'d, T, M> { 323impl<'d, T: Instance + 'd, M: Mode> I2c<'d, T, M> {
74 fn new_inner( 324 fn new_inner(
75 _peri: impl Peripheral<P = T> + 'd, 325 _peri: impl Peripheral<P = T> + 'd,
76 scl: PeripheralRef<'d, AnyPin>, 326 scl: PeripheralRef<'d, AnyPin>,
77 sda: PeripheralRef<'d, AnyPin>, 327 sda: PeripheralRef<'d, AnyPin>,
78 _tx_dma: Option<PeripheralRef<'d, AnyChannel>>,
79 _rx_dma: Option<PeripheralRef<'d, AnyChannel>>,
80 config: Config, 328 config: Config,
81 ) -> Self { 329 ) -> Self {
82 into_ref!(_peri); 330 into_ref!(_peri);
@@ -87,6 +335,10 @@ impl<'d, T: Instance, M: Mode> I2c<'d, T, M> {
87 let p = T::regs(); 335 let p = T::regs();
88 336
89 unsafe { 337 unsafe {
338 let reset = T::reset();
339 crate::reset::reset(reset);
340 crate::reset::unreset_wait(reset);
341
90 p.ic_enable().write(|w| w.set_enable(false)); 342 p.ic_enable().write(|w| w.set_enable(false));
91 343
92 // Select controller mode & speed 344 // Select controller mode & speed
@@ -172,12 +424,7 @@ impl<'d, T: Instance, M: Mode> I2c<'d, T, M> {
172 p.ic_enable().write(|w| w.set_enable(true)); 424 p.ic_enable().write(|w| w.set_enable(true));
173 } 425 }
174 426
175 Self { 427 Self { phantom: PhantomData }
176 _tx_dma,
177 _rx_dma,
178 _dma_buf: [0; 256],
179 phantom: PhantomData,
180 }
181 } 428 }
182 429
183 fn setup(addr: u16) -> Result<(), Error> { 430 fn setup(addr: u16) -> Result<(), Error> {
@@ -198,6 +445,23 @@ impl<'d, T: Instance, M: Mode> I2c<'d, T, M> {
198 Ok(()) 445 Ok(())
199 } 446 }
200 447
448 #[inline]
449 fn tx_fifo_full() -> bool {
450 Self::tx_fifo_capacity() == 0
451 }
452
453 #[inline]
454 fn tx_fifo_capacity() -> u8 {
455 let p = T::regs();
456 unsafe { FIFO_SIZE - p.ic_txflr().read().txflr() }
457 }
458
459 #[inline]
460 fn rx_fifo_len() -> u8 {
461 let p = T::regs();
462 unsafe { p.ic_rxflr().read().rxflr() }
463 }
464
201 fn read_and_clear_abort_reason(&mut self) -> Result<(), Error> { 465 fn read_and_clear_abort_reason(&mut self) -> Result<(), Error> {
202 let p = T::regs(); 466 let p = T::regs();
203 unsafe { 467 unsafe {
@@ -240,7 +504,7 @@ impl<'d, T: Instance, M: Mode> I2c<'d, T, M> {
240 // NOTE(unsafe) We have &mut self 504 // NOTE(unsafe) We have &mut self
241 unsafe { 505 unsafe {
242 // wait until there is space in the FIFO to write the next byte 506 // wait until there is space in the FIFO to write the next byte
243 while p.ic_txflr().read().txflr() == FIFO_SIZE {} 507 while Self::tx_fifo_full() {}
244 508
245 p.ic_data_cmd().write(|w| { 509 p.ic_data_cmd().write(|w| {
246 w.set_restart(restart && first); 510 w.set_restart(restart && first);
@@ -249,7 +513,7 @@ impl<'d, T: Instance, M: Mode> I2c<'d, T, M> {
249 w.set_cmd(true); 513 w.set_cmd(true);
250 }); 514 });
251 515
252 while p.ic_rxflr().read().rxflr() == 0 { 516 while Self::rx_fifo_len() == 0 {
253 self.read_and_clear_abort_reason()?; 517 self.read_and_clear_abort_reason()?;
254 } 518 }
255 519
@@ -379,7 +643,7 @@ mod eh1 {
379 type Error = Error; 643 type Error = Error;
380 } 644 }
381 645
382 impl<'d, T: Instance, M: Mode> embedded_hal_1::i2c::blocking::I2c for I2c<'d, T, M> { 646 impl<'d, T: Instance, M: Mode> embedded_hal_1::i2c::I2c for I2c<'d, T, M> {
383 fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Self::Error> { 647 fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Self::Error> {
384 self.blocking_read(address, buffer) 648 self.blocking_read(address, buffer)
385 } 649 }
@@ -421,16 +685,14 @@ mod eh1 {
421 fn transaction<'a>( 685 fn transaction<'a>(
422 &mut self, 686 &mut self,
423 address: u8, 687 address: u8,
424 operations: &mut [embedded_hal_1::i2c::blocking::Operation<'a>], 688 operations: &mut [embedded_hal_1::i2c::Operation<'a>],
425 ) -> Result<(), Self::Error> { 689 ) -> Result<(), Self::Error> {
426 Self::setup(address.into())?; 690 Self::setup(address.into())?;
427 for i in 0..operations.len() { 691 for i in 0..operations.len() {
428 let last = i == operations.len() - 1; 692 let last = i == operations.len() - 1;
429 match &mut operations[i] { 693 match &mut operations[i] {
430 embedded_hal_1::i2c::blocking::Operation::Read(buf) => { 694 embedded_hal_1::i2c::Operation::Read(buf) => self.read_blocking_internal(buf, false, last)?,
431 self.read_blocking_internal(buf, false, last)? 695 embedded_hal_1::i2c::Operation::Write(buf) => self.write_blocking_internal(buf, last)?,
432 }
433 embedded_hal_1::i2c::blocking::Operation::Write(buf) => self.write_blocking_internal(buf, last)?,
434 } 696 }
435 } 697 }
436 Ok(()) 698 Ok(())
@@ -438,23 +700,106 @@ mod eh1 {
438 700
439 fn transaction_iter<'a, O>(&mut self, address: u8, operations: O) -> Result<(), Self::Error> 701 fn transaction_iter<'a, O>(&mut self, address: u8, operations: O) -> Result<(), Self::Error>
440 where 702 where
441 O: IntoIterator<Item = embedded_hal_1::i2c::blocking::Operation<'a>>, 703 O: IntoIterator<Item = embedded_hal_1::i2c::Operation<'a>>,
442 { 704 {
443 Self::setup(address.into())?; 705 Self::setup(address.into())?;
444 let mut peekable = operations.into_iter().peekable(); 706 let mut peekable = operations.into_iter().peekable();
445 while let Some(operation) = peekable.next() { 707 while let Some(operation) = peekable.next() {
446 let last = peekable.peek().is_none(); 708 let last = peekable.peek().is_none();
447 match operation { 709 match operation {
448 embedded_hal_1::i2c::blocking::Operation::Read(buf) => { 710 embedded_hal_1::i2c::Operation::Read(buf) => self.read_blocking_internal(buf, false, last)?,
449 self.read_blocking_internal(buf, false, last)? 711 embedded_hal_1::i2c::Operation::Write(buf) => self.write_blocking_internal(buf, last)?,
450 }
451 embedded_hal_1::i2c::blocking::Operation::Write(buf) => self.write_blocking_internal(buf, last)?,
452 } 712 }
453 } 713 }
454 Ok(()) 714 Ok(())
455 } 715 }
456 } 716 }
457} 717}
718#[cfg(all(feature = "unstable-traits", feature = "nightly"))]
719mod nightly {
720 use core::future::Future;
721
722 use embedded_hal_1::i2c::Operation;
723 use embedded_hal_async::i2c::AddressMode;
724
725 use super::*;
726
727 impl<'d, A, T> embedded_hal_async::i2c::I2c<A> for I2c<'d, T, Async>
728 where
729 A: AddressMode + Into<u16> + 'static,
730 T: Instance + 'd,
731 {
732 type ReadFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a
733 where Self: 'a;
734 type WriteFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a
735 where Self: 'a;
736 type WriteReadFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a
737 where Self: 'a;
738 type TransactionFuture<'a, 'b> = impl Future<Output = Result<(), Error>> + 'a
739 where Self: 'a, 'b: 'a;
740
741 fn read<'a>(&'a mut self, address: A, buffer: &'a mut [u8]) -> Self::ReadFuture<'a> {
742 let addr: u16 = address.into();
743
744 async move {
745 Self::setup(addr)?;
746 self.read_async_internal(buffer, false, true).await
747 }
748 }
749
750 fn write<'a>(&'a mut self, address: A, write: &'a [u8]) -> Self::WriteFuture<'a> {
751 let addr: u16 = address.into();
752
753 async move {
754 Self::setup(addr)?;
755 self.write_async_internal(write.iter().copied(), true).await
756 }
757 }
758
759 fn write_read<'a>(
760 &'a mut self,
761 address: A,
762 bytes: &'a [u8],
763 buffer: &'a mut [u8],
764 ) -> Self::WriteReadFuture<'a> {
765 let addr: u16 = address.into();
766
767 async move {
768 Self::setup(addr)?;
769 self.write_async_internal(bytes.iter().cloned(), false).await?;
770 self.read_async_internal(buffer, false, true).await
771 }
772 }
773
774 fn transaction<'a, 'b>(
775 &'a mut self,
776 address: A,
777 operations: &'a mut [Operation<'b>],
778 ) -> Self::TransactionFuture<'a, 'b> {
779 let addr: u16 = address.into();
780
781 async move {
782 let mut iterator = operations.iter_mut();
783
784 while let Some(op) = iterator.next() {
785 let last = iterator.len() == 0;
786
787 match op {
788 Operation::Read(buffer) => {
789 Self::setup(addr)?;
790 self.read_async_internal(buffer, false, last).await?;
791 }
792 Operation::Write(buffer) => {
793 Self::setup(addr)?;
794 self.write_async_internal(buffer.into_iter().cloned(), last).await?;
795 }
796 }
797 }
798 Ok(())
799 }
800 }
801 }
802}
458 803
459fn i2c_reserved_addr(addr: u16) -> bool { 804fn i2c_reserved_addr(addr: u16) -> bool {
460 (addr & 0x78) == 0 || (addr & 0x78) == 0x78 805 (addr & 0x78) == 0 || (addr & 0x78) == 0x78
@@ -462,6 +807,7 @@ fn i2c_reserved_addr(addr: u16) -> bool {
462 807
463mod sealed { 808mod sealed {
464 use embassy_cortex_m::interrupt::Interrupt; 809 use embassy_cortex_m::interrupt::Interrupt;
810 use embassy_sync::waitqueue::AtomicWaker;
465 811
466 pub trait Instance { 812 pub trait Instance {
467 const TX_DREQ: u8; 813 const TX_DREQ: u8;
@@ -470,6 +816,8 @@ mod sealed {
470 type Interrupt: Interrupt; 816 type Interrupt: Interrupt;
471 817
472 fn regs() -> crate::pac::i2c::I2c; 818 fn regs() -> crate::pac::i2c::I2c;
819 fn reset() -> crate::pac::resets::regs::Peripherals;
820 fn waker() -> &'static AtomicWaker;
473 } 821 }
474 822
475 pub trait Mode {} 823 pub trait Mode {}
@@ -496,23 +844,38 @@ impl_mode!(Async);
496pub trait Instance: sealed::Instance {} 844pub trait Instance: sealed::Instance {}
497 845
498macro_rules! impl_instance { 846macro_rules! impl_instance {
499 ($type:ident, $irq:ident, $tx_dreq:expr, $rx_dreq:expr) => { 847 ($type:ident, $irq:ident, $reset:ident, $tx_dreq:expr, $rx_dreq:expr) => {
500 impl sealed::Instance for peripherals::$type { 848 impl sealed::Instance for peripherals::$type {
501 const TX_DREQ: u8 = $tx_dreq; 849 const TX_DREQ: u8 = $tx_dreq;
502 const RX_DREQ: u8 = $rx_dreq; 850 const RX_DREQ: u8 = $rx_dreq;
503 851
504 type Interrupt = crate::interrupt::$irq; 852 type Interrupt = crate::interrupt::$irq;
505 853
854 #[inline]
506 fn regs() -> pac::i2c::I2c { 855 fn regs() -> pac::i2c::I2c {
507 pac::$type 856 pac::$type
508 } 857 }
858
859 #[inline]
860 fn reset() -> pac::resets::regs::Peripherals {
861 let mut ret = pac::resets::regs::Peripherals::default();
862 ret.$reset(true);
863 ret
864 }
865
866 #[inline]
867 fn waker() -> &'static AtomicWaker {
868 static WAKER: AtomicWaker = AtomicWaker::new();
869
870 &WAKER
871 }
509 } 872 }
510 impl Instance for peripherals::$type {} 873 impl Instance for peripherals::$type {}
511 }; 874 };
512} 875}
513 876
514impl_instance!(I2C0, I2C0_IRQ, 32, 33); 877impl_instance!(I2C0, I2C0_IRQ, set_i2c0, 32, 33);
515impl_instance!(I2C1, I2C1_IRQ, 34, 35); 878impl_instance!(I2C1, I2C1_IRQ, set_i2c1, 34, 35);
516 879
517pub trait SdaPin<T: Instance>: sealed::SdaPin<T> + crate::gpio::Pin {} 880pub trait SdaPin<T: Instance>: sealed::SdaPin<T> + crate::gpio::Pin {}
518pub trait SclPin<T: Instance>: sealed::SclPin<T> + crate::gpio::Pin {} 881pub trait SclPin<T: Instance>: sealed::SclPin<T> + crate::gpio::Pin {}
diff --git a/embassy-rp/src/rtc/mod.rs b/embassy-rp/src/rtc/mod.rs
index 7f3bbbe73..e4b6f0b1d 100644
--- a/embassy-rp/src/rtc/mod.rs
+++ b/embassy-rp/src/rtc/mod.rs
@@ -145,6 +145,8 @@ impl<'d, T: Instance> RealTimeClock<'d, T> {
145 filter.write_setup_1(w); 145 filter.write_setup_1(w);
146 }); 146 });
147 147
148 self.inner.regs().inte().modify(|w| w.set_rtc(true));
149
148 // Set the enable bit and check if it is set 150 // Set the enable bit and check if it is set
149 self.inner.regs().irq_setup_0().modify(|w| w.set_match_ena(true)); 151 self.inner.regs().irq_setup_0().modify(|w| w.set_match_ena(true));
150 while !self.inner.regs().irq_setup_0().read().match_active() { 152 while !self.inner.regs().irq_setup_0().read().match_active() {
diff --git a/embassy-rp/src/spi.rs b/embassy-rp/src/spi.rs
index 03293e064..754e2dd30 100644
--- a/embassy-rp/src/spi.rs
+++ b/embassy-rp/src/spi.rs
@@ -523,25 +523,25 @@ mod eh1 {
523 type Error = Error; 523 type Error = Error;
524 } 524 }
525 525
526 impl<'d, T: Instance, M: Mode> embedded_hal_1::spi::blocking::SpiBusFlush for Spi<'d, T, M> { 526 impl<'d, T: Instance, M: Mode> embedded_hal_1::spi::SpiBusFlush for Spi<'d, T, M> {
527 fn flush(&mut self) -> Result<(), Self::Error> { 527 fn flush(&mut self) -> Result<(), Self::Error> {
528 Ok(()) 528 Ok(())
529 } 529 }
530 } 530 }
531 531
532 impl<'d, T: Instance, M: Mode> embedded_hal_1::spi::blocking::SpiBusRead<u8> for Spi<'d, T, M> { 532 impl<'d, T: Instance, M: Mode> embedded_hal_1::spi::SpiBusRead<u8> for Spi<'d, T, M> {
533 fn read(&mut self, words: &mut [u8]) -> Result<(), Self::Error> { 533 fn read(&mut self, words: &mut [u8]) -> Result<(), Self::Error> {
534 self.blocking_transfer(words, &[]) 534 self.blocking_transfer(words, &[])
535 } 535 }
536 } 536 }
537 537
538 impl<'d, T: Instance, M: Mode> embedded_hal_1::spi::blocking::SpiBusWrite<u8> for Spi<'d, T, M> { 538 impl<'d, T: Instance, M: Mode> embedded_hal_1::spi::SpiBusWrite<u8> for Spi<'d, T, M> {
539 fn write(&mut self, words: &[u8]) -> Result<(), Self::Error> { 539 fn write(&mut self, words: &[u8]) -> Result<(), Self::Error> {
540 self.blocking_write(words) 540 self.blocking_write(words)
541 } 541 }
542 } 542 }
543 543
544 impl<'d, T: Instance, M: Mode> embedded_hal_1::spi::blocking::SpiBus<u8> for Spi<'d, T, M> { 544 impl<'d, T: Instance, M: Mode> embedded_hal_1::spi::SpiBus<u8> for Spi<'d, T, M> {
545 fn transfer(&mut self, read: &mut [u8], write: &[u8]) -> Result<(), Self::Error> { 545 fn transfer(&mut self, read: &mut [u8], write: &[u8]) -> Result<(), Self::Error> {
546 self.blocking_transfer(read, write) 546 self.blocking_transfer(read, write)
547 } 547 }
diff --git a/embassy-rp/src/uart/mod.rs b/embassy-rp/src/uart/mod.rs
index 567c79db3..56c25e189 100644
--- a/embassy-rp/src/uart/mod.rs
+++ b/embassy-rp/src/uart/mod.rs
@@ -486,7 +486,7 @@ mod eh1 {
486 type Error = Error; 486 type Error = Error;
487 } 487 }
488 488
489 impl<'d, T: Instance, M: Mode> embedded_hal_1::serial::nb::Read for UartRx<'d, T, M> { 489 impl<'d, T: Instance, M: Mode> embedded_hal_nb::serial::Read for UartRx<'d, T, M> {
490 fn read(&mut self) -> nb::Result<u8, Self::Error> { 490 fn read(&mut self) -> nb::Result<u8, Self::Error> {
491 let r = T::regs(); 491 let r = T::regs();
492 unsafe { 492 unsafe {
@@ -509,7 +509,7 @@ mod eh1 {
509 } 509 }
510 } 510 }
511 511
512 impl<'d, T: Instance, M: Mode> embedded_hal_1::serial::blocking::Write for UartTx<'d, T, M> { 512 impl<'d, T: Instance, M: Mode> embedded_hal_1::serial::Write for UartTx<'d, T, M> {
513 fn write(&mut self, buffer: &[u8]) -> Result<(), Self::Error> { 513 fn write(&mut self, buffer: &[u8]) -> Result<(), Self::Error> {
514 self.blocking_write(buffer) 514 self.blocking_write(buffer)
515 } 515 }
@@ -519,7 +519,7 @@ mod eh1 {
519 } 519 }
520 } 520 }
521 521
522 impl<'d, T: Instance, M: Mode> embedded_hal_1::serial::nb::Write for UartTx<'d, T, M> { 522 impl<'d, T: Instance, M: Mode> embedded_hal_nb::serial::Write for UartTx<'d, T, M> {
523 fn write(&mut self, char: u8) -> nb::Result<(), Self::Error> { 523 fn write(&mut self, char: u8) -> nb::Result<(), Self::Error> {
524 self.blocking_write(&[char]).map_err(nb::Error::Other) 524 self.blocking_write(&[char]).map_err(nb::Error::Other)
525 } 525 }
@@ -529,13 +529,13 @@ mod eh1 {
529 } 529 }
530 } 530 }
531 531
532 impl<'d, T: Instance, M: Mode> embedded_hal_1::serial::nb::Read for Uart<'d, T, M> { 532 impl<'d, T: Instance, M: Mode> embedded_hal_nb::serial::Read for Uart<'d, T, M> {
533 fn read(&mut self) -> Result<u8, nb::Error<Self::Error>> { 533 fn read(&mut self) -> Result<u8, nb::Error<Self::Error>> {
534 embedded_hal_02::serial::Read::read(&mut self.rx) 534 embedded_hal_02::serial::Read::read(&mut self.rx)
535 } 535 }
536 } 536 }
537 537
538 impl<'d, T: Instance, M: Mode> embedded_hal_1::serial::blocking::Write for Uart<'d, T, M> { 538 impl<'d, T: Instance, M: Mode> embedded_hal_1::serial::Write for Uart<'d, T, M> {
539 fn write(&mut self, buffer: &[u8]) -> Result<(), Self::Error> { 539 fn write(&mut self, buffer: &[u8]) -> Result<(), Self::Error> {
540 self.blocking_write(buffer) 540 self.blocking_write(buffer)
541 } 541 }
@@ -545,7 +545,7 @@ mod eh1 {
545 } 545 }
546 } 546 }
547 547
548 impl<'d, T: Instance, M: Mode> embedded_hal_1::serial::nb::Write for Uart<'d, T, M> { 548 impl<'d, T: Instance, M: Mode> embedded_hal_nb::serial::Write for Uart<'d, T, M> {
549 fn write(&mut self, char: u8) -> nb::Result<(), Self::Error> { 549 fn write(&mut self, char: u8) -> nb::Result<(), Self::Error> {
550 self.blocking_write(&[char]).map_err(nb::Error::Other) 550 self.blocking_write(&[char]).map_err(nb::Error::Other)
551 } 551 }
diff --git a/embassy-rp/src/usb.rs b/embassy-rp/src/usb.rs
index 0a904aab3..6dc90b98e 100644
--- a/embassy-rp/src/usb.rs
+++ b/embassy-rp/src/usb.rs
@@ -522,7 +522,7 @@ impl<'d, T: Instance> driver::Endpoint for Endpoint<'d, T, In> {
522 trace!("wait_enabled IN WAITING"); 522 trace!("wait_enabled IN WAITING");
523 let index = self.info.addr.index(); 523 let index = self.info.addr.index();
524 poll_fn(|cx| { 524 poll_fn(|cx| {
525 EP_OUT_WAKERS[index].register(cx.waker()); 525 EP_IN_WAKERS[index].register(cx.waker());
526 let val = unsafe { T::dpram().ep_in_control(self.info.addr.index() - 1).read() }; 526 let val = unsafe { T::dpram().ep_in_control(self.info.addr.index() - 1).read() };
527 if val.enable() { 527 if val.enable() {
528 Poll::Ready(()) 528 Poll::Ready(())
@@ -811,8 +811,8 @@ impl<'d, T: Instance> driver::ControlPipe for ControlPipe<'d, T> {
811 async move { 811 async move {
812 trace!("control: accept"); 812 trace!("control: accept");
813 813
814 let bufcontrol = T::dpram().ep_in_buffer_control(0);
814 unsafe { 815 unsafe {
815 let bufcontrol = T::dpram().ep_in_buffer_control(0);
816 bufcontrol.write(|w| { 816 bufcontrol.write(|w| {
817 w.set_length(0, 0); 817 w.set_length(0, 0);
818 w.set_pid(0, true); 818 w.set_pid(0, true);
@@ -826,6 +826,18 @@ impl<'d, T: Instance> driver::ControlPipe for ControlPipe<'d, T> {
826 w.set_available(0, true); 826 w.set_available(0, true);
827 }); 827 });
828 } 828 }
829
830 // wait for completion before returning, needed so
831 // set_address() doesn't happen early.
832 poll_fn(|cx| {
833 EP_IN_WAKERS[0].register(cx.waker());
834 if unsafe { bufcontrol.read().available(0) } {
835 Poll::Pending
836 } else {
837 Poll::Ready(())
838 }
839 })
840 .await;
829 } 841 }
830 } 842 }
831 843