diff options
| author | Dario Nieuwenhuis <[email protected]> | 2025-09-27 17:34:36 +0200 |
|---|---|---|
| committer | Dario Nieuwenhuis <[email protected]> | 2025-09-27 18:37:57 +0200 |
| commit | e5328c78259c7e288bf54c83bc80c2d2311abdf2 (patch) | |
| tree | 9cbb775413029ffb08475bdcf46516b3b18e18f4 /embassy-nrf/src | |
| parent | b29c7295e406045ec137b78ca5f220bf7909006b (diff) | |
nrf/twim: erase instance generics
Diffstat (limited to 'embassy-nrf/src')
| -rw-r--r-- | embassy-nrf/src/twim.rs | 75 |
1 files changed, 41 insertions, 34 deletions
diff --git a/embassy-nrf/src/twim.rs b/embassy-nrf/src/twim.rs index 3fc59a39a..ffc9b39f6 100644 --- a/embassy-nrf/src/twim.rs +++ b/embassy-nrf/src/twim.rs | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | 2 | ||
| 3 | #![macro_use] | 3 | #![macro_use] |
| 4 | 4 | ||
| 5 | use core::future::{poll_fn, Future}; | 5 | use core::future::poll_fn; |
| 6 | use core::marker::PhantomData; | 6 | use core::marker::PhantomData; |
| 7 | use core::sync::atomic::compiler_fence; | 7 | use core::sync::atomic::compiler_fence; |
| 8 | use core::sync::atomic::Ordering::SeqCst; | 8 | use core::sync::atomic::Ordering::SeqCst; |
| @@ -112,12 +112,15 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl | |||
| 112 | } | 112 | } |
| 113 | 113 | ||
| 114 | /// TWI driver. | 114 | /// TWI driver. |
| 115 | pub struct Twim<'d, T: Instance> { | 115 | pub struct Twim<'d> { |
| 116 | _p: Peri<'d, T>, | 116 | r: pac::twim::Twim, |
| 117 | irq: interrupt::Interrupt, | ||
| 118 | state: &'static State, | ||
| 117 | tx_ram_buffer: &'d mut [u8], | 119 | tx_ram_buffer: &'d mut [u8], |
| 120 | _p: PhantomData<&'d ()>, | ||
| 118 | } | 121 | } |
| 119 | 122 | ||
| 120 | impl<'d, T: Instance> Twim<'d, T> { | 123 | impl<'d> Twim<'d> { |
| 121 | /// Create a new TWI driver. | 124 | /// Create a new TWI driver. |
| 122 | /// | 125 | /// |
| 123 | /// `tx_ram_buffer` is required if any write operations will be performed with data that is not in RAM. | 126 | /// `tx_ram_buffer` is required if any write operations will be performed with data that is not in RAM. |
| @@ -125,8 +128,8 @@ impl<'d, T: Instance> Twim<'d, T> { | |||
| 125 | /// needs to be at least as large as the largest write operation that will be executed with a buffer | 128 | /// needs to be at least as large as the largest write operation that will be executed with a buffer |
| 126 | /// that is not in RAM. If all write operations will be performed from RAM, an empty buffer (`&[]`) may | 129 | /// that is not in RAM. If all write operations will be performed from RAM, an empty buffer (`&[]`) may |
| 127 | /// be used. | 130 | /// be used. |
| 128 | pub fn new( | 131 | pub fn new<T: Instance>( |
| 129 | twim: Peri<'d, T>, | 132 | _twim: Peri<'d, T>, |
| 130 | _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, | 133 | _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, |
| 131 | sda: Peri<'d, impl GpioPin>, | 134 | sda: Peri<'d, impl GpioPin>, |
| 132 | scl: Peri<'d, impl GpioPin>, | 135 | scl: Peri<'d, impl GpioPin>, |
| @@ -167,8 +170,11 @@ impl<'d, T: Instance> Twim<'d, T> { | |||
| 167 | r.enable().write(|w| w.set_enable(vals::Enable::ENABLED)); | 170 | r.enable().write(|w| w.set_enable(vals::Enable::ENABLED)); |
| 168 | 171 | ||
| 169 | let mut twim = Self { | 172 | let mut twim = Self { |
| 170 | _p: twim, | 173 | r: T::regs(), |
| 174 | irq: T::Interrupt::IRQ, | ||
| 175 | state: T::state(), | ||
| 171 | tx_ram_buffer, | 176 | tx_ram_buffer, |
| 177 | _p: PhantomData {}, | ||
| 172 | }; | 178 | }; |
| 173 | 179 | ||
| 174 | // Apply runtime peripheral configuration | 180 | // Apply runtime peripheral configuration |
| @@ -201,7 +207,7 @@ impl<'d, T: Instance> Twim<'d, T> { | |||
| 201 | return Err(Error::TxBufferTooLong); | 207 | return Err(Error::TxBufferTooLong); |
| 202 | } | 208 | } |
| 203 | 209 | ||
| 204 | let r = T::regs(); | 210 | let r = self.r; |
| 205 | 211 | ||
| 206 | // We're giving the register a pointer to the stack. Since we're | 212 | // We're giving the register a pointer to the stack. Since we're |
| 207 | // waiting for the I2C transaction to end before this stack pointer | 213 | // waiting for the I2C transaction to end before this stack pointer |
| @@ -228,7 +234,7 @@ impl<'d, T: Instance> Twim<'d, T> { | |||
| 228 | return Err(Error::RxBufferTooLong); | 234 | return Err(Error::RxBufferTooLong); |
| 229 | } | 235 | } |
| 230 | 236 | ||
| 231 | let r = T::regs(); | 237 | let r = self.r; |
| 232 | 238 | ||
| 233 | // We're giving the register a pointer to the stack. Since we're | 239 | // We're giving the register a pointer to the stack. Since we're |
| 234 | // waiting for the I2C transaction to end before this stack pointer | 240 | // waiting for the I2C transaction to end before this stack pointer |
| @@ -250,7 +256,7 @@ impl<'d, T: Instance> Twim<'d, T> { | |||
| 250 | } | 256 | } |
| 251 | 257 | ||
| 252 | fn clear_errorsrc(&mut self) { | 258 | fn clear_errorsrc(&mut self) { |
| 253 | let r = T::regs(); | 259 | let r = self.r; |
| 254 | r.errorsrc().write(|w| { | 260 | r.errorsrc().write(|w| { |
| 255 | w.set_anack(true); | 261 | w.set_anack(true); |
| 256 | w.set_dnack(true); | 262 | w.set_dnack(true); |
| @@ -259,8 +265,8 @@ impl<'d, T: Instance> Twim<'d, T> { | |||
| 259 | } | 265 | } |
| 260 | 266 | ||
| 261 | /// Get Error instance, if any occurred. | 267 | /// Get Error instance, if any occurred. |
| 262 | fn check_errorsrc() -> Result<(), Error> { | 268 | fn check_errorsrc(&mut self) -> Result<(), Error> { |
| 263 | let r = T::regs(); | 269 | let r = self.r; |
| 264 | 270 | ||
| 265 | let err = r.errorsrc().read(); | 271 | let err = r.errorsrc().read(); |
| 266 | if err.anack() { | 272 | if err.anack() { |
| @@ -276,7 +282,7 @@ impl<'d, T: Instance> Twim<'d, T> { | |||
| 276 | } | 282 | } |
| 277 | 283 | ||
| 278 | fn check_rx(&self, len: usize) -> Result<(), Error> { | 284 | fn check_rx(&self, len: usize) -> Result<(), Error> { |
| 279 | let r = T::regs(); | 285 | let r = self.r; |
| 280 | if r.rxd().amount().read().0 != len as u32 { | 286 | if r.rxd().amount().read().0 != len as u32 { |
| 281 | Err(Error::Receive) | 287 | Err(Error::Receive) |
| 282 | } else { | 288 | } else { |
| @@ -285,7 +291,7 @@ impl<'d, T: Instance> Twim<'d, T> { | |||
| 285 | } | 291 | } |
| 286 | 292 | ||
| 287 | fn check_tx(&self, len: usize) -> Result<(), Error> { | 293 | fn check_tx(&self, len: usize) -> Result<(), Error> { |
| 288 | let r = T::regs(); | 294 | let r = self.r; |
| 289 | if r.txd().amount().read().0 != len as u32 { | 295 | if r.txd().amount().read().0 != len as u32 { |
| 290 | Err(Error::Transmit) | 296 | Err(Error::Transmit) |
| 291 | } else { | 297 | } else { |
| @@ -295,7 +301,7 @@ impl<'d, T: Instance> Twim<'d, T> { | |||
| 295 | 301 | ||
| 296 | /// Wait for stop or error | 302 | /// Wait for stop or error |
| 297 | fn blocking_wait(&mut self) { | 303 | fn blocking_wait(&mut self) { |
| 298 | let r = T::regs(); | 304 | let r = self.r; |
| 299 | loop { | 305 | loop { |
| 300 | if r.events_suspended().read() != 0 || r.events_stopped().read() != 0 { | 306 | if r.events_suspended().read() != 0 || r.events_stopped().read() != 0 { |
| 301 | r.events_suspended().write_value(0); | 307 | r.events_suspended().write_value(0); |
| @@ -312,7 +318,7 @@ impl<'d, T: Instance> Twim<'d, T> { | |||
| 312 | /// Wait for stop or error | 318 | /// Wait for stop or error |
| 313 | #[cfg(feature = "time")] | 319 | #[cfg(feature = "time")] |
| 314 | fn blocking_wait_timeout(&mut self, timeout: Duration) -> Result<(), Error> { | 320 | fn blocking_wait_timeout(&mut self, timeout: Duration) -> Result<(), Error> { |
| 315 | let r = T::regs(); | 321 | let r = self.r; |
| 316 | let deadline = Instant::now() + timeout; | 322 | let deadline = Instant::now() + timeout; |
| 317 | loop { | 323 | loop { |
| 318 | if r.events_suspended().read() != 0 || r.events_stopped().read() != 0 { | 324 | if r.events_suspended().read() != 0 || r.events_stopped().read() != 0 { |
| @@ -333,10 +339,10 @@ impl<'d, T: Instance> Twim<'d, T> { | |||
| 333 | } | 339 | } |
| 334 | 340 | ||
| 335 | /// Wait for stop or error | 341 | /// Wait for stop or error |
| 336 | fn async_wait(&mut self) -> impl Future<Output = Result<(), Error>> { | 342 | async fn async_wait(&mut self) -> Result<(), Error> { |
| 337 | poll_fn(move |cx| { | 343 | poll_fn(|cx| { |
| 338 | let r = T::regs(); | 344 | let r = self.r; |
| 339 | let s = T::state(); | 345 | let s = self.state; |
| 340 | 346 | ||
| 341 | s.end_waker.register(cx.waker()); | 347 | s.end_waker.register(cx.waker()); |
| 342 | if r.events_suspended().read() != 0 || r.events_stopped().read() != 0 { | 348 | if r.events_suspended().read() != 0 || r.events_stopped().read() != 0 { |
| @@ -349,15 +355,16 @@ impl<'d, T: Instance> Twim<'d, T> { | |||
| 349 | if r.events_error().read() != 0 { | 355 | if r.events_error().read() != 0 { |
| 350 | r.events_error().write_value(0); | 356 | r.events_error().write_value(0); |
| 351 | r.tasks_stop().write_value(1); | 357 | r.tasks_stop().write_value(1); |
| 352 | if let Err(e) = Self::check_errorsrc() { | 358 | if let Err(e) = self.check_errorsrc() { |
| 353 | return Poll::Ready(Err(e)); | 359 | return Poll::Ready(Err(e)); |
| 354 | } else { | 360 | } else { |
| 355 | panic!("Found events_error bit without an error in errorsrc reg"); | 361 | return Poll::Ready(Err(Error::Timeout)); |
| 356 | } | 362 | } |
| 357 | } | 363 | } |
| 358 | 364 | ||
| 359 | Poll::Pending | 365 | Poll::Pending |
| 360 | }) | 366 | }) |
| 367 | .await | ||
| 361 | } | 368 | } |
| 362 | 369 | ||
| 363 | fn setup_operations( | 370 | fn setup_operations( |
| @@ -367,7 +374,7 @@ impl<'d, T: Instance> Twim<'d, T> { | |||
| 367 | last_op: Option<&Operation<'_>>, | 374 | last_op: Option<&Operation<'_>>, |
| 368 | inten: bool, | 375 | inten: bool, |
| 369 | ) -> Result<usize, Error> { | 376 | ) -> Result<usize, Error> { |
| 370 | let r = T::regs(); | 377 | let r = self.r; |
| 371 | 378 | ||
| 372 | compiler_fence(SeqCst); | 379 | compiler_fence(SeqCst); |
| 373 | 380 | ||
| @@ -511,7 +518,7 @@ impl<'d, T: Instance> Twim<'d, T> { | |||
| 511 | 518 | ||
| 512 | fn check_operations(&mut self, operations: &[Operation<'_>]) -> Result<(), Error> { | 519 | fn check_operations(&mut self, operations: &[Operation<'_>]) -> Result<(), Error> { |
| 513 | compiler_fence(SeqCst); | 520 | compiler_fence(SeqCst); |
| 514 | Self::check_errorsrc()?; | 521 | self.check_errorsrc()?; |
| 515 | 522 | ||
| 516 | assert!(operations.len() == 1 || operations.len() == 2); | 523 | assert!(operations.len() == 1 || operations.len() == 2); |
| 517 | match operations { | 524 | match operations { |
| @@ -696,14 +703,14 @@ impl<'d, T: Instance> Twim<'d, T> { | |||
| 696 | } | 703 | } |
| 697 | } | 704 | } |
| 698 | 705 | ||
| 699 | impl<'a, T: Instance> Drop for Twim<'a, T> { | 706 | impl<'a> Drop for Twim<'a> { |
| 700 | fn drop(&mut self) { | 707 | fn drop(&mut self) { |
| 701 | trace!("twim drop"); | 708 | trace!("twim drop"); |
| 702 | 709 | ||
| 703 | // TODO: check for abort | 710 | // TODO: check for abort |
| 704 | 711 | ||
| 705 | // disable! | 712 | // disable! |
| 706 | let r = T::regs(); | 713 | let r = self.r; |
| 707 | r.enable().write(|w| w.set_enable(vals::Enable::DISABLED)); | 714 | r.enable().write(|w| w.set_enable(vals::Enable::DISABLED)); |
| 708 | 715 | ||
| 709 | gpio::deconfigure_pin(r.psel().sda().read()); | 716 | gpio::deconfigure_pin(r.psel().sda().read()); |
| @@ -759,7 +766,7 @@ macro_rules! impl_twim { | |||
| 759 | mod eh02 { | 766 | mod eh02 { |
| 760 | use super::*; | 767 | use super::*; |
| 761 | 768 | ||
| 762 | impl<'a, T: Instance> embedded_hal_02::blocking::i2c::Write for Twim<'a, T> { | 769 | impl<'a> embedded_hal_02::blocking::i2c::Write for Twim<'a> { |
| 763 | type Error = Error; | 770 | type Error = Error; |
| 764 | 771 | ||
| 765 | fn write(&mut self, addr: u8, bytes: &[u8]) -> Result<(), Error> { | 772 | fn write(&mut self, addr: u8, bytes: &[u8]) -> Result<(), Error> { |
| @@ -767,7 +774,7 @@ mod eh02 { | |||
| 767 | } | 774 | } |
| 768 | } | 775 | } |
| 769 | 776 | ||
| 770 | impl<'a, T: Instance> embedded_hal_02::blocking::i2c::Read for Twim<'a, T> { | 777 | impl<'a> embedded_hal_02::blocking::i2c::Read for Twim<'a> { |
| 771 | type Error = Error; | 778 | type Error = Error; |
| 772 | 779 | ||
| 773 | fn read(&mut self, addr: u8, bytes: &mut [u8]) -> Result<(), Error> { | 780 | fn read(&mut self, addr: u8, bytes: &mut [u8]) -> Result<(), Error> { |
| @@ -775,7 +782,7 @@ mod eh02 { | |||
| 775 | } | 782 | } |
| 776 | } | 783 | } |
| 777 | 784 | ||
| 778 | impl<'a, T: Instance> embedded_hal_02::blocking::i2c::WriteRead for Twim<'a, T> { | 785 | impl<'a> embedded_hal_02::blocking::i2c::WriteRead for Twim<'a> { |
| 779 | type Error = Error; | 786 | type Error = Error; |
| 780 | 787 | ||
| 781 | fn write_read<'w>(&mut self, addr: u8, bytes: &'w [u8], buffer: &'w mut [u8]) -> Result<(), Error> { | 788 | fn write_read<'w>(&mut self, addr: u8, bytes: &'w [u8], buffer: &'w mut [u8]) -> Result<(), Error> { |
| @@ -804,27 +811,27 @@ impl embedded_hal_1::i2c::Error for Error { | |||
| 804 | } | 811 | } |
| 805 | } | 812 | } |
| 806 | 813 | ||
| 807 | impl<'d, T: Instance> embedded_hal_1::i2c::ErrorType for Twim<'d, T> { | 814 | impl<'d> embedded_hal_1::i2c::ErrorType for Twim<'d> { |
| 808 | type Error = Error; | 815 | type Error = Error; |
| 809 | } | 816 | } |
| 810 | 817 | ||
| 811 | impl<'d, T: Instance> embedded_hal_1::i2c::I2c for Twim<'d, T> { | 818 | impl<'d> embedded_hal_1::i2c::I2c for Twim<'d> { |
| 812 | fn transaction(&mut self, address: u8, operations: &mut [Operation<'_>]) -> Result<(), Self::Error> { | 819 | fn transaction(&mut self, address: u8, operations: &mut [Operation<'_>]) -> Result<(), Self::Error> { |
| 813 | self.blocking_transaction(address, operations) | 820 | self.blocking_transaction(address, operations) |
| 814 | } | 821 | } |
| 815 | } | 822 | } |
| 816 | 823 | ||
| 817 | impl<'d, T: Instance> embedded_hal_async::i2c::I2c for Twim<'d, T> { | 824 | impl<'d> embedded_hal_async::i2c::I2c for Twim<'d> { |
| 818 | async fn transaction(&mut self, address: u8, operations: &mut [Operation<'_>]) -> Result<(), Self::Error> { | 825 | async fn transaction(&mut self, address: u8, operations: &mut [Operation<'_>]) -> Result<(), Self::Error> { |
| 819 | self.transaction(address, operations).await | 826 | self.transaction(address, operations).await |
| 820 | } | 827 | } |
| 821 | } | 828 | } |
| 822 | 829 | ||
| 823 | impl<'d, T: Instance> SetConfig for Twim<'d, T> { | 830 | impl<'d> SetConfig for Twim<'d> { |
| 824 | type Config = Config; | 831 | type Config = Config; |
| 825 | type ConfigError = (); | 832 | type ConfigError = (); |
| 826 | fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError> { | 833 | fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError> { |
| 827 | let r = T::regs(); | 834 | let r = self.r; |
| 828 | r.frequency().write(|w| w.set_frequency(config.frequency)); | 835 | r.frequency().write(|w| w.set_frequency(config.frequency)); |
| 829 | 836 | ||
| 830 | Ok(()) | 837 | Ok(()) |
