|
75 | 75 | //! |
76 | 76 | //! # Limitations |
77 | 77 | //! |
78 | | -//! ## embedded-hal 0.2 Transaction API |
79 | | -//! |
80 | | -//! Due to [a hardware defect][1], this driver does not yet support the EH02 SPI transaction API. |
81 | | -//! An early iteration of this driver reproduced the issue discussed in that forum. This driver may |
82 | | -//! be able to work around the defect in software, but it hasn't been explored. |
83 | | -//! |
84 | | -//! [1]: https://community.nxp.com/t5/i-MX-RT/RT1050-LPSPI-last-bit-not-completing-in-continuous-mode/m-p/898460 |
85 | | -//! |
86 | | -//! [`Transaction`] exposes the continuous / continuing flags, so you're free to model advanced |
87 | | -//! transactions. However, keep in mind that disabling the receiver during a continuous transaction |
88 | | -//! may not work as expected. |
89 | | -//! |
90 | | -//! ## embedded-hal 1.0 `SpiDevice` |
91 | | -//! |
92 | 78 | //! The current implementation of the EH1 `SpiDevice` trait does not support the `DelayNs` |
93 | 79 | //! operation. Implementing this was impossible while keeping backwards compatibility. |
94 | 80 | //! This may change in a future release. |
95 | 81 | //! |
96 | 82 | //! If you need support for the `DelayNs` operation you can use one of the devices from |
97 | | -//! [`embedded_hal_bus::spi`][2]. |
| 83 | +//! [`embedded_hal_bus::spi`][1]. |
98 | 84 | //! |
99 | | -//! [2]: https://docs.rs/embedded-hal-bus/latest/embedded_hal_bus/spi/index.html |
| 85 | +//! [1]: https://docs.rs/embedded-hal-bus/latest/embedded_hal_bus/spi/index.html |
100 | 86 |
|
101 | 87 | use core::marker::PhantomData; |
102 | 88 | use core::task::Poll; |
@@ -1447,6 +1433,56 @@ where |
1447 | 1433 | } |
1448 | 1434 | } |
1449 | 1435 |
|
| 1436 | +impl<P, const N: u8, W> eh02::blocking::spi::Transactional<W> for Lpspi<P, N> |
| 1437 | +where |
| 1438 | + P: HasChipSelect, |
| 1439 | + W: Word + 'static, |
| 1440 | +{ |
| 1441 | + type Error = LpspiError; |
| 1442 | + |
| 1443 | + fn exec( |
| 1444 | + &mut self, |
| 1445 | + operations: &mut [eh02::blocking::spi::Operation<'_, W>], |
| 1446 | + ) -> Result<(), Self::Error> { |
| 1447 | + use eh02::blocking::spi::Operation; |
| 1448 | + |
| 1449 | + let operations_len = operations.len(); |
| 1450 | + |
| 1451 | + if operations_len == 0 { |
| 1452 | + return Ok(()); |
| 1453 | + } |
| 1454 | + |
| 1455 | + crate::spin_on(async { |
| 1456 | + let mut continuing = false; |
| 1457 | + |
| 1458 | + for (i, op) in operations.iter_mut().enumerate() { |
| 1459 | + // For the last transaction `continuous` needs to be set to false. |
| 1460 | + // Otherwise the hardware fails to correctly de-assert CS. |
| 1461 | + let continuous = i + 1 != operations_len; |
| 1462 | + match op { |
| 1463 | + Operation::Write(data) => { |
| 1464 | + self.spin_write_no_read(continuous, continuing, data) |
| 1465 | + .await? |
| 1466 | + } |
| 1467 | + Operation::Transfer(data) => { |
| 1468 | + self.spin_transfer_in_place(continuous, continuing, data) |
| 1469 | + .await?; |
| 1470 | + } |
| 1471 | + } |
| 1472 | + |
| 1473 | + continuing = true; |
| 1474 | + } |
| 1475 | + |
| 1476 | + Ok(()) |
| 1477 | + }) |
| 1478 | + .map_err(|err| { |
| 1479 | + self.recover_from_error(); |
| 1480 | + err |
| 1481 | + })?; |
| 1482 | + |
| 1483 | + self.flush() |
| 1484 | + } |
| 1485 | +} |
1450 | 1486 |
|
1451 | 1487 | impl eh1::spi::Error for LpspiError { |
1452 | 1488 | fn kind(&self) -> eh1::spi::ErrorKind { |
|
0 commit comments