要想在linux下讀寫晶元的i2c暫存器,一般需要在linux編寫乙份該晶元的i2c驅動,關於linux下如何編寫i2c驅動,前一篇文章《手把手教你寫linux i2c裝置驅動》已經做了初步的介紹,並且留下了兩個疑問尚未解決,第乙個是如何對linux提供的i2c操作函式進行進一步封裝,實現對晶元暫存器的讀寫;另乙個是如何在使用者空間呼叫該i2c驅動**。本文將討論前乙個問題。
首先,我們要了解linux系統提供的i2c操作函式怎麼使用,上篇文章已經提到過,對i2c裝置的讀寫,linux系統提供了多種介面,這些介面可以在核心的 i2c.h 中找到,這裡我主要介紹下面這組讀寫介面:
extern第乙個引數是 i2c_client 物件指標,第二個引數是要傳輸的資料buffer指標,第三個引數為buffer的大小。inti2c_master_send(
struct
i2c_client *,
const
char
* ,int
);
extern
inti2c_master_recv(
struct
i2c_client *,
char
* ,int
);
介面函式已經有了,下面我們要解決的問題就是以何種形式/規則去使用這些介面才能正確地讀寫晶元的相關暫存器。
首先,我們需要查詢晶元手冊,找到晶元手冊中,關於暫存器的i2c讀寫時序,其實,大多數晶元的i2c暫存器的讀寫時序都是一樣的,下面我還是以手頭的tvp5158晶元為例。
首先分析寫操作,該晶元的手冊中給出的i2c暫存器寫時序圖如下:
從上圖可以看出,真正需要執行寫操作的有兩處,step4 和 step6 ,step4首先寫入暫存器的偏移位址,而step6則是寫入到該暫存器的值。由此已經很清楚了,對於寫i2c暫存器,我們需要做的就是給 i2c_master_send 函式傳入兩個位元組的資料即可,第乙個位元組為暫存器的位址,第二個位元組為要寫入暫存器的資料。示例如下:
static其實挺簡單的,沒有什麼複雜的**。下面再看看讀時序。inttvp5158_i2c_write(
struct
i2c_client* client,uint8_t reg,uint8_t data)
return
0;
}
由上圖可以,讀時序需要做的操作是,先向i2c匯流排上寫入需要讀的暫存器位址,然後讀i2c匯流排上的值。**寫起來也不難,示例如下:
staticinttvp5158_i2c_read(
struct
i2c_client* client,uint8_t reg,uint8_t *data)
// wait
msleep(10);
// read
if( 1!= i2c_master_recv(client,data,1) )
return
0;
}
手把手教你寫Undo Redo程式
手把手教你寫 undo redo程式 undo redo 操作是很多具體編輯功能的軟體所不能缺少的。最典型兩種型別就是文字編輯和影象編輯軟體。然而它的實現在某種程度上來說也不是很簡單。我也廢話少說。要在程式中支援 undo redo 操作,就需要儲存一些必要的資訊,這個是眾所周知的。如果想支援無限級...
手把手教你寫Undo Redo程式
手把手教你寫undo redo程式 undo redo操作是很多具體編輯功能的軟體所不能缺少的。最典型兩種型別就是文字編輯和影象編輯軟體。然而它的實現在某種程度上來說也不是很簡單。我也廢話少說。要在程式中支援undo redo操作,就需要儲存一些必要的資訊,這個是眾所周知的。如果想支援無限級的und...
手把手教你寫ORM(三)
昨天處於暈死狀態,少寫了乙個元件,還需要乙個元件用來專門管理cache的,這裡說道為什麼要分這麼多元件,其實這是習慣問題,很多人喜歡寫乙個很大的dll,不過我比較喜歡拆分,小粒度的專案比較好管理和單獨測試,把用單元測試驗證好了的小組件湊起來除錯和寫成乙個巨大的dll慢慢一行行的追蹤 肯定是前者更加舒...