Interface: Inter Integrated Circuit(I2C) AND Linux: I2C subsystem

I2C是一個非常簡易又經常使用到的介面,常常是用來當作device driver要傳送command的媒介,標準模式的傳輸速度視100kbps,快速模式則是支援到400kbps,印象中之後會支援更高的速度,有到Mbps等級的。

I2C比之前提到的SPI介面來的更為單純,只需要兩條線即可傳輸接收資料,並且支援多個裝置同時在該介面上掛接。

所謂的兩條線即是SDA(Serial Data)和SCL(Serial Clock),兩條線預設都保持在open drain的狀態,就是預設為high準位,主要是因應I2C可以銜接多個裝置的緣故,如果預設不是high準位,則在兩個裝置中一個要將準為拉high,但另一個裝置卻要將準為拉low的時候就會導致短路的情況發生。

在bus上的每個裝置都會有自己的slave address,這些slave address在同一個bus並不能重複,若是有重複的話,就必須要更換為其他裝置,讓slave address保持唯一性,目前也有遇過i2c bus不止一組的情況,我想要是有一組以上的i2c bus,若是遇到slave address相同,只需要讓他們在不同的i2c bus上應該就可以使用。

就像之前提到的,SDA和SCL兩條Line是雙向的(雖說是雙向,但是資料的寫入和讀取都是由master主動發起,slave無法啟動傳輸過程,除非多拉一條interrupt pin出來通知master要進行讀取,像是之前porting過的NFC就是用如此的方法),預設的情況兩者都是High(此情況稱為open drain,中文的部分照書本上翻譯似乎是翻成"開汲",這麼做主要是因為i2c可以支援多個slave,在open drain的情況下,slave只可以將訊號拉low而不能拉high,所以可避免short的情況發生。若slave可以將訊號拉high和low,那麼若同時間有兩個slave作動,一個high一個low就會出問題。),Start condition是由SDA先拉low,接著SCL拉low來產生。所以我們在示波器上所看到圖形會呈現SDA先拉low接著才是SCL拉low。相反的,Stop condition則是SCL先拉回high接著才是SDA拉回high的狀態。另外在資料的取樣部分,I2C並不像SPI那樣還有極性(clock polarity)和相位(clock phase)的設定而有不同的取樣方式。I2C很單純的是在SCL的上升沿去取樣SDA的資料作為有效位元,SDA必須保持其狀態直到SCL回復到low準位。如此所截取到的資料才是正確的。



每次Master裝置傳送八個bit給slave裝置之後,會釋放SDA,接著多產生一個SCL的時脈,作為第九個bit的CLK,若是slave裝置有接上而且正常的運作中,就會在這第九個bit作回應(ACK),將SDA拉low,所以我們一般在porting過程中量測訊號時,要是一切運作正常,可以在示波器上看到SCL有九根,對應到SDA上可以知道傳送的是0 or 1,就可以驗證是否和程式中所要傳送的slave address、register address、data是否正確,記得ACK是SDA low準位。另外read/write command的區分則是在我們傳送slave address的時候,基本上一般都是7bit address,另外也有10bit的,不過我沒有使用過。傳送都是一個byte在傳送,以7bit address為範例,第八個bit是0則代表著write command,1則代表read command。

剛開始接觸I2C這個介面的時候,以write command來說,一般都會傳送slave address,接著傳送要寫入的register的value(好比要寫資料到0x16著個暫存器上),最後才是要寫入的資料。一直到有次porting一個較為簡易的原件時發現他並不需要帶暫存器位址,只需要帶slave address就可,我想是因為這個chip相當單純,內部暫存器數量並不多,只要依循著上電,拉power on sequence,接著他就知道送來的第一個write command要寫去哪個暫存器,第二個command又是寫哪個站存器位址,而不需要我們主動去指定,也才發現原來最初I2C的原意是這樣的,還需要寫入register address的方式其實是後來衍伸出來的。



軟體的部分,

未完成...

留言

熱門文章