aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-stm32/src/spi/mod.rs29
-rw-r--r--embassy-stm32/src/spi/v1.rs36
-rw-r--r--embassy-stm32/src/spi/v2.rs28
-rw-r--r--embassy-stm32/src/spi/v3.rs56
4 files changed, 56 insertions, 93 deletions
diff --git a/embassy-stm32/src/spi/mod.rs b/embassy-stm32/src/spi/mod.rs
index be4061e0f..76857ae64 100644
--- a/embassy-stm32/src/spi/mod.rs
+++ b/embassy-stm32/src/spi/mod.rs
@@ -3,7 +3,7 @@
3use crate::dma; 3use crate::dma;
4use crate::gpio::sealed::{AFType, Pin}; 4use crate::gpio::sealed::{AFType, Pin};
5use crate::gpio::{AnyPin, NoPin, OptionalPin}; 5use crate::gpio::{AnyPin, NoPin, OptionalPin};
6use crate::pac::spi::vals; 6use crate::pac::spi::{regs, vals};
7use crate::peripherals; 7use crate::peripherals;
8use crate::rcc::RccPeripheral; 8use crate::rcc::RccPeripheral;
9use crate::time::Hertz; 9use crate::time::Hertz;
@@ -374,6 +374,33 @@ impl RegsExt for crate::pac::spi::Spi {
374 } 374 }
375} 375}
376 376
377fn check_error_flags(sr: regs::Sr) -> Result<(), Error> {
378 if sr.ovr() {
379 return Err(Error::Overrun);
380 }
381 #[cfg(not(any(spi_f1, spi_v3)))]
382 if sr.fre() {
383 return Err(Error::Framing);
384 }
385 #[cfg(spi_v3)]
386 if sr.tifre() {
387 return Err(Error::Framing);
388 }
389 if sr.modf() {
390 return Err(Error::ModeFault);
391 }
392 #[cfg(not(spi_v3))]
393 if sr.crcerr() {
394 return Err(Error::Crc);
395 }
396 #[cfg(spi_v3)]
397 if sr.crce() {
398 return Err(Error::Crc);
399 }
400
401 Ok(())
402}
403
377trait Word {} 404trait Word {}
378 405
379impl Word for u8 {} 406impl Word for u8 {}
diff --git a/embassy-stm32/src/spi/v1.rs b/embassy-stm32/src/spi/v1.rs
index c1a9cdbfd..3a7d948ae 100644
--- a/embassy-stm32/src/spi/v1.rs
+++ b/embassy-stm32/src/spi/v1.rs
@@ -1,7 +1,9 @@
1#![macro_use] 1#![macro_use]
2 2
3use crate::dma::NoDma; 3use crate::dma::NoDma;
4use crate::spi::{Error, Instance, RegsExt, RxDmaChannel, TxDmaChannel, WordSize}; 4use crate::spi::{
5 check_error_flags, Error, Instance, RegsExt, RxDmaChannel, TxDmaChannel, WordSize,
6};
5use core::future::Future; 7use core::future::Future;
6use core::ptr; 8use core::ptr;
7use embassy_traits::spi as traits; 9use embassy_traits::spi as traits;
@@ -263,19 +265,9 @@ use super::Word;
263fn write_word<W: Word>(regs: &'static crate::pac::spi::Spi, word: W) -> Result<(), Error> { 265fn write_word<W: Word>(regs: &'static crate::pac::spi::Spi, word: W) -> Result<(), Error> {
264 loop { 266 loop {
265 let sr = unsafe { regs.sr().read() }; 267 let sr = unsafe { regs.sr().read() };
266 if sr.ovr() { 268
267 return Err(Error::Overrun); 269 check_error_flags(sr)?;
268 } 270
269 #[cfg(not(spi_f1))]
270 if sr.fre() {
271 return Err(Error::Framing);
272 }
273 if sr.modf() {
274 return Err(Error::ModeFault);
275 }
276 if sr.crcerr() {
277 return Err(Error::Crc);
278 }
279 if sr.txe() { 271 if sr.txe() {
280 unsafe { 272 unsafe {
281 ptr::write_volatile(regs.tx_ptr(), word); 273 ptr::write_volatile(regs.tx_ptr(), word);
@@ -289,19 +281,9 @@ fn write_word<W: Word>(regs: &'static crate::pac::spi::Spi, word: W) -> Result<(
289fn read_word<W: Word>(regs: &'static crate::pac::spi::Spi) -> Result<W, Error> { 281fn read_word<W: Word>(regs: &'static crate::pac::spi::Spi) -> Result<W, Error> {
290 loop { 282 loop {
291 let sr = unsafe { regs.sr().read() }; 283 let sr = unsafe { regs.sr().read() };
292 if sr.ovr() { 284
293 return Err(Error::Overrun); 285 check_error_flags(sr)?;
294 } 286
295 #[cfg(not(spi_f1))]
296 if sr.fre() {
297 return Err(Error::Framing);
298 }
299 if sr.modf() {
300 return Err(Error::ModeFault);
301 }
302 if sr.crcerr() {
303 return Err(Error::Crc);
304 }
305 if sr.rxne() { 287 if sr.rxne() {
306 unsafe { 288 unsafe {
307 return Ok(ptr::read_volatile(regs.rx_ptr())); 289 return Ok(ptr::read_volatile(regs.rx_ptr()));
diff --git a/embassy-stm32/src/spi/v2.rs b/embassy-stm32/src/spi/v2.rs
index 1ca90619d..2f02dc867 100644
--- a/embassy-stm32/src/spi/v2.rs
+++ b/embassy-stm32/src/spi/v2.rs
@@ -1,7 +1,7 @@
1#![macro_use] 1#![macro_use]
2 2
3use crate::dma::NoDma; 3use crate::dma::NoDma;
4use crate::spi::{Error, Instance, RegsExt, RxDmaChannel, TxDmaChannel, WordSize}; 4use crate::spi::{Error, Instance, RegsExt, RxDmaChannel, TxDmaChannel, WordSize, check_error_flags};
5use core::future::Future; 5use core::future::Future;
6use core::ptr; 6use core::ptr;
7use embassy_traits::spi as traits; 7use embassy_traits::spi as traits;
@@ -180,15 +180,10 @@ use super::Word;
180fn write_word<W: Word>(regs: &'static crate::pac::spi::Spi, word: W) -> Result<(), Error> { 180fn write_word<W: Word>(regs: &'static crate::pac::spi::Spi, word: W) -> Result<(), Error> {
181 loop { 181 loop {
182 let sr = unsafe { regs.sr().read() }; 182 let sr = unsafe { regs.sr().read() };
183 if sr.ovr() { 183
184 return Err(Error::Overrun); 184 check_error_flags(sr)?;
185 } else if sr.fre() { 185
186 return Err(Error::Framing); 186 if sr.txe() {
187 } else if sr.modf() {
188 return Err(Error::ModeFault);
189 } else if sr.crcerr() {
190 return Err(Error::Crc);
191 } else if sr.txe() {
192 unsafe { 187 unsafe {
193 ptr::write_volatile(regs.tx_ptr(), word); 188 ptr::write_volatile(regs.tx_ptr(), word);
194 } 189 }
@@ -201,15 +196,10 @@ fn write_word<W: Word>(regs: &'static crate::pac::spi::Spi, word: W) -> Result<(
201fn read_word<W: Word>(regs: &'static crate::pac::spi::Spi) -> Result<W, Error> { 196fn read_word<W: Word>(regs: &'static crate::pac::spi::Spi) -> Result<W, Error> {
202 loop { 197 loop {
203 let sr = unsafe { regs.sr().read() }; 198 let sr = unsafe { regs.sr().read() };
204 if sr.ovr() { 199
205 return Err(Error::Overrun); 200 check_error_flags(sr)?;
206 } else if sr.modf() { 201
207 return Err(Error::ModeFault); 202 if sr.rxne() {
208 } else if sr.fre() {
209 return Err(Error::Framing);
210 } else if sr.crcerr() {
211 return Err(Error::Crc);
212 } else if sr.rxne() {
213 unsafe { 203 unsafe {
214 return Ok(ptr::read_volatile(regs.rx_ptr())); 204 return Ok(ptr::read_volatile(regs.rx_ptr()));
215 } 205 }
diff --git a/embassy-stm32/src/spi/v3.rs b/embassy-stm32/src/spi/v3.rs
index 052924db0..e63dbcb29 100644
--- a/embassy-stm32/src/spi/v3.rs
+++ b/embassy-stm32/src/spi/v3.rs
@@ -1,7 +1,7 @@
1#![macro_use] 1#![macro_use]
2 2
3use crate::dma::NoDma; 3use crate::dma::NoDma;
4use crate::spi::{Error, Instance, RegsExt, RxDmaChannel, TxDmaChannel, WordSize}; 4use crate::spi::{Error, Instance, RegsExt, RxDmaChannel, TxDmaChannel, WordSize, check_error_flags};
5use core::future::Future; 5use core::future::Future;
6use core::ptr; 6use core::ptr;
7use embassy_traits::spi as traits; 7use embassy_traits::spi as traits;
@@ -249,29 +249,14 @@ impl<'d, T: Instance> embedded_hal::blocking::spi::Transfer<u8> for Spi<'d, T, N
249 if sr.rxp() { 249 if sr.rxp() {
250 break; 250 break;
251 } 251 }
252 if sr.tifre() { 252
253 return Err(Error::Framing); 253 check_error_flags(sr)?;
254 }
255 if sr.ovr() {
256 return Err(Error::Overrun);
257 }
258 if sr.crce() {
259 return Err(Error::Crc);
260 }
261 } 254 }
262 unsafe { 255 unsafe {
263 *word = ptr::read_volatile(T::regs().rx_ptr()); 256 *word = ptr::read_volatile(T::regs().rx_ptr());
264 } 257 }
265 let sr = unsafe { regs.sr().read() }; 258 let sr = unsafe { regs.sr().read() };
266 if sr.tifre() { 259 check_error_flags(sr)?;
267 return Err(Error::Framing);
268 }
269 if sr.ovr() {
270 return Err(Error::Overrun);
271 }
272 if sr.crce() {
273 return Err(Error::Crc);
274 }
275 } 260 }
276 261
277 Ok(words) 262 Ok(words)
@@ -296,15 +281,9 @@ impl<'d, T: Instance> embedded_hal::blocking::spi::Write<u16> for Spi<'d, T, NoD
296 } 281 }
297 loop { 282 loop {
298 let sr = unsafe { regs.sr().read() }; 283 let sr = unsafe { regs.sr().read() };
299 if sr.tifre() { 284
300 return Err(Error::Framing); 285 check_error_flags(sr)?;
301 } 286
302 if sr.ovr() {
303 return Err(Error::Overrun);
304 }
305 if sr.crce() {
306 return Err(Error::Crc);
307 }
308 if !sr.txp() { 287 if !sr.txp() {
309 // loop waiting for TXE 288 // loop waiting for TXE
310 continue; 289 continue;
@@ -350,15 +329,8 @@ impl<'d, T: Instance> embedded_hal::blocking::spi::Transfer<u16> for Spi<'d, T,
350 if sr.rxp() { 329 if sr.rxp() {
351 break; 330 break;
352 } 331 }
353 if sr.tifre() { 332
354 return Err(Error::Framing); 333 check_error_flags(sr)?;
355 }
356 if sr.ovr() {
357 return Err(Error::Overrun);
358 }
359 if sr.crce() {
360 return Err(Error::Crc);
361 }
362 } 334 }
363 335
364 unsafe { 336 unsafe {
@@ -366,15 +338,7 @@ impl<'d, T: Instance> embedded_hal::blocking::spi::Transfer<u16> for Spi<'d, T,
366 *word = ptr::read_volatile(rxdr); 338 *word = ptr::read_volatile(rxdr);
367 } 339 }
368 let sr = unsafe { regs.sr().read() }; 340 let sr = unsafe { regs.sr().read() };
369 if sr.tifre() { 341 check_error_flags(sr)?;
370 return Err(Error::Framing);
371 }
372 if sr.ovr() {
373 return Err(Error::Overrun);
374 }
375 if sr.crce() {
376 return Err(Error::Crc);
377 }
378 } 342 }
379 343
380 Ok(words) 344 Ok(words)