aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-nrf/src/twim.rs75
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
5use core::future::{poll_fn, Future}; 5use core::future::poll_fn;
6use core::marker::PhantomData; 6use core::marker::PhantomData;
7use core::sync::atomic::compiler_fence; 7use core::sync::atomic::compiler_fence;
8use core::sync::atomic::Ordering::SeqCst; 8use 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.
115pub struct Twim<'d, T: Instance> { 115pub 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
120impl<'d, T: Instance> Twim<'d, T> { 123impl<'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
699impl<'a, T: Instance> Drop for Twim<'a, T> { 706impl<'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 {
759mod eh02 { 766mod 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
807impl<'d, T: Instance> embedded_hal_1::i2c::ErrorType for Twim<'d, T> { 814impl<'d> embedded_hal_1::i2c::ErrorType for Twim<'d> {
808 type Error = Error; 815 type Error = Error;
809} 816}
810 817
811impl<'d, T: Instance> embedded_hal_1::i2c::I2c for Twim<'d, T> { 818impl<'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
817impl<'d, T: Instance> embedded_hal_async::i2c::I2c for Twim<'d, T> { 824impl<'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
823impl<'d, T: Instance> SetConfig for Twim<'d, T> { 830impl<'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(())