【NXP i.MX RT1170 技術手冊】- 使用 FlexSPI 與 QSPI Panel 通訊

 

筆者將以 FlexSPI範例開始帶入,介紹如何將 FlexSPI 範例調整為QSPI Panel所需的輸出資料格式,請注意,本文僅說明調整方式而不是完整 QSPI Panel 範例,讀者需具備SPI Flash 讀寫基本概念。

1.  SDK Example 中選取 RT1170 開發板,在搜尋欄輸入 FlexSPI,會列出 SDK 中所有 FlexSPI 範例,本文選擇 flexspi_nor_edma_transfer_cm7 這個範例進行修改
 

點開該範例可看到該範例是透過 FlexSPI Flash 進行溝通讀寫,由於目標是透過 FlexSPI 輸出 Quad SPI 資料給 Panel ,為達此目標重點在於調整 Look up Table

2.  在通訊中首先要先確認 baud rate,筆者一般來說是透過 NXP MCU Config Tool 進行配置,但在此範例中 flexspi_nor_flash_init 可看到 flexSPI init 中另外重新配置 FlexSPI Clock
 

點進函數中可看到配置,CLOCK_SetRootClockDiv 是將 FlexSPI 除頻 2CLOCK_SetRootClockMux 是甚麼意思就需要參考一下 reference manual 
     

RT1170 reference manual Chapter 15 Clock Controller Module (CCM) Table 15-4. Clock Roots 可看到 0 代表的是 OSC_RC_48M_DIV2 由內部 RC 48M 除頻得到
            
 

在由同章節中 15.4 Clock Tree 可確認,如此可確認 FlexSPI Module 是處於 24MHz
 

但實際 FlexSPI SCLK 頻率是多少??

這點可參閱 Chapter 30 FlexSPI Controller (FLEXSPI) 30.3.8 Clocks 可確認 SCLK 的頻率為根據所設定的運作模式 (DDR/SDR) 而有所不同

  



3.  再來是 SPI 運作就要考慮 CPOL (Clock Polarity) CPHA (Clock Phase) 關於此點在手冊中的描述在 30.3.2.1 SPI clock mode


有了以上資訊,接下來要確認 QSPI Panel 是否可使用

以筆者目前手邊的 Panel driver ST77903 來說最高支援 50MHz

 

從讀寫模式的說明中可看到SCK Idle 是低電位,資料是在第 1 Clock 變化取值,也就是 SPI mode 0 (CPOL=0 , CPHA=0)SDR 模式
    

4.  該確認的都確認完畢後,回到 SDK 範例,以預設的來看 24MHz 還在 Panel 接受範圍,可以不用調整,讀者可根據所使用的 Panel 進行調整

接下來就是透過調整 Look up table 設定通訊方式,Look up table 主要是用於記憶體讀寫的預設 sequenceFlexSPI 會根據所呼叫的 index 的通訊方式

以範例來說


這是什麼意思!!?

來看看手冊 Chapter 30 FlexSPI Controller (FLEXSPI) 30.3.6 Look Up Table Figure 30-5. LUT and sequence structure


由圖中可看到 Look Up Table 是由很多個 Sequence 組成,每 Sequence 8 Instruction,每 Instruction 由三個部分組成,回到 code 的宣告,這樣就對起來
 

當中 NOR_CMD_LUT_SEQ_IDX_READ_NORMAL 則是該 Sequence LUT 中的 Index,不知道讀者有沒有注意到為什麼 NOR_CMD_LUT_SEQ_IDX_READ_NORMAL 前面為什麼是乘 4,這是因為每 FLEXSPI_LUT_SEQ 包含二個 Instruction,整個 array 2*4 為一個間隔,如此符合 LUT 規劃每 sequence 2*4 Instruction

5.  再來說明 OPCODENXP 在底層已經做好 enum 宣告直接使用即可,本文需要使用 kFLEXSPI_Command_SDRkFLEXSPI_Command_RADDR_SDRkFLEXSPI_Command_WRITE_SDRkFLEXSPI_Command_STOP 這四


根據 LCD Driver 手冊描述,每命令前都會帶有 0xDE,0x00,0xXX(command),00 後再接著Data

以手冊中 command PWR3 為例,是以 1 command 加上 4 parameter

首先我們根據固定開頭會有一個 DE 故我們第一個 Instruction SDR 使用 1 調資料線

l   kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0xDE

再來我們要接個一個 00 故與 DE 相同只要將 operand 改為 00

l   kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x00

接下來要接 cmd 這邊要透過原本機制中 RADDR 來達到此格式,只是在此 operand 變成,因筆者是將 cmd + 0x00 為一組單位故在此可調整為 0x10 (16bit address),細節可參考手冊 Table 30-16. PAGE PROGRAM (QPI mode) command (Cypress serial NOR flash) 只是在手冊中描述因為是針對 flash 讀寫故是需要使用 24bit 32 bit address,故整個 Instruction 如下

l   kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_1PAD, 0x10

最後就是要發送參數,由於 QSPI 在初始化僅需要一條線故在此使用 1 pad 即可,最後的 operand 是針對當 datasize 0 時,相關描述同樣可參考 Table 30-16. PAGE PROGRAM (QPI mode) command (Cypress serial NOR flash)

l   kFLEXSPI_Command_WRITE_SDR, kFLEXSPI_1PAD, 0x04

  

6.  最後我們的命令傳送的LUT 會是長這樣並給予 CMD_LUT_SEQ_IDX_SINGLE 這個 index  ,實際數字由使用者自行定義,不要重複即可
         

至於我們 FlexSPI 需要怎麼使用這個 LUT ?

其實在範例中已經有明確的使用方式,參考 flexspi_nor_flash_page_program 這隻函數,可看到在 struct flashXfer 中使用配置 seqIndex 選擇所需的 LUT index,但在 QSPI Panel 中不需要使用 flexspi_nor_wait_bus_busy flexspi_nor_write_enable,故我們需要參考的僅有下圖框選處,當中可看到有使用一個 while 圈等待 FlexSPI 傳送完畢,如在 Flex 尚未完成發送資料就再次呼叫 FLEXSPI_TransferEDMA 將會導致異常
     
 

將函是調整為如下,將 seuqIndex 改為自己所調整的 CMD_LUT_SEQ_IDX_SINGLE
  
 

最後只要將參數以 array 形式定義完成並透過自己所定義的函數發送即可


最後 QSPI 不是 4 條線嗎?以前面描述只用了 1 條線 (kFLEXSPI_1PAD),其實也很簡單只要將 kFLEXSPI_Command_WRITE_SDR pad 改為 kFLEXSPI_4PAD ,其他的部分皆相同

每個人的邏輯不同,筆者整理自己的使用方式,也許有更好的寫法,故筆者只在說明如何進行修改調整

★博文內容均由個人提供,與平台無關,如有違法或侵權,請與網站管理員聯繫。

★博文作者未開放評論功能