Electronics > Projects, Designs, and Technical Stuff

SPI MISO data corruption at faster speeds on Arduino with ATmega328

(1/2) > >>

jeraymond:
Hello,

I was testing out my new SDS 1104X-E oscilloscope's SPI decode feature by sending SPI messages between two ATmega328 based Arduinos. I send 0xAB to the slave and then 0x13 back to the master.

When I run at the fastest SPI speed (using SPI.setClockDivider(SPI_CLOCK_DIV2)) I sometimes get data corruption on MISO. The 0x13 becomes 0x09. Looking at the captured waveform on the scope I see a timing issue where the slave isn't pulling MISO high soon enough and two bits are read as 0s instead of 1s. So I get a 00001001 = 0x09 instead of 00010011 = 0x13. A lower SPI speeds (e.g. SPI_CLOCK_DIV8) I don't seen this issue.

The Arduino is configured on SPI_MODE0 capturing data on the rising edge. In the image MISO is channel 2 (purple) and the clock is channel 1 (yellow).



What might be causing this timing issue? Is the ATmega328 too slow, could it be some effect of my breadboard setup wiring the two devices together or something else?

T3sl4co1l:
- Add a 100 ohm series resistor to each pin driver however you possibly can (cut traces?), or a small ferrite bead/chip.
- Twist the signals (MISO, MOSI, SCK) with a ground wire each, and interleave ground positions where they meet on the breadboard.

Probably either one of these will do, with both being preferable.  You will see somewhat softer edges and MUCH less signal bounce.

Tim

grouchobyte:

--- Quote from: T3sl4co1l on June 15, 2020, 03:25:55 am ---- Add a 100 ohm series resistor to each pin driver however you possibly can (cut traces?), or a small ferrite bead/chip.
- Twist the signals (MISO, MOSI, SCK) with a ground wire each, and interleave ground positions where they meet on the breadboard.

Probably either one of these will do, with both being preferable.  You will see somewhat softer edges and MUCH less signal bounce.

Tim

--- End quote ---

Tim is correct. You need a series R for sure. A fast edge into an unterminated line like you have will cause all kinds of signal integrity/fidelity issues.

Bob

jeraymond:
Thanks for the series resistor tip. I added a 100 ohm resistor for each line in place of one set of wires and it smoothed the signals out some.

I'm still seeing the MISO reading issue. At the faster SPI clock speeds it looks like the MISO signal (purple) from the slave comes too late some times relative to the read on rising edge of the clock (yellow).

My suspicion is that the slave Arduino just isn't fast enough responding at these higher clock speeds. Perhaps an Arduino SPI driver issue or the ATmega328 is to slow for the SPI clock speed. Does this make sense or might the issue be something else?



T3sl4co1l:
In the first one it looks like it's the wrong phase (rising edge triggered) maybe, plus a little delay somewhere, somehow.  The second one is delayed erroneously, somehow.

I forget if -- and which AVRs, if it varies -- the slave SPI is externally clocked, or if SCK is taken in and re-synchronized to peripheral clock and then processed as any other internal signal.  That might be something to look for.  So if their peripheral clocks aren't synchronized, as they drift in and out of phase, you'll see errors come and go.  Or if they're clocked at very different rates, they'll come and go frequently, perhaps multiple times within a given frame, but also perhaps sometimes none and sometimes many.

If nothing else, you could add a D flip-flop and reclock MISO to SCK (possibly with an inverter, if needed to align it to the correct edge), and advance the edge timing on both sides accordingly; but this shouldn't at all be necessary.

If one or the other is reclocking internally, you'll basically have to deal with that as it is, either by using a lower clock rate, external reclocking, or changing to a chip that isn't so dumb.

Tim

Navigation

[0] Message Index

[#] Next page

There was an error while thanking
Thanking...
Go to full version
Powered by SMFPacks Advanced Attachments Uploader Mod