Skip to content

Commit 418c95f

Browse files
committed
Implement eh02 spi::Transactional for LPSPI
1 parent 171de66 commit 418c95f

File tree

1 file changed

+52
-16
lines changed

1 file changed

+52
-16
lines changed

src/common/lpspi.rs

Lines changed: 52 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -75,28 +75,14 @@
7575
//!
7676
//! # Limitations
7777
//!
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-
//!
9278
//! The current implementation of the EH1 `SpiDevice` trait does not support the `DelayNs`
9379
//! operation. Implementing this was impossible while keeping backwards compatibility.
9480
//! This may change in a future release.
9581
//!
9682
//! 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].
9884
//!
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
10086
10187
use core::marker::PhantomData;
10288
use core::task::Poll;
@@ -1447,6 +1433,56 @@ where
14471433
}
14481434
}
14491435

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+
}
14501486

14511487
impl eh1::spi::Error for LpspiError {
14521488
fn kind(&self) -> eh1::spi::ErrorKind {

0 commit comments

Comments
 (0)