Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

STM32: SPI clock not returning to idle state and generating additional clock cycles #11104

Open
MichelRottleuthner opened this issue Mar 5, 2019 · 4 comments
Assignees
Labels
Area: drivers Area: Device drivers State: don't stale State: Tell state-bot to ignore this issue Type: bug The issue reports a bug / The PR fixes a bug (including spelling errors)

Comments

@MichelRottleuthner
Copy link
Contributor

Description

This issue is meant to keep track of the problems discovered when testing #7354. For more details see comments there.
On some stm32 platforms the RIOT SPI driver generates faulty output on the SPI pins.
For now the problem could be reproduced on the following boards: nucleo-f446ze, nucleo-l073rz and nucleo-l476rg (no other STM32 were tested until now).

Steps to reproduce the issue

Connect a logic analyzer to your spi pins, use tests/periph_spi and try the following cases:
1)init 0 0 0 3 14
clock state is NOT reset to zero properly after transmission.

2)init 0 0 1 3 14
clock state is NOT reset to zero properly after transmission.

3)init 0 0 2 3 14
clock state is NOT reset to zero properly after transmission.

4)init 0 0 3 3 14
clock state is reset to zero properly after transmission.

5)init 0 0 4 3 14
clock state is reset to zero properly after transmission.

Expected results

No additional clock cycles before/after sending data, clock returns to idle state after transmission.

Actual results

A) not returning to zero, using config (1) from above:
spi_0
B) returning to zero, using config (5) from above:
spi_4

C) If you start another transmission after (A), you get this:
spi_0_1

copied from #7354(comment):

The root cause of this seems to be that the driver is disabling the SPI peripheral to early after the last bit was clocked out, after the transmission in spi_transfer_bytes. If you insert a small timeout of ~half an SPI-clock period before the disable command, you won't see the faulty behaviour. As this hapens only with slow SPI-clock settings (clk setting <=1 in spi periph test) I assume it's some kind of race condition based on internal clock-synchronisation problems where the hardware doesn't reach the point where it switches the clock back to idle before the peripheral is disabled by the riot driver. I double checked that the driver uses the correct procedure for turning off SPI (waiting for TXE, BSY etc.) and I can't find a problem there.
Possible workarounds I identified so far:

  1. don't disable SPI -> solves A and C, possibly bad for low power and/or shared peripheral usage
  2. change the SPI prescalers to not support the slow clock speeds on affected MCUs -> avoids A and C but decreases functionality
  3. move setting the MSTR bit from spi_acquire to spi_transfer_bytes -> solves only C, but with no additional clock cycles it is at least ensured to not transmit borked data. Leaving the clock on the active level might not be a good thing though.
  4. poll clock gpio till returnig to idle level before disabling SPI -> solves A and C - but a bit hacky

Versions

The last version this was reproduced with is 3c9eb94 (between 2018.04 and 2018.07). Needs to be confirmed with current master again.

@MichelRottleuthner MichelRottleuthner added Type: bug The issue reports a bug / The PR fixes a bug (including spelling errors) Area: drivers Area: Device drivers labels Mar 5, 2019
@stale
Copy link

stale bot commented Sep 6, 2019

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. If you want me to ignore this issue, please mark it with the "State: don't stale" label. Thank you for your contributions.

@stale stale bot added the State: stale State: The issue / PR has no activity for >185 days label Sep 6, 2019
@MrKevinWeiss
Copy link
Contributor

Not stale! SPI tests incoming.

@stale stale bot removed the State: stale State: The issue / PR has no activity for >185 days label Sep 9, 2019
@maribu maribu added the State: don't stale State: Tell state-bot to ignore this issue label May 27, 2020
@miri64 miri64 added this to the Release 2020.07 milestone Jul 4, 2020
@ghost
Copy link

ghost commented Jan 24, 2021

Hi all!,
I reproduce this error with a STM32F303CCT6 board.

I dont know if I'm forgotting something, but I resolved the problem adding a PullDown to SCLK pin with:
GPIOB->PUPDR |= GPIO_PUPDR_PUPDR13_1; //PB13 = SCLK con pulldown
GPIOB->PUPDR &= ~(GPIO_PUPDR_PUPDR13_0);

@MrKevinWeiss MrKevinWeiss removed this from the Release 2021.07 milestone Jul 15, 2021
@maribu
Copy link
Member

maribu commented May 30, 2023

Maybe #19431 fixed the issue?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area: drivers Area: Device drivers State: don't stale State: Tell state-bot to ignore this issue Type: bug The issue reports a bug / The PR fixes a bug (including spelling errors)
Projects
None yet
Development

No branches or pull requests

5 participants