diff options
| author | Grant Miller <[email protected]> | 2021-12-06 22:45:40 -0600 |
|---|---|---|
| committer | Grant Miller <[email protected]> | 2021-12-07 00:03:52 -0600 |
| commit | bf1f80afa1bde29963fb41008bb44349b5f464d7 (patch) | |
| tree | 4a06ff9b186d02c6fd70a6ed70cd5730ee73921a | |
| parent | 3a17e3a2a523773d5e025d99139385616aaebc87 (diff) | |
Unify blocking trait impls
| -rw-r--r-- | embassy-stm32/src/spi/mod.rs | 112 | ||||
| -rw-r--r-- | embassy-stm32/src/spi/v1.rs | 103 | ||||
| -rw-r--r-- | embassy-stm32/src/spi/v2.rs | 110 | ||||
| -rw-r--r-- | embassy-stm32/src/spi/v3.rs | 182 |
4 files changed, 125 insertions, 382 deletions
diff --git a/embassy-stm32/src/spi/mod.rs b/embassy-stm32/src/spi/mod.rs index f39fc746d..d3d78e2a8 100644 --- a/embassy-stm32/src/spi/mod.rs +++ b/embassy-stm32/src/spi/mod.rs | |||
| @@ -1,6 +1,7 @@ | |||
| 1 | #![macro_use] | 1 | #![macro_use] |
| 2 | 2 | ||
| 3 | use crate::dma; | 3 | use crate::dma; |
| 4 | use crate::dma::NoDma; | ||
| 4 | use crate::gpio::sealed::{AFType, Pin}; | 5 | use crate::gpio::sealed::{AFType, Pin}; |
| 5 | use crate::gpio::{AnyPin, NoPin, OptionalPin}; | 6 | use crate::gpio::{AnyPin, NoPin, OptionalPin}; |
| 6 | use crate::pac::spi::{regs, vals}; | 7 | use crate::pac::spi::{regs, vals}; |
| @@ -9,6 +10,7 @@ use crate::rcc::RccPeripheral; | |||
| 9 | use crate::time::Hertz; | 10 | use crate::time::Hertz; |
| 10 | use core::future::Future; | 11 | use core::future::Future; |
| 11 | use core::marker::PhantomData; | 12 | use core::marker::PhantomData; |
| 13 | use core::ptr; | ||
| 12 | use embassy::util::Unborrow; | 14 | use embassy::util::Unborrow; |
| 13 | use embassy_hal_common::unborrow; | 15 | use embassy_hal_common::unborrow; |
| 14 | use embassy_traits::spi as traits; | 16 | use embassy_traits::spi as traits; |
| @@ -403,11 +405,121 @@ fn check_error_flags(sr: regs::Sr) -> Result<(), Error> { | |||
| 403 | Ok(()) | 405 | Ok(()) |
| 404 | } | 406 | } |
| 405 | 407 | ||
| 408 | fn spin_until_tx_ready(regs: &'static crate::pac::spi::Spi) -> Result<(), Error> { | ||
| 409 | loop { | ||
| 410 | let sr = unsafe { regs.sr().read() }; | ||
| 411 | |||
| 412 | check_error_flags(sr)?; | ||
| 413 | |||
| 414 | #[cfg(not(spi_v3))] | ||
| 415 | if sr.txe() { | ||
| 416 | return Ok(()); | ||
| 417 | } | ||
| 418 | #[cfg(spi_v3)] | ||
| 419 | if sr.txp() { | ||
| 420 | return Ok(()); | ||
| 421 | } | ||
| 422 | } | ||
| 423 | } | ||
| 424 | |||
| 425 | fn spin_until_rx_ready(regs: &'static crate::pac::spi::Spi) -> Result<(), Error> { | ||
| 426 | loop { | ||
| 427 | let sr = unsafe { regs.sr().read() }; | ||
| 428 | |||
| 429 | check_error_flags(sr)?; | ||
| 430 | |||
| 431 | #[cfg(not(spi_v3))] | ||
| 432 | if sr.rxne() { | ||
| 433 | return Ok(()); | ||
| 434 | } | ||
| 435 | #[cfg(spi_v3)] | ||
| 436 | if sr.rxp() { | ||
| 437 | return Ok(()); | ||
| 438 | } | ||
| 439 | } | ||
| 440 | } | ||
| 441 | |||
| 406 | trait Word {} | 442 | trait Word {} |
| 407 | 443 | ||
| 408 | impl Word for u8 {} | 444 | impl Word for u8 {} |
| 409 | impl Word for u16 {} | 445 | impl Word for u16 {} |
| 410 | 446 | ||
| 447 | fn transfer_word<W: Word>(regs: &'static crate::pac::spi::Spi, tx_word: W) -> Result<W, Error> { | ||
| 448 | spin_until_tx_ready(regs)?; | ||
| 449 | |||
| 450 | unsafe { | ||
| 451 | ptr::write_volatile(regs.tx_ptr(), tx_word); | ||
| 452 | |||
| 453 | #[cfg(spi_v3)] | ||
| 454 | regs.cr1().modify(|reg| reg.set_cstart(true)); | ||
| 455 | } | ||
| 456 | |||
| 457 | spin_until_rx_ready(regs)?; | ||
| 458 | |||
| 459 | let rx_word = unsafe { ptr::read_volatile(regs.rx_ptr()) }; | ||
| 460 | return Ok(rx_word); | ||
| 461 | } | ||
| 462 | |||
| 463 | impl<'d, T: Instance> embedded_hal::blocking::spi::Write<u8> for Spi<'d, T, NoDma, NoDma> { | ||
| 464 | type Error = Error; | ||
| 465 | |||
| 466 | fn write(&mut self, words: &[u8]) -> Result<(), Self::Error> { | ||
| 467 | self.set_word_size(WordSize::EightBit); | ||
| 468 | let regs = T::regs(); | ||
| 469 | |||
| 470 | for word in words.iter() { | ||
| 471 | let _ = transfer_word(regs, *word)?; | ||
| 472 | } | ||
| 473 | |||
| 474 | Ok(()) | ||
| 475 | } | ||
| 476 | } | ||
| 477 | |||
| 478 | impl<'d, T: Instance> embedded_hal::blocking::spi::Transfer<u8> for Spi<'d, T, NoDma, NoDma> { | ||
| 479 | type Error = Error; | ||
| 480 | |||
| 481 | fn transfer<'w>(&mut self, words: &'w mut [u8]) -> Result<&'w [u8], Self::Error> { | ||
| 482 | self.set_word_size(WordSize::EightBit); | ||
| 483 | let regs = T::regs(); | ||
| 484 | |||
| 485 | for word in words.iter_mut() { | ||
| 486 | *word = transfer_word(regs, *word)?; | ||
| 487 | } | ||
| 488 | |||
| 489 | Ok(words) | ||
| 490 | } | ||
| 491 | } | ||
| 492 | |||
| 493 | impl<'d, T: Instance> embedded_hal::blocking::spi::Write<u16> for Spi<'d, T, NoDma, NoDma> { | ||
| 494 | type Error = Error; | ||
| 495 | |||
| 496 | fn write(&mut self, words: &[u16]) -> Result<(), Self::Error> { | ||
| 497 | self.set_word_size(WordSize::SixteenBit); | ||
| 498 | let regs = T::regs(); | ||
| 499 | |||
| 500 | for word in words.iter() { | ||
| 501 | let _ = transfer_word(regs, *word)?; | ||
| 502 | } | ||
| 503 | |||
| 504 | Ok(()) | ||
| 505 | } | ||
| 506 | } | ||
| 507 | |||
| 508 | impl<'d, T: Instance> embedded_hal::blocking::spi::Transfer<u16> for Spi<'d, T, NoDma, NoDma> { | ||
| 509 | type Error = Error; | ||
| 510 | |||
| 511 | fn transfer<'w>(&mut self, words: &'w mut [u16]) -> Result<&'w [u16], Self::Error> { | ||
| 512 | self.set_word_size(WordSize::SixteenBit); | ||
| 513 | let regs = T::regs(); | ||
| 514 | |||
| 515 | for word in words.iter_mut() { | ||
| 516 | *word = transfer_word(regs, *word)?; | ||
| 517 | } | ||
| 518 | |||
| 519 | Ok(words) | ||
| 520 | } | ||
| 521 | } | ||
| 522 | |||
| 411 | impl<'d, T: Instance, Tx, Rx> traits::Spi<u8> for Spi<'d, T, Tx, Rx> { | 523 | impl<'d, T: Instance, Tx, Rx> traits::Spi<u8> for Spi<'d, T, Tx, Rx> { |
| 412 | type Error = Error; | 524 | type Error = Error; |
| 413 | } | 525 | } |
diff --git a/embassy-stm32/src/spi/v1.rs b/embassy-stm32/src/spi/v1.rs index efe7e468c..92449ea80 100644 --- a/embassy-stm32/src/spi/v1.rs +++ b/embassy-stm32/src/spi/v1.rs | |||
| @@ -1,15 +1,10 @@ | |||
| 1 | #![macro_use] | 1 | #![macro_use] |
| 2 | 2 | ||
| 3 | use crate::dma::NoDma; | ||
| 4 | use crate::spi::{ | ||
| 5 | check_error_flags, Error, Instance, RegsExt, RxDmaChannel, TxDmaChannel, WordSize, | ||
| 6 | }; | ||
| 7 | use core::ptr; | ||
| 8 | pub use embedded_hal::blocking; | 3 | pub use embedded_hal::blocking; |
| 9 | pub use embedded_hal::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; | 4 | pub use embedded_hal::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; |
| 10 | use futures::future::join3; | 5 | use futures::future::join3; |
| 11 | 6 | ||
| 12 | use super::Spi; | 7 | use super::*; |
| 13 | 8 | ||
| 14 | impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { | 9 | impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { |
| 15 | pub(super) async fn write_dma_u8(&mut self, write: &[u8]) -> Result<(), Error> | 10 | pub(super) async fn write_dma_u8(&mut self, write: &[u8]) -> Result<(), Error> |
| @@ -155,99 +150,3 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { | |||
| 155 | } | 150 | } |
| 156 | } | 151 | } |
| 157 | } | 152 | } |
| 158 | |||
| 159 | impl<'d, T: Instance> embedded_hal::blocking::spi::Write<u8> for Spi<'d, T, NoDma, NoDma> { | ||
| 160 | type Error = Error; | ||
| 161 | |||
| 162 | fn write(&mut self, words: &[u8]) -> Result<(), Self::Error> { | ||
| 163 | self.set_word_size(WordSize::EightBit); | ||
| 164 | let regs = T::regs(); | ||
| 165 | |||
| 166 | for word in words.iter() { | ||
| 167 | write_word(regs, *word)?; | ||
| 168 | let _: u8 = read_word(regs)?; | ||
| 169 | } | ||
| 170 | |||
| 171 | Ok(()) | ||
| 172 | } | ||
| 173 | } | ||
| 174 | |||
| 175 | impl<'d, T: Instance> embedded_hal::blocking::spi::Transfer<u8> for Spi<'d, T, NoDma, NoDma> { | ||
| 176 | type Error = Error; | ||
| 177 | |||
| 178 | fn transfer<'w>(&mut self, words: &'w mut [u8]) -> Result<&'w [u8], Self::Error> { | ||
| 179 | self.set_word_size(WordSize::EightBit); | ||
| 180 | let regs = T::regs(); | ||
| 181 | |||
| 182 | for word in words.iter_mut() { | ||
| 183 | write_word(regs, *word)?; | ||
| 184 | *word = read_word(regs)?; | ||
| 185 | } | ||
| 186 | |||
| 187 | Ok(words) | ||
| 188 | } | ||
| 189 | } | ||
| 190 | |||
| 191 | impl<'d, T: Instance> embedded_hal::blocking::spi::Write<u16> for Spi<'d, T, NoDma, NoDma> { | ||
| 192 | type Error = Error; | ||
| 193 | |||
| 194 | fn write(&mut self, words: &[u16]) -> Result<(), Self::Error> { | ||
| 195 | self.set_word_size(WordSize::SixteenBit); | ||
| 196 | let regs = T::regs(); | ||
| 197 | |||
| 198 | for word in words.iter() { | ||
| 199 | write_word(regs, *word)?; | ||
| 200 | let _: u8 = read_word(regs)?; | ||
| 201 | } | ||
| 202 | |||
| 203 | Ok(()) | ||
| 204 | } | ||
| 205 | } | ||
| 206 | |||
| 207 | impl<'d, T: Instance> embedded_hal::blocking::spi::Transfer<u16> for Spi<'d, T, NoDma, NoDma> { | ||
| 208 | type Error = Error; | ||
| 209 | |||
| 210 | fn transfer<'w>(&mut self, words: &'w mut [u16]) -> Result<&'w [u16], Self::Error> { | ||
| 211 | self.set_word_size(WordSize::SixteenBit); | ||
| 212 | let regs = T::regs(); | ||
| 213 | |||
| 214 | for word in words.iter_mut() { | ||
| 215 | write_word(regs, *word)?; | ||
| 216 | *word = read_word(regs)?; | ||
| 217 | } | ||
| 218 | |||
| 219 | Ok(words) | ||
| 220 | } | ||
| 221 | } | ||
| 222 | |||
| 223 | use super::Word; | ||
| 224 | |||
| 225 | fn write_word<W: Word>(regs: &'static crate::pac::spi::Spi, word: W) -> Result<(), Error> { | ||
| 226 | loop { | ||
| 227 | let sr = unsafe { regs.sr().read() }; | ||
| 228 | |||
| 229 | check_error_flags(sr)?; | ||
| 230 | |||
| 231 | if sr.txe() { | ||
| 232 | unsafe { | ||
| 233 | ptr::write_volatile(regs.tx_ptr(), word); | ||
| 234 | } | ||
| 235 | return Ok(()); | ||
| 236 | } | ||
| 237 | } | ||
| 238 | } | ||
| 239 | |||
| 240 | /// Read a single word blocking. Assumes word size have already been set. | ||
| 241 | fn read_word<W: Word>(regs: &'static crate::pac::spi::Spi) -> Result<W, Error> { | ||
| 242 | loop { | ||
| 243 | let sr = unsafe { regs.sr().read() }; | ||
| 244 | |||
| 245 | check_error_flags(sr)?; | ||
| 246 | |||
| 247 | if sr.rxne() { | ||
| 248 | unsafe { | ||
| 249 | return Ok(ptr::read_volatile(regs.rx_ptr())); | ||
| 250 | } | ||
| 251 | } | ||
| 252 | } | ||
| 253 | } | ||
diff --git a/embassy-stm32/src/spi/v2.rs b/embassy-stm32/src/spi/v2.rs index e905a1b9c..de78676c2 100644 --- a/embassy-stm32/src/spi/v2.rs +++ b/embassy-stm32/src/spi/v2.rs | |||
| @@ -1,14 +1,9 @@ | |||
| 1 | #![macro_use] | 1 | #![macro_use] |
| 2 | 2 | ||
| 3 | use crate::dma::NoDma; | ||
| 4 | use crate::spi::{ | ||
| 5 | check_error_flags, Error, Instance, RegsExt, RxDmaChannel, TxDmaChannel, WordSize, | ||
| 6 | }; | ||
| 7 | use core::ptr; | ||
| 8 | pub use embedded_hal::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; | 3 | pub use embedded_hal::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; |
| 9 | use futures::future::{join, join3}; | 4 | use futures::future::{join, join3}; |
| 10 | 5 | ||
| 11 | use super::Spi; | 6 | use super::*; |
| 12 | 7 | ||
| 13 | impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { | 8 | impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { |
| 14 | pub(super) async fn write_dma_u8(&mut self, write: &[u8]) -> Result<(), Error> | 9 | pub(super) async fn write_dma_u8(&mut self, write: &[u8]) -> Result<(), Error> |
| @@ -100,7 +95,11 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { | |||
| 100 | Ok(()) | 95 | Ok(()) |
| 101 | } | 96 | } |
| 102 | 97 | ||
| 103 | pub(super) async fn read_write_dma_u8(&mut self, read: &mut [u8], write: &[u8]) -> Result<(), Error> | 98 | pub(super) async fn read_write_dma_u8( |
| 99 | &mut self, | ||
| 100 | read: &mut [u8], | ||
| 101 | write: &[u8], | ||
| 102 | ) -> Result<(), Error> | ||
| 104 | where | 103 | where |
| 105 | Tx: TxDmaChannel<T>, | 104 | Tx: TxDmaChannel<T>, |
| 106 | Rx: RxDmaChannel<T>, | 105 | Rx: RxDmaChannel<T>, |
| @@ -170,100 +169,3 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { | |||
| 170 | } | 169 | } |
| 171 | } | 170 | } |
| 172 | } | 171 | } |
| 173 | |||
| 174 | use super::Word; | ||
| 175 | |||
| 176 | /// Write a single word blocking. Assumes word size have already been set. | ||
| 177 | fn write_word<W: Word>(regs: &'static crate::pac::spi::Spi, word: W) -> Result<(), Error> { | ||
| 178 | loop { | ||
| 179 | let sr = unsafe { regs.sr().read() }; | ||
| 180 | |||
| 181 | check_error_flags(sr)?; | ||
| 182 | |||
| 183 | if sr.txe() { | ||
| 184 | unsafe { | ||
| 185 | ptr::write_volatile(regs.tx_ptr(), word); | ||
| 186 | } | ||
| 187 | return Ok(()); | ||
| 188 | } | ||
| 189 | } | ||
| 190 | } | ||
| 191 | |||
| 192 | /// Read a single word blocking. Assumes word size have already been set. | ||
| 193 | fn read_word<W: Word>(regs: &'static crate::pac::spi::Spi) -> Result<W, Error> { | ||
| 194 | loop { | ||
| 195 | let sr = unsafe { regs.sr().read() }; | ||
| 196 | |||
| 197 | check_error_flags(sr)?; | ||
| 198 | |||
| 199 | if sr.rxne() { | ||
| 200 | unsafe { | ||
| 201 | return Ok(ptr::read_volatile(regs.rx_ptr())); | ||
| 202 | } | ||
| 203 | } | ||
| 204 | } | ||
| 205 | } | ||
| 206 | |||
| 207 | impl<'d, T: Instance, Rx> embedded_hal::blocking::spi::Write<u8> for Spi<'d, T, NoDma, Rx> { | ||
| 208 | type Error = Error; | ||
| 209 | |||
| 210 | fn write(&mut self, words: &[u8]) -> Result<(), Self::Error> { | ||
| 211 | self.set_word_size(WordSize::EightBit); | ||
| 212 | let regs = T::regs(); | ||
| 213 | |||
| 214 | for word in words.iter() { | ||
| 215 | write_word(regs, *word)?; | ||
| 216 | let _: u8 = read_word(regs)?; | ||
| 217 | } | ||
| 218 | |||
| 219 | Ok(()) | ||
| 220 | } | ||
| 221 | } | ||
| 222 | |||
| 223 | impl<'d, T: Instance> embedded_hal::blocking::spi::Transfer<u8> for Spi<'d, T, NoDma, NoDma> { | ||
| 224 | type Error = Error; | ||
| 225 | |||
| 226 | fn transfer<'w>(&mut self, words: &'w mut [u8]) -> Result<&'w [u8], Self::Error> { | ||
| 227 | self.set_word_size(WordSize::EightBit); | ||
| 228 | let regs = T::regs(); | ||
| 229 | |||
| 230 | for word in words.iter_mut() { | ||
| 231 | write_word(regs, *word)?; | ||
| 232 | *word = read_word(regs)?; | ||
| 233 | } | ||
| 234 | |||
| 235 | Ok(words) | ||
| 236 | } | ||
| 237 | } | ||
| 238 | |||
| 239 | impl<'d, T: Instance, Rx> embedded_hal::blocking::spi::Write<u16> for Spi<'d, T, NoDma, Rx> { | ||
| 240 | type Error = Error; | ||
| 241 | |||
| 242 | fn write(&mut self, words: &[u16]) -> Result<(), Self::Error> { | ||
| 243 | self.set_word_size(WordSize::SixteenBit); | ||
| 244 | let regs = T::regs(); | ||
| 245 | |||
| 246 | for word in words.iter() { | ||
| 247 | write_word(regs, *word)?; | ||
| 248 | let _: u16 = read_word(regs)?; | ||
| 249 | } | ||
| 250 | |||
| 251 | Ok(()) | ||
| 252 | } | ||
| 253 | } | ||
| 254 | |||
| 255 | impl<'d, T: Instance> embedded_hal::blocking::spi::Transfer<u16> for Spi<'d, T, NoDma, NoDma> { | ||
| 256 | type Error = Error; | ||
| 257 | |||
| 258 | fn transfer<'w>(&mut self, words: &'w mut [u16]) -> Result<&'w [u16], Self::Error> { | ||
| 259 | self.set_word_size(WordSize::SixteenBit); | ||
| 260 | let regs = T::regs(); | ||
| 261 | |||
| 262 | for word in words.iter_mut() { | ||
| 263 | write_word(regs, *word)?; | ||
| 264 | *word = read_word(regs)?; | ||
| 265 | } | ||
| 266 | |||
| 267 | Ok(words) | ||
| 268 | } | ||
| 269 | } | ||
diff --git a/embassy-stm32/src/spi/v3.rs b/embassy-stm32/src/spi/v3.rs index cbe2861e0..ef0f23063 100644 --- a/embassy-stm32/src/spi/v3.rs +++ b/embassy-stm32/src/spi/v3.rs | |||
| @@ -1,15 +1,9 @@ | |||
| 1 | #![macro_use] | 1 | #![macro_use] |
| 2 | 2 | ||
| 3 | use crate::dma::NoDma; | ||
| 4 | use crate::spi::{ | ||
| 5 | check_error_flags, Error, Instance, RegsExt, RxDmaChannel, TxDmaChannel, WordSize, | ||
| 6 | }; | ||
| 7 | use core::ptr; | ||
| 8 | pub use embedded_hal::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; | 3 | pub use embedded_hal::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; |
| 9 | |||
| 10 | use futures::future::join3; | 4 | use futures::future::join3; |
| 11 | 5 | ||
| 12 | use super::Spi; | 6 | use super::*; |
| 13 | 7 | ||
| 14 | impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { | 8 | impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { |
| 15 | pub(super) async fn write_dma_u8(&mut self, write: &[u8]) -> Result<(), Error> | 9 | pub(super) async fn write_dma_u8(&mut self, write: &[u8]) -> Result<(), Error> |
| @@ -105,7 +99,11 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { | |||
| 105 | Ok(()) | 99 | Ok(()) |
| 106 | } | 100 | } |
| 107 | 101 | ||
| 108 | pub(super) async fn read_write_dma_u8(&mut self, read: &mut [u8], write: &[u8]) -> Result<(), Error> | 102 | pub(super) async fn read_write_dma_u8( |
| 103 | &mut self, | ||
| 104 | read: &mut [u8], | ||
| 105 | write: &[u8], | ||
| 106 | ) -> Result<(), Error> | ||
| 109 | where | 107 | where |
| 110 | Tx: TxDmaChannel<T>, | 108 | Tx: TxDmaChannel<T>, |
| 111 | Rx: RxDmaChannel<T>, | 109 | Rx: RxDmaChannel<T>, |
| @@ -173,171 +171,3 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { | |||
| 173 | } | 171 | } |
| 174 | } | 172 | } |
| 175 | } | 173 | } |
| 176 | |||
| 177 | impl<'d, T: Instance> embedded_hal::blocking::spi::Write<u8> for Spi<'d, T, NoDma, NoDma> { | ||
| 178 | type Error = Error; | ||
| 179 | |||
| 180 | fn write(&mut self, words: &[u8]) -> Result<(), Self::Error> { | ||
| 181 | self.set_word_size(WordSize::EightBit); | ||
| 182 | let regs = T::regs(); | ||
| 183 | |||
| 184 | for word in words.iter() { | ||
| 185 | while unsafe { !regs.sr().read().txp() } { | ||
| 186 | // spin | ||
| 187 | } | ||
| 188 | unsafe { | ||
| 189 | ptr::write_volatile(regs.tx_ptr(), *word); | ||
| 190 | regs.cr1().modify(|reg| reg.set_cstart(true)); | ||
| 191 | } | ||
| 192 | loop { | ||
| 193 | let sr = unsafe { regs.sr().read() }; | ||
| 194 | if sr.tifre() { | ||
| 195 | return Err(Error::Framing); | ||
| 196 | } | ||
| 197 | if sr.ovr() { | ||
| 198 | return Err(Error::Overrun); | ||
| 199 | } | ||
| 200 | if sr.crce() { | ||
| 201 | return Err(Error::Crc); | ||
| 202 | } | ||
| 203 | if !sr.txp() { | ||
| 204 | // loop waiting for TXE | ||
| 205 | continue; | ||
| 206 | } | ||
| 207 | break; | ||
| 208 | } | ||
| 209 | unsafe { | ||
| 210 | // discard read to prevent pverrun. | ||
| 211 | let _: u8 = ptr::read_volatile(T::regs().rx_ptr()); | ||
| 212 | } | ||
| 213 | } | ||
| 214 | |||
| 215 | while unsafe { !regs.sr().read().txc() } { | ||
| 216 | // spin | ||
| 217 | } | ||
| 218 | |||
| 219 | Ok(()) | ||
| 220 | } | ||
| 221 | } | ||
| 222 | |||
| 223 | impl<'d, T: Instance> embedded_hal::blocking::spi::Transfer<u8> for Spi<'d, T, NoDma, NoDma> { | ||
| 224 | type Error = Error; | ||
| 225 | |||
| 226 | fn transfer<'w>(&mut self, words: &'w mut [u8]) -> Result<&'w [u8], Self::Error> { | ||
| 227 | self.set_word_size(WordSize::EightBit); | ||
| 228 | let regs = T::regs(); | ||
| 229 | |||
| 230 | for word in words.iter_mut() { | ||
| 231 | unsafe { | ||
| 232 | regs.cr1().modify(|reg| { | ||
| 233 | reg.set_ssi(false); | ||
| 234 | }); | ||
| 235 | } | ||
| 236 | while unsafe { !regs.sr().read().txp() } { | ||
| 237 | // spin | ||
| 238 | } | ||
| 239 | unsafe { | ||
| 240 | ptr::write_volatile(T::regs().tx_ptr(), *word); | ||
| 241 | regs.cr1().modify(|reg| reg.set_cstart(true)); | ||
| 242 | } | ||
| 243 | loop { | ||
| 244 | let sr = unsafe { regs.sr().read() }; | ||
| 245 | |||
| 246 | if sr.rxp() { | ||
| 247 | break; | ||
| 248 | } | ||
| 249 | |||
| 250 | check_error_flags(sr)?; | ||
| 251 | } | ||
| 252 | unsafe { | ||
| 253 | *word = ptr::read_volatile(T::regs().rx_ptr()); | ||
| 254 | } | ||
| 255 | let sr = unsafe { regs.sr().read() }; | ||
| 256 | check_error_flags(sr)?; | ||
| 257 | } | ||
| 258 | |||
| 259 | Ok(words) | ||
| 260 | } | ||
| 261 | } | ||
| 262 | |||
| 263 | impl<'d, T: Instance> embedded_hal::blocking::spi::Write<u16> for Spi<'d, T, NoDma, NoDma> { | ||
| 264 | type Error = Error; | ||
| 265 | |||
| 266 | fn write(&mut self, words: &[u16]) -> Result<(), Self::Error> { | ||
| 267 | self.set_word_size(WordSize::SixteenBit); | ||
| 268 | let regs = T::regs(); | ||
| 269 | |||
| 270 | for word in words.iter() { | ||
| 271 | while unsafe { !regs.sr().read().txp() } { | ||
| 272 | // spin | ||
| 273 | } | ||
| 274 | unsafe { | ||
| 275 | let txdr = regs.txdr().ptr() as *mut u16; | ||
| 276 | ptr::write_volatile(txdr, *word); | ||
| 277 | regs.cr1().modify(|reg| reg.set_cstart(true)); | ||
| 278 | } | ||
| 279 | loop { | ||
| 280 | let sr = unsafe { regs.sr().read() }; | ||
| 281 | |||
| 282 | check_error_flags(sr)?; | ||
| 283 | |||
| 284 | if !sr.txp() { | ||
| 285 | // loop waiting for TXE | ||
| 286 | continue; | ||
| 287 | } | ||
| 288 | break; | ||
| 289 | } | ||
| 290 | |||
| 291 | unsafe { | ||
| 292 | let rxdr = regs.rxdr().ptr() as *const u8; | ||
| 293 | // discard read to prevent pverrun. | ||
| 294 | let _ = ptr::read_volatile(rxdr); | ||
| 295 | } | ||
| 296 | } | ||
| 297 | |||
| 298 | while unsafe { !regs.sr().read().txc() } { | ||
| 299 | // spin | ||
| 300 | } | ||
| 301 | |||
| 302 | Ok(()) | ||
| 303 | } | ||
| 304 | } | ||
| 305 | |||
| 306 | impl<'d, T: Instance> embedded_hal::blocking::spi::Transfer<u16> for Spi<'d, T, NoDma, NoDma> { | ||
| 307 | type Error = Error; | ||
| 308 | |||
| 309 | fn transfer<'w>(&mut self, words: &'w mut [u16]) -> Result<&'w [u16], Self::Error> { | ||
| 310 | self.set_word_size(WordSize::SixteenBit); | ||
| 311 | let regs = T::regs(); | ||
| 312 | |||
| 313 | for word in words.iter_mut() { | ||
| 314 | while unsafe { !regs.sr().read().txp() } { | ||
| 315 | // spin | ||
| 316 | } | ||
| 317 | unsafe { | ||
| 318 | let txdr = regs.txdr().ptr() as *mut u16; | ||
| 319 | ptr::write_volatile(txdr, *word); | ||
| 320 | regs.cr1().modify(|reg| reg.set_cstart(true)); | ||
| 321 | } | ||
| 322 | |||
| 323 | loop { | ||
| 324 | let sr = unsafe { regs.sr().read() }; | ||
| 325 | |||
| 326 | if sr.rxp() { | ||
| 327 | break; | ||
| 328 | } | ||
| 329 | |||
| 330 | check_error_flags(sr)?; | ||
| 331 | } | ||
| 332 | |||
| 333 | unsafe { | ||
| 334 | let rxdr = regs.rxdr().ptr() as *const u16; | ||
| 335 | *word = ptr::read_volatile(rxdr); | ||
| 336 | } | ||
| 337 | let sr = unsafe { regs.sr().read() }; | ||
| 338 | check_error_flags(sr)?; | ||
| 339 | } | ||
| 340 | |||
| 341 | Ok(words) | ||
| 342 | } | ||
| 343 | } | ||
