Interface: Serial Peripherial Interface (SPI)
SPI: 序列周邊界面。是由Motorola所開發,用來在MicroController和周邊的晶片之間提供一個低成本且易於使用的界面(Interface)。支援SPI介面的原件很多。最近因為Porting新的LCM有使用到,之前較常用的是I2C界面,之後會整理並且說明。一般而言,SPI協定必須有四個訊號線,所以通常有4跟pin腳
-MOSI:Master Out Slave In (由Master輸出)
-MISO: Master In Slave Out (從Master接收)
-SCLK: Serial Clock
-CS: Chip Select
常用的方法是使用一般的GPIO,透過SW config成為SPI介面。
在Driver Porting的初期,最主要的工作是確保Interface是可以運作的,一方面可以確認硬體的打鍵和線路以及電源都是正確的,另一方面確保軟體在之後的實作上通訊的管道是暢通的。
SPI是一個同步的通訊協定,它的傳輸會根據一個共同的時脈訊號(此時脈訊號產生自處理器),而slave裝置則是根據這個signal來同步所接收到的資料。在SPI這個協定下,一個master可以連接多個slave裝置,此時則必須透過chip select來選擇要接收的slave裝置。
SPI有個優點,就是在Master和Slave裝置上都有一個data register存在,透過這樣的方式,可以讓寫入以及讀取的功能同步進行,也就是欲從Master寫入Slave以及要從Slave上傳送進Master的資料,呈現一個環狀的傳送管到,同步的送出和接收。當然若是單傳只想要進行寫入,那Master就可以忽略掉從Slave來的資訊,相對的讀取也是。
關於SPI介面在資料的擷取部分,有clock polarity和clock phase的參數可以調整,可以參考wiki:http://en.wikipedia.org/wiki/Serial_Peripheral_Interface_Bus
Porting時遇到的問題:
- code版號不同,有些版本SPI Interface尚未完成,導致SPI無法做動,從示波器中看到CLK和CS沒有同步。
- SPI也可以透過general gpio來模擬SPI的傳輸,只要震動出對的波形即可傳送資料。
- SPI相位和極性要注意,有些裝置並沒有支援所有的極性和相位,關於極性和相位的關係可以搜尋一下wiki中對於SPI的說明,另外CS的作動一般來說是Low active,也可以透過config來轉換成High active。
以上的部分似乎較多著墨在硬體以及介面的除錯方法,
在軟體的部分,其實SPI介面的register相當容易,以我porting過的LCM driver舉例:.
裝置的掛載如下:
static int __init lcdc_xxx_panel_init(void) {
...
//在init的時候就把spi driver註冊起來。
spi_register_driver(&lcdc_xxx_spi_driver);
...
}
module_init(lcdc_xxx_panel_init);
spi_register_driver()就會串到bus driver的部分(spi.c)
那device的部分呢?device的註冊則是在board-xxx.c裡面,在程式碼中可以看到
static void __init board_init(void) {
...
//註冊到spi bus上,架構上跟I2C一樣透過xxx_register_board_info(),詳細我會補在I2C的文章裡。
spi_register_board_info();
...
}
在register的board_info包含了:
- module name
- spi極性的設定,極性的部分上面已經提過
- bus的編號
- 選用的chip select,通常在同個bus number上是唯一的,不然應該會誤動作。
- spi的clock speed,這邊要配合modem的部分,數值不是你想填多少都可以。在modem code裡面會有定義好的struct,必須配合使用,才能順利調整clock。
以上是簡短的說明。
若有需要會再補充。
-MOSI:Master Out Slave In (由Master輸出)
-MISO: Master In Slave Out (從Master接收)
-SCLK: Serial Clock
-CS: Chip Select
常用的方法是使用一般的GPIO,透過SW config成為SPI介面。
在Driver Porting的初期,最主要的工作是確保Interface是可以運作的,一方面可以確認硬體的打鍵和線路以及電源都是正確的,另一方面確保軟體在之後的實作上通訊的管道是暢通的。
SPI是一個同步的通訊協定,它的傳輸會根據一個共同的時脈訊號(此時脈訊號產生自處理器),而slave裝置則是根據這個signal來同步所接收到的資料。在SPI這個協定下,一個master可以連接多個slave裝置,此時則必須透過chip select來選擇要接收的slave裝置。
SPI有個優點,就是在Master和Slave裝置上都有一個data register存在,透過這樣的方式,可以讓寫入以及讀取的功能同步進行,也就是欲從Master寫入Slave以及要從Slave上傳送進Master的資料,呈現一個環狀的傳送管到,同步的送出和接收。當然若是單傳只想要進行寫入,那Master就可以忽略掉從Slave來的資訊,相對的讀取也是。
關於SPI介面在資料的擷取部分,有clock polarity和clock phase的參數可以調整,可以參考wiki:http://en.wikipedia.org/wiki/Serial_Peripheral_Interface_Bus
Porting時遇到的問題:
- code版號不同,有些版本SPI Interface尚未完成,導致SPI無法做動,從示波器中看到CLK和CS沒有同步。
- SPI也可以透過general gpio來模擬SPI的傳輸,只要震動出對的波形即可傳送資料。
- SPI相位和極性要注意,有些裝置並沒有支援所有的極性和相位,關於極性和相位的關係可以搜尋一下wiki中對於SPI的說明,另外CS的作動一般來說是Low active,也可以透過config來轉換成High active。
以上的部分似乎較多著墨在硬體以及介面的除錯方法,
在軟體的部分,其實SPI介面的register相當容易,以我porting過的LCM driver舉例:.
裝置的掛載如下:
static int __init lcdc_xxx_panel_init(void) {
...
//在init的時候就把spi driver註冊起來。
spi_register_driver(&lcdc_xxx_spi_driver);
...
}
module_init(lcdc_xxx_panel_init);
spi_register_driver()就會串到bus driver的部分(spi.c)
那device的部分呢?device的註冊則是在board-xxx.c裡面,在程式碼中可以看到
static void __init board_init(void) {
...
//註冊到spi bus上,架構上跟I2C一樣透過xxx_register_board_info(),詳細我會補在I2C的文章裡。
spi_register_board_info();
...
}
在register的board_info包含了:
- module name
- spi極性的設定,極性的部分上面已經提過
- bus的編號
- 選用的chip select,通常在同個bus number上是唯一的,不然應該會誤動作。
- spi的clock speed,這邊要配合modem的部分,數值不是你想填多少都可以。在modem code裡面會有定義好的struct,必須配合使用,才能順利調整clock。
以上是簡短的說明。
若有需要會再補充。
版主你好
回覆刪除你有遇過 SPI 速度過慢狀況嗎?