注:本文針對xilinx的zynqMP系列芯片講解SPI驅動
一、引言
SPI接口是Motorola 首先提出的全雙工三線同步串行外圍接口,採用主從模式(Master Slave)架構。支持多slave模式應用,一般僅支持單Master。時鐘由Master控制,在時鐘移位脈衝下,數據按位傳輸,高位在前,低位在後(MSB first)。SPI接口有2根單向數據線,爲全雙工通信,目前應用中的數據速率可達幾Mbps的水平。
二、SPI總線結構
三、SPI接口
SPI接口共有4根信號線,分別是:設備選擇線、時鐘線、串行輸出數據線、串行輸入數據線。
MOSI |
主器件數據輸出,從器件數據輸入 |
MISO |
主器件數據輸入,從器件數據輸出 |
SCLK |
時鐘信號,由主器件產生 |
SS |
從器件使能信號,由主器件控制 |
四、SPI工作原理
SPI接口在內部硬件實際上是兩個簡單的移位寄存器,傳輸的數據爲8位,在主器件產生的從器件使能信號和移位脈衝下,按位傳輸,高位在前,低位在後。如下圖所示,在SCLK的下降沿上數據改變,上升沿一位數據被存入移位寄存器。
在一個SPI時鐘週期內,會完成如下操作:
- 主機通過MOSI線發送1位數據,從機通過該線讀取這1位數據;
- 從機通過MISO線發送1位數據,主機通過該線讀取這1位數據。這是通過移位寄存器來實現的。如下圖所示,主機和從機各有一個移位寄存器,且二者連接成環。隨着時鐘脈衝,數據按照從高位到低位的方式依次移出主機寄存器和從機寄存器,並且依次移入從機寄存器和主機寄存器。當寄存器中的內容全部移出時,相當於完成了兩個寄存器內容的交換。
注意:SPI控制器工作時,主機每發送一個字節,從機在收到主機的一個字節後,從機將緩衝區中的一個字節也放到MISO上,傳輸給主機,因此不管是主機對從機進行讀操作,還是寫操作,都需要主機來向MOSI總線上寫數據,而讀操作和寫操作的區別就在於,寫操作是直接往MOSI總線上寫就行了,對於同時從MISO上返回的數據直接丟掉,而讀操作是往MOSI上寫數據,同時收取MISO上返回的數據。SPI的這種工作方式決定了其收發是同時的,所以效率比232/422/485這種串口高。
五、SPI接口的優缺點
- 優點:
- 支持全雙工操作;
- 操作簡單;
- 數據傳輸速率較高(相對的)。
- 缺點:
- 多個spi設備需要佔用主機較多的管腳(每個從機都需要一根片選線);
- 只支持單個主機;
- 沒有指定的流控制,沒有應答機制確認是否接收到數據。
六、SPI工作模式
SPI有四種工作模式,具體由CPOL(Clock Polarity 時鐘極性),CPHA(Clock Phase時鐘相位)決定
MODE0 | CPOL=0,CPHA=0 |
MODE1 | CPOL=0,CPHA=1 |
MODE2 | CPOL=1,CPHA=0 |
MODE3 | CPOL=1,CPHA=1 |
- 當CPOL爲0時,空閒的時候SCLK電平是低電平;
- 當CPOL爲1時,空閒的時候SCLK電平是高電平;
- 當CPHA爲0時,採集數據發生在時鐘週期的前邊緣(第一個邊緣,可能是上升緣也可能是下降緣,由CPOL決定),這同時意味着輸出數據發生在後邊緣;
- 當CPHA爲1時,採集數據發生在時鐘週期的後邊緣(第二個邊緣,可能是上升緣也可能是下降緣,由CPOL決定),這同時意味着輸出數據發生在前邊緣;
摘抄一張網上的圖:
我們編寫spi接口的設備驅動程序的時候,最需要關心的就是spi控制器的部分是spi設備採用的是那種模式,確定模式後,我們得將spi控制器配置成一樣的模式才能正常工作。所以說如何選擇SPI控制器的工作模式,是根據從設備的工作模式來定的,一般從設備是FLASH、eeprom之類的存儲介質,其工作模式是在出廠時就確定的,所以只能通過修改SPI控制器的工作模式,來適應從設備,從而實現SPI通信流程。
二、zynqMP芯片的SPI控制器
- 介紹
SPI總線控制器支持與各種外設的通信,例如內存,溫度傳感器,壓力傳感器,模擬轉換器,實時時鐘,顯示器,以及任何支持串行模式的SD卡。SPI控制器可以在主機模式、從機模式或多主機模式這三種模式下工作。在ZYNQMP系列芯片中包含有兩個SPI實例控制器,兩個控制器完全相同,並都可以由軟件獨立控制驅動。這兩個SPI控制器可以同時操作,以下討論適用於兩個SPI控制器的實例。
-
特徵
-
全雙工操作可同時接收和發送。
-
主機或從機SPI操作模式。
-
四線bus:數據RX,數據TX,時鐘和片選。
-
支持多主機環境:如果不止一個主機被探測到,則指出錯誤情況
-
內存映射的APB接口。
-
具有獨立的發送和接收FIFO的緩衝操作:APB可以讀取
RXFIFO以及寫入TXFIFO。
-
在主模式下,可以從三個獨立的時鐘源之一來產生SPI時鐘
-
可編程的主模式時鐘頻率。
-
具有可編程極性的串行時鐘。
-
可編程的傳輸格式。
-
通過DUT輸出或通過軟件訪問寄存器的方式獲得FIFO級別。
-
FIFO級別狀態可以通過軟件查詢或可以由中斷驅動。
-
可編程中斷產生。
-
功能說明
圖23-1顯示了SPI控制器框圖
3.1 FIFOs
RX和TX FIFO的深度均爲128字節。 軟件使用寄存器映射的數據端口寄存器來讀取和寫入這些FIFO。 FIFO橋接兩個時鐘域, APB接口(LPD_LSBUS_CLK)和控制器的SPI_REF_CLK。 軟件在APB時鐘域中寫入TXFIFO,控制器讀取SPI_Ref_Clk域中的TXFIFO。控制器在SPI_Ref_Clk域中將RXFIFO填滿,然後軟件會在APB時鐘域讀取RXFIFO。
3.1.1接收FIFO
如果控制器嘗試將數據發送到已滿的RXFIFO中,則內容將丟失,並且粘性溢出標誌被置位。如果沒有數據添加到已滿的RXFIFO。 軟件將寫1來清除[RX_OVERFLOW]位。
3.1.2 發送FIFO
如果軟件嘗試將數據寫入已滿的TXFIFO,則該寫入會被忽略,沒有數據可以添加到已滿的TXFIFO。[TX_FIFO_full]位被置位,直到讀取TXFIFO並TXFIFO不再滿。 如果TXFIFO溢出,則 [RX_OVERFLOW]位置1。
3.2 時鐘
SPI控制器從PS時鐘子系統接收兩個時鐘輸入,在從模式下,時鐘來自連接的SPI主設備的SCLK時鐘。
-
SPI_REF_CLK時鐘操作主機模式下SCLK控制器和輸入的波特率分頻器。
-
LPD_LSBUS_CLK時鐘操作APB從接口來訪問寄存器。
這些時鐘彼此異步運行。 時鐘生成在第37章PS Clock子系統中進行了介紹,時鐘頻率規格在數據手冊中定義。
3.2.1 主模式SCLK
在主機模式下,I/O信號由控制器產生的SCLK來計時,從SPI_REF_CLK中使用spi.Config [BAUD_RATE_DIV] 字段使用波特率分頻器。 波特率分頻器的範圍從最小4到最大256以二進制步長(即除以4、8、16,... 256)。 從機片選選擇輸入引腳必須被SCLK輸入同步驅動。
3.2.2 從模式SCLK
在從模式下,控制器採樣MOSI和SS I/O信號並驅動MISO使用來自所連接主機的SCLK發送信號。 輸入信號同步到SPI_REF_CLK並由控制器處理。
注意:爲了正確檢測SPI總線上字傳輸的開始,SPI_REF_CLK頻率應至少爲控制器SCLK頻率的2倍。
3.3復位
控制器由PS復位子系統單獨復位,也可以由系統或POR復位復位。
-
SPI控制器操作模式
SPI控制器以三種模式運行:
-
主機模式
-
多主機模式
-
從機模式
在多主機模式下,當控制器未處在活躍狀態,且檢測競爭錯誤機制被使能時,控制器的輸出信號爲三態。 復位SPI使能位可以立即將輸出設置爲三態。一箇中斷狀態寄存器可以指示模式錯誤。
在從模式下,控制器從主設備接收串行時鐘,並使用SPI_REF_CLK時鐘來同步數據捕獲。 從機片選(SS)信號被置位,控制器被使能,從機模式包含可編程起始檢測機制。讀和寫FIFO在SPI I/O接口和接口之間提供緩衝區,軟件可以通過APB從機接口爲控制器提供服務。 FIFO用於從機和主機I/O模式。
4.1 主機模式
在主機模式下,SPI I/O接口可以將數據傳輸到從機或初始化一個發送操作來通過從機接收數據。 在這種模式下,通過支持SPI多主機模式的選項,控制器驅動串行時鐘和從機片選。串行時鐘派生來自PS時鐘子系統。
控制器從三個從機選擇線之一來選擇一個從設備。 如果超過三個從屬設備需要連接到主設備,可以添加一個MIO或EMIO接口上的3/8譯碼器。使用spi.Config [PERI_SEL]位來啓用多路複用器。
控制器使用多達三個獨立的從機片選輸出信號來初始化消息,可以從外部擴展。 控制器通過將字節寫入32位讀/寫數據端口寄存器實現讀取和寫入從機設備。
4.2 多主機模式
對於多主機模式,控制器被編程爲主機模式[MODE_SEL],同時被初始化爲在任何從機選擇線上啓動傳輸。 當軟件準備好啓動傳輸時,它使用[SPI_EN]位使能控制器。傳輸完成後,軟件會禁用控制器。 外部主機無法選擇控制器當控制器處於主模式時。
控制器通過監視漏極開路從機片選來檢測總線上的另一個主機信號(低電平有效)。 通過[Modefail_gen_en]來啓用檢測機制。當控制器檢測到另一個主機時,它將設置spi.ISR [MODE_FAIL]中斷狀態位並清除spi.Enable [SPI_EN]控制位。軟件可以接收[MODE_FAIL]中斷,以便它可以中止傳輸,重置控制器並重新發送傳輸。
-
SPI數據傳輸
SPI控制器遵循一系列特定的操作來初始化和控制數據通過SPI總線傳輸。以下小節詳細介紹了數據傳輸握手機制。
5.1 數據傳輸
SCLK時鐘和MOSI信號在主機的控制下。要傳輸的數據是使用寄存器寫操作通過軟件將其寫入TXFIFO,然後由控制器硬件以手動或自動啓動順序進行傳輸。數據是驅動到主輸出(MOSI)數據引腳上。TXFIFO中有數據時會持續傳輸。數據在MISO數據引腳上串行接收,並一次將8位數據加載進入RXFIFO。軟件通過寄存器來讀取RXFIFO。在開始下一次傳輸之前,在TXFIFO中每寫入n個字節時,必須由軟件讀取n個存儲在RXFIFO中的字節。
5.2 自動/手動從機選擇並啓動
可以使用軟件手動啓動或自動啓動I/O接口上的數據傳輸。另外,從機片選置位/未置位可以由控制器硬件或軟件完成。
-
手動從機選擇
軟件通過設置spi.Config [Manual_CS] = 1選擇手動從機選擇方法。在這種模式下,軟件必須明確控制從機片選置位/置低。當[Manual_CS] = 0時,控制器硬件自動判斷從機在數據傳輸期間選擇。
-
自動從機選擇
軟件通過編程spi.Config [Manual_CS] = 0來選擇自動從機選擇方法。SPI控制器爲TXFIFO的每次傳輸置位/置低從機選擇MOSI信號上的內容。 軟件將數據寫入TXFIFO,然後控制器自動選擇從機,在TXFIFO中傳輸數據,然後使從機無效選擇。傳輸TXFIFO中的所有數據後,從機選擇將置爲無效,直到這個發送結束。在自動從機選擇模式下,軟件需要確保以下操作。
-
軟件連續將要發送的數據字節填充到TXFIFO中,在TXFIFO不爲空的情況下,維持已聲明的從機選擇。
-
軟件需要連續讀取RXFIFO中接收的數據字節,以避免溢出
軟件可以通過TXFIFO和RXFIFO的閾值級別來避免FIFO不滿或者溢出。當TXFIFO中的字節數少於以下字節時,TXFIFO的未滿條件被標誌。當RXFIFO中的字節數等於128時,RXFIFO將被標誌爲已滿。
5.3 手動啓動
以下過程描述瞭如何以手動模式開始數據傳輸。
-
啓用
軟件通過設置spi.Config [Man_start_en]選擇手動傳輸方法位=1。在這種模式下,軟件必須使用手動啓動來顯式啓動數據傳輸命令機制。當[Man_start_en]位= 0時,控制器硬件當TXFIFO中有可用數據時,它將自動開始數據傳輸。
-
命令
軟件通過將1寫入spi.Config [Man_start_com]位來啓動手動傳輸。當軟件寫入1時,控制器硬件開始數據傳輸,然後傳輸TXFIFO中存在的所有數據字節。 [Man_start_com]位是自動清除的。如果[Man_start_en] = 0,則向該位寫入1。不管模式如何,將0寫入[Man_start_com],都沒有效果。
-
時鐘
從機選擇輸入引腳必須被SCLK輸入同步驅動。控制器工作在SPI_REF_CLK時鐘域中。輸入信號已同步並在SPI_REF_CLK域中進行分析。
-
數據檢測
在SPI_REF_CLK時鐘域中檢測到數據的開頭。
-
啓用控制器時進行檢測:如果在從機片選處於置低狀態啓用了控制器(從禁用狀態),控制器將忽略數據,並在捕獲數據之前,等待SCLK處於非活動狀態(字邊界)。 控制器對SPI_REF_CLK域中的SCLK不活動進行計數。當SCLK空閒計數達到在[Slave_Idle_count]位域編程的值時,一個新數據到達。
-
從機選擇有效時的檢測:啓用控制器,檢測到從機選擇如果爲高(無效),控制器假定數據的開頭出現在從機片選轉變爲低電平後,SCLK的下一個有效沿。
重要信息:開始條件必須至少保持四個SPI_REF_CLK週期被有效檢測到。如果在主機非常接近開始數據傳輸時使能從機模式,錯誤同步的可能性很小,從而導致數據包損壞。這個問題可以通過以下任何一種設計選擇來避免
-
確保外部主機至少在使能從機模式後十個SPI_REF_CLK週期完後才啓動數據傳輸。
-
確保在啓用主機之前啓用了從機模式。
-
確保啓用從機時,從機片選輸入信號未激活。