ftdi-embedded-hal icon indicating copy to clipboard operation
ftdi-embedded-hal copied to clipboard

SPI idle high handling with SpiBus

Open andreasWallnerIFX opened this issue 3 months ago • 1 comments

We are facing a similar issue to the one that was fixed in #69 - just when using the SpiBus instead of SpiDevice.

Running this code:

pub mod error;
use error::Result;

use ftdi_embedded_hal::eh1::digital::OutputPin;
use ftdi_embedded_hal::eh1::spi::{SpiBus, SpiDevice};
use ftdi_embedded_hal::libftd2xx::FtdiCommon;
use ftdi_embedded_hal::{self as hal};

fn main() -> Result<()> {
    let mut ftdi = ftdi_embedded_hal::libftd2xx::Ft4232h::with_description("Quad RS232-HS B")?;
    println!("found ftdi with device info: {:?}", ftdi.device_info());

    let hal = hal::FtHal::init_default(ftdi)?;
    let mut device = hal.spi()?;
    let mut cs = hal.ad3()?;

    cs.set_high()?;
    device.set_clock_polarity(hal::eh0::spi::Polarity::IdleHigh);
    device.write(&[0; 1])?;
    cs.set_low()?;

    let command = [1, 0xff, 0x80];

    device.write(&command)?;

    cs.set_high()?;

    Ok(())
}

What we get is this:

Image (Note that the logic analyzer only shows the correct data because we configured the "wrong" phase)

Where you can see too short clocks at the start of the communication and between bytes. If we use the SpiDevice this does not happen. I currently don't see a way to work around this since there is no public API with which I could "fix" the polarity of the clock, similar to what was done in #69. A possible fix would be to preset the clock bit in FtInner::lower in the set_clock_polarity call - we'll be testing that.

Or did we mess up here / overlook some function?

To preempt the question: we are not using SpiDevice since we are communicating with a device where we need to poll for a non-zero byte, without releasing the CS pin. I don't see a way to do this with the features of the SpiDevice trait.

andreasWallnerIFX avatar Aug 27 '25 12:08 andreasWallnerIFX