Spidev nicht gleichzeitig schreiben / lesen mit ioctl

Ich hoffe, Hilfe zu finden, auch wenn dieses Problem mehr mit Hardware als mit Software zusammenhängt (wir werden sehen). Ich arbeite an einem benutzerdefinierten Board, das auf dem Freescales P1021-Prozessor (ppc, e500v2-Core) basiert. Eine externe Platine wird angeschlossen und kann von SPI konfiguriert werden. Die Spezifikationen dieser externen Platine sehen so aus, dass sie einen 2-Byte-Befehl im Vollduplexmodus erwartet und dass nur das letzte Byte für die Rückübertragung von Daten auf MISO verwendet wird.

In diesem Wissen arbeite ich derzeit daran, einige Software-Teile vorzubereiten, um dieses Gerät zu testen. Also habe ich mit dem Bekannten angefangenspi_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, dass es nur Daten in der ersten Hälfte gibt. Ich entscheide mich, es mit Loopback zu untersuchen und zu testen - MOSI-MISO schleift die Daten in den Empfangspuffer zurück. 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:~#

Dieses Signal zeigt an, dass das ganze Telegramm aus irgendeinem Grund wiederholt wird (ich weiß nicht warum). Das Programm zeigt jedoch die empfangenen Daten in der Konsole korrekt an, so dass es möglicherweise so ist, wie es der spi_test erwartet hat.

Weiter manipuliere ich das Muster, das in diesem Programm gesendet wird, auf 2 Bytes (um das gewünschte Befehlsformat zu simulieren, das ich anstrebe) 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 wie ich nicht erwartet hatte, werden 32 Bits auf den SPI-Bus verschoben - anstatt auf 16. Während der ersten zwei Bytes liefert MOSI die beiden Bytes vom tx [] und für die anderen 2 Bytes ist es niedrig / 0. Hier sind die Ergebnisse der Konsolenausgaben 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 selbst wenn ich MOSI nach MISO schleife, werden keine Daten empfangen (Konsolenausgang ist immer noch der gleiche und empfängt "00 00"):

Ich spiele ein bisschen mit allen Parametern herum und entscheide mich, das Testprogramm zu ändern, um den Halbduplex-Modus (nur Senden) zu verwenden:

#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

Da dies kompiliert und ausgeführt wird, sind die Dinge wie erwartet. SPI_CLK zykliert 16-mal für 16 Bits und MOSI liefert die Daten wie erwartet. Der Cosole-Ausgang zeigt keine empfangenen Daten und die 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:~#

Eigentlich scheint es mir, dass ich anstatt einer 2-Byte-Vollduplex-Übertragung eine N-Byte-Übertragung gefolgt von einem N-Byte-Empfang durchführe.

Eigentlich gibt es zwei Fragen:

Warum werden 0xAA, 0x81 und 0x00, 0x00 übertragen?Warum kann der ursprüngliche Code (mithilfe von Loopback) die Daten in Empfangspuffern zurückholen, aber wenn er auf 2 Byte reduziert wird, werden keine Daten empfangen?

Antworten auf die Frage(2)

Ihre Antwort auf die Frage