Slow SPI performance to an ADC

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Slow SPI performance to an ADC

925 Views
RogueWarrior65
Contributor I

I've got an iMX6 processor running Linux 4.9.11 (Yocto) connected to a Microchip MCP3202 ADC via the SPI interface.  I'm talking to it via the spidev driver.  I'm finding that the sample rate is about one tenth what it's rated for.  This device requires the chip select line to be brought low, configuration bits clocked out, 2 bytes of sample data clocked in, and the chip select line to be brought high before another sample can be taken.

The system spends 20 microseconds doing nothing between the chip select line being brought low and the data being clocked out and a further 60-65 microseconds after the sample data is clocked out before the chip select line is brought high.

I've dug into the SPI code in the kernel and narrowed things down to spi-imx.c where it appears that the code is waiting for an interrupt (or something) to occur before calling the function that changes the chip select line.  I've read references to BURST mode but I don't know how to set this up.  Furthermore, since this device requires chip select to toggle before taking another sample, would burst mode even work.  FYI, I can tell from debugging that DMA isn't being used.

So, the question is: is there a configuration issue here that I'm missing or is this just the nature of the beast?

Here's userspace code snippet I used to talk to the device:

bufIn[0] = 0x1A;
xfer[0].tx_buf = (unsigned long)bufIn;
xfer[0].rx_buf = (unsigned long)buf1;
xfer[0].len = 3;
xfer[0].delay_usecs = 0;
xfer[0].cs_change = 0;
xfer[0].tx_nbits = 8;
xfer[0].rx_nbits = 8;
xfer[0].speed_hz = 1800000;

status = ioctl(fd, SPI_IOC_MESSAGE(1), xfer);

 

Here's what the device tree looks like:

&ecspi2 {
     fsl,spi-num-chipselects = <3>;
     cs-gpios = <&gpio5 31 0>, <&gpio1 6 0>, <&gpio8 7 0>;
     pinctrl-names = "default";
     pinctrl-0 = <&pinctrl_ecspi2>;
     status = "okay";

     spidevdc1: spi@2 {
         compatible = "spidev";
         reg = <2>;
         spi-max-frequency = <1000000>;
     };
};

0 Kudos
2 Replies

898 Views
jimmychan
NXP TechSupport
NXP TechSupport

Please try the official release. e.g. Linux 4.14.98_2.0.0, Linux 5.4.24_2.1.0​​)

https://www.nxp.com/design/software/embedded-software/i-mx-software/embedded-linux-for-i-mx-applicat...

0 Kudos

907 Views
RogueWarrior65
Contributor I

A followup to my original post:

After studying the flow of things in spi-imx.c, what appears to be happening is that the system is spending a lot of time (60-70 microseconds) after the xfer_done task is flagged as "completed" in spi_imx_isr before wait_for_completion_timeout returns in spi_imx_pio_transfer.

So perhaps the issue isn't really SPI but rather Linux completions.

0 Kudos