Skip to content

Conversation

andreasWallner
Copy link

Instead of just storing the correct polarity, also set this polarity in the GPIO struct, so that changes that write to GPIOs (e.g. asserting CS) will maintain the correct idle level.

If this is not done, the FTDI will create invalid output with clock spikes.

I did now implement the version with the API change because this way we get very similar results independent of whether we first deassert CS or set the clock polarity. One could argue that there is one valid order here, but it feels safer/more intuitive this way (but for sure for you to decide what you want to go forward with).

With this example code:

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

fn main() -> eyre::Result<()> {
    for device in ftdi_embedded_hal::libftd2xx::list_devices()? {
        println!("Found device: {:?}", device);
    }

    let mut ftdi = ftdi_embedded_hal::libftd2xx::Ft4232h::with_description("FT4232H MiniModule A")?;
    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)?;

    cs.set_low()?;
    device.write(&[0x01, 0xff, 0x80])?;
    cs.set_high()?;

    Ok(())
}

We now get this on the logic analyzer:

image
w/o writing in `set_clock_polarity`

For completeness, if set_clock_polarity does not immediately change the state and set_high and set_clock_polarity in the above example are swapped then we get this:

image

Where the polarity only get set the moment we select the chip - so we need to take care that there is a delay for most devices that mandate stable signals for a certain setup time before asserting CS. This difference only occurs then on the first CS...

Fixes #75

Instead of just storing the correct polarity, also set this polarity in
the GPIO struct, so that changes that write to GPIOs (e.g. asserting CS)
will maintain the correct idle level.

If this is not done, the FTDI will create invalid output with clock
spikes.

Fixes ftdi-rs#75
@andreasWallner andreasWallner force-pushed the fix_polarity_for_device branch from 0a7e341 to b740883 Compare September 5, 2025 15:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

SPI idle high handling with SpiBus
1 participant