Spidev nie zapisuje / odczytuje jednocześnie za pomocą ioctl

Mam nadzieję znaleźć pomoc, nawet jeśli ten problem może być bardziej sprzętowy niż związany z oprogramowaniem (zobaczymy). Pracuję na niestandardowej płycie opartej na procesorze Freescales P1021 (rdzeń ppc, e500v2). Zewnętrzna płytka drukowana zostanie podłączona i może zostać skonfigurowana przez SPI. Specyfikacje tej zewnętrznej płytki drukowanej odczytuje się, ponieważ oczekuje 2-bajtowego polecenia w trybie pełnego dupleksu i że tylko ostatni bajt jest używany do przesyłania danych z powrotem do MISO.

Wiedząc o tym, pracuję obecnie nad przygotowaniem części oprogramowania do testowania tego urządzenia. Zacząłem więc od dobrze znanegospi_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:~#

Sygnał pokazuje 608 zegarów i wydaje się, że są tylko dane w pierwszej połowie. Postanawiam zbadać i przetestować go za pomocą pętli zwrotnej - wycinanie MOSI-MISO zapętla dane z powrotem do bufora rx. Wyniki:

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:~#

Sygnały te ujawniają, że cały telegram jest powtarzany z dowolnego powodu (nie wiem dlaczego). Jednak program wyświetla poprawnie odebrane dane w konsoli, więc może być tak, jak oczekiwał tego spi_test.

Dalej manipuluję wzorcem, który zostanie wysłany w tym programie do 2 bajtów (aby zasymulować żądany format polecenia, do którego dążę) w ten sposób:

#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

Ale ponieważ nie spodziewałem się, że 32 bity zostaną przesunięte na szynę SPI - zamiast 16. Podczas pierwszych dwóch bajtów MOSI dostarcza oba bajty z tx [], a dla pozostałych 2 bajtów jest niski / 0. Oto wyniki wyjścia i sygnałów konsoli:

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:~#

I nawet jeśli wykonam pętlę zwrotną MOSI do MISO, żadne dane nie zostaną odebrane (dane wyjściowe konsoli są nadal takie same jako „00 00”):

Gram trochę ze wszystkimi parametrami i decyduję się zmienić program testowy, aby użyć trybu półdupleksu (tylko transmisja):

#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

Ponieważ jest to skompilowane i wykonane, rzeczy są jak oczekiwane. Cykle SPI_CLK 16 razy dla 16 bitów i MOSI dostarczają dane zgodnie z oczekiwaniami. Wyjście Cosole pokazuje, że żadne odebrane dane i sygnały nie są podobne do oczekiwanych:

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:~#

Właściwie wydaje mi się, że zamiast wykonywać 2-bajtowy transfer w trybie pełnego dupleksu, wykonuję transmisję N-bajtów, po której następuje odbiór bajtu N.

Właściwie są dwa pytania:

Dlaczego przesyłane są 0xAA, 0x81 i 0x00, 0x00?Dlaczego (przy użyciu pętli zwrotnej) oryginalny kod jest w stanie odzyskać dane w buforach rx, ale jeśli zostanie zredukowany do 2 bajtów, nie zostaną odebrane żadne dane?

questionAnswers(2)

yourAnswerToTheQuestion