Hi,
In my project I need to use full duplex communication with RF module, so I started looking how to use SPI.
I didn't test it on image distributed by Olimex, because I need to use custom kernel.
At first we need to download kernel source, for example:
git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
Next we should perform initial kernel configuration for A20:
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- sun7i_defconfig
Now we need to patch our kernel in few steps:
1. create file linux-sunxi/drivers/spi/spi-sun7i.c with this content
spi-sun7i.c (https://drive.google.com/file/d/0By-R7wZiBUI4SWI1VDRCQjNxaE0/view?usp=sharing/)2. To linux-sunxi/drivers/spi/Makefile at the end add:
obj-$(CONFIG_SPI_SUN7I) += spi-sun7i.o
3. Update linux-sunxi/drivers/spi/Kconfig:
config SPI_SUN7I
tristate "SUN7I SPI Controller"
depends on ARCH_SUN7I
help
Allwinner Soc SPI controller,present on SUN7I chips.
config SUN7I_SPI_NDMA
bool "SUN7I SPI Normal DMA mode select"
depends on SPI_SUN7I
help
This selects SPI DMA mode with DMA transfer
Y select NDMA mode and N select DDMA mode
4. Update kernel config
CONFIG_SPI_SUN7I=y
CONFIG_SUN7I_SPI_NDMA=y
It's important to have hard compiled spidev in kernel.
Now we can compile kernel with command:
make -j4 ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- uImage modules
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- INSTALL_MOD_PATH=output modules_install
Also we need to update FEX file, important is to set full_duplex to 1, example:
[spi_board3]
modalias = "spidev"
max_speed_hz = 12000000
bus_num = 3
chip_select = 0
mode = 0
full_duplex = 1
manual_cs = 0
Now we can test install kernel, modules and then test them. For test I used
pyA20 (https://pypi.python.org/pypi/pyA20/) and kernel/linux-sunxi/Documentation/spi/spidev_fdx.c
To get working correct spi, we also need to update /usr/include/linux/spi/spidev.h on our board with:
struct spi_ioc_transfer {
__u64 tx_buf;
__u64 rx_buf;
__u32 len;
__u32 speed_hz;
__u16 interbyte_usecs;
__u16 delay_usecs;
__u8 bits_per_word;
__u8 cs_change;
__u32 pad;
}
Test results:pyA20 from Olimex didn't correct support full duplex.
Here are commend which I used to test SPI in python
>>> from pyA20 import spi
>>> spi.open("/dev/spidev1.0")
>>> spi.xfer([0x01, 0x02], 2)
[14, 8]
Here are results
(https://lh3.googleusercontent.com/-WVNMxJCYZ-s/VEam68EZ60I/AAAAAAAAAtA/mD4eDLQJ6G8/w1597-h535-no/pya20_xfer.png)
index | start-time | end-time | event? | | MOSI data | MISO data |
0 | 20,00 ns | 20,00 ns | true | CS_LOW | | |
1 | 14,60 μs | 14,60 μs | false | | 0 | |
2 | 14,60 μs | 14,60 μs | false | | | 14 |
3 | 35,94 μs | 35,94 μs | false | | 0 | |
4 | 35,94 μs | 35,94 μs | false | | | 8 |
5 | 115,92 μs | 115,92 μs | false | | 1 | |
6 | 115,92 μs | 115,92 μs | false | | | 8 |
7 | 137,26 μs | 137,26 μs | false | | 2 | |
8 | 137,26 μs | 137,26 μs | false | | | 8 |
9 | 418,80 μs | 418,80 μs | true | CS_HIGH | | |
Problem is that this function first read SPI and then send data, and didn't return read data during sending data.
spidev_fdx is working better but not enough good for me, here are results.
Command:
./spidev_fdx -v -m1 -r2 /dev/spidev1.0
/dev/spidev1.0: spi mode 0, 8 bits per word, 100000 Hz max
response( 1, 2): 08
read( 2, 2): 0e 08,
(https://lh4.googleusercontent.com/-X_7UNIDjAeI/VEam7KPbyMI/AAAAAAAAAtE/nHAWgPtJ_lU/w1597-h535-no/spidev_fdx.png)
index | start-time | end-time | event? | | MOSI data | MISO data |
0 | 20,00 ns | 20,00 ns | true | CS_LOW | | |
1 | 13,98 μs | 13,98 μs | false | | 0 | |
2 | 13,98 μs | 13,98 μs | false | | | 14 |
3 | 155,16 μs | 155,16 μs | false | | 0 | |
4 | 155,16 μs | 155,16 μs | false | | | 8 |
5 | 259,48 μs | 259,48 μs | true | CS_HIGH | | |
6 | 430,06 μs | 430,06 μs | true | CS_LOW | | |
7 | 443,22 μs | 443,22 μs | false | | 0 | |
8 | 443,22 μs | 443,22 μs | false | | | 14 |
9 | 464,54 μs | 464,54 μs | false | | 0 | |
10 | 464,54 μs | 464,54 μs | false | | | 8 |
11 | 513,76 μs | 513,76 μs | true | CS_HIGH | | |
References:Kernel compile (http://linux-sunxi.org/Linux_Kernel/)
Fex edit (http://linux-sunxi.org/Fex_Guide#spi_configuration/)
Orginal information source (http://will-tm.com/spi-on-the-cubieboard2/)
Feedback is expected ;)
Quote from: Cosik on October 21, 2014, 09:48:51 PM
Or you suggest to perform test on loop back?
Can be interesting too but that was only a question on how you perform your test :-)