Skip to content

ESP32C3: SPI errors due to late MISO sampling #10917

@danielkucera

Description

@danielkucera

Board

ESP32C3 super mini

Device Description

Qorvo DW1000 UWB module via SPI

Hardware Configuration

SPI running at 16Mhz

Version

v2.0.17

IDE Name

platformio

Operating System

Ubuntu

Flash frequency

no idea

PSRAM enabled

no

Upload speed

460800

Description

I noticed (often) random errors when reading from SPI when communicating with DW1000.

See attached screenshot:

Image

Logic analyzer (PulseView) reads the value correctly (0xDC) but C3 does not (0x9C - highlighted in terminal).

Here you can see the MISO went down about 26ns after clock rise:

Image

When I migrated the project from C3 to good old ESP32 all errors were gone.

So I prepared a test bed to find out the sampling delay (data latch-in after CLK rise).
It is a breadboard with a series of logical inverter pairs in 74AC04 package. Each inverter introduces about 4ns delay so 1 pair gives 8ns delay (detailed numbers on scope pictures). Then the signal is fed back to MISO and read by the module.

Image

Now the results comparison for ESP32 and ESP32C3

number of inverter pairs ESP32 read value ESP32C3 read value note
0 - SPICLK connected directly to MISO 0xFF 0xFF
1 pair 0x00 0xFF Scope 1.
2 0x00 0xFF
3 0x00 0xFF
4 0x00 0x80 Scope 2.
5 0x7F 0x00 Scope 3.
6 0x7F 0x00

Oscilloscope pictures follow. CH1 - CLKOUT, CH2 - MISO

Scope 1.:
Image

Scope 2.:
Image

Scope 3.:
Image

From this data it is obvious that ESP32 samples data less than 9ns after clock rise. 👍
ESP32C3 samples data somewhere around 27ns after clock rise which explains why the bit from the module was read as 0.

The api reference explains some settings for sampling but how can this be configured from Arduino?

Sketch

simply read from SPI at 16Mhz

Debug Message

N/A

Other Steps to Reproduce

No response

I have checked existing issues, online documentation and the Troubleshooting Guide

  • I confirm I have checked existing issues, online documentation and Troubleshooting guide.

Activity

me-no-dev

me-no-dev commented on Jan 29, 2025

@me-no-dev
Member

Have you tried with SPI MODE 1 or 2? Looks like it should sample on the falling edge

danielkucera

danielkucera commented on Jan 29, 2025

@danielkucera
Author

I haven't tried because the device is configured for MODE 0. The sampling should happen on the rising edge but it is obviously happening 27ns after.

me-no-dev

me-no-dev commented on Jan 29, 2025

@me-no-dev
Member

The point of sampling is done inside the hardware and can only be controlled by switching the mode. We do not have other way to influence it. I suggest you try another mode and see if that will make the device work

danielkucera

danielkucera commented on Jan 29, 2025

@danielkucera
Author

Chapter 27.8 GP-SPI2 Timing Compensation in ESP32-C3 Technical Reference Manual Version 1.2 show some comprehensive options to configure the timing, especially this diagram:

Image

So I believe there should be some way to configure it.

Jason2866

Jason2866 commented on Jan 30, 2025

@Jason2866
Collaborator

Maybe, but if only in espidf. Arduino code does no low level code to control hardware.

danielkucera

danielkucera commented on Jan 31, 2025

@danielkucera
Author

I suspect this might be a HW bug. Did/could someone from espressif validate the SPI hardware?
Why else would it perfectly work on ESP32 but not on ESP32C3?

danielkucera

danielkucera commented on Feb 1, 2025

@danielkucera
Author

I spent some more hours on this. It seems it all boils down to Register 27.12. SPI_CLOCK_REG (0x000C)
For 16Mhz:

  • ESP32 on Arduino has value 0x80003043 - 0 read with 1 delay
  • C3 on Arduino has value 0x4002 - 0x0 read with 5 delays
  • C3 on esp-idf has value 0x4044 - 0x0 read with 3 delay! so esp-idf does something better here.

My question now is, how this value should calculated? There is no mention in C3 TRM.
I also looked into esp32-hal-spi.c but it does not give me much sense.

Ideally, I would like to read 0x0 with 1 delay also on C3 and I feel this should be doable.

danielkucera

danielkucera commented on Feb 1, 2025

@danielkucera
Author

There is no explanation for SPI_CLKCNT_L and SPI_CLKCNT_H in C3 TRM.
It says, for example, that SPI_CLKCNT_L ... must be equal to SPI_CLKCNT_N which is not true for Arduino as I have shown in above examples.
SPI_CLKCNT_H In master mode, this field must be floor((SPI_CLKCNT_N + 1)/2 - 1). - which is not true again...

danielkucera

danielkucera commented on Feb 1, 2025

@danielkucera
Author

Ok, I think I understand the clock config now:

clk_hclk -> [ clock divider by value SPI_CLKDIV_PRE ] - > [ timer ] -> CLK_OUT

timer config:

  • SPI_CLKCNT_N - reset value
  • SPI_CLKCNT_H - value which triggers falling edge
  • SPI_CLKCNT_L - value which triggers rising edge

Now these are the measured values with C3:

  • register value 0x4004 - 1 interval high, 4 low, MISO latched before 8ns

Image

  • register value 0x4044 - 2 high, 3 low, MISO latched before 20ns

Image

  • register value 0x4084 - 3 high, 2 low, MISO latched before 32ns

Image

Now the ultimate question: Why does the sample delay changes with moving falling edge? It should be only related to rising edges in MODE0.

Jason2866

Jason2866 commented on Mar 13, 2025

@Jason2866
Collaborator

@danielkucera In your opinion is the observation you made "something" that can be changed / fixed in Arduino Core code? Or should this better moved to IDF where low level code access is possible?

EDIT: Is the seen behaviour still there in actual Arduino core? The underlying IDF version has changed!

danielkucera

danielkucera commented on Apr 27, 2025

@danielkucera
Author

Hi @Jason2866 , I've reproduced the issue with esp-idf and opened an issue there. Let's see if they find out something.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @danielkucera@me-no-dev@Jason2866

        Issue actions

          ESP32C3: SPI errors due to late MISO sampling · Issue #10917 · espressif/arduino-esp32