# SPI software select not staying low

...and a few other things. I am working my way through Geoffrey Brown's book Discovering the STM32 Microcontroller and it's largely been smooth so far. I've come across an exercise where the reader can try to read/write to an EEPROM over SPI. I've had the SPI interface working in loopback, although last night when I was testing it, I noticed that on the logic analyzer I was seeing the NSS pushing high before the message was complete. Then in the morning, no changes, everything is working fine again. OK.

I set up everything to read/write the ROM (Micro 25LC256) but the signal I see on the analyzer isn't what I am expecting. I see the NSS pushing high from time to time in the middle of communicating. Further, the clock looks inconsistent and the data looks wrong, and the analyzer is giving me a ton of errors.

I thought, OK, I will take off the NSS altogether as the ROM is the only thing hooked up anyway, then it will stay low and I can check it out. But still the clock looks wonky... I'm just getting started with this stuff, but I don't have anything adjusting clock frequency at all, so not sure how thats changing? The code can be found here, and I think it's quite simple. most of the important logic looks like

  // Drop select level low then send the write enable flag
GPIO_WriteBit(EEPROM_PORT, EEPROM_CS, 0);
GPIO_WriteBit(EEPROM_PORT, EEPROM_CS, 1);
Delay(1); // Debugging aid, Wait 1 ms to make analyzer easier to read


I have all the speeds set low (the SPI CLK/MOSI/MISO are 72 / 64 = 1.125 < 10Mhz = 25LC256 max speed and the GPIO I'm using for NSS is 2MHz), and I put in a delay of 1ms between operations just to make it easier to read on the analyzer, it doesn't seem to affect the output.

Here is a capture of the analyzer data with the NSS forced low (unplugged):

Zooming in on the first pulses I see that the clock width is all over the place, doesn't look like CPOL/CPHA = 0/0 to me, and doesn't look like it's sending the write enable value WREN = 0x06 = 0b0000 0110...

...and it doesn't seem to get better...

And one last one that shows the NSS pushing high for no reason

How do I debug from here? Is there something obvious that I'm overlooking? Is it common to have such bad looking timing problems? Thanks!

• First thing that comes to mind, you need CS pin to interface this chip. From 3.2 in datasheet: "After all eight bits of the instruction are transmitted, the CS must be brought high to set the write enable latch". Second, did you connect "hold" pin properly? Jun 9, 2018 at 22:49
• What speed is your logic analyser sampling at? Looks like it might be too slow relative to your SPI clock. Jun 9, 2018 at 23:10
• @brhans I have it set at it's max, which is 50MS/s. I think that should be enough to sample a < 2MHz signal? Jun 10, 2018 at 2:10
• @Maple Thanks, I actually know about the CS being used to set the write latch. I only disabled it to see if I could 'force' the correct signal out of MOSI (I expect to see 0x06 which is the write enable value), but it's not even getting that far. As for the hold pin, I will double check in the morning, but everything is pretty simply connected on it's own breadboard, so I'm pretty sure that it's connected well. Jun 10, 2018 at 2:13

One part which is pretty obvious:

Do not leave chip select unconnected or low all the time. In most slave devices the chip select is an essential part of the state machine of the slave. In EEPROMs for example the write to the actual cells is often performed after the chip select goes high.

Now your logic analyzer captures do look very wonky. My guess is that you have some noise on your lines (coupling from the other lines, ground loops) so that you aren't actually seeing what's really going on there. I've also had reports from colleagues that the logic analyzer itself was injecting a fair amount of noise.

You haven't mentioned if you actually looked at what the software is telling you - do you get the read buffer to be the same as what you have written? That's the prime thing you should be worried about, if that is not the case then you can start looking at the bus, but before that I'd try to see what I can get in the debugger.

If your analyzer supports analog mode, it might be worth looking at analog signals to see if some of the edges cause significant noise on the other lines. Or use an oscilloscope of course.

• Thanks! I checked the values on the ROM, and I'm not seeing my writes, but I am getting back the correct number of zero values when I check in the debugger (I have it pull the entire first page, and I get back 64 zeros, which seems like a good sign). It actually makes the situation more confusing since if the read is working correctly, I could just have something wrong in software with the writes (which is why I was trying to debug with the logic analyzer in the first place) but am just unable to troubleshoot it because of analyzer issues. :-/ Jun 10, 2018 at 2:16
• Acting on your answer, I tied all the grounds to a better source. Turns out the ground the I was using for the CS pin is wacky (probably the entire board is faulty somehow). I now get a clearer signal, although something still seems to be a little off. Thanks for your help! Jun 10, 2018 at 2:25
• Thanks again for the help, I'm accepting your answer since it got me up and running. The logic analyzer still has a little noise, but I got everything humming along very nicely. Not sure how it's possible, but one of the ground pins on my discovery board gives a ton of noise even though the rest of the board seems to work fine. My suspicion is that the other grounds might be to blame for the rest of the erratic behavior I see on the analyzer, but since it's working I'm not going to go crazy testing that for now. Jun 10, 2018 at 19:22
• @TrivialCase If one of the ground pins is giving you a lot of extra noise, it might be that it is not connected to ground (bad soldering?) or a different ground (some boards have separated grounds, but I don't think that is the case for the discovery boards). Could also be that the pin has a bad routing to ground (long loop instead of directly to the plane). Glad I could help you a bit. Jun 10, 2018 at 21:40