2013-04-09 62 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個時鐘,它似乎有僅在第一半數據。我決定用loopback進行調查和測試 - 將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預期的。

另外我操縱,這將在該程序被向下發送到2個字節的模式(模擬請求的命令格式I瞄準)所示:

#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位被移位輸出到SPI總線 - 而不是16個。在前兩個字節中,MOSI提供來自tx []的兩個字節,而另外兩個字節則爲低/ 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

即使我回環MOSI到MISO沒有數據被接收(控制檯輸出仍是相同的接收「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字節接收。

其實有兩個問題:

  1. 爲什麼和0xAA,0x81表示和0×00,0×00傳輸?
  2. 爲什麼(使用回送)原始代碼能夠將數據返回到rx緩衝區,但是如果減少到2個字節,則不會接收到數據?
+0

郵政別處的圖像和鏈接添加到他們的答案 - 那麼高代表用戶可以編輯您的答案,包括他們 – 2013-04-09 16:51:42

+0

我會檢查今天,如果spidev與SPI_MASTER_HALF_DUPLEX標誌編譯啓用,強制spi設備半雙工。 – stede 2013-04-11 05:47:09

+0

SPI_MASTER_HALF_DUPLEX未設置。 – stede 2013-04-11 14:47:31

回答

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()。 – 2017-06-18 11:36:03

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