From 98daa7a25df2e20faa8c676b1d2a97460d2713a6 Mon Sep 17 00:00:00 2001 From: Paul Paterson Date: Fri, 28 Oct 2022 13:21:55 -0400 Subject: [PATCH] implement embedded-hal aplha SPI traits --- rp2040-hal/src/spi.rs | 86 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 85 insertions(+), 1 deletion(-) diff --git a/rp2040-hal/src/spi.rs b/rp2040-hal/src/spi.rs index 1edd01b..233fb0b 100644 --- a/rp2040-hal/src/spi.rs +++ b/rp2040-hal/src/spi.rs @@ -230,7 +230,91 @@ macro_rules! impl_write { type Error = Infallible; } -/* disabled for now - nb was migrated to separate crate + #[cfg(feature = "eh1_0_alpha")] + impl eh1::SpiBusFlush for Spi { + fn flush(&mut self) -> Result<(), Self::Error> { + while self.is_busy() {} + Ok(()) + } + } + + #[cfg(feature = "eh1_0_alpha")] + impl eh1::SpiBusRead<$type> for Spi { + fn read(&mut self, words: &mut [$type]) -> Result<(), Self::Error> { + for word in words.iter_mut() { + // write empty word + while !self.is_writable() {} + self.device + .sspdr + .write(|w| unsafe { w.data().bits(0) }); + + // read one word + while !self.is_readable() {} + *word = self.device.sspdr.read().data().bits() as $type; + } + Ok(()) + } + } + + #[cfg(feature = "eh1_0_alpha")] + impl eh1::SpiBusWrite<$type> for Spi { + fn write(&mut self, words: &[$type]) -> Result<(), Self::Error> { + for word in words.iter() { + // write one word + while !self.is_writable() {} + self.device + .sspdr + .write(|w| unsafe { w.data().bits(*word as u16) }); + + // drop read wordd + while !self.is_readable() {} + let _ = self.device.sspdr.read().data().bits(); + } + Ok(()) + } + } + + #[cfg(feature = "eh1_0_alpha")] + impl eh1::SpiBus<$type> for Spi { + fn transfer(&mut self, read: &mut [$type], write: &[$type]) -> Result<(), Self::Error>{ + let len = read.len().max(write.len()); + for i in 0..len { + // write one word. Send empty word if buffer is empty. + let wb = write.get(i).copied().unwrap_or(0); + while !self.is_writable() {} + self.device + .sspdr + .write(|w| unsafe { w.data().bits(wb as u16) }); + + // read one word. Drop extra words if buffer is full. + while !self.is_readable() {} + let rb = self.device.sspdr.read().data().bits() as $type; + if let Some(r) = read.get_mut(i) { + *r = rb; + } + } + + Ok(()) + } + + fn transfer_in_place(&mut self, words: &mut [$type]) -> Result<(), Self::Error>{ + for word in words.iter_mut() { + // write one word + while !self.is_writable() {} + self.device + .sspdr + .write(|w| unsafe { w.data().bits(*word as u16) }); + + // read one word + while !self.is_readable() {} + *word = self.device.sspdr.read().data().bits() as $type; + } + + Ok(()) + } + } + + /* disabled for now - nb was migrated to separate crate #[cfg(feature = "eh1_0_alpha")] impl eh1::nb::FullDuplex<$type> for Spi { fn read(&mut self) -> Result<$type, nb::Error> {