October 22, 2020, 08:48:07 am


Have you visited the Allwinner Chipset wiki? - http://linux-sunxi.org/

Getting SPI to work?

Started by mahdichi, August 03, 2013, 01:42:48 am

Previous topic - Next topic


Hi all,

i try getting SPI to work. i use blow link and this is the result:

i compiled kernel v4.3.43 with CONFIG_SPI_SUN4I=y and CONFIG_SPI_SPIDEV=m

in /dev i have spidev0.0 but when i compile spidev_test.c it run with error.

I am hoping someone here test it before and can help me.
thanks in advance.


Unfortunately spi_sunxi have no support for full-duplex, this way spidev0.0 doesn't work. But a patch was submitted: https://groups.google.com/forum/?fromgroups=#!topic/linux-sunxi/yEmBiaJ3LAI



i test this patch.

one other question,
i don't need  full-duplex support, so can i use spi for read from peripheral without this patch?
do you have any example for half-duplex interface. ( i want connect a ADC to cubieboard)

thank for reply.


August 04, 2013, 10:09:17 am #3 Last Edit: August 04, 2013, 10:16:07 am by vinifr
Without the patch, you must set .tx_buf=0 when reading and .rx_buf=0 when writing! You can not use .tx_buf and .rx_buf at same time, as spidev does.

.tx_buf = (unsigned long)tx,
.rx_buf = (unsigned long)rx,

This way, it is necessary to transfer two messages, one for reading and one for writing.

// for writing
struct spi_ioc_transfer tx = {
.tx_buf = (unsigned long)tx,
.rx_buf = 0,
.len = ARRAY_SIZE(tx),
.delay_usecs = delay,
.speed_hz = speed,
.bits_per_word = bits,
// for reading
struct spi_ioc_transfer rx = {
.tx_buf = 0,
.rx_buf = (unsigned long)rx,
.len = ARRAY_SIZE(tx),
.delay_usecs = delay,
.speed_hz = speed,
.bits_per_word = bits,

// writing
ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tx);
// reading
ret = ioctl(fd, SPI_IOC_MESSAGE(1), &rx);

Have you already searched the driver specific to this ADC?


Hi everyone,

My SPI doesn't work. The SPI devices are defined in script.bin. I selected user mode SPI driver in kernel config and got  /dev/spidev0.0 .


spi_used = 1

spi_cs_bitmap = 1

spi_cs0 = port:PI10<3><default><default><default>

spi_sclk = port:PI11<3><default><default><default>

spi_mosi = port:PI12<3><default><default><default>

spi_miso = port:PI13<3><default><default><default>


spi_used = 0

spi_cs_bitmap = 1

spi_cs0 = port:PA00<4><default><default><default>

spi_sclk = port:PA01<4><default><default><default>

spi_mosi = port:PA02<4><default><default><default>

spi_miso = port:PA03<4><default><default><default>


spi_used = 0

spi_cs_bitmap = 1

spi_cs0 = port:PB14<2><default><default><default>

spi_sclk = port:PB15<2><default><default><default>

spi_mosi = port:PB16<2><default><default><default>

spi_miso = port:PB17<2><default><default><default>

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>


spi_used = 0

spi_cs_bitmap = 1

spi_cs0 = port:PA05<3><default><default><default>

spi_sclk = port:PI06<3><default><default><default>

spi_mosi = port:PI07<3><default><default><default>

spi_miso = port:PI08<3><default><default><default>

spi_cs1 = port:PA09<3><default><default><default>


spi_dev_num = 1


modalias = "spidev"

max_speed_hz = 10000000

bus_num = 0

chip_select = 0

mode = 0

full_duplex = 0

manual_cs = 0


Compiling a test program (spidev-test.c) and running it I get logic 1 on the CS pin and absolutely nothing on the SCK pin.

The output from dmesg:

[    1.478782] [spi]: sw spi init !!

[    1.485940] [spi]: Found 1 spi devices in config files

[    1.497356] [spi]: boards num modalias         max_spd_hz       bus_num  cs   mode

[    1.511386] [spi]: 0          spidev           10000000         0        0    0x0

[    1.522303] [spi]: bus num = 0, spi used = 1

[    1.532500] [spi]: source = sdram_pll_p, src_clk = 480000000, mclk 96000000

[    1.545339] sun4i-spi sun4i-spi.0: master is unqueued, this is deprecated

[    1.558988] [spi]: allwinners SoC SPI Driver loaded for Bus SPI-0 with 2 Slaves attached

[    1.574916] [spi]: [spi-0]: driver probe succeed, base f1c05000, irq 10, dma_tx_id 36, dma_rx_id

Please, may be someone here may help me with my problem?


As I said, you can not use .tx_buf and .rx_buf at same time. What software do you use to test SPI0. Is SPI0 available?

Also look for pins conflicting into script.fex. ;)


Hello all. Please help.
How to use SPI in slave mode?


November 19, 2013, 01:57:44 pm #7 Last Edit: November 19, 2013, 02:01:01 pm by dariuszb
I have spi working under userspace, but i must compile it with my custom header:

gcc -I /usr/src/linux*5/include spidev_test.c  -o spidev_test

Ofcourse it give me an warning about using kernel in user mode. I connected a 2MB flash to SPI0. There isn't any loopback. I want to read it's id by sending two bytes (9F FF) to this device. But all i got is:

spi mode: 0
bits per word: 8
max speed: 500000 Hz (500 KHz)


When I use it with -l (loopback parameter everything is allright.

./spidev_test -l
spi mode: 32
bits per word: 8
max speed: 500000 Hz (500 KHz)

00 1F

My questions:
1) How to avoid this warning, or any hints how to compile program without custom kernel?
2) How to use SPI without -l parameter?

Thanks for any answers!


November 20, 2013, 05:39:32 pm #8 Last Edit: November 20, 2013, 05:49:19 pm by dariuszb
I will anwser to one of my questions;)
Quote1) How to avoid this warning, or any hints how to compile program without custom kernel?

Look here:
Changing one file and no more invalid argument error.

File in /usr/include/linux/spi/spidev.h should have a changed struct inside:
struct spi_ioc_transfer {
        __u64           tx_buf;
        __u64           rx_buf;

        __u32           len;
        __u32           speed_hz;

        __u16           delay_usecs;
        __u16           interbyte_usecs;
        __u8            bits_per_word;
        __u8            cs_change;
        __u32           pad;

        /* If the contents of 'struct spi_ioc_transfer' ever change
         * incompatibly, then the ioctl number (currently 0) must change;
         * ioctls with constant size fields get a bit more in the way of
         * error checking than ones (like this) where that field varies.
         * NOTE: struct layout is the same in 64bit and 32bit userspace.

Loopback parameteter can be related with kernel. I think there is an unset bit in config register. Try to check it.