Author Topic: SPI MISO data corruption at faster speeds on Arduino with ATmega328  (Read 1493 times)

0 Members and 1 Guest are viewing this topic.

Offline jeraymondTopic starter

  • Contributor
  • Posts: 39
  • Country: ca
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?

 

Offline T3sl4co1l

  • Super Contributor
  • ***
  • Posts: 22436
  • Country: us
  • Expert, Analog Electronics, PCB Layout, EMC
    • Seven Transistor Labs
Re: SPI MISO data corruption at faster speeds on Arduino with ATmega328
« Reply #1 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
Seven Transistor Labs, LLC
Electronic design, from concept to prototype.
Bringing a project to life?  Send me a message!
 

Offline grouchobyte

  • Regular Contributor
  • *
  • Posts: 244
  • Country: cn
Re: SPI MISO data corruption at faster speeds on Arduino with ATmega328
« Reply #2 on: June 15, 2020, 03:39:51 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

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
 

Offline jeraymondTopic starter

  • Contributor
  • Posts: 39
  • Country: ca
Re: SPI MISO data corruption at faster speeds on Arduino with ATmega328
« Reply #3 on: June 15, 2020, 05:03:27 am »
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?



 

Offline T3sl4co1l

  • Super Contributor
  • ***
  • Posts: 22436
  • Country: us
  • Expert, Analog Electronics, PCB Layout, EMC
    • Seven Transistor Labs
Re: SPI MISO data corruption at faster speeds on Arduino with ATmega328
« Reply #4 on: June 15, 2020, 07:11:30 am »
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
Seven Transistor Labs, LLC
Electronic design, from concept to prototype.
Bringing a project to life?  Send me a message!
 

Online Someone

  • Super Contributor
  • ***
  • Posts: 5156
  • Country: au
    • send complaints here
Re: SPI MISO data corruption at faster speeds on Arduino with ATmega328
« Reply #5 on: June 15, 2020, 07:14:52 am »
The Arduino is configured on SPI_MODE0 capturing data on the rising edge.
4 SPI modes to pick from, and you picked wrong.
 

Offline jeraymondTopic starter

  • Contributor
  • Posts: 39
  • Country: ca
Re: SPI MISO data corruption at faster speeds on Arduino with ATmega328
« Reply #6 on: June 15, 2020, 04:02:50 pm »
Doing some more digging I discovered that "when the SPI is configured as slave, the SPI is only guaranteed to work at fosc/4 or lower." I was trying to drive the ATmega328 as a SPI slave at fosc/2 which is out of spec. It's seems to work fine at fosc/4.

http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-7810-Automotive-Microcontrollers-ATmega328P_Datasheet.pdf

Thanks for the help!
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf