Skip to content

stm32 HAL DMA SPI CLK pin floats during start of transfer #1094

Closed
@JoshMcguigan

Description

@JoshMcguigan

Problem description

The embassy stm32 HAL for DMA SPI lets the clock line float briefly during the setup of a transaction, rather than continuing to drive it (it should be driven low, in the configuration shown here). This results in the sensor reading errant data (see below). The MOSI line also floats during this time, but that is less of a problem.

Reproduction

#[embassy_executor::main]
async fn main(_spawner: Spawner) {
    let p = embassy_stm32::init(Default::default());

    let spi_bus_1 = {
        let sck = p.PA5;
        let miso = p.PA6;
        let mosi = p.PA7;
        let spi = Spi::new(
            p.SPI1,
            sck,
            mosi,
            miso,
            p.DMA2_CH3,
            p.DMA2_CH0,
            mhz(1),
            spi::Config::default(),
        );
        SPI_BUS.init(Mutex::<ThreadModeRawMutex, _>::new(spi))
    };
    let csn = Output::new(p.PB6, Level::High, Speed::High);
    let mut spi_dev_1 = SpiDevice::new(spi_bus_1, csn);

    let mut buf = [0u8, 0];
    embedded_hal_async::spi::SpiDevice::transfer_in_place(&mut spi_dev_1, &mut buf).await.unwrap();
    println!("{:?}", buf);
}

Relevant code

There may not be an easy fix for this, since control of the chip select line is handled outside this HAL code - and the stm32 reference manual says you are required to disable SPI before setting up a DMA transfer. The specific line that lets the pin start floating is below:

w.set_spe(false);

Potential solutions

A few solutions to this were discussed in the matrix chat.

  • Keep the DMA transaction open across calls to read/write
    • This may be problematic if the user changes bus settings between calls, and also the reference manual says the chip should not be placed into low power mode while SPI is enabled
  • Set the CLK (and maybe MOSI) pins as pull-down on setup (or pull-up, depending on config - and this would need to be updated if the user modified the config)
    • This is less good than driving the pin to the correct value, but may be better than nothing
  • Document this and require users fix it themselves (add a pull-up/down resistor - or configure the pins as pull-up/pull-down before passing them into SPI setup)
  • Dig around in the reference manual and determine if there is a better way to start/stop a DMA transaction while keeping active control of the clock the whole time

Extra data

Expected (taken from stm32f4xx-hal)

nice-spi

Embassy stm32 HAL w/ DMA (note the long CLK "pulse" at the beginning)

buggy-embassy-hal-spi

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions