diff options
| author | Mathias <[email protected]> | 2022-10-24 12:14:26 +0200 |
|---|---|---|
| committer | Mathias <[email protected]> | 2022-10-24 12:14:26 +0200 |
| commit | 8d809c96ecf2fabf77f0fb72f2a59acd18306bf2 (patch) | |
| tree | da3e28e491bbaadbc448b9a021291e2164b7531e /embassy-rp/src | |
| parent | 7152031229da19005e5b0d52c8c72d359d3e0daa (diff) | |
| parent | ce1cba761c2942b7faa27f4098487c6468784729 (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.rs | 54 | ||||
| -rw-r--r-- | embassy-rp/src/i2c.rs | 425 | ||||
| -rw-r--r-- | embassy-rp/src/rtc/mod.rs | 2 | ||||
| -rw-r--r-- | embassy-rp/src/spi.rs | 8 | ||||
| -rw-r--r-- | embassy-rp/src/uart/mod.rs | 12 | ||||
| -rw-r--r-- | embassy-rp/src/usb.rs | 16 |
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 | ||
| 663 | pub struct AnyPin { | 675 | pub 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 @@ | |||
| 1 | use core::future; | ||
| 1 | use core::marker::PhantomData; | 2 | use core::marker::PhantomData; |
| 3 | use core::task::Poll; | ||
| 2 | 4 | ||
| 5 | use embassy_cortex_m::interrupt::InterruptExt; | ||
| 3 | use embassy_hal_common::{into_ref, PeripheralRef}; | 6 | use embassy_hal_common::{into_ref, PeripheralRef}; |
| 7 | use embassy_sync::waitqueue::AtomicWaker; | ||
| 4 | use pac::i2c; | 8 | use pac::i2c; |
| 5 | 9 | ||
| 6 | use crate::dma::AnyChannel; | ||
| 7 | use crate::gpio::sealed::Pin; | 10 | use crate::gpio::sealed::Pin; |
| 8 | use crate::gpio::AnyPin; | 11 | use crate::gpio::AnyPin; |
| 9 | use crate::{pac, peripherals, Peripheral}; | 12 | use crate::{pac, peripherals, Peripheral}; |
| @@ -52,31 +55,276 @@ impl Default for Config { | |||
| 52 | const FIFO_SIZE: u8 = 16; | 55 | const FIFO_SIZE: u8 = 16; |
| 53 | 56 | ||
| 54 | pub struct I2c<'d, T: Instance, M: Mode> { | 57 | pub 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 | ||
| 61 | impl<'d, T: Instance> I2c<'d, T, Blocking> { | 61 | impl<'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 | |||
| 73 | impl<'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 | ||
| 73 | impl<'d, T: Instance, M: Mode> I2c<'d, T, M> { | 323 | impl<'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"))] | ||
| 719 | mod 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 | ||
| 459 | fn i2c_reserved_addr(addr: u16) -> bool { | 804 | fn 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 | ||
| 463 | mod sealed { | 808 | mod 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); | |||
| 496 | pub trait Instance: sealed::Instance {} | 844 | pub trait Instance: sealed::Instance {} |
| 497 | 845 | ||
| 498 | macro_rules! impl_instance { | 846 | macro_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 | ||
| 514 | impl_instance!(I2C0, I2C0_IRQ, 32, 33); | 877 | impl_instance!(I2C0, I2C0_IRQ, set_i2c0, 32, 33); |
| 515 | impl_instance!(I2C1, I2C1_IRQ, 34, 35); | 878 | impl_instance!(I2C1, I2C1_IRQ, set_i2c1, 34, 35); |
| 516 | 879 | ||
| 517 | pub trait SdaPin<T: Instance>: sealed::SdaPin<T> + crate::gpio::Pin {} | 880 | pub trait SdaPin<T: Instance>: sealed::SdaPin<T> + crate::gpio::Pin {} |
| 518 | pub trait SclPin<T: Instance>: sealed::SclPin<T> + crate::gpio::Pin {} | 881 | pub 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 | ||
