Linux 上的 GPIO / I2C 其實是很有趣的一個東西,可以用 GPIO 控制的方法去和硬體做溝通。和硬體的溝通比軟體有趣的地方在於馬上就「具現化」在你眼前,所以感覺實在多了,而且也有很多想像的空間。不過,I2C 在 Linux 上的實踐方法其實有兩種: GPIO 拉 I2C 的 protocol 跟 adapter driver 的方式。 I2C 靠 adapter driver 運作的方式我還不會,所以我會談的,都只有用 GPIO 實做 I2C protocol 的方式,這樣的做法其實很多變數在裡面,用到最後會不好整理,不好維護,結果也不夠穩定。不過優點就是在還不了解 linux i2c adapter driver 這一層的時候,不用花多少時間,光靠別的平台的 source code 仿照寫法,就可以開發完成,所以應該可以說是快速開發的方法。
準備材料
在開始工作之前,我們要先了解 GPIO/I2C 的需求:
a. SDA / SCL 兩根 GPIO 的腳位在哪裡。
b. 和 I2C 裝置交談的具體內容 意即是 I2C 裝置的 datasheet
I2C 的交談內容大要
如果把 I2C 簡單化,那麼 I2C 就像是在吟詩一樣,把平當作不動,仄當作腳位拉高再拉低,就會有 平平仄仄仄平平,仄仄平平平仄仄 像這種鬼東西出來。那誰看得懂呢?所以我們先跳過吧。
把 鬼東西 跳過之後,I2C 的交談內容大致上會是這樣的內容:
[S][Device ID][A][Data][A][Data][N][P]
[S] 代表的意思是 Start ,就是按 I2C protocol 拉一個 Start 。
[Device ID] 就是按 DataSheet 裡頭的說明,拉 Device ID 的值出來。
[A] 就是按 I2C protocol 拉一個 Ack。
[Data] 看 DataSheet 裡面需要送什麼 Data (一開始的 command byte 通常就一個 byte 而已)
[N] 就是按 I2C protocol 拉一個 NAK。
[P] 就是按 I2C protocol 拉一個 Stop。
所以其實很簡單吧?
因為 I2C 的特性是用一個 Device ID (也就是 Slave Address),做為識別,在同一個 Data Bus 上面進行溝通。因為每一個 Slave Device 的 ID 不一樣,所以在溝通的時候不會發生混亂,可以分時進行。但是每一個 I2C 裝置的交談內容都不大一樣,所以在實作的時候,需要參考各家產品的 data sheet 來進行實作。
在實作的時候因為每個裝置的需要,大致上會有一些名詞:
Config 設定
Polarity 極性
Input 輸入
Output 輸出
Read 讀取
Write 寫入
Register 註冊位址
Command / Control Byte 命令位元
Data Byte 資料位元
你暈了嗎?其實也都還在 [S][Device ID][A][Data][A][Data][N][P] 這個格式裡頭打轉。
執行的順序用人話來說明,大概會是:
1. Config (Initial 這個裝置)
2. Register (說明你要執行或讀寫哪個位址)
3. Control Byte (送出命令)
4. Write Data (寫入資料) 或 Read Data (讀取資料)
別睡,別睡,下文就要開始舉例說明,如何參考一份 datasheet 來開始在 Linux Kernel 上面實作 GPIO / I2C 了:
--
圈重點:
* 所以在溝通的時候,時間差(timer)和延遲(delay)很重要,務必在一開始看 datasheet 的時候就先把時間差先圈出來。
參考資料:
* [Linux] Linux 上的 GPIO / I2C 實作筆記之一 http://antontw.blogspot.com/2011/06/linux-linux-gpio-i2c.html
* 拉平仄 S, P, A, N 什麼鬼的可以參考這裡 I2C 的協定內容 http://en.wikipedia.org/wiki/I%C2%B2C
沒有留言:
張貼留言