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
Copy link
Member

@newAM newAM left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the incredibly slow review, this got buried at the bottom of my inbox.

Thank you for the fix! Can you make the same change for the embedded-hal version 1 implementation near line 474?

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

2 participants