8

この問題がソフトウェア関連よりもハードウェア関連である場合でも、何らかの助けが得られることを願っています (後で説明します)。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:~#

写真1

信号は 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:~#

写真2

この信号は、テレグラム全体が何らかの理由で繰り返されていることを示しています (理由はわかりません)。ただし、プログラムは受信したデータをコンソールに正しく表示するため、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:~#

写真3

また、MOSI を MISO にループバックしても、データは受信されません (コンソール出力は「00 00」を受信して​​も同じです)。

写真4

すべてのパラメーターを少しいじって、半二重 (送信のみ) モードを使用するようにテスト プログラムを変更することにしました。

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

写真5

写真6

実際には、2 バイトの全二重転送を行う代わりに、N バイトの送信に続いて N バイトの受信を行うように思えます。

実際には、次の 2 つの質問があります。

  1. なぜ 0xAA, 0x81 と 0x00, 0x00 が送信されるのですか?
  2. (ループバックを使用して) 元のコードが rx バッファーにデータを戻すことができるのに、2 バイトに減らすとデータが受信されないのはなぜですか?
4

2 に答える 2

0

これが非常に古いスレッドであることは知っていますが、OpenWRT を実行している RT5350 で spidev を使用しています。私はあなたとまったく同じ結果を得ています。全二重転送を行うことができません。RT5350 データシートを読むと、ハードウェアは半二重 SPI 転送しかできないようです。各転送は、書き込み (MOSI にバイトを出力し、何も読み取らない) または読み取り (MOSI にゼロを出力し、MISO を読み取る) のいずれかです。

P1021 チップのデータシートは入手できませんが、結果の類似性を考慮すると、そのハードウェア SPI は同様の方法で実装されていると言えます。

これは、カーネルモジュールが答えではないことを意味します (ioctl SPI_IOC_MESSAGE は最終的に spi_async() を呼び出します)。全二重 SPI を実行する唯一の方法は、ソフトウェアで GPIO を使用することです。

RT5350 リファレンス: http://forum.vocore.io/viewtopic.php?f=3&t=72#p233

于 2014-12-04T14:19:35.260 に答える