2013-04-09 21 views
6

この問題がソフトウェアに関連するハードウェアよりも多いかもしれないとしても(私たちが参照します)私は、Freescales P1021プロセッサ(ppc、e500v2コア)をベースにしたカスタムボードに取り組んでいます。外部PCBが接続され、SPIによって設定することができます。この外部PCBの仕様は、全二重モードで2バイトのコマンドを期待しており、最後のバイトのみがMISOでデータを戻すのに使用されます。Spidevはioctlを使用して同時に書き込み/読み取りをしません

私は現在、このデバイスをテストするソフトウェアのいくつかを準備しています。だから私はよく知られている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]:~# 

Pic1

信号608のクロックを示し、最初の半分にのみデータが存在すると思われます。私は調査し、ループバックでそれをテストすることにしました。MOSI-MISOループはデータをrxバッファに戻します。結果:

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

Pic2

この信号は、全体の電報が何らかの理由(私はなぜ知らない)のために繰り返されることを、明らかになりました。しかし、プログラムは受信したデータをコンソールに正しく表示しているため、spi_testが期待していたデータと同じである可能性があります。

#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 

をしかし、私は期待していなかったとして、32ビットがシフトされています

は、私は2つのバイトまで、このプログラムに送信されますパターンを操作さらに、このように(私が目指して要求されたコマンドの形式をシミュレートするために)最初の2バイトの間にMOSIはtx []から両方のバイトを提供し、他の2バイトは0/0になります。

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

Pic3

そして、私は何もデータをMISOないようにMOSIループバックても受信される(コンソール出力は依然として同じ受信「00 00」である):ここで、コンソール出力の結果と信号である

Pic4

私はすべてのパラメータを持つビットの周りに再生すると、半二重を使用するようにテストプログラムを変更することを決定した(送信のみ)モード:

#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出力には、データを受け取っ示していないと信号が予想さのようなものです:

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

Pic5

Pic6

実際にではなく2バイトで全二重転送を行うので、私は、その後Nバイトの送信を行うように私には思えますNバイト受信する。0xAAを、0x81と0x00のと、0x00のが送信されるのはなぜ

  1. は、実際には2つの質問がありますか?

  2. なぜ(ループバックを使用して)元のコードはrxバッファにデータを戻すことができますが、2バイトに減らしてもデータは受信されません。
+0

ポスト他の場所の画像との回答でそれらへのリンクを追加 - 高担当者の利用者は、spidevがSPI_MASTER_HALF_DUPLEXフラグ付きでコンパイルされた場合、私は今日チェックします彼らに –

+0

を含めるようにあなたの答えを編集することができますこれによりspiデバイスは半二重になります。 – stede

+0

SPI_MASTER_HALF_DUPLEXが設定されていませんでした。 – stede

答えて

1

まあ、投稿は静かで圧倒的です。私はちょうどいくつかの部分を読んで、最近Linux上でSPIに触れました。ただし、 https://www.kernel.org/doc/Documentation/spi/spidev で説明されているように、非同期読み取り/書き込みはユーザー空間では使用できません。 AFAIK読み取り/書き込みは、fcntlのラッパーです。したがって、非同期I/Oを実現するために独自のカーネルモジュールを作成する必要があります。

+0

この回答は間違っています。 https://www.kernel.org/doc/Documentation/spi/spidevの記事では、特に「ioctl()リクエストを使用して、全二重転送を利用できます...」と表示されています。また、spi-test(https://github.com/KnCMiner/spi-test/blob/master/spi-test.c#L97など)では、そのioctl()が使用されます。 –

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

関連する問題