1.QSPI協議簡介
QSPI是Queued SPI的簡寫,是Motorola公司推出的SPI接口的擴展,比SPI應用更加廣泛。在SPI協議的基礎上,Motorola公司對其功能進行了增強,增加了隊列傳輸機制,推出了隊列串行外圍接口協議(即QSPI協議)。QSPI 是一種專用的通信接口,連接單、雙或四(條數據線) SPI Flash 存儲介質。
該接口可以在以下三種模式下工作:
① 間接模式:使用 QSPI 寄存器執行全部操作
② 狀態輪詢模式:周期性讀取外部 Flash 狀態寄存器,而且標志位置 1 時會產生中斷(如擦除或燒寫完成,會產生中斷)
③ 內存映射模式:外部 Flash 映射到微控制器地址空間,從而系統將其視作內部存儲器
采用雙閃存模式時,將同時訪問兩個 Quad-SPI Flash,吞吐量和容量均可提高二倍。
1.1 QSPI功能框圖
QSPI功能框圖,雙閃存模式禁止見圖1。

我們的開發板采用的是雙閃存禁止的模式連接單片QSPI Flash。QSPI 使用 6 個信號連接Flash,分別是四個數據線BK1_IO0~BK1_IO3,一個時鍾輸出CLK,一個片選輸出(低電平有效)BK1_nCS,它們的作用介紹如下:
(1) BK1_nCS:片選輸出(低電平有效),適用於 FLASH 1。如果 QSPI 始終在雙閃存模式下工作,則其也可用於 FLASH 2從設備選擇信號線。QSPI通訊以BK1_nCS線置低電平為開始信號,以BK1_nCS線被拉高作為結束信號。
(2) CLK:時鍾輸出,適用於兩個存儲器,用於通訊數據同步。它由通訊主機產生,決定了通訊的速率,不同的設備支持的最高時鍾頻率不一樣,如STM32的QSPI時鍾頻率最大為fpclk/2,兩個設備之間通訊時,通訊速率受限於低速設備。
(3) BK1_IO0:在雙線 / 四線模式中為雙向 IO,單線模式中為串行輸出,適用於FLASH 1。
(4) BK1_IO1:在雙線 / 四線模式中為雙向 IO,單線模式中為串行輸入,適用於FLASH 1。
(5) BK1_IO2:在四線模式中為雙向 IO,適用於 FLASH 1。
(6) BK1_IO3:在四線模式中為雙向 IO,適用於 FLASH 1。
QSPI命令序列
QUADSPI 通過命令與 Flash 通信 每條命令包括指令、地址、交替字節、空指令和數據這五個階段 任一階段均可跳過,但至少要包含指令、地址、交替字節或數據階段之一。nCS 在每條指令開始前下降,在每條指令完成后再次上升。先看看QSPI四線模式下的讀命令時序,見圖2。

- 指令階段
這一階段,將在 QUADSPI_CCR[7:0] 寄存器的 INSTRUCTION 字段中配置的一條 8 位指令發送到 Flash,指定待執行操作的類型。
盡管大多數 Flash 從 IO0/SO 信號(單線 SPI 模式)只能以一次 1 位的方式接收指令,但指令階段可選擇一次發送 2 位(在雙線 SPI 模式中通過 IO0/IO1)或一次發送 4 位(在四線SPI 模式中通過 IO0/IO1/IO2/IO3)。這可通過 QUADSPI_CCR[9:8] 寄存器中的 IMODE[1:0]字段進行配置。
若 IMODE = 00,則跳過指令階段,命令序列從地址階段(如果存在)開始。 - 地址階段
在地址階段,將1-4字節發送到Flash,指示操作地址。待發送的地址字節數在QUADSPI_CCR[13:12]寄存器的ADSIZE[1:0]字段中進行配置。在間接模式和自動輪詢模式下,待發送的地址字節在QUADSPI_AR寄存器的ADDRESS[31:0]中指定在內存映射模式下,則通過 AHB(來自於 Cortex ® 或 DMA)直接給出地址。地址階段可一次發送1 位(在單線SPI模式中通過SO)、2位(在雙線SPI模式中通過IO0/IO1)或4位(在四線 SPI 模式中通過 IO0/IO1/IO2/IO3)。這可通過QUADSPI_CCR[11:10]寄存器中的ADMODE[1:0]字段進行配置。
若 ADMODE = 00,則跳過地址階段,命令序列直接進入下一階段(如果存在)。 - 交替字節階段
在交替字節階段,將 1-4 字節發送到 Flash,一般用於控制操作模式。待發送的交替字節數在 QUADSPI_CCR[17:16] 寄存器的 ABSIZE[1:0] 字段中進行配置。待發送的字節在QUADSPI_ABR 寄存器中指定。
交替字節階段可一次發送 1 位(在單線 SPI 模式中通過 SO)、2 位(在雙線 SPI 模式中通過 IO0/IO1)或 4 位(在四線 SPI 模式中通過 IO0/IO1/IO2/IO3)。這可通過QUADSPI_CCR[15:14] 寄存器中的 ABMODE[1:0] 字段進行配置。
若 ABMODE = 00,則跳過交替字節階段,命令序列直接進入下一階段(如果存在)。交替字節階段存在僅需發送單個半字節而不是一個全字節的情況,比如采用雙線模式並且僅使用兩個周期發送交替字節時。在這種情況下,固件可采用四線模式 (ABMODE = 11) 並發送一個字節,方法是 ALTERNATE 的位 7 和 3 置“1”(IO3 保持高電平)且位 6 和 2 置“0”(IO2 線保持低電平)。此時,半字節的高 2 位存放在 ALTERNATE 的位 4:3,低 2位存放在位 1 和 0 中。例如,如果半字節 2 (0010) 通過 IO0/IO1 發送,則 ALTERNATE 應設置為 0x8A (1000_1010)。 - 空指令周期階段
在空指令周期階段,給定的 1-31 個周期內不發送或接收任何數據,目的是當采用更高的時鍾頻率時,給 Flash 留出准備數據階段的時間。這一階段中給定的周期數在QUADSPI_CCR[22:18] 寄存器的 DCYC[4:0] 字段中指定。在 SDR 和 DDR 模式下,持續時間被指定為一定個數的全時鍾周期。若 DCYC 為零,則跳過空指令周期階段,命令序列直接進入數據階段(如果存在)。空指令周期階段的操作模式由 DMODE 確定。為確保數據信號從輸出模式轉變為輸入模式有足夠的“周轉”時間,使用雙線和四線模式從Flash 接收數據時,至少需要指定一個空指令周期。 - 數據階段
在數據階段,可從 Flash 接收或向其發送任意數量的字節。
在間接模式和自動輪詢模式下,待發送/接收的字節數在 QUADSPI_DLR 寄存器中指定。在間接寫入模式下,發送到 Flash 的數據必須寫入 QUADSPI_DR 寄存器。在間接讀取模式下,通過讀取 QUADSPI_DR 寄存器獲得從 Flash 接收的數據。在內存映射模式下,讀取的數據通過 AHB 直接發送回 Cortex 或 DMA。數據階段可一次發送/接收 1 位(在單線 SPI 模式中通過 SO)、2 位(在雙線 SPI 模式中通過 IO0/IO1)或 4 位(在四線 SPI 模式中通過 IO0/IO1/IO2/IO3)。這可通過QUADSPI_CCR[15:14] 寄存器中的 ABMODE[1:0] 字段進行配置。若 DMODE = 00,則跳過數據階段,命令序列在拉高 nCS 時立即完成。這一配置僅可用於僅間接寫入模式。
2.QUADSPI 信號接口協議模式
3.1 單線 SPI 模式
傳統 SPI 模式允許串行發送/接收單獨的 1 位。在此模式下,數據通過 SO 信號(其 I/O 與IO0 共享)發送到 Flash。從 Flash 接收到的數據通過 SI(其 I/O 與 IO1 共享)送達。通過將(QUADSPI_CCR 中的)IMODE/ADMODE/ABMODE/DMODE 字段設置為 01,可對不同的命令階段分別進行配置,以使用此單個位模式。在每個已配置為單線模式的階段中:
IO0 (SO) 處於輸出模式
IO1 (SI) 處於輸入模式(高阻抗)
IO2 處於輸出模式並強制置“0”(以禁止“寫保護”功能)
IO3 處於輸出模式並強制置“1”(以禁止“保持”功能)
若 DMODE = 01,這對於空指令階段也同樣如此。
3.2 雙線 SPI 模式
在雙線模式下,通過 IO0/IO1 信號同時發送/接收兩位。通過將 QUADSPI_CCR 寄存器的 IMODE/ADMODE/ABMODE/DMODE 字段設置為 10,可對不同的命令階段分別進行配置,以使用雙線 SPI 模式。在每個已配置為單線模式的階段中:
IO0/IO1 在數據階段進行讀取操作時處於高阻態(輸入),在其他情況下為輸出
IO2 處於輸出模式並強制置“0”
IO3 處於輸出模式並強制置“1”
在空指令階段,若 DMODE = 01,則 IO0/IO1 始終保持高阻態。
3.3 四線 SPI 模式
在四線模式下,通過 IO0/IO1/IO2/IO3 信號同時發送/接收四位。通過將 QUADSPI_CCR 寄存器的 IMODE/ADMODE/ABMODE/DMODE 字段設置為 11,可對不同的命令階段分別進行配置,以使用四線 SPI 模式。在每個已配置為四線模式的階段中,IO0/IO1/IO2/IO3 在數據階段進行讀取操作時均處於高阻態(輸入),在其他情況下為輸出。在空指令階段中,若 DMODE = 11,則 IO0/IO1/IO2/IO3 均為高阻態。IO2 和 IO3 僅用於 Quad SPI 模式 如果未配置任何階段使用四線 SPI 模式,即使 UADSPI激活,對應 IO2 和 IO3 的引腳也可用於其他功能。
3.4 SDR 模式
默認情況下,DDRM 位 (QUADSPI_CCR[31]) 為 0,QUADSPI 在單倍數據速率 (SDR) 模式下工作。在 SDR 模式下,當 QUADSPI 驅動 IO0/SO、IO1、IO2、IO3 信號時,這些信號僅在 CLK的下降沿發生轉變。在 SDR 模式下接收數據時,QUADSPI 假定 Flash 也通過 CLK 的下降沿發送數據。默認情況下 (SSHIFT = 0 時),將使用 CLK 后續的邊沿(上升沿)對信號進行采樣。
3.5 DDR 模式
若 DDRM 位 (QUADSPI_CCR[31]) 置 1,則 QUADSPI 在雙倍數據速率 (DDR) 模式下工作。在 DDR 模式下,當 QUADSPI 在地址/交替字節/數據階段驅動 IO0/SO、IO1、IO2、IO3 信號時,將在 CLK 的每個上升沿和下降沿發送 1 位。指令階段不受 DDRM 的影響。始終通過 CLK 的下降沿發送指令。在 DDR 模式下接收數據時,QUADSPI 假定 Flash 通過 CLK 的上升沿和下降沿均發送數據。若 DDRM = 1,固件必須清零 SSHIFT 位 (QUADSPI_CR[4])。因此,在半個 CLK 周期后(下一個反向邊沿)對信號采樣。四線模式下DDR命令時序見圖3。

3.6 雙閃存模式
若 DFM 位 (QUADSPI_CR[6]) 為 1,QUADSPI 處於雙閃存模式。QUADSPI 使用兩個外部四線 SPI Flash(FLASH 1 和 FLASH 2),在每個周期中發送/接收 8 位(在 DDR 模式下為16 位),能夠有效地將吞吐量和容量擴大一倍。每個 Flash 使用同一個 CLK 並可選擇使用同一個 nCS 信號,但其 IO0、IO1、IO2 和 IO3 信號是各自獨立的。雙閃存模式可與單比特模式、雙比特模式以及四比特模式結合使用,也可與 SDR 或 DDR 模式相結合。Flash 的大小在 FSIZE[4:0] (QUADSPI_DCR[20:16]) 中指定,指定的值應能夠反映 Flash 的總容量,即單個組件容量的 2 倍。如果地址 X 為偶數,QUADSPI 賦給地址 X 的字節是存放於 FLASH 1 的地址 X/2 中的字節,QUADSPI 賦給地址 X+1 的字節是存放於 FLASH 2 的地址 X/2 中的字節。也就是說,偶地址中的字節存儲於 FLASH 1,奇地址中的字節存儲於 FLASH 2。
在雙閃存模式下讀取 Flash 狀態寄存器時,需要讀取的字節數是單閃存模式下的 2 倍。這意味着在狀態寄存器獲取指令到達后,如果每個 Flash 給出 8 個有效位,則 QUADSPI 必須配置為 2 個字節(16 位)的數據長度,它將從每個 Flash 接收 1 個字節。如果每個 Flash 給出一個 16 位的狀態,則 QUADSPI 必須配置為讀取 4 字節,以在雙閃存模式下可獲取兩個Flash 的所有狀態位。結果(在數據寄存器中)的最低有效字節是 FLASH 1 狀態寄存器的最低有效字節,而下一個字節是 FLASH 2 狀態寄存器的最低有效字節。數據寄存器的第三個字節是 FLASH 1 的第二個字節,第四個字節是 FLASH 2 的第二個字節(Flash 具有 16 位狀態寄存器時)。
偶數個字節必須始終在雙閃存模式下訪問。因此,若 DRM = 1,則數據長度字段(QUADSPI_DLR[0]) 的位 0 始終保持為 1。
在雙閃存模式下,FLASH 1 接口信號的行為基本上與正常模式下相同。在指令、地址、交替字節以及空指令周期階段,FLASH 2 接口信號具有與 FLASH 1 接口信號完全相同的波形。也就是說,每個 Flash 總是接收相同的指令與地址。然后,在數據階段,BK1_IOx 和BK2_IOx 總線並行傳輸數據,但發送到 FLASH 1(或從其接收)的數據與 FLASH 2 中的不同。
3.QUADSPI 間接模式
在間接模式下,通過寫入 QUADSPI 寄存器來觸發命令;並通過讀寫數據寄存器來傳輸數據,就如同對待其他通信外設那樣。
若 FMODE = 00 (QUADSPI_CCR[27:26]),則 QUADSPI 處於間接寫入模式,字節在數據階段中發送到 Flash。通過寫入數據寄存器 (QUADSPI_DR) 的方式提供數據。
若 FMODE = 01,則 QUADSPI 處於間接讀取模式,在數據階段中從 Flash 接收字節。通過讀取 QUADSPI_DR 來獲取數據。
讀取/寫入的字節數在數據長度寄存器 QUADSPI_DLR) 中指定。
如果 QUADSPI_DLR =0xFFFF_FFFF(全為“1”),則數據長度視為未定義,QUADSPI 將繼續傳輸數據,直到到達(由 FSIZE 定義的)Flash 的結尾。如果不傳輸任何字節,DMODE (QUADSPI_CCR[25:24])應設置為 00。如果 QUADSPI_DLR = 0xFFFF_FFFF 並且 FSIZE = 0x1F(最大值指示一個 4GB 的Flash),在此特殊情況下,傳輸將無限繼續下去,僅在出現終止請求或 QUADSPI 被禁止后停止。在讀取最后一個存儲器地址后(地址為 0xFFFF_FFFF),將從地址 = 0x0000_0000開始繼續讀取。
當發送或接收的字節數達到編程設定值時,如果 TCIE = 1,則 TCF 置 1 並產生中斷。在數據數量不確定的情況下,將根據 QUADSPI_CR 中定義的 Flash 大小,在達到外部 SPI 的限制時,TCF 置 1。
3.1 觸發命令啟動
從本質上講,在固件給出命令所需的最后一點信息時,命令即會啟動。根據 QUADSPI 的配置,在間接模式下有三種觸發命令啟動的方式。在出現以下情形時,命令立即啟動:
1、 對 INSTRUCTION[7:0] (QUADSPI_CCR) 執行寫入操作,如果沒有地址是必需的(當ADMODE = 00)並且不需要固件提供數據(當 FMODE = 01 或 DMODE = 00);
2、 對 ADDRESS[31:0] (QUADSPI_AR) 執行寫入操作,如果地址是必需的(當 ADMODE =00)並且不需要固件提供數據 (當 FMODE = 01 或 DMODE = 00);
3、 對 DATA[31:0] (QUADSPI_DR) 執行寫入操作,如果地址是必需的(當 ADMODE != 00)並且需要固件提供數據(當 FMODE = 00 並且 DMODE != 00)。
寫入交替字節寄存器 (QUADSPI_ABR) 始終不會觸發命令啟動。如果需要交替字節,必須預先進行編程。如果命令啟動,BUSY 位(QUADSPI_SR 的位 5)將自動置 1。
3.2 FIFO 和數據管理
在間接模式中,數據將通過 QUADSPI 內部的一個 32 字節 FIFO。FLEVEL5:0 指示 FIFO 目前保存了多少字節。
在間接寫入模式下 (FMODE = 00),固件寫入 QUADSPI_DR 時,將在 FIFO 中加入數據。字寫入將在 FIFO 中增加 4 個字節,半字寫入增加 2 個字節,而字節寫入僅增加 1 個字節。如果固件在 FIFO 中加入的數據過多(超過 DL[31:0] 指示的值),將在寫入操作結束(TCF置 1)時從 FIFO 中清除超出的字節。
對 QUADSPI_DR 的字節/半字訪問必須僅針對該 32 位寄存器的最低有效字節/半字。FTHRES[3:0] 用於定義 FIFO 的閾值 如果達到閾值,FTF(FIFO 閾值標志)置 1 在間接讀取模式下,從 FIFO 中讀取的有效字節數超過閾值時,FTF 置 1。從 Flash 中讀取最后一個字節后,如果 FIFO 中依然有數據,則無論 FTHRES 的設置為何,FTF 也都會置 1。在間接寫入模式下,當 FIFO 中的空字節數超過閾值時,FTF 置 1。
如果 FTIE = 1,則 FTF 置 1 時產生中斷。如果 DMAEN = 1,則 FTF 置 1 時啟動數據傳送。如果閾值條件不再為“真”(CPU 或 DMA 傳輸了足夠的數據后),則 FTF 由 HW 清零。在間接模式下,當 FIFO 已滿,QUADSPI 將暫時停止從 Flash 讀取字節以避免上溢。請注意,只有在 FIFO 中的 4 個字節為空 (FLEVEL ≤ 11) 時才會重新開始讀取 Flash。因此,若FTHRES ≥ 13,應用程序必須讀取足夠的字節以確保 QUADSPI 再次從 Flash 檢索數據。否則,只要 11 < FLEVEL < FTHRES,FTF 標志將保持為“0”。
4. QUADSPI Flash 配置
外部 SPI Flash的參數可以通過配置寄存器 (QUADSPI_DCR)實現。這里配置Flash的容量是設置FSIZE[4:0] 字段,使用下面的公式定義外部存儲器的大小:
FSIZE+1 是對 Flash 尋址所需的地址位數。在間接模式下,Flash 容量最高可達 4GB(使用32 位進行尋址),但在內存映射模式下的可尋址空間限制為 256MB。如果 DFM = 1,FSIZE 表示兩個 Flash 容量的總和。QUADSPI 連續執行兩條命令時,它在兩條命令之間將片選信號 (nCS) 置為高電平默認僅一個 CLK 周期時長。如果 Flash 需要命令之間的時間更長,可使用片選高電平時間 (CSHT) 字段指定 nCS 必須保持高電平的最少 CLK 周期數(最大為 8)。時鍾模式 (CKMODE) 位指示命令之間的 CLK 信號邏輯電平(nCS = 1 時)。
