この問題がソフトウェア関連よりもハードウェア関連である場合でも、何らかの助けが得られることを願っています (後で説明します)。Freescales P1021 プロセッサ (ppc、e500v2 コア) に基づくカスタム ボードに取り組んでいます。外部 PCB が接続され、SPI によって構成できます。この外部 PCB の仕様は、全二重モードで 2 バイトのコマンドを想定し、MISO でデータを転送するために最後のバイトのみが使用されることを読み取ります。
これを知って、私は現在、このデバイスをテストするためのいくつかのソフトウェアの準備に取り組んでいます。そこで、よく知られているspi_testプログラムから始めました。
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:~#
信号は 608 クロックを示しており、前半のデータしかないようです。ループバックを使用して調査およびテストすることにしました-MOSI-MISOループをショートカットして、データをrxバッファーに戻します。結果:
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:~#
この信号は、テレグラム全体が何らかの理由で繰り返されていることを示しています (理由はわかりません)。ただし、プログラムは受信したデータをコンソールに正しく表示するため、spi_test が期待したとおりである可能性があります。
さらに、このプログラムで送信されるパターンを次のように 2 バイトまで操作します (要求されたコマンド形式をシミュレートするため)。
#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
しかし、予想していなかったように、16 ビットではなく 32 ビットが SPI バスにシフトアウトされます。最初の 2 バイトの間、MOSI は tx[] からの両方のバイトを提供し、残りの 2 バイトは Low/0 です。コンソール出力とシグナルの結果は次のとおりです。
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:~#
また、MOSI を MISO にループバックしても、データは受信されません (コンソール出力は「00 00」を受信しても同じです)。
すべてのパラメーターを少しいじって、半二重 (送信のみ) モードを使用するようにテスト プログラムを変更することにしました。
#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
これがコンパイルされて実行されるので、期待どおりです。SPI_CLK は 16 ビットに対して 16 回サイクルし、MOSI は期待どおりにデータを提供します。Cosole の出力には、受信したデータが表示されず、信号は予想どおりです。
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:~#
実際には、2 バイトの全二重転送を行う代わりに、N バイトの送信に続いて N バイトの受信を行うように思えます。
実際には、次の 2 つの質問があります。
- なぜ 0xAA, 0x81 と 0x00, 0x00 が送信されるのですか?
- (ループバックを使用して) 元のコードが rx バッファーにデータを戻すことができるのに、2 バイトに減らすとデータが受信されないのはなぜですか?