0

I'm trying to communicate with SPI slave using Arduino DUE as master. Device requires commands to be 32 bit wide, SPI mode 3.

I've ran the minimum code (using Arduino IDE 1.8.12) to send some 32 bit wide nonsense, and I've noticed that clock stops for a while after each octet is sent. Also the pause after CS goes LOW is too long.

What is the best practice to achieve a clean 32 bit wide transmission?

#include <SPI.h>

const int cs_pin = 25;
const SPISettings spi_settings(2000000, MSBFIRST, SPI_MODE3);
uint8_t tx_buffer[4];

void setup() {
  pinMode(cs_pin, OUTPUT);
  SPI.begin();
}

void loop() {
  tx_buffer[0] = 0xDE;
  tx_buffer[1] = 0xAD;
  tx_buffer[2] = 0xBE;
  tx_buffer[3] = 0xEF;

  SPI.beginTransaction(spi_settings);
  digitalWrite(cs_pin, LOW);
  SPI.transfer(tx_buffer, 4);
  digitalWrite(cs_pin, HIGH);
  SPI.endTransaction();
}
  • SCLK - CH1 (Yellow)
  • CS - CH3 (Purple)
  • MOSI - CH4 (Blue)

overview zoom in

Expected signal:

enter image description here

3
  • Noticed timing states it's actually 40, not 32 bits, but that doesn't seem to affect the question.
    – IceGlow
    Jun 3 '20 at 16:32
  • The SPI data register is only 8 bits wide. So you have to have some time once one byte is out to load the next byte in. There’s not really anything you can do about it aside from using different hardware.
    – Delta_G
    Jun 3 '20 at 16:41
  • @Delta_G yep, thought so too. But it actually happens even if I set slower SPI clock. Looks like this is intentional. I guess I should have a look at what's going on in the library.
    – IceGlow
    Jun 3 '20 at 19:30
1

SPI is synchronous. That means that within certain constraints the timing and the width of any part of the signal is irrelevant.

What makes you think that it's bad to have a slight variance in the timing, or that the "pause after CS goes LOW!" is "too low"?

If you think it's from the timing diagrams, those times are minimum times (generally) and all things happen at either the rising or falling edge of the clock (depending on the SPI mode).

7
  • Well if you look at bottom diagram, you can see that after 8 raising edges of clock signal the 9th doesn't happen right away as it would in continuous stream. It pauses for one cycle before transmitting next byte. I understand it will work, just will take a bit longer. Just wonder why and if I can avoid it.
    – IceGlow
    Jun 3 '20 at 19:27
  • It is completely normal. Why would you want to avoid it?
    – Majenko
    Jun 3 '20 at 19:30
  • In SPI there's no requirement to wait so many cycles after pulling CS low before starting transmission. It waits about 6 Tcl extra time.
    – IceGlow
    Jun 3 '20 at 19:32
  • @IceGlow The Arduino way of working with SPI is that it is blocking. You get a byte. You put it in the SPI data register. You wait for it to send. You retrieve the received byte. You store it somewhere. You get the next byte. You put it in the SPI data register... etc. If you want to make it more "fluid" for some reason then you will have to do it outside the Arduino API and directly interface with the SPI registers. And even use DMA for ultimate background operation.
    – Majenko
    Jun 3 '20 at 19:32
  • well I'm playing around with directly controlling currents on the actuator from SPI commands. I'd like to have a predictable and minimum delays between commands, as that increases the accuracy. Does that make sense? But the question is - could I control those delays, before first byte is sent, between bytes, after last byte, if I want to.
    – IceGlow
    Jun 3 '20 at 19:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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