3

I'm trying to figure out why my SPI device isn't responding as expected. So I hooked up my logic analyzer and am a bit confused by the results.

I'm seeing what appears to be random pulses on the chip select/slave select line (CS in the images below). The pulses happen in random locations with random counts. Always matching either a falling edge or rising edge in the CLK line.

Logic Analyser Screen Capture 1 Logic Analyser Screen Capture 2

The code I'm running is part of a library, but I've pulled it all out for a minimum functional example:

#include <SPI.h>

#define DC_PIN          9
#define CS_PIN          10 
#define BUSY_PIN        7

int IfInit(void) {
    pinMode(CS_PIN, OUTPUT);
    SPI.begin();
    SPI.beginTransaction(SPISettings(2000000, MSBFIRST, SPI_MODE0));
    return 0;
}

void SpiTransfer(unsigned char data) {
    digitalWrite(CS_PIN, LOW);
    SPI.transfer(data);
    digitalWrite(CS_PIN, HIGH);
}

int Init() {

    if (IfInit() != 0) {
        return -1;
    }

    SendCommand(0x01); //POWER_SETTING
    SendData(0x03);                  // VDS_EN, VDG_EN
    SendData(0x00);                  // VCOM_HV, VGHL_LV[1], VGHL_LV[0]
    SendData(0x2b);                  // VDH
    SendData(0x2b);                  // VDL
    SendData(0xff);                  // VDHR
    SendCommand(0x06); //BOOSTER_SOFT_START
    SendData(0x17);
    SendData(0x17);
    SendData(0x17);                  //07 0f 17 1f 27 2F 37 2f
    SendCommand(0x04); //POWER_ON
    WaitUntilIdle();
    SendCommand(0x00); //PANEL_SETTING
    SendData(0xbf);    // KW-BF   KWR-AF  BWROTP 0f
    SendData(0x0b);
    SendCommand(0x30); //PLL_CONTROL
    SendData(0x3c);        // 3A 100HZ   29 150Hz 39 200HZ  31 171HZ

    return 0; 
}

void SendCommand(unsigned char command) {
//    digitalWrite(DC_PIN, LOW);
    SpiTransfer(command);
}

void SendData(unsigned char data) {
//    digitalWrite(DC_PIN, HIGH);
    SpiTransfer(data);
}

void WaitUntilIdle(void) {
    while(digitalRead(BUSY_PIN) == 0) {      //0: busy, 1: idle
        delay(100);
    }      
}

void setup() {

  pinMode(CS_PIN, OUTPUT);
  digitalWrite(CS_PIN, HIGH);

  Serial.begin(9600);
  Serial.println("Start");

  if (Init() != 0) {
    Serial.println("init failed");
    return;
  }

  Serial.print("init success");

}

void loop() {

}

I've tried on two different ATMEGA chips (same Arduino Uno board), same results. I've also tried with the device disconnected. Again same results. I've also tried changing the pin used for the CS, still didn't change anything.

Anyone have some insight as to what might be causing this, and/or what can be done to stop it?

8
  • ground is connected?
    – Juraj
    Commented Feb 6, 2018 at 6:43
  • What processor (Arduino board) are you using?
    – Nick Gammon
    Commented Feb 6, 2018 at 8:12
  • Doing SPI.begin() after SPI.beginTransaction is the wrong order to do things. SPI.begin() should be done first.
    – Nick Gammon
    Commented Feb 6, 2018 at 8:18
  • Yes each test line of the logic analyzer is grounded.
    – Mazaryk
    Commented Feb 6, 2018 at 18:31
  • @NickGammon That is how the library had it, nonetheless I believe you are correct. I have updated the code, re-ran the test, however the issue persists.
    – Mazaryk
    Commented Feb 6, 2018 at 18:34

2 Answers 2

1

I shortened the leads between my arduino board and the device from 15 inches down to ~5 inches and the issue disappeared.

I would have to guess that it was some RF interference.

1
  • Interesting. A possible alternative would have been to slow down SPI. However that doesn't totally explain the glitches on SS.
    – Nick Gammon
    Commented Feb 7, 2018 at 4:57
0

See my page about SPI.

Pin 10 of the Arduino is the SS line - so does this mean you have to use it for the peripheral SS line? Or should it be kept high? The answer (from the Atmega documentation) is that the SS line (pin 10) must be configured as an output (regardless of what value is on it). If configured as an output the Arduino ignores the value on that line, and thus the SPI hardware will not be put into slave mode.

Since the value on pin 10 is ignored, providing it is set as an output, then it can also be used as the SS line for your first, or only, slave. You could then use other pins (eg. 5, 6, 7, 8, 9) to control other slaves.

For you to successfully make an SPI master then pin 10 on your Uno must be configured as an output, regardless of whether or not you actually use pin 10 for SS. Under the circumstances, you may as well use pin 10 for SS if you are going to make it an output anyway.


This issue persists when using pin 10 as the SS.

I tried your code with my Uno (no device connected) and had no such problems. Sounds like an electrical issue to me.

SPI timing

3
  • This issue persists when using pin 10 as the SS.
    – Mazaryk
    Commented Feb 7, 2018 at 0:11
  • See amended reply. I cannot reproduce that issue with your code.
    – Nick Gammon
    Commented Feb 7, 2018 at 2:38
  • Interesting. That definitely suggests it's an issue specific to my setup. Thanks.
    – Mazaryk
    Commented Feb 7, 2018 at 3:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.