2015-08-19 32 views
0

我正在開發具有STM32F1 MCU的自定義板的應用程序,該應用程序需要能夠從意外的數據損壞中恢復。使用STM32F1 MCU處理損壞的SPI數據

數據流如下: 主設備(一臺Linux機器)發送一個請求給解析消息並準備發送回覆的從站。然後主人讀回答。交換是快速的(@ 18MHz)並且執行是這樣的:

if (::ioctl(_fd, SPI_IOC_MESSAGE(2), &transaction) < 0) { 
    warn("message not sent"); 
    return false; 
} 

這兩條消息之間的延遲是~50us。消息長度是固定的。

在STM端,我使用了一個DMA驅動的SPI驅動程序,這個驅動程序以我將在下面寫的方式實現。我使用SPI2 @ 36MHz(HSE @ 24 MHz; AHB @ 72MHz; APB1 @ 36MHz)的SPI2。

SPI配置爲通過在RXNEIE(CR2-> RXDMAEN)上發出DMA請求來讀取消息(固定長度!)。消息處理完成後,答案將通過DMA1(CR2-> TXDMAEN)傳輸。

一切都像一個魅力,直到我干涉莫名其妙。我試圖恢復的場景是在傳輸時拔出SCLK線。

我正努力從此恢復。我將闡明我的想法,因爲我不確定錯誤在哪裏。

DMA配置爲處理固定長度的消息。這就是爲什麼當我以某種方式干涉時,DMA控制器一直等待,直到整個消息被處理並且緩衝區被移位。假設,當SCLK突然消失時,我收到了三分之一的信息。 DMA將等待剩下的三分之二。主人繼續發送請求。因此,在SCLK回來之後,下一個消息的2/3將被放置在緩衝區中。發出DMA中斷,但最後一條消息的剩餘路徑丟失。它肯定會丟失,但我可以檢測到使用ERRIE標誌在要設置的OVR標誌上發出中斷。

我試過處理那個中斷,但無濟於事。

我現在檢查中斷處理程序是否設置了BSY標誌(該軌跡正在通過SPI控制器進行處理)。如果它被設置,我殺死DMA(已經開始處理下一條消息)並且保留OVR標誌。一旦BSY被清除,我清除OVR並重置DMA接收。

這沒什麼幫助。

我可能使用的另一個選項是一個專用定時器,它在SCLK的上升沿得到復位(AN3109應用筆記啓發式解決方案)。這樣我可以實現DMA超時。如果我只有部分消息,如果SCLK長時間不在我們身邊,我可以在定時器溢出時產生一箇中斷。雖然這個解決方案有問題。

我知道描述是模糊的,但我已經盡力了,希望有更深入洞察力的人可以幫助。

+0

我不知道爲什麼你的時鐘信號會突然消失,但你的設計本身似乎有問題。似乎你的基本假設是你的奴隸將在50us完成工作,你的主人會要求回覆。那實際上是行不通的。你需要在較短的時間內輪詢你的奴隸,並檢查奴隸是否已完成。或者,您應該使用雙主模式,因爲通常奴隸應該是完全由主人驅動的消費者,並且在您的情況下,它不適合。 – HuStmpHrrr

+0

SPI使用'SS'作爲幀同步。你需要超時。 – Olaf

+0

在DMA中斷處理程序中,我複製已填充的數組並設置DMA以傳輸它。這很重要嗎?奴隸總是準備好。如果主設備在事務過程中重啓,時鐘可以消失。所以這是可能的,不是嗎? – staroselskii

回答

0

在CS線上安裝中斷處理程序。在上升趨勢中,如果傳輸尚未完成,則放棄所有內容並通過DMA重新開始。使用SPI_CR1中的SSI位,在上升沿設置,在下降沿清零。