SPI data garbled at high speed

Go To Last Post
22 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello,

 

i made a 4 layer custom PCB with 1 master MCU and 32 slave MCUs on. All the MCUs are Atmega3209. Basicaly the main MCU has 32 SS lines and activates each individual SLAVE, get data from it via SPI and after all data is gathered, the MASTER sends all the data via USART to PC. Basically all works like a charm, but then i wanted to speed SPI up, then the problems started.  I set the SPI speed in register CTRLA, using prescalers. I tried all 4 options and at slow speeds (prescaler 128 and 64) things work perfect to ok, but at high speeds(prescaler 4 or 16) data gets garbled. I attached oscilloscope to MOSI, SCK and MISO lines and noticed that at higher speed the signals get garbled. 

 

Now i ASSUME this is due to poor traces design, which causes stray capacitance/inductance at higher speeds, which makes problems when clock/data signal goes from high to low or vise versa. So now i am thinking what can i do on next PCB version to fix this? I planned on adding more layers and put SPI lines in between 2 ground planes and also increase spacing between them, to prevent this from happening to them. I also read some application notes on adding pullup/down resistors to help lines to switch faster. At the moment SPI traces are in same layer and next to other traces (5V/200mA power lines and UART lines). 

 

In attachments are oscilloscope pictures of signals at different prescalers. 

 

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I can't believe that you have 33 individual ATmega3209 chips on one pcb.

 

I would expect the Master SPI to be able to drive 32 Slaves with reasonably shaped signals.   i.e. respectable rise and fall times with minimal ringing.

The Master has push-pull output on the SPI drive pins.   It should be able to drive 320pF bus capacitance ok.    But typical 32 loads would be nearer 160pF.

 

Hey-ho.   It is your design.

 

David.

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I guess it's too late for this now but a better idea might have been to connecting them in a ring? (though it's quite a lot of clocking to get the updates into all the units - but I guess you would have been 32 separate exchanges anyway?)

Last Edited: Wed. Jul 31, 2019 - 10:44 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have to sense 800 pressure+capacitance points, and i use each slave atmega to sense 25 :P Also this is prototype so all MCUs were hand soldered. Could bad joints cause higher capacitance? PCB itself is 350x350mm.

Last Edited: Wed. Jul 31, 2019 - 10:42 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Was also my idea at first, but it doesnt fit requirements. From 32 Slaves only 5 to 15 are active at once, other are in sleep, so calling and listening to individual ones seemed liek better solution.

Last Edited: Wed. Jul 31, 2019 - 10:41 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Klemko wrote:
other are in sleep
This whole thing is battery powered? With 33 micros on it??

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Nono, it is powered via USB from PC. But the thing is that total power consumption needs to be under 500mA bcs it needs to be compatible with usb 2.0. Total configuration is 4 PCBs like this connected together and each has power consumption of 260mA if all MCUs are on. Thats is why at least half of them need to be in sleep at any given time. 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Sight of your PCB layout and a schematic would help diagnose the problem.

 

However, if you are saying that you have 33 devices connected to each of MOSI, MISO and SCK then that's your problem right there. Each pin has capacitance, usually around 10pF, so that each output driver is trying to drive 33 x 10pF = 330pF.

 

Try this experiment...take a chip, configured as an SPI master, and connect a 330pF capacitor to its SCK line and send something over SPI, you don't need a slave connected. Look at the waveform. What do you see?

#1 This forum helps those that help themselves

#2 All grounds are not created equal

#3 How have you proved that your chip is running at xxMHz?

#4 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand." - Heater's ex-boss

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Your scope probes don't look like they're properly grounded, so this is causing the scope to lie to you. As well, are the probes set to x10?  A logic analyser might give a better idea of the delays due to bus capacitance.

 

In the slaves, have you measured your code to see how fast it can respond to the spi peripheral?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 2


This is what SCK looks like at Fcpu/4 with a 16MHz Oscillator...

 

 

...this is what it looks like when you put 330pF on it...

 

 

#1 This forum helps those that help themselves

#2 All grounds are not created equal

#3 How have you proved that your chip is running at xxMHz?

#4 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand." - Heater's ex-boss

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Options:

    1. Mega 3209 has 3 UARTS and one SPI. One UART you need to communicate with the PC. If other is available, it can be used in SPI mode, so you could split the 32 SPI slaves in two or maybe even three. Use HC138 to free pins.

    2. Based on the above idea, if possible, and before to commit to another PCB run, try to isolate 16 or 22 or the slaves so your actual master drives only a third of them and see if the signal improves enough. If not, you can use buffers that are stronger than micro's output. There are small SOT363 ones. Look at the clock line first to achieve enough Hi-LO and LO-Hi speed. Once this is achieved, consider series resistors to eliminate ringings. Note that series resistors and load capacitance does not work well.

    3. You need good PCB design skills. A good PCB design starts with component placements. Give priority to this SPI communication and less to what happen between slaves and board connectors. By simply moving traces to the inner layers does not solve this bad signal shape. Place ground copper between traces to reduce crosstalk.

    4. Consider another master controller with multiple SPI - UARTs.

 

 

Klemko wrote:

Nono, it is powered via USB from PC. But the thing is that total power consumption needs to be under 500mA bcs it needs to be compatible with usb 2.0. Total configuration is 4 PCBs like this connected together and each has power consumption of 260mA if all MCUs are on. Thats is why at least half of them need to be in sleep at any given time. 

In IDLE mode, SPI is still active, so it will pass the signal through.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ah-ha.   Looking at your scope trace it looks like 50ns risetime.    I agree that the traces in #1 look like poor probe/earth choices.

 

Assuming that the AVR has an output impedance of 200R.   RC = 200R * 330pF = 66ns.

 

So my "rule of thumb" output impedance is nearer 150R.    Obviously Brian can do some better measurements.

 

The main lesson is that you either need to reduce your bus capacitance or add an active bus driver chip.

 

It also shows that simple RC time-constant assumptions work pretty well.

 

I am still horrified by 33  QFN-48 chips and attendant copper traces.

 

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

OK thanks all, you gave me a lot of things to test up. I tested what i coudl and it look like  Brian Fairchild  pointed out the real problem.

 

I took a fresh PCB, only soldered on Master and Slave that is closest to it, and checked with scope on all 4 SPI speeds and all the signals were perfect. Then i added a 300pF(i didnt have a 330pF lying around) and did the test again and it this run, i basically replicated the identical issue that i have when i measure SPI lines on my fully assembled PCB with 32 slaves. 

 

So now i have to find a fix for this capacitance. What angelu suggested looks pretty straight forward. Will check out this buffers and tried with them (if you know one that performed good in your project, could you mention it?). And if this doesnt work, i will find MCU with 3 or 4 SPI interfaces and connect slaves in packets of 8 to each.

 

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

    One is 74LVC2G34GW,125. You can try with half of it or with both in parallel per line. Even if this solves the problem, MISO line is more difficult to fix since you need one buffer with Enable/Disable feature like this one for each slave because the hi Z thing. I would go for the multiple SPIs.

    Now that you have one board with one slave on it, you can add another 7 and see how it works with 8 in parallel.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0


As you're going to need a new PCB it's worth checking something.

 

This is due to the capacitance on the lines...

 

 

But this...

 

 

...and this (the signal goes below 0V)...

 

 

...is usually down to a poor 0V connection. It might be how you measured the signals on your scope but it might be lack of good PCB design practice on your PCB.

#1 This forum helps those that help themselves

#2 All grounds are not created equal

#3 How have you proved that your chip is running at xxMHz?

#4 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand." - Heater's ex-boss

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have to sense 800 pressure+capacitance points,

What do you mean by that?  Are you just muxing into 800 ADC channels (then maybe you just need a super-mux).   Or are you using the AVR touch sensing?  I didn't see it listed for the Mega3209 (took a 20 second look).

 

If you use the driver chips, you may still want to break it up into a few banks, rather than tying all 32 to one drive line.

For the 32 MISO lines you could prob group them into 4 banks of 8 (tie 8 together) & then run the 4 groups through a 4way mux to the main AVR MISO line

 

If in an enclosure, you could use bounced opto coupling ...Master AVR sends packets out on led to each micro's led rcvr (light bounces around inside enclosure).  Then there is no capacitance/loading issue.  However, it might not get the speed you need. How fast do you need to read these 800?

 

 

 

 

 

 

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

Last Edited: Wed. Jul 31, 2019 - 06:23 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Im reading pressure via digital inputs (pulse duration) and yes, i am using touch sensing, but i designed my own hardware for it and also made my own library. I didnt use qtouch or anything like that, just the simple principle of RC circuit(one resistor per pin and capacitance of touch pad) and measuring rise/fall time along with some smart filtering to get better results then a expected :P 

I wish to read all 800 pins around 100 times per second. ATM i get aroudn 30-50 reads per second so it is still good. The slowest thing is uart from master to PC. If i disable it, i get around 90 reads per seconds. So i am thinking if changing my Atmega3209 as MASTER with another one that has 4x SPI lines and integrated USB peripheal, for faster data sending.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Brian yes, i only had GNDconnection to scope on SCK line probe, after i added GND to MISO and MOSI probe, the small ripples below 0V were gone. Thanks for pointing it out.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Cool project!

 

By the time you have 32 remote uC's, what's four more for splitting the system up into smaller data collection segments?

 

JC

 

Edit: Typo

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Couple of dumb ideas form my side of the world....

 

Try using some pull up resistors on your clock and data lines at the end of the buss.  might help things, might not.  Try 1kohm first then adjust accordingly.

 

If you plan on re-spinning the board, why not use a few large pin count AVRs as opposed to 32 smaller ones?  Your current consumption should lower itself where you can keep them all awake.

 

 

JIm

Edit:
You could also try pull down resistors

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

 

"The critical shortage here is not stuff, but time." - Johan Ekdahl

 

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

 

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB user

Last Edited: Thu. Aug 1, 2019 - 07:04 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I wish to read all 800 pins around 100 times per second.

Are you trying to send 80000 measurements (pulse width) per sec to the PC?  That's a lot of data for a uart.  What do you need to send to the PC?

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

DocJC   i wanna have only 1 master mcu, and i will use SAMD21 since it supports up to 6x SPI and direct USB output for better data transfer.

 

jgmdesign i use small pin count since i only connect 5x5 matrix (25pin) of touch pins to each slave, so the traces are not too long and dont cause interference with other stuff on PCB or other touch pads.

 

avrcandies avrcandies  yes, my goal is to send 800 uint_8 variables to pc 100 times per sec. Atm im doing it 40 times per sec max, without getting garbled data. With a SAMD21, 4 spi lines for 8slaves per bus, and USB output, i plan to achieve 100 read per second without problems.