Electronic – SPI Signal Integrity

signal integrityspi

A couple of days ago I had an issue where I was unable to read data from an SPI slave. I finally fixed and I'm now able to read data quite well.

However, I found another interesting issue today. If I connect the slave's output directly to the MCU, the data is corrupted. The following picture shows this:

enter image description here

However, if I put in a series 220 Ohm resistor the data comes in just fine, like so:

enter image description here

The byte transferred was 11001101. You can see the start and end of the transfer from the two small dips in the waveform. The starting dip is seen near the trigger indicator. These are nowhere to be seen in the corrupted waveform.

The rate of data transfer is not very fast. The clock rate is just 62500 Hz.

What could cause this? And how can I make sure that it does not occur when I finally layout the PCB?

The top waveform is the clock (SCK) and the bottom is MISO.

These waveforms show the ringing in more detail. Again, top waveform is the clock and the bottom is MISO. This picture has the CPLD and MCU connected via 220 Ohm resistor:

enter image description here

This shows the ringing when the MCU and CPLD are connected directly (no resistor between them). Note that I cannot get to the source pin (in this case, the CPLD's pin) because the CPLD is on a development board and the chip is on a BGA package. I will try and see if the pin can be probed. Also, I forgot to add, I also have a 100 Ohm resistance in series on the SCK like. I needed this to reduce ringing from the MCU on the clock and because its required for the AVR ISP programmer. Otherwise, AVR Studio simply puts out an error. So, on the final PCB layout they are going to be needed.

enter image description here

Best Answer

When probing, you need to probe the signal where it hits the input pin, and make sure the probe ground is connected to a ground near that pin, so it doesn't hide any ground bounce. It looks to me like you're probing at the output pin, which will hide any ringing.

In the first plot, I see spikes at the signal edges. This tells me that you have some overshoot and possibly potential ringing. The fact that a 220 ohm resistor fixed it is indicative of this as well.

There are three usual solutions to this problem.

The first solution is to use a ferrite bead in series to damp the spike. The ferrite bead will look like a large resistance at high frequencies and a short at low frequencies. It's not the same as an inductor (and a spike usually means you have more than enough inductance in your line).

The second solution is to use a series resistor like you did, but typical values for this resistor are around 22 to 50 ohms, depending on the transmission line impedance, and the resistor must be placed at the source (driver output) end of the line (usually within 0.2 inch, though that may not make any difference at 62.5 kHz). The function of this resistor is to slow down the rising and falling edges of the waveform, damping their high-frequency components. 220 ohms seems like too much resistance to me. You can also use a ferrite bead (or similar EMI filter) with the resistor, usually if your line is part of a cable.

Finally, you might be able to program your driver for a slower edge rate (several nanoseconds instead of one or two), though this is still an unusual feature. This is actually the best solution, and greatly reduces EMI to boot.