-
Notifications
You must be signed in to change notification settings - Fork 7.7k
Description
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:
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:
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.
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
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.To pick up a draggable item, press the space bar. While dragging, use the arrow keys to move the item. Press space again to drop the item in its new position, or press escape to cancel.
Activity
me-no-dev commentedon Jan 29, 2025
Have you tried with SPI MODE 1 or 2? Looks like it should sample on the falling edge
danielkucera commentedon Jan 29, 2025
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 commentedon Jan 29, 2025
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 commentedon Jan 29, 2025
Chapter
27.8 GP-SPI2 Timing Compensation
inESP32-C3 Technical Reference Manual Version 1.2
show some comprehensive options to configure the timing, especially this diagram:So I believe there should be some way to configure it.
Jason2866 commentedon Jan 30, 2025
Maybe, but if only in espidf. Arduino code does no low level code to control hardware.
danielkucera commentedon Jan 31, 2025
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 commentedon Feb 1, 2025
I spent some more hours on this. It seems it all boils down to
Register 27.12. SPI_CLOCK_REG (0x000C)
For 16Mhz:
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 commentedon Feb 1, 2025
There is no explanation for
SPI_CLKCNT_L
andSPI_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 commentedon Feb 1, 2025
Ok, I think I understand the clock config now:
clk_hclk -> [ clock divider by value SPI_CLKDIV_PRE ] - > [ timer ] -> CLK_OUT
timer config:
Now these are the measured values with C3:
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 commentedon Mar 13, 2025
@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 commentedon Apr 27, 2025
Hi @Jason2866 , I've reproduced the issue with esp-idf and opened an issue there. Let's see if they find out something.