Skip to content

Commit

Permalink
Add LPSPI sampling configuration API
Browse files Browse the repository at this point in the history
Expose a public method to allow users to change sampling point of an
LPSPI peripheral.

I've experienced RX FIFO overruns when the SAMPLE: SAMPLE_1 (delayed
edge) is used with non-hardware controlled chip select pins (ie,
manually driving a CS pin with GPIO embedded_hal traits). Changing this
configuration setting to SAMPLE_0 fixed the issue.

Tested on a Teensy 4.0 and 4.1.
  • Loading branch information
dstric-aqueduct authored and mciantyre committed Apr 21, 2023
1 parent 6807a45 commit 68624ca
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 2 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

## [Unreleased]

Add LPSPI API to configure the sample point.

## [0.5.1] 2023-03-07

Add support for i.MX RT 1020 processors. Enable support with the `"imxrt1020"`
Expand Down
28 changes: 26 additions & 2 deletions src/common/lpspi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
//! use imxrt_ral as ral;
//! # use eh02 as embedded_hal;
//! use embedded_hal::blocking::spi::Transfer;
//! use hal::lpspi::{Lpspi, Pins};
//! use hal::lpspi::{Lpspi, Pins, SamplePoint};
//! use ral::lpspi::LPSPI4;
//!
//! let mut pads = // Handle to all processor pads...
Expand All @@ -53,6 +53,7 @@
//! # const LPSPI_CLK_HZ: u32 = 1;
//! spi.disabled(|spi| {
//! spi.set_clock_hz(LPSPI_CLK_HZ, 1_000_000);
//! spi.set_sample_point(SamplePoint::Edge);
//! });
//!
//! let mut buffer: [u8; 3] = [1, 2, 3];
Expand Down Expand Up @@ -102,6 +103,15 @@ pub enum BitOrder {
Lsb,
}

/// Receive sample point behavior.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum SamplePoint {
/// Input data is sampled on SCK edge.
Edge,
/// Input data is sampled on delayed SCK edge.
DelayedEdge,
}

/// Possible errors when interfacing the LPSPI.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum LpspiError {
Expand Down Expand Up @@ -368,7 +378,7 @@ where
///
/// When this call returns, the LPSPI pins are configured for their function.
/// The peripheral is enabled after reset. The LPSPI clock speed is unspecified.
/// The mode is [`MODE_0`].
/// The mode is [`MODE_0`]. The sample point is [`SamplePoint::DelayedEdge`].
pub fn new(lpspi: ral::lpspi::Instance<N>, mut pins: Pins<SDO, SDI, SCK, PCS0>) -> Self {
lpspi::prepare(&mut pins.sdo);
lpspi::prepare(&mut pins.sdi);
Expand Down Expand Up @@ -950,6 +960,20 @@ impl<'a, const N: u8> Disabled<'a, N> {

watermark
}

/// Set the sampling point of the LPSPI peripheral.
///
/// When set to `SamplePoint::DelayedEdge`, the LPSPI will sample the input data
/// on a delayed LPSPI_SCK edge, which improves the setup time when sampling data.
#[inline]
pub fn set_sample_point(&mut self, sample_point: SamplePoint) {
match sample_point {
SamplePoint::Edge => ral::modify_reg!(ral::lpspi, self.lpspi, CFGR1, SAMPLE: SAMPLE_0),
SamplePoint::DelayedEdge => {
ral::modify_reg!(ral::lpspi, self.lpspi, CFGR1, SAMPLE: SAMPLE_1)
}
}
}
}

impl<const N: u8> Drop for Disabled<'_, N> {
Expand Down

0 comments on commit 68624ca

Please sign in to comment.