Hey folks.
I'm debugging a SPI slave configuration on an ESP32. The master device is a Keithley 197. I can't control or alter the signals coming from this device, and it has a glitch.
A nice full write-up of this problem is
available here.
The data I am expecting (because the multimeter reading isn't changing) is this:
20 30 4A 14 00 18 11 20 80 EB EB EF EB EB FB 04 04
20 30 4A 14 00 18 11 20 80 EB EB EF EB EB FB 04 04
20 30 4A 14 00 18 11 20 80 EB EB EF EB EB FB 04 04
However, what I see is this:
20 30 4A 14 00 18 11 20 80 EB EB EF EB EB FB 04 04
20 30 4A 14 00 18 11 20 80 EB EB EF EB EB FB 04 04
20 30 4A 14 00 18 11 20 80 EB EB EF EB EB FB 04 04
(... after a dozen or so readings ...)
20 30 4A 14 00 18 11 20 80 EB EB EF EB EB FB 00 00
20 30 4A 14 00 18 11 20 80 EB EB EF EB EB FB 00 00
20 30 4A 14 00 18 11 20 80 EB EB EF EB EB FB 00 00
(... forever until reset ...)
After a ton of playing and debugging, I found an exact correlation with this changeover from correct reads to incorrect reads.
Here is a animation of the SPI being captured and decoded on an oscilloscope. There are two long pauses: one at the very beginning, which explains how I'm triggering (yellow trace, a pulse of a few microseconds duration, on an extra GPIO, which is generated from the spi_trans_callback). This pulse is essentially as close as possible to the moment the SPI bus is done reading the bytes. The second pause shows the read during which the spi clock glitch occurs on the last bit of the last byte. After this glitch (which reads the data correctly), all following reads are incorrect.
Here is the same animation, but zoomed in so you can see the exact timing. Note that the glitch is quite a long pulse compared to the normal pulses. Also note that the yellow trace normally concludes a few microseconds after the last clock pulse has fallen. But after the glitch, the yellow trace has shifted to earlier: it returns during the last clock pulse. It is true that this should be acceptable (because I'm in mode = 0, so positive polarity and rising edge), but it nevertheless fails to grab the last byte (in this case, the last two bytes) of 17.
Anyone have any clues about this? Any routes to debugging this problem?