Laying out SPI bus traces - Page 1
Forum section: electronics / general

author: rrinker
author_rank: Super Contributor
timestamp: February 12, 2020, 09:52:56 pm
content: My next project will have an ATMega328 driving 3-5 MCP23S17 I/O expanders via SPI.This is all on one board - no long runs of the SPI lines other than enough length to reach all the chips, no board to board SPI connections.I say 3-5 of the 23S17s because I want to design the board for the worst case need for I/O pins, but for other cases where I don't need them all, leave a chip or two unpopulated.Playing around on a breadboard, it doesn't seem to matter much, but with limited PCB layout experience, is there anything special I should watch out for? I was planning to lay it out so the chips left off for the reduced port version would be ones between the ATMega and IO chips that remain - so no open tails hanging off the end.(not so young young player)

author: thm_w
author_rank: Super Contributor
timestamp: February 12, 2020, 11:13:55 pm
content: If you are running them at 100-400kHz, its really not going to matter how you lay it out. Even if you could somehow get the Atmega to output 10MHz, its not super critical, but avoid stubs and wire all the IC's in a line if possible. Keep trace lengths roughly of the same length.https://electronics.stackexchange.com/questions/9819/how-should-i-route-spi-lineshttps://electronics.stackexchange.com/questions/121087/50mhz-spi-pcb-routing-use-vias-or-resistors

author: T3sl4co1l
author_rank: Super Contributor
timestamp: February 13, 2020, 01:19:37 am
content: Well, you can get clock bounce at any frequency. The trick is to source-terminate the traces with resistors to prevent ringing. Minimum resistance is trace impedance minus pin driving resistance. Typically 50-150 ohms trace (depends on board and trace geometry -- use ground planes, in any case), and 30-50 ohms pin, so 100 ohms is a good start. Ferrite beads are also good (similar Z at 100MHz).That's for each output, so the MCU's SCK, MOSI and CS pins (and any other output pins driving CMOS inputs, for that matter), and all the expanders' MISO pins. Place the resistance close to each output pin.I've had SPI issues on breadboard before, using relatively long leads flying through air (which gives a higher impedance, making the ringing worse). ATMEGAs are just fast enough for it to be a problem even over typical breadboard distances. That particular instance I used ferrite beads on the offending wires, which tamed it just fine.Tim

author: rrinker
author_rank: Super Contributor
timestamp: February 13, 2020, 02:52:29 am
content: What about I2C? Same considerations? My reasons for using the SPI version of the chip are really kind of silly - the potential to make a super IO version, because the 23x17 has a 3 bit ID, so a given SPI chain with a shared CS can drive 8 chips, and I could have 4 or 5 chains, even more since there would be plenty of pins left on the ATMega. But the truth is, such a condition in my use case ould never ever arise, I will never need more than 3-5 total 23x17's per board.I have nothing invested, except the 5 23s17s I bought to test with, so I2C vs SPI, there doesn't seem to be much of a reason to pick one or the other. Speed is not an issue, a 16MHz Atmega328 won't do 10MHz SPI, and 100Kb should be plenty fast enough, certainly fat mode at 400Kb would be. So besides the 4k7 pullups for SDA and SCL lines, is there anything else to worry about with I2C?There is a commercial product that does sort of what my thing is going to do, they use I2C and actually break out the additional IO to multiple boards. One factor in my idea to use SPI instead was there already is a board out there that does I2C. But I'm not tied to either one at this point.

author: T3sl4co1l
author_rank: Super Contributor
timestamp: February 13, 2020, 03:29:13 am
content: I2C is slower, due to the risetime caused by the resistor pullups; nominal is 400kHz (there's also a high speed version, but it's not commonly used). Fall time can be quite fast though; drivers aren't supposed to be too fast -- they are supposed to incorporate filtering or slew-rate limiting -- but some manufacturers don't seem to care. I've seen a hard <3ns on one device, and 50MHz+ chattering on another!So, you can still get ringing from some devices, on the falling edge. Same strategy applies -- introduce series impedance. Now, the DC pullup makes a series resistor less preferable -- together they make a voltage divider, increasing the voltage on the bus. That's a limitation, but we can calculate whether it will actually be a problem. As long as a valid logic threshold is reached within a reasonable time frame, it's okay. Valid logic is usually < 0.3*VDD, so a pull down to 0.15*VDD or less is good, which implies a pulldown resistance of less than 4.7k * (0.15) / (1 - 0.15) or 830 ohms. Which indeed isn't hard to pull off; again a 100 ohm resistor will do, or a ferrite bead.I2C is a bit more annoying to use (you have to address everything), but it definitely saves on IOs over SPI -- you don't have to fan out all those CS's. (CS at least can be scaled reasonably by using decoders -- three lines to control seven CS for example -- but it's still extra, and still more than just two lines!)SPI is okay for taking off the board, following some precautions (and maybe transceivers, e.g. RS-422), while I2C really isn't suitable over much distance at all, and at the very least needs a shielded cable to do so. But as you're not going anywhere off board, this isn't any concern. Do provide a contiguous ground plane (2 layers stitched, or multilayer in the middle), and that's about it.Tim

author: nctnico
author_rank: Super Contributor
timestamp: February 13, 2020, 12:31:23 pm
content: Make sure to put some capacitors on the SPI lines to ground. Something like 220pf and put small series resistors on the driver pins on every chip. An SPI bus can be very susceptible to picking up noise (especially in industrial environments). Updating the outputs continuously and not only when there is a change helps to recover from the case where an SPI transfer goed wrong. The resistors and capacitance will limit the maximum transfer rate; I'd keep this as low as possible so the capacitance can be large.However for I/O expansion I2C is just easier. You only need two wires to each chip and the I2C bus takes care of the addressing.@T3sl4co1l : I have to disagree that SPI is more suitable to take offboard. I'd say I2C is more suitable because it has noise filtering by design (or at least it is supposed to have this if it follows the specs) where SPI does not. Actually I2C is used to communicate between electronic devices over cables. Think about HDMI. For longer distances you can even get special I2C buffers.

author: T3sl4co1l
author_rank: Super Contributor
timestamp: February 13, 2020, 06:30:06 pm
content: Quote from: nctnico on February 13, 2020, 12:31:23 pmEhh. Filtering is nice, but the clock needs to be sharp, and only so much delay can be tolerated before  data gets misaligned. The amount that is acceptable depends on the clock frequency, and whether the slave devices have schmitt triggers on their inputs -- which they should, but who knows.QuotePrecisely: HDMI is a fully shielded interface.Digital filtering doesn't do anything if the logic levels are being actively and repetitively violated by RF noise. And even if it's analog filtering on chip, enough RF to activate ESD diodes will still violate levels.Only analog filtering can help with that -- but only as much as the filter can offer, which is limited by the total bus capacitance and desired clock speed. That is, the number of filters, their number of poles, and their cutoff frequency, are all constrained by total bus capacitance.Example: if you need say -40dB by 10MHz (to deal with some conducted, and the low end of radiated, noise), then a 2nd order filter needs Fc ~ 1MHz, and for Zo = 100R (ballpark typical for non-paired multiconductor cable), C = 1.6nF. With that at each end of the line, and 2.2k pullups, risetime is 5-10us, pushing Fclk below 100kHz most likely. Whereas if you use Fc = 3MHz and a 4th order filter, you need 3 times less capacitance each (~1nF), but twice as many. 2/3rds the capacitance helps a bit, but it's still a burden (now you can do maybe 150kHz).Maybe you target radiated noise more directly, say at 50 or 100MHz, in which case the capacitors are much more reasonable, 100pF and thereabouts; but you're still wide open to conducted noise.This does make a good case for small extension boards -- like a keypad or display board, with no external connections, only its cable back to the main board. This will have a resonance defined by the size of the boards and the distance between them, and the length and style of cable, and how many grounds are used (in particular, the size of grounding). A modest say 0.3m cable will give a first resonance around 100MHz, with no anomalous susceptibility below there. So a 2nd order filter cutting at 10MHz or so is quite reasonable, and should pass modest RFI levels (3, maybe 10 V/m).The same of course applies to SPI, where the filtering also serves to minimize emissions (SPI pin drivers are rarely if ever filtered or slew-rate limited). SPI is probably more vulnerable here simply because more signals are needed, and it would be nice to pack in more grounds to compensate, but, y'know, pins, connectors, size, cost...Going back to the OP's situation -- SPI can still be attractive, in more limited circumstances. If the pin directions or types don't need to be controllable, then a huge ass shift register chain can be used. No CS's needed, just one common strobe. Just keep sending frames until the data's gone once around, then hit the strobe to set all the outputs (e.g. 74HC595) and sample all the inputs (e.g. 74HC165). Basically, bake-your-own shift register. Great for LEDs, GPOs and GPIs, but not so great for GPIOs, anything time critical (it's polled only), etc.I mean, you can tack on some GPIO functionality -- say, add a tristate buffer driven from a GPO, so the port direction is just another bit on the chain. Or diode + pull-up/down from more GPOs to set pull states as needed. You probably aren't going to go too far in this direction before the parts count gets messy, at which point the IO expanders will look more attractive.Tim

author: rrinker
author_rank: Super Contributor
timestamp: February 13, 2020, 08:38:01 pm
content: Yikes, looks like I opened a can of worms hereMy initial reasoning for SPI over I2C was ease of use. The MCP23S17 still needs addressing, even with SPI, because of the individual address in each chip. One CS can be as many as 8 of them, although I was thinking of basically dividing them into two sets, with 2 CS lines. One set would be the ones configured for outputs, the other would be the ones set for inputs.Pin count, I am not worried about. Basically I have 2 pins for serial I/O (RS485, tying all these boards to a controlling PC), a blinky LED to know the code is executing, and then the 3 SPI lines plus 2 CS lines. Even using a wasteful but simple 6 lines with a pullup and DIP switch to set the address for the protocol being used over the RS485 drop, I have pins left over. 6 more to add something else - but I don't need anything else on this board. Maybe individual LEDs for RS486 TX and RX.There may be other/better options, but the MCP23S17 seems pretty common, and not very expensive. The data sheet sure details all the information about the programming and control registers of this chip, but it doesn't say one word about it having proper tri-state output or schmitt trigger inputs.Speed is not terribly critical - this is for model railroad signals and block detectors. No need to try and read from the i/o at 10MHz.Basically though, it sounds like I should try to make the traces all the same length, and not have any stubs hanging off the end (so much for not populating unneeded chips?) and have good ground planes both sides of my board with plenty of vias. It's all through hole, 2 sided board. And the usual bypass caps on the power pins and power input to the board.

author: thm_w
author_rank: Super Contributor
timestamp: February 14, 2020, 12:18:11 am
content: Quote from: rrinker on February 13, 2020, 08:38:01 pmIts done in good faith but people don't seem to target their advice to who is asking it and why.QuoteYeah.Don't worry about unpopulated chips, its more about the trace routing, so you'd go from chip A to B to C. Instead of from A to B, then from A to C. See "series" diagram here:https://electronics.stackexchange.com/questions/91755/i2c-and-spi-bus-routingIf you are thinking of using in an industrial environment, then the further ESD/etc protection mentioned might be added, or the end termination. Haven't used it myself.

author: SiliconWizard
author_rank: Super Contributor
timestamp: February 14, 2020, 12:29:29 am
content: Agree with thm_w, don't overfret it really. The typical SPI works with the data changing on one edge (eg. rising) and sampled on the following edge (eg. falling), so you have almost half a period (minus setup time) before things start getting bad. In that respect, yes clock speed matters and for anything but high speed communication, there's a lot of leeway when it comes to laying out traces on a PCB and especially trace length. Reflections can be another matter but I've personally never seen it on low speed designs (knowing the driving strength of the IOs in that case is usually not enough to bother).Sure some people are talking about routing high-speed differential signals, the OP is just going to use an ATMega328. Let's keep things in perspective.

author: langwadt
author_rank: Super Contributor
timestamp: February 14, 2020, 12:56:47 am
content: Quote from: nctnico on February 13, 2020, 12:31:23 pmI2C is terrible, so many controllers and devices get stuck in lala land if you as much as fart in the wrong direction

author: nctnico
author_rank: Super Contributor
timestamp: February 14, 2020, 02:04:07 am
content: There is a simple solution for that: use quality parts. For example I2C expanders from NXP (formerly Philips who invented I2C). Also make sure to implement / support things like clock stretching and bus reset.

author: T3sl4co1l
author_rank: Super Contributor
timestamp: February 14, 2020, 07:24:10 am
content: SPI controllers get stuck in la-la land too. An ADI 24-bit ADC I think it was, doesn't reset state when CS is deasserted. It's always watching SCK, andany stray edgewill desync it. At which point you have to power cycle the poor bastard.Alas, no surprises there. Everything is terrible, software or hardware. Such is our lot. Best bet, test parts before committing.Tim

author: rrinker
author_rank: Super Contributor
timestamp: February 14, 2020, 04:27:54 pm
content: I figure if it works on a breadboard with all those wires and pins sticking out all over the place, it ought to work one a fairly clean PCB. I guess being new at this (I AM an EE by degree, but I've never really worked as one, been pretty much IT since graduating many moons ago - played with electronics from a young age, and just dabble for personal use these days, and these last two projects are my most complex things I ever designed, and the first PCBs I've ever done) makes me nervous about making sure I'm doing things correctly and that they will work as intended. It was a huge thrill when I built up the first of my other unit, which controls servos, and it actually works - needed a few software tweaks but considering that between the version that worked on a breadboard and the version on the PCB, I changed nearly every IO line on the micro to make it easier to lay out, it was all good.My best friend who is also an EE, but stayed working as an EE his whole career, keeps telling me not to worry with this slow stuff (he'as an RF and microwave guy). I'm sue he's right - none of this is running at speeds where an extra half a mm of a lead I didn't cut off quite as short as the others will through the whole thing into crazy oscillation.As for that series and parallel wiring - It never even occurred to me to wire it in parallel with direct runs back to the pins on the micro. Even with limited knowledge that screams "wrong" to me. Guess that means there is hope for me yetI do appreciate the advice. I'm sure I'll be back asking more once I get to the board stage. I do have a lot of projects going on, remember this is for my model railroad, which is my primary hobby, doing the electronics for it is a secondary hobby (I can always buy someone else's, but DIY is more fun). I'm nearing the end of getting my basement completely refinished into a suitable environment to build my dream layout, and then I will be starting on getting that going. I do need to assemble the other 4 turnout controller boards, and order more, as I need those pretty much right from the start, but this board with the IO ports comes in a bit later in the game. I just had some time while waiting for things to get done so I thought I'd get started in formally designing these IO nodes. I see maybe two other projects related to this as well, one a current sensing block detector (sense current flow with a current transformer, detection pulls a pin on the IO board low) and a structure lighting controller built around ATTiny85s that can make the lights go on and off in buildings at random as if someone was actually going room to room, and also for some generator a flicker to simulate a TV set (B&W in my 1950's setting).

author: nctnico
author_rank: Super Contributor
timestamp: February 14, 2020, 06:19:12 pm
content: Quote from: T3sl4co1l on February 14, 2020, 07:24:10 amTrue. I once used an SPI temperature sensor from Microchip near a DC-DC converter to monitor the temperature. As soon as the DC-DC converter went on the temperature didn't make sense. SPI bus was the first suspect but it turned out the chip itself didn't like to be near a bunch of MOSFETs doing some hefty DC-DC converting.@rrinker: please make sure to post some pictures on your model railroad. I hope to do some model rail-roading myself -if I ever retire-.