I hope to find some help even if this issue might be more hardware than software related (we'll see). I'm working on a custom board based on Freescales P1021 processor (ppc, e500v2 core). A external PCB will be connected and could be configured by SPI. The specifications of this external PCB reads as it expects a 2-byte command in full duplex mode and that only the last byte is used to transfer data back on MISO.
Knowing this i currently work to prepare some pieces of software to test this device. So I started with the well known spi_test program.
root@p1021rdb:~# ./spi_test -D /dev/spidev32766.3
spi mode: 0
bits per word: 8
max speed: 500000 Hz (500 KHz)
00 00 00 00 00 00
00 00 00 00 00 00
00 00 00 00 00 00
00 00 00 00 00 00
00 00 00 00 00 00
00 00 00 00 00 00
00 00
root@p1021rdb:~#
The signal shows 608 clocks and it seems there are only data in the first half. I decide to investigate and testing it with loopback - shorcutting MOSI-MISO loops back the data into the rx buffer. The results:
root@p1021rdb:~# ./spi_test -D /dev/spidev32766.3
spi mode: 0
bits per word: 8
max speed: 500000 Hz (500 KHz)
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
root@p1021rdb:~#
This signals reveals, that the whole telegram is repeated for any reason (I don't know why). However, the program shows the received data in the console correctly, so it may be as the spi_test expected it.
Further I manipulate the pattern which will be sent in this program down to 2 bytes (to simulate the requested command format I aim for) like this:
#ifdef ORIG
uint8_t tx[] = {
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0x40, 0x00, 0x00, 0x00, 0x00, 0x95,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xDE, 0xAD, 0xBE, 0xEF, 0xBA, 0xAD,
0xF0, 0x0D,
};
#else
uint8_t tx[] = {
0xAA, 0x81,
};
#endif
But as I did not expect 32bits are shifted out to SPI bus - instead of 16. During the first two bytes MOSI provides the both bytes from the tx[] and for the other 2 bytes it is low/0. Here are the results of console output and signals:
root@p1021rdb:~# ./spi_test_2bytes -D /dev/spidev32766.3
spi mode: 0
bits per word: 8
max speed: 500000 Hz (500 KHz)
00 00
root@p1021rdb:~#
And even if I loopback MOSI to MISO no data is received (console output is still the same receiving "00 00") :
I play around a bit with all parameters and decide to change the test program to use half duplex (transmit only) mode:
#ifdef ORIG
uint8_t tx[] = {
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0x40, 0x00, 0x00, 0x00, 0x00, 0x95,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xDE, 0xAD, 0xBE, 0xEF, 0xBA, 0xAD,
0xF0, 0x0D,
};
#else
uint8_t tx[] = {
0xAA, 0x81,
};
#endif
uint8_t rx[ARRAY_SIZE(tx)] = {0, };
struct spi_ioc_transfer tr = {
.tx_buf = (unsigned long)tx,
#ifdef ORIG
.rx_buf = (unsigned long)rx,
#else
.rx_buf = 0,
#endif
As this is compiled and executed thing are like expected. SPI_CLK cycles 16 times for 16 bits and MOSI provide the data as expected. Cosole output shows no received data and signals are like expected:
root@p1021rdb:~# ./spi_test_2bytes -D /dev/spidev32766.3
spi mode: 0
bits per word: 8
max speed: 500000 Hz (500 KHz)
00 00
root@p1021rdb:~#
Actually it seems to me that instead of doing 2 bytes full duplex transfer I do a N byte transmit followed by an N byte receive.
Actually there are two questions:
Well, the post is quiet overwhelming. I just read a few parts and recently got in touch with SPI on Linux. However, as mentioned in https://www.kernel.org/doc/Documentation/spi/spidev async read/write is not available in userspace. AFAIK read/write is just a wrapper around fcntl. Thus you'll need to write your own kernel module to achieve async I/O.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With