SPI in userspace aka spidev

Started by jeroends, February 08, 2013, 10:06:18 AM

Previous topic - Next topic

vinifr

QuoteNotice that the spi test program is just the standard test program, the only difference is that the spi receive buffer is zero'd out. The driver doesn't support full duplex communication (sadly).

Exactly.

You need also change csi_used = 1 to csi_used = 0 because there is a conflict
csi_pck = port:PE00<3> and spi_cs0 = port:PE00<4>

jeroends

the spi cs's are a problem I'm dealing with right now (or going to deal with, cfr my other post). Since I'm not going to use the csi interface (for the moment it is still enabled in my fex file) I'm not seeing a big problem with conflicts.

vinifr

If you do not resolve this conflict, the kernel does not know what you want:
csi_pck or spi_cs0

And others conflicts:

spi_sclk = port:PE01<4><default><default><default>
spi_mosi = port:PE02<4><default><default><default>
spi_miso = port:PE03<4><default><default><default>



csi_ck = port:PE01<3><default><default><default>
csi_hsync = port:PE02<3><default><default><default>
csi_vsync = port:PE03<3><default><default><default>


Please, just test it! ;)

jeroends

For know I didn't noticed problems with it, but I only tried the spi out to a slave (in my case the leds).
Maybe to be sure I'd better put the csi used to zero. But first I'm going to dig deeper into the chip selects because I need more than 2 of them. I know by now the A13 supports 4 of them but they aren't implemented into the driver (only the first 2).

BJFreeman

the conflict I see is you can only have in or out, you can switch directions.
both those use the same pins but different directions.
Fulltimer since 89

Tele

Quote from: jeroends on May 25, 2013, 05:37:37 PM
the spi cs's are a problem I'm dealing with right now (or going to deal with, cfr my other post). Since I'm not going to use the csi interface (for the moment it is still enabled in my fex file) I'm not seeing a big problem with conflicts.

I could be wrong, but I think you forgot an important line:


[spi2_para]
spi_used = 1
spi_cs0 = port:PE00<4><default><default><default>
spi_sclk = port:PE01<4><default><default><default>
spi_mosi = port:PE02<4><default><default><default>
spi_miso = port:PE03<4><default><default><default>


add a line:

[spi2_para]
spi_used = 1
spi_cs_bitmap = 1
spi_cs0 = port:PE00<4><default><default><default>
spi_sclk = port:PE01<4><default><default><default>
spi_mosi = port:PE02<4><default><default><default>
spi_miso = port:PE03<4><default><default><default>



jeroends

correct, if you need the chip selects. The example fex file I gave is no more no less to get some spi output.

oldpenguin

Hi
I was following this thread and others to be able to use spidev, but with no success.

I found that script.bin is missing the following entry
[spi_devices]
spi_dev_num = 1


This is needed by driver spi_sunxi.c when parsing the script.bin file, otherwise the spi_board_info is empty by default.


oldpenguin

Hello all

I had a hard time putting spidev to work.
I have followed many threads and most of them contain useful info, although some info seems a bit outdated, because of recent kernel updates.
Anyway, the following procedure should be enough:

Make sure script.bin contains
[spi2_para]
spi_used = 1
spi_cs_bitmap = 1
spi_cs0 = port:PE00<4><default><default><default>
spi_sclk = port:PE01<4><default><default><default>
spi_mosi = port:PE02<4><default><default><default>
spi_miso = port:PE03<4><default><default><default>

[spi_devices]
spi_dev_num = 1

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


Make sure there are no conflicts on PE00..PE03 pins, namely by deactivating csi (camera) interface:
[csi0_para]
csi_used = 0
...


linux-sunxi/drivers/spi/spi_sunxi.c code will read script.bin and fill the spi_board_info structure, that would otherwise be empty.

Be sure to enable spidev in kernel by setting
Device drivers → SPI support → User mode SPI device driver support as module or compiled inside the kernel.

When the driver is loaded you should see:
root@debian:~# dmesg | grep spi
[    1.187576] [spi]: sw spi init !!
[    1.195933] [spi]: sw spi init fetch spi0 uning configuration failed
[    1.206125] [spi]: Found 1 spi devices in config files
[    1.217520] [spi]: boards num modalias         max_spd_hz       bus_num  cs   mode
[    1.228313] [spi]: spi_board0 irq gpio not used
[    1.239261] [spi]: 0          spidev           1000000          2        0    0x3   
[    1.250157] [spi]: bus num = 2, spi used = 1
[    1.260474] [spi]: source = sdram_pll_p, src_clk = 408000000, mclk 102000000
[    1.273374] sun5i-spi sun5i-spi.2: master is unqueued, this is deprecated
[    1.287005] [spi]: allwinners SoC SPI Driver loaded for Bus SPI-2 with 2 Slaves attached
[    1.301349] [spi]: [spi-2]: driver probe succeed, base f1c17000, irq 12, dma_id 2!


And obviously a device should have been created:
root@debian:~# ls -l /dev/spidev2.0
crw------- 1 root root 153, 0 Nov 13 17:11 /dev/spidev2.0


To test, use the standard spidev_test.c (The version from https://www.kernel.org/doc/Documentation/spi/spidev_test.c)

I had some trouble with this app because the cross-compiler toolchain I am using is missing an entry in spidev.h. The app failed with the following error:
./spidev_test -D/dev/spidev2.0
spi mode: 0
bits per word: 8
max speed: 500000 Hz (500 KHz)
can't send spi message: Invalid argument
Aborted

Can you believe it ? It took many ours to find the solution. I finally found it here https://groups.google.com/forum/#!msg/cubieboard/Mjm8c5umEfU/4msuJgZYQJcJ
Make sure you add the interbyte_usecs definition if missing.
__u16 delay_usecs;
__u16 interbyte_usecs;
__u8 bits_per_word;


root@debian:~# ./spidev_test -D/dev/spidev2.0 -s1000000
spi mode: 0
bits per word: 8
max speed: 1000000 Hz (1000 KHz)
[spi]: /home/asc/projects/olinuxino/a13/sunxi-bsp-20131018/linux-sunxi/drivers/spi/spi_sunxi.c(L1025) [ 3189.553812] [spi]: /home/asc/projects/olinuxino/a13/sunxi-bsp-20131018/linux-sunxi/drivers/spi/spi_sunxi.c(L1025) cpu tx data time out!
cpu tx data time out!

FF FF FF FF FF FF
40 00 00 00 00 95
FF FF FF FF FF FF
FF FF FF FF FF FF
FF FF FF FF FF FF
DE AD BE EF BA AD
F0 0D


Data is correctly output at the MOSI pin (UEXT pin 8 )
The kernel I am using (3.4.61) already has the DMA patch.
With .rx_buf = 0,//(unsigned long)rx, in the source code, the timeout message disappears.

Intend to test with an MCP23S17. Will post when I have something useful.

Hope this info is useful to someone.

oldpenguin

Hello again

I did manage to make MCP23S17 work with olinuxino-a13.
As promised, the source code is here: https://drive.google.com/file/d/0B_6t4W1iA8KqRi1YMXVaQUNjVGc/edit?usp=sharing

The code is based on several sources: spidev.c, spidev_fdx.c and some test code for MCP23S17.
The most important function is spiSendReceive that performs a write or write-and-then-a-read operation. In the former case, the write operation is performed with spi.rx_buf = 0; to avoid the dreadful timeout. The latter is done with a full-duplex structure.

Enjoy

vinifr

Quote from: oldpenguin on November 22, 2013, 08:49:58 PM
Hello again

I did manage to make MCP23S17 work with olinuxino-a13.
As promised, the source code is here: https://drive.google.com/file/d/0B_6t4W1iA8KqRi1YMXVaQUNjVGc/edit?usp=sharing

The code is based on several sources: spidev.c, spidev_fdx.c and some test code for MCP23S17.
The most important function is spiSendReceive that performs a write or write-and-then-a-read operation. In the former case, the write operation is performed with spi.rx_buf = 0; to avoid the dreadful timeout. The latter is done with a full-duplex structure.

Enjoy

Great job!  ;D