Yikes! Exponential SPI weirdness - Page 1
Forum section: electronics / general

author: andyturk
author_rank: Frequent Contributor
timestamp: December 30, 2012, 03:31:15 am
content: I'm working on aprojectto read some analog sensors and display the results on an LCD screen. One of the issues I've run into is that the SPI traffic causes lots of noise on the board which throws off the ADC readings.As part of minimizing the noise, I'm experimenting with interleaving ADC and SPI activity to make sure the two never occur at the same time. The ADC has to collect samples on a specific interval (currently ~6K times per second), so I've been disabling the SPI peripheral just before the ADC wakes up, and then re-enabling SPI after the data has been read. It seems to work and does reduce (some of) the noise being picked up by the ADC. The mcu is a STM32F103RG.While poking around with my scope, I noticed this decidedly non-digital artifact on the MOSI (Master Out Slave In) line shown in blue:The yellow trace is a GPIO that goes high just before SPI is being shut down. After the ADC is done, the yellow trace goes low, and SPI starts up shortly thereafter. The interesting part is the exponential ramp of the MOSI line while the SPI peripheral is disabled. My guess is that something goes high-Z internally and a weak pull-up on the I/O pad acts through some capacitance gradually ramps it up to VDD. The RC time constant looks to be about one division, or roughly 5uS.This doesn't seem to cause any problems for the LCD I'm using (ST7735Rfrom Adafruit), but having a floating SPI line can't be a good thing in general. Should I put an external pull down resistor on the next spin of the board?Also, is there any general wisdom for keeping SPI noise away from an ADC on a mixed signal board? For now, I'm using a 2-layer design for prototyping since that's much cheaper than 4-layer.

author: svofski
author_rank: Regular Contributor
timestamp: December 30, 2012, 04:37:49 am
content: I think that your guess about something getting tristated is correct. How do you shut down SPI? Maybe before shutting it down you could reconfigure the SPI pins to become GPIO and set them to zero, then reconfigure them back again next time when you need SPI: thus you would avoid uncertainty on the pins.

author: amyk
author_rank: Super Contributor
timestamp: December 30, 2012, 07:33:23 am
content: If the LCD /CS is inactive (is that the GPIO) then it shouldn't cause any problems as long as the voltage is within spec since the controller isn't reading what's on the MOSI while it's deselected.

author: andyturk
author_rank: Frequent Contributor
timestamp: December 30, 2012, 07:42:58 am
content: Quote from: amyk on December 30, 2012, 07:33:23 amAs it turns out, the CS stays put through the entire ordeal... apparently the LCD doesn't care. I used a different GPIO for the yellow trace (with an LED on it), but you're right, I probably ought to toggle the chip select too.

author: MikeK
author_rank: Super Contributor
timestamp: December 30, 2012, 07:36:39 pm
content: Don't you need pullups on the SPI lines?

author: AndyC_772
author_rank: Super Contributor
timestamp: December 30, 2012, 07:55:59 pm
content: Why disable the SPI peripheral at all? Provided there's no actual SPI communication being performed when the ADC is working, there will be no switching and therefore no noise.

author: svofski
author_rank: Regular Contributor
timestamp: December 31, 2012, 12:16:52 am
content: Quote from: MikeK on December 30, 2012, 07:36:39 pmUsually, no.

author: lewis
author_rank: Frequent Contributor
timestamp: December 31, 2012, 12:35:18 am
content: Quote from: MikeK on December 30, 2012, 07:36:39 pmThat's I2C

author: CarlG
author_rank: Regular Contributor
timestamp: December 31, 2012, 02:12:13 am
content: Quote from: andyturk on December 30, 2012, 03:31:15 amI don't really see why you have to make sure of this by changing MOSI to GPIO? Can't you avoid accesses by SW? If not, how can you be sure SW doesn't try to make an SPI access while it's turned off?

author: CarlG
author_rank: Regular Contributor
timestamp: December 31, 2012, 02:21:54 am
content: Quote from: AndyC_772 on December 30, 2012, 07:55:59 pmIf you're unlucky, you might get noise fed to the ADC anyway.That is, if a) the ADC is sensitive to noise on the SPI interface, and b) you have a noisy Vcc or GND at (or rather, inside) the MCU. Remember that the interface pins are shorted to (the MCU internal) Vcc or GND, so any noise will propagate to the ADC.However, I'd guess that in most cases this isn't a problem. But be aware.//C

author: andyturk
author_rank: Frequent Contributor
timestamp: December 31, 2012, 07:20:42 pm
content: Quote from: AndyC_772 on December 30, 2012, 07:55:59 pmWell, the theory was that since I saw all kinds of noise showing up on my oscilloscope when the SPI was sending bits to the LCD, that some of that noise would also find its way to the ADC. Here's what my scope shows when I probe one of the ADC input lines. Yuck!This project uses the STM32's DMA to feed data into SPI. Basically, you set up the DMA channel with a pointer and a byte count and then it feeds data directly to the SPI peripheral without CPU intervention. So even though the CPU is off doing something else, data is still being sent to the LCD. The ADC works the same way--via DMA transfers, so keeping these two parts of the chip from stepping on each other was a little tricky.Here's a logic analyzer trace showing SPI activity (look at SCK) occurring at the same time as the ADC is taking samples (when the top trace is high):I tweaked the code so that just before the ADC takes a reading, the SPI peripheral is disabled. Note that the SPI won't necessarily shut down right away if it's in the middle of transmitting a byte. There's a slight overlap at the beginning of the ADC period, and the ADC collects an extra "dummy" sample at the beginning to skip over that part.Here's a trace showing SPI being suspended before each ADC run:There's a very slight overlap at the beginning while the SPI clears its transmit buffer. After that, SCK goes low and MOSI (for whatever reason) goes tri-state and/or high depending on which tool is used to measure it.The $64K question is whether this trick improves the ADC measurements. Unfortunately, my "lab" is a little limited and the best tool I have for generating signals is a DG1022 function generator. Setting it to put out a DC voltage at about 50% of what the board's input stage can handle looks like this on the scope:I put a T-connector on the output of the DG1022. One side of the T has a 50-ohm terminator and the other side is a short length of BNC that runs directly into the scope's input. The function generator's output impedance is set to 50 ohms. The result is about 8mV of high frequency noise on top of the DC signal.The board's firmware now lets ADC and SPI overlap by default, but if you press one of the buttons, it separates them (the change only occurs between screen updates). To test the board, I leave the T and the terminator in place and use a BNC-to-alligator cable to apply the signal to one of the board's sensor inputs. Here's what that DC signals looks like with ADC overlapping SPI:Here's what Rigol's version of DC looks like when ADC and SPI *don't* overlap. Note the finger on button #4:They look pretty much the same to me. Here's the same experiment using a 10mV square wave as generated by the DG1022. First, how it looks to the scope:How it looks to the board without SPI noise reduction:And with the noise reduction:There might be a difference, but it's not very big. I still havescreen shotsof previous experiments that showed more objectionable noise, but I can't recreate those results now, and I can't explain why they happened either (very annoying).At any rate, I think I've been chasing my tail on this noise "problem" and will put it aside for now. Measuring single-digit millivolts (reliably) is proving to be a challenge with the equipment I have.The next spin of this board will have the LCD connector the right way up, and won't require the LCD breakout board and the shameful bodge wires, which can't be helping the situation.

author: AndyC_772
author_rank: Super Contributor
timestamp: December 31, 2012, 08:14:04 pm
content: Ah, OK - so really you're disabling the SPI peripheral in order to stall the DMA engine, rather than for the effect on the I/O characteristics of the pins. I guess that's OK provided it works and you don't lose data.Can I ask how you're probing the signal? Are you using the proper technique of using a very short ground spike on the probe to contact the ground pin of the ADC chip? If not, it's possible that the noise you're seeing in the first photo isn't 'real', but is just an artefact created by less than ideal grounding of the scope probe.

author: andyturk
author_rank: Frequent Contributor
timestamp: December 31, 2012, 08:31:33 pm
content: Quote from: AndyC_772 on December 31, 2012, 08:14:04 pmIt seems to work without losing data, although the datasheet says bad things might happen. It doesn't say which bad things though.QuoteErr, um, in the worst possible way? Yeah, I had the probe's flying ground lead attached to the board's ground several inches away. The "hook" of the probe was hanging off one of the jumpers at the top-left of the LCD. I added those jumpers intending them to be test points, but they're not very useful since there's no easily accessible ground nearby for proper probing.QuoteI'm almost certain that's what's happening. With extreme tongue-angle, I was able to do a more proper probing (less than 1cm between naked probe tip and ground) between a couple of resistors. That showed less noise than before, but quite a bit more than the ADC sees.

author: svofski
author_rank: Regular Contributor
timestamp: January 05, 2013, 11:59:16 am
content: Do the signals on the screenshots correspond to 10mVp-pinput on ADC pin, or are they instrumented before getting digitized? If that's really 10mV and your AREF is 3.3V that's close to 1-bit noise for a 10-bit ADC, a reasonable noise for a builtin converter I guess.

author: andyturk
author_rank: Frequent Contributor
timestamp: January 10, 2013, 06:27:34 am
content: Quote from: svofski on January 05, 2013, 11:59:16 amYup, the (device) screen shots showed what the ADC read in. AREF is 3.3V (the LQFP-64 pinout doesn't have separate AREF inputs). The ADC resolution in this case is 12-bit.The DG1022 doesn't seem capable of putting out a noise-free signal down at such a low level. Maybe I should throw an attenuator on the FG and run it at a higher level?

author: svofski
author_rank: Regular Contributor
timestamp: January 15, 2013, 03:40:53 pm
content: I don't know, given the scale, this is a very high resolution, 3.3/4096 = 0.8e-3V.. I do not have any toolage to measure signals so small. I guess it's not a bad idea to scale the signal up.