SPI协议学习
SPI協議學習
- 背景
- SPI協議時序
- SPI接口
- SPI時序
- SPI協議封裝
- USB-SPI模塊
- SPI數據格式定義
- FLASH數據格式參考
- 數據格式定義
背景
家里有一塊ZYNQ開發板,經常想去寫一寫模塊學習總線之類的東西,但是由于本人軟件能力比較弱,ZYNQ的PS部分無論是Linux還是裸機用起來著實吃力,所以準備拋棄ARM部分,主要用PL部分。于是就想通過PC作為上位機,來訪問內部的一些寄存器完成控制與調試。
常用的低速接口有UART、I2C、SPI等,從速率上看,SPI最佳。雖然是簡單的調試,但是訪問速度還是希望越快越好嘛。于是在某寶上淘來了USB轉SPI的模塊,準備通過SPI連到PL來完成簡單的訪問。
于是想寫一個自定義的SPI SLAVE模塊,方便邏輯簡單的調試。
SPI協議時序
SPI是串行外設接口(Serial Peripheral Interface)的縮寫,是一種相對高速的,源同步通信總線。
SPI接口
SPI一般有4根信號線:
- SS_N:片選信號,拉低代表片選有效;SPI支持一對多傳輸,在有多個從設備的時候,主設備會到每一個從設備都有一個SS_N信號;
- SCLK:時鐘信號,用于給從設備提供源同步時鐘,僅在數據傳輸時才存在;
- MOSI:Master Out Slave In信號,主設備→從設備的數據信號;
- MISO:Master In Slave Out信號,從設備→主設備的數據信號;
上述這種數據定義是指的標準SPI模式,也就是Standard/Normal SPI模式。在某些對傳輸速率有要求的場合還會有Dual SPI模式和Quad SPI模式,常見于SPI NOR Flash這類的器件。
- Dual SPI:這種模式下MOSI與MISO信號變成了半雙工,名稱一般變為了SIO0、SIO1;因為一般Master與Slave不會同時輸出數據,因此在Master發送數據的時候,兩個信號均從Master傳往Slave,在Slave回復數據的時候兩根信號均從Slave傳往Master,傳輸速率是標準模式的2倍。
- Quad SPI:這種模式下相比Dual SPI模式又多了兩根依舊是半雙工的數據線,即SIO2、SIO3,通常在SPI NOR FLASH上可能會和WP、HOLD管腳復用;傳輸模式與Dual SPI一樣,因此傳輸速率是標準模式的4倍。
SPI時序
SPI的具體時序如下圖所示:(圖片源于《SPI協議(上)——基礎介紹》)
SPI協議里有2個和時序相關的參數,我介紹一下自己的理解:
- CPOL:clk polar,時鐘的極性,代表空閑狀態下SCLK的狀態;0:空閑為低;1:空閑為高;
- CPHA:clk phase,時鐘的相位,代表第幾個時鐘沿是采樣沿;0:第1個;1:第2個
主從設備均根據SCK對應的采樣沿與數據輸出沿進行數據的操作與傳輸。
SPI協議封裝
由于SPI的接口時序相對簡單,簡單來說就是一個源同步的串口,具體傳輸規則的定義就自由度很大了。
USB-SPI模塊
在某寶上買的這個USB-SPI模塊看了下好像還挺高級,既支持當SPI Master還支持當Slave,還有I2C功能,當時看著功能挺多的就選了這個,以備不時之需。當然目前我需要用的功能就是PC端通過這個模塊當MASTER。
看了下基本上都是以Byte為單位操作,一次性最多可以傳輸4096-byte也就是32768-bit的數據。那后面Slave的相關設計就保底按照這個規格來考慮了。
SPI數據格式定義
FLASH數據格式參考
格式定義準備參考SPI FLASH的數據格式,這里是一份SPI FLASH的datasheet里的格式參考:
其中主要以 操作碼 開頭,后面再跟著不同操作的不同的數據格式
數據格式定義
之前自己開發過一個SPI的master和slave,也是進行簡單的寄存器讀寫訪問的,遇到了一個問題:設計幀格式的時候,沒有考慮內部總線的時延,當時的幀格式是操作碼+地址+數據,地址之后緊接著就是數據,這樣在讀操作的時候,收完地址后立馬要去內部總線里去尋址讀數據,緊接著就要立馬輸出讀取到數據的第一個bit了,那么尋址返回數據的時間只有辦個SCLK的周期,這個在一定程度上導致了SPI整體的速率上不去。
其中一個解決方案就是像上面那份FLASH的FAST READ一樣,在發送完地址之后,定義一個byte的DUMMY字段,這樣就給尋址返回數據預留了充足的時間。
但是我想為了提升效率,幀格式定義為了地址+操作碼+數據,讀寫的區分定義在操作碼的第1bit,這樣也就預留了一定的時間給數據返回用。
整體數據格式的定義:
| 地址 | Byte0~Byte2 | 24 (簡單調試24bit應該綽綽有余) |
| 操作碼 | Byte3 | 8 |
| 數據 | 剩余Byte | 剩余數據(根據SS_N何時結束來判斷) |
操作碼含義的定義:
| bit[7] | 讀寫指示;0:讀;1:寫; |
| bit[6:4] | 操作位寬指示(指示總線有效數據位寬) 0:8-bit; 1:16-bit; 2:32-bit; 3:64-bit: 4:128-bit; 5:256-bit; 6:512-bit; 7:1024-bit |
| bit[3:0] | 保留字段 |
總結
- 上一篇: Dependency Property
- 下一篇: 【机器学习】六种算法在人脸补全中的应用比