Spidev nicht schreiben/Lesen gleichzeitig mit ioctl
Hoffe ich finde etwas Hilfe auch wenn das Problem vielleicht eher hardware-als software-bezogene (wir werden sehen). Ich arbeite auf einem custom-board auf Basis Freescales P1021-Prozessor (ppc, e500v2-Kern). Eine externe Leiterplatte verbunden werden und konfiguriert werden kann über SPI. Die Spezifikationen dieser externen PCB liest, da es erwartet, dass ein 2-byte-Befehl im full-duplex-Modus, und dass nur das Letzte byte wird verwendet, um Daten zu übertragen wieder auf MISO.
Wissen, das ich derzeit die arbeiten zur Vorbereitung, ein paar Stücke von software, test von diesem Gerät. So begann ich mit der gut bekannten spi_test Programm.
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:~#
Das signal zeigt 608 Uhren, und es scheint, es werden nur die Daten in der ersten Hälfte. Ich entscheiden, zu untersuchen und testen Sie es mit loopback - shorcutting MOSI-MISO-Schleifen Sie die Daten in den rx-Puffer. Die Ergebnisse:
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:~#
Dieser Signale zeigt, dass das ganze Telegramm wird wiederholt aus irgendeinem Grund (ich weiß nicht, warum). Jedoch zeigt das Programm die empfangenen Daten in der Konsole korrekt, so kann es sein das spi_test erwartet.
Weiter-ich manipuliere die Muster, die gesendet werden, in dieses Programm herunter auf 2 bytes, (zum simulieren der angeforderte Befehl format ich für Ziel) wie folgt:
#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
Aber ich hatte nicht erwartet, 32bits sind verschoben-zu-SPI-bus - statt 16. Während die ersten beiden bytes MOSI bietet die beiden bytes aus dem tx[] und für die anderen 2 Byte niedrig ist/0. Hier sind die Ergebnisse von der Ausgabe der Konsole und Signale:
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:~#
Und auch wenn ich loopback-MOSI zu MISO keine Daten empfangen (Ausgabe in der Konsole ist immer noch das gleiche empfangen "00 00") :
Spiele ich ein bisschen herum mit allen Parametern und entscheiden, ob Sie das test-Programm zu verwenden, Halbduplex (nur übertragen) Modus:
#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
Als dieser wird kompiliert und ausgeführt, was wie erwartet. SPI_CLK Zyklen 16 mal für 16 bit und MOSI liefern die Daten, wie erwartet. Cosole Ausgabe zeigt keine empfangenen Daten und Signale sind wie erwartet:
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:~#
Tatsächlich scheint es mir, dass zu tun, anstatt 2 bytes full-duplex-übertragung, die ich tun, ein N-byte übertragen, gefolgt von einer N-byte-Empfangs.
Eigentlich sind es zwei Fragen:
- Warum 0xAA, 0x81 und 0x00, 0x00 übertragen?
- Warum (mit loopback) der ursprüngliche code ist in der Lage, um die Daten zurück in rx-Puffer, aber wenn auf 2 reduziert bytes, die keine Daten empfangen?
- Veröffentlichen der Bilder an anderer Stelle und fügen Sie links zu Ihnen in der Antwort - einen höheren rep-Benutzer kann dann Bearbeiten Sie Ihre Antwort auf diese
- Ich check heute, wenn spidev wurden mit SPI_MASTER_HALF_DUPLEX flag aktiviert die Kräfte der spi-Gerät auf Halbduplex.
- SPI_MASTER_HALF_DUPLEX war nicht gesetzt.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Gut, der post ist ruhig überwältigend. Gerade lese ich ein paar Teile und vor kurzem kam in Kontakt mit SPI auf Linux. Jedoch, wie bereits erwähnt, in
https://www.kernel.org/doc/Documentation/spi/spidev
asynchronen lese - /Schreibzugriff nicht verfügbar ist in userspace.
AFAIK schreiben/Lesen ist nur ein wrapper um fcntl. So müssen Sie schreiben Sie Ihren eigenen kernel-Modul zu erreichen async I/O.
Ich weiß, das ist ein sehr Alter thread, aber ich habe mit spidev auf die RT5350 läuft OpenWRT. Ich bin immer genau die gleichen Ergebnisse wie Sie; ich bin einfach nicht in der Lage, eine full-duplex-übertragung geschieht. Lesen Sie die RT5350 Datenblatt scheint es, dass die hardware nur in der Lage zu tun, halb-duplex-SPI-transfers. Jede übertragung wird entweder eine write (output-bytes auf MOSI, Lesen Sie nichts), oder eine lese (Ausgabe Nullen auf MOSI, Lesen MISO).
Ich kann nicht erhalten Sie das Datenblatt für Ihre P1021 chip, aber in Anbetracht der ähnlichkeit der Ergebnisse würde ich sagen, dass seine hardware-SPI-Implementierung in einer ähnlichen Weise.
Dies bedeutet, dass ein kernel-Modul ist nicht die Antwort (ioctl SPI_IOC_MESSAGE schließlich fordert spi_async() sowieso). Der einzige Weg, zu tun, full-duplex-SPI ist mit GPIOs in der software.
RT5350 Referenz:
http://forum.vocore.io/viewtopic.php?f=3&t=72#p233