Background on the issue:
I currently have an SPI bus between an Atmel ATSAM3X8E and a Spansion FL164K flash memory chip.
SPI has always been super reliable for me in past projects, but this design is being very temperamental (the routing is far from ideal). Some boards work fine, some have very occasional data loss in the SPI comms, some have nearly constant data loss. The data loss that I refer to is most easily reproduced by constantly polling the ready flag during a ~50 second erase. Mostly the busy response is 0x03 (0b00000011), but occasionally comes back as not busy - 0x00 (0b00000000).
Fortunately I can reproduce the fault on the bench, and fortunately I can also make the problem go away. Unfortunately though, connecting a passive probe is one of the things that makes the issue go away, so I can't 'see' the fault. And I'm not happy to call it fixed if I am not certain what I am actually fixing.
Circuit design info:
- The SPI bus is routed to 3 things - SPI flash, SD card (which is not installed), and a basic 6 pin header
- The red pad in the bottom right is the MCU (clk source), the stub that comes off immediately goes to an n-channel FET which drives an LED, the SOIC8 IC with the red pad is the SPI flash, the 6 pin header above it is unpopulated, and the blue pad at the left side at of the trace is an unpopulated SD card connector.
- The actual distance from the MCU to the SPI flash is ~35mm, and the SPI flash to the SD card pad is ~30mm. The stub to the FET is ~25mm and the stub to the header is ~8mm.
- The layout is far from ideal, and I understand that, but the intention was to only run it at <1MHz, so I incorrectly assumed that transmission line theory/terminations/reflections were not needed.
Ways that I can already prevent the problem:
- Add a ceramic capacitor from CLK to ground in the 6 pin header (I have tried values from 18p to 330p). All of them slow the rise time, and the problem doesn't persist
- Add a 1k resistor from CLK to ground.
- Attach a scope probe
- Touch the CLK line with my finger
So basically any way of adding capacitance or loading to the circuit seems to make the reads 100% reliable.
Waveforms (taken with a Rigol DS1054Z with the 100MHz option, and a 150MHz passive probe using a ground spring):
Note: a scope probe is obviously connected for all these (which stops the problem happening). The waveforms we see here are not actually bad enough to cause the problem, but hopefully give an idea of what could be bad enough to cause the issue when the capacitance of the probe is removed.
Note 2: These shots were taken at a 5MHz clock rate, but the problem seems to manifest at anywhere from 100kHz to 20MHz.
On initial inspection the clock signal looks good (albeit very fast ~8ns rise time).
But a closeup shows a bit of a step halfway up
And at the fastest time scale, this is what I see.
Finally, the questions
- Is a step in the rising waveform typical of transmission line reflections or something else?
- Given that the read issue occurs regardless of clock frequency, I assume that the rise time (8ns with probe attached) must be combining with the poor routing to cause the data issues. But don't fast rise times cause ringing, not a stepped waveform? Is it common for a scope probe to dampen ringing that otherwise occurs?
- Looking at the waveform, what actually happens inside the slave to cause an issue? (the SPI slave double clocks because of that step? or the SPI flash isn't getting it's specified 0.1v/ns slew rate? or something else that I don't understand yet?)
- Finally, what else could I do to try to assess the signal without loading (fixing) the signal, short of spending $$$ on an active probe that may or may not make a difference?
As you can tell, higher frequency theory is not my area of expertise, so I appreciate anyone's experiences in this area.