A20SOM strange SPI problem

Started by Paul Morrison, May 09, 2018, 02:08:34 PM

Previous topic - Next topic

Paul Morrison

Hi, Im trying to read from a device over SPI and I allways get the same error from ioctl: "Invalid argument".
I have tryed different code examples, configurations and so on but allways the same, Im starting to think there must be some different kind of problem with this.

Here are the details:


Board:
A20SOM with Image: a20-SOM_mainline_uboot_GMAC_master_sunxi_kernel_3.4.103_jessie_NAND_rel_10.img

SPI Slave (SCLT3-8):
http://www.st.com/content/ccc/resource/technical/document/datasheet/07/e7/55/6e/7a/92/4b/27/DM00183227.pdf/files/DM00183227.pdf/jcr:content/translations/en.DM00183227.pdf
http://www.st.com/content/ccc/resource/technical/document/application_note/76/2a/94/87/3a/ac/47/bc/CD00215227.pdf/files/CD00215227.pdf/jcr:content/translations/en.CD00215227.pdf


script.fex (SPI section):

[spi0_para]
spi_used = 0
spi_cs_bitmap = 1
spi_cs0 = port:PI10<2><default><default><default>
spi_cs1 = port:PI14<2><default><default><default>
spi_sclk = port:PI11<2><default><default><default>
spi_mosi = port:PI12<2><default><default><default>
spi_miso = port:PI13<2><default><default><default>

[spi1_para]
spi_used = 1
spi_cs_bitmap = 1
spi_cs0 = port:PI16<2><default><default><default>
spi_sclk = port:PI17<2><default><default><default>
spi_mosi = port:PI18<2><default><default><default>
spi_miso = port:PI19<2><default><default><default>

[spi2_para]
spi_used = 1
spi_cs_bitmap = 1
spi_cs0 = port:PC19<3><default><default><default>
spi_sclk = port:PC20<3><default><default><default>
spi_mosi = port:PC21<3><default><default><default>
spi_miso = port:PC22<3><default><default><default>

[spi3_para]
spi_used = 0
spi_cs_bitmap = 1
spi_cs0 = port:PA05<3><default><default><default>
spi_cs1 = port:PA09<3><default><default><default>
spi_sclk = port:PA06<3><default><default><default>
spi_mosi = port:PA07<3><default><default><default>
spi_miso = port:PA08<3><default><default><default>

[spi_devices]
spi_dev_num = 2

[spi_board0]
modalias = "spidev"
max_speed_hz = 1000000
bus_num = 2
chip_select = 0
mode = 3
full_duplex = 0
manual_cs = 0

[spi_board1]
modalias = "spidev"
max_speed_hz = 1000000
bus_num = 1
chip_select = 0
mode = 0
full_duplex = 0
manual_cs = 0


dmesg output (SPI Section):

[   11.466849] [spi-inf] Found 2 spi devices in config files
[   11.495899] [spi-inf] boards num modalias         max_spd_hz       bus_num  cs   mode
[   11.581873] [spi-inf] spi_board0 irq gpio not used
[   11.615292] [spi-inf] 0          spidev           1000000          2        0    0x3
[   11.664957] [spi-inf] spi_board1 irq gpio not used
[   11.736732] [spi-inf] 1          spidev           1000000          1        0    0x0
[   11.826811] [spi-inf] sun7i_spi_probe: spi1 dma type: normal
[   11.868506] [spi-inf] bus num = 1, spi used = 1
[   11.901536] [spi-inf] sun7i_spi_probe: spi1 cs bitmap: 0x1
[   11.953135] [spi-inf] sun7i_spi_set_mclk: spi1 source = sdram_pll_p, src_clk = 384000000, mclk 96000000
[   12.042933] sun7i-spi sun7i-spi.1: master is unqueued, this is deprecated
[   12.092349] [spi-inf] sun7i_spi_probe: reuuimlla's SoC SPI Driver loaded for Bus SPI1 with 2 Slaves at most
[   12.117001] [spi-inf] sun7i_spi_probe: spi1 driver probe succeed, base f0b9a000, irq 43, dma_id_rx 25, dma_id_tx 25
[   12.138898] [spi-inf] sun7i_spi_probe: spi2 dma type: normal
[   12.159132] [spi-inf] bus num = 2, spi used = 1
[   12.168310] [spi-inf] sun7i_spi_probe: spi2 cs bitmap: 0x1
[   12.191531] [spi-inf] sun7i_spi_set_mclk: spi2 source = sdram_pll_p, src_clk = 384000000, mclk 96000000
[   12.214314] sun7i-spi sun7i-spi.2: master is unqueued, this is deprecated
[   12.232339] [spi-inf] sun7i_spi_probe: reuuimlla's SoC SPI Driver loaded for Bus SPI2 with 2 Slaves at most
[   12.253089] [spi-inf] sun7i_spi_probe: spi2 driver probe succeed, base f0c12000, irq 44, dma_id_rx 26, dma_id_tx 26



Used example:

#include <stdint.h>
#include <errno.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <getopt.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/types.h>
#include <linux/spi/spidev.h>

static const char *device = "/dev/spidev1.0";
static uint8_t mode = 0;
static uint8_t bits = 8;
static uint32_t speed = 1000000;

static void pabort(const char *s)
{
        perror(s);
        abort();
}

int main(int argc, char *argv[])
{
        int ret = 0, i = 0;
        int fd;
        struct spi_ioc_transfer read_tr;
        uint8_t rx[2] = {0x00, 0x00};

        fd = open(device, O_RDWR);
        if (fd < 0)
                pabort("can't open device");

        ret = ioctl(fd, SPI_IOC_WR_MODE, &mode);
        if (ret == -1)
                pabort("can't set spi mode");

        ret = ioctl(fd, SPI_IOC_RD_MODE, &mode);
        if (ret == -1)
                pabort("can't get spi mode");

        ret = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits);
        if (ret == -1)
                pabort("can't set bits per word");

        ret = ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits);
        if (ret == -1)
                pabort("can't get bits per word");

        ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed);
        if (ret == -1)
                pabort("can't set max speed hz");

        ret = ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed);
        if (ret == -1)
                pabort("can't get max speed hz");

        printf("device: %s\n", device);
        printf("spi mode: %d\n", mode);
        printf("bits per word: %d\n", bits);
        printf("max speed: %d Hz (%d KHz)\n", speed, speed/1000);

        memset(&read_tr, 0, sizeof(read_tr));
        read_tr.tx_buf = 0; //half duplex
        read_tr.rx_buf = (unsigned long)rx;
        read_tr.len = sizeof(rx);
        read_tr.speed_hz = speed;
        read_tr.bits_per_word = bits;

        ret = ioctl(fd, SPI_IOC_MESSAGE(1), &read_tr);
        if (ret < 0)
                pabort("can't send spi message");
        printf("%.2X %.2X\n", rx[0], rx[1]);

        close(fd);

        return ret;
}


Output:

device: /dev/spidev1.0
spi mode: 0
bits per word: 8
max speed: 1000000 Hz (1000 KHz)
can't send spi message: Invalid argument
Aborted


I have tried as well with the well known spidev_test (https://github.com/torvalds/linux/blob/master/tools/spi/spidev_test.c)
./spidev_test -D /dev/spidev1.0

Output:

spi mode: 0x0
bits per word: 8
max speed: 500000 Hz (500 KHz)
can't send spi message: Invalid argument
Aborted





Many thanks for considering my request.


LubOlimex

For the test commands try with flag -l as shown here: https://www.olimex.com/forum/index.php?topic=5354.0

Also for the SPI you should try with the Python package: https://pypi.org/project/pyA20EVB/ (there is example at the bottom of the page for the SPI).
Technical support and documentation manager at Olimex

Paul Morrison

Thanks for your reply.

I have tried over armbian mainline 4.14 and the same examples works well except spidev_test when executed with argument -l, whats its fine for now