Mam nadzieję, że znajdę pomoc, nawet jeśli ten problem może być więcej sprzętu niż oprogramowania (zobaczymy). Pracuję na niestandardowej płycie opartej na procesorze Freescales P1021 (ppc, rdzeń e500v2). Zewnętrzna płytka PCB zostanie podłączona i może być skonfigurowana przez SPI. Specyfikacje tej zewnętrznej płytki drukowanej są odczytywane w oczekiwaniu na 2-bajtowe polecenie w trybie pełnego dupleksu i że tylko ostatni bajt jest używany do przesyłania danych z powrotem do MISO.Spidev nie pisze/czyta jednocześnie, używając ioctl
Wiedząc, że obecnie pracuję nad przygotowaniem niektórych programów do przetestowania tego urządzenia. Zacząłem więc od znanego programu spi_test.
[email protected]:~# ./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
[email protected]:~#
Sygnał pokazuje 608 zegary i wydaje się, że są tylko dane w pierwszej połowie. Decyduję się zbadać i przetestować go z pętlą zwrotną - shorcutting MOSI-MISO zapętla dane do bufora rx. Wyniki:
[email protected]:~# ./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
[email protected]:~#
Te sygnały ujawnia, że cała telegram jest powtarzany z jakiegokolwiek powodu (nie wiem dlaczego). Jednak program poprawnie pokazuje odebrane dane w konsoli, więc może być tak, jak spi_test tego oczekiwał.
Dalsze manipulować wzór, który zostanie wysłany w tym programie w dół do 2 bajtów (do symulacji żądany format polecenia Dążę do) tak:
#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 nie spodziewałem się 32-bitowego są przesunięte do magistrali 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 konsoli i sygnały:
[email protected]:~# ./spi_test_2bytes -D /dev/spidev32766.3
spi mode: 0
bits per word: 8
max speed: 500000 Hz (500 KHz)
00 00
[email protected]:~#
i odbierana nawet gdybym LOOPBACK MOSI do miso żadnych danych (wyjście konsola jest wciąż ten sam odbierający „00 00”):
trybGram się trochę ze wszystkimi parametrami i podjąć decyzję o zmianie programu testowego użyć pół dupleksu (transmitować tylko):
#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 oczekiwano. SPI_CLK wykonuje 16 cykli dla 16 bitów, a MOSI dostarcza danych zgodnie z oczekiwaniami. Wyjście Cosole nie wykazuje otrzymane dane i sygnały są jak oczekiwano:
[email protected]:~# ./spi_test_2bytes -D /dev/spidev32766.3
spi mode: 0
bits per word: 8
max speed: 500000 Hz (500 KHz)
00 00
[email protected]:~#
Właściwie wydaje mi się, że zamiast robić 2 bajty pełne przeniesienie dupleksu robię nadawczo N bajtowy przez N-bajtowy odbiór.
Właściwie istnieją dwa pytania:
- Dlaczego 0xAA, 0x81 i 0x00, 0x00 jest transmitowane?
- Dlaczego (używając sprzężenia zwrotnego) oryginalny kod jest w stanie odzyskać dane w buforze rx, ale jeśli zostanie zredukowany do 2 bajtów, żadne dane nie zostaną odebrane?
opublikować zdjęcia gdzie indziej i dodać linki do nich w odpowiedzi - użytkownik wyższe rep można następnie edytować swoją odpowiedź na to im –
będę sprawdzał dziś jeśli spidev został skompilowany z SPI_MASTER_HALF_DUPLEX flagą włączone, które zmusza urządzenie SPI do półdupleksu. – stede
SPI_MASTER_HALF_DUPLEX nie został ustawiony. – stede