SPI Observation/Question

CPJ

New member
Apologies if this has been asked before, but I can't find a similar question after a search...

I'm using an external 5MS/s ADC; www.linear.com/LTC2315-12.

Using SPI.transfer16 on a Teensy 4.1 appears to insert a delay in the order of 120ns between CS going low and the start of the CLK pulses, and another similar delay after the end of the CLK pulses and the CS going high...

This is the same on SPI and SPI1. Using a fast CLK (nearly 80MHz) achieves good results, but with the time overhead of the pre and post CLK delays only about 2MS/s can be achieved.

Code:
#include <SPI.h>

SPISettings spiSettings(79000000, MSBFIRST, SPI_MODE0);

const uint8_t CS = 0;

const float resSPI = 4.096 / 4096; //12 bit

void setup() {
  // put your setup code here, to run once:

  pinMode(CS, OUTPUT);
  digitalWriteFast(CS, HIGH);

  Serial.begin(115200);
  delay(5000);

  SPI1.begin();
  SPI1.beginTransaction(spiSettings); //Only need to call begin/end transaction once as there is nothing else on SPI1
  SPI1.endTransaction();

}

void loop() {
  // put your main code here, to run repeatedly:

  digitalWriteFast(CS, LOW);

  uint16_t vSPI = SPI1.transfer16(0);

  digitalWriteFast(CS, HIGH);

  vSPI = vSPI >> 3;

  Serial.print(vSPI, BIN); Serial.print("\t"); Serial.print(vSPI * resSPI, 5); Serial.println("v");

  delay(1000);

}

Best regards,


Chris.
 
The line of code below from SPI.h sets the value for the CCR (clock configuration register) of the LPSPI, and determines the lengths of those delays. You can experiment with shorter delays by hard-coding different values, with a minimum of 0 (2 clocks)

Code:
			_ccr = LPSPI_CCR_SCKDIV(div) | LPSPI_CCR_DBT(div/2) | LPSPI_CCR_PCSSCK(div/2);
 
The line of code below from SPI.h sets the value for the CCR (clock configuration register) of the LPSPI, and determines the lengths of those delays. You can experiment with shorter delays by hard-coding different values, with a minimum of 0 (2 clocks)

Code:
			_ccr = LPSPI_CCR_SCKDIV(div) | LPSPI_CCR_DBT(div/2) | LPSPI_CCR_PCSSCK(div/2);

Thanks for the reply Joe...

Hard coding the _ccr value changes the CLK, but not the pre delay between CS going active (LOW) and the first CLK pulse (HIGH), or the post delay.
 
Thanks for the reply Joe...

Hard coding the _ccr value changes the CLK, but not the pre delay between CS going active (LOW) and the first CLK pulse (HIGH), or the post delay.

You're welcome. That may be because the SPI library does not support the use of the chip selects that are integrated with the SPI peripheral. One of these days I'm going to make a simple SPI driver that uses the config/data queue to hold both the data and also control the chip selects, delays, etc., but so far I haven't found the time. I've done some searching and haven't found any existing libraries that provide that capability. The TeensyDuino SPI library is really good, with reasonably high performance while maintaining Arduino compatibility and ease of use. If you want to get closer to maximum throughput, you'll probably need to get into the library details and rework it for your own purposes.
 
Back
Top