Why transfer function in linux official spidev_test.c can only send one time data even it is called in a while loop when test Naon dev kit spi function?

Hi guys,

When test spi function on Nano kit, we change the official spidev_test tool to test it. And it work fine as below.
.

But when we want to send the same data many times, so we called the “transfer(fd, default_tx, default_rx, sizeof(default_tx));” in a loop. when the logical analyzer finished catching one time wave, I mean the wave generated by the first call of the transfer function, it stop normally just like the the program only call one time transfer function.

For simplicity, I just use two transfer function in the main function of spidev_test tool program as below code section.

int main(int argc, char *argv[])
{
...
transfer(fd, default_tx, default_rx, sizeof(default_tx));
transfer(fd, default_tx, default_rx, sizeof(default_tx));
...
}

And I add some printf log into the transfer function. The log below shows the above transfer functions run the same codes. But why the second transfer function can’t output data through MOSI?

garret:~$ sudo ./spidev_test -D /dev/spidev0.0 -v -p "j"
    spi mode: 0x0
    bits per word: 8
    max speed: 4000000 Hz (4000 KHz)
    Function:[main]--LineNum:[384]: else branch 1
    Function:[transfer]--LineNum:[145]
    Function:[transfer]--LineNum:[158]
    Function:[transfer]--LineNum:[168]
    TX | 34 __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __  | 4
    Function:[transfer]--LineNum:[174]
    RX | 00 __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __  | .
    -----------
    Function:[main]--LineNum:[394]: else branch 2
    Function:[transfer]--LineNum:[145]
    Function:[transfer]--LineNum:[158]
    Function:[transfer]--LineNum:[168]
    TX | 34 __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __  | 4
    Function:[transfer]--LineNum:[174]
    RX | 00 __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __  | .

The program just call SPI_IOC_MESSAGE(1) several times, still the MOSI just output the first time data.

main((){
    struct spi_ioc_transfer tr = {
            .tx_buf = (unsigned long)(&tx),
            .rx_buf = (unsigned long)(&tx),
            .len = 1,
            .delay_usecs = 10,
            .speed_hz = 4000000,
            .bits_per_word = 8,
        };
    int i = 0;
    for (;i < 10; i++)
    {
        ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);
    }
}

@garretzon
What if have a delay in each message?
Does the behavior any different with any others platform?
Could you have add some debug message at spi kernel driver to check.

Hi ShaneCCC,

We test with a 0.1s, 0.5s, 1.0s and 1.5s delay respectively, no data output MOSI except the first transfer function can be caught by logical analyzer.

@garretzou

How can I add a image into my comments just like you? Thanks!

Hello NautilusZZ,

  1. upload your local image to a server like github.

  2. copy the image link like “http.xxx.xxx/img” on the server.

  3. click the image tool on the top right corner of the editor of devtalk.nvidia, then you will get a “[img][/img]”.

  4. paste the image link in the middle of “[img][/img]”.

Could you add some message to the spidev.c to check the package is down to this level.

@garretzou Try the attached version of spidev_test.c and see if it helps.

I did some work on it to add features:

  • The input file will be transferred in its entirety
  • You can pipe input to the program
  • The output is to stdout unless you use the "-o" option. Send it to /dev/null if you don't need it.
  • The "-c" option causes the data read from the SPI device to be compared with what was written (you need a physical loop of MOSI to MISO)
  • The "-f" option causes the input to be repeatedly sent. Only works for files, not stdin.
  • The "-k" option sets the transfer buffer size. Defaults to 1 byte.
  • Example to send the letter “U” once at 5MHz, 1 byte per transfer, discard output and compare sent to received.

    echo -n "U" | ./spidev_test -D /dev/spidev0.0 -s 5000000 -k 1 -o /dev/null -c
    

    Example to continuously send the letter “U” at 5MHz, 1 byte per transfer, discard output and compare sent to received.

    ( while true ; do echo -n "U" ; done; ) | ./spidev_test -D /dev/spidev0.0 -s 5000000 -k 1 -o /dev/null -c
    

    Example to continuously send the file “abc.txt” at 5MHz, 8 byte per transfer, discard output and compare sent to received.

    ./spidev_test -D /dev/spidev0.0 -i abc.txt -s 5000000 -k 8 -o /dev/null -c -f
    

    spidev_test.c (8.91 KB)