手把手教你寫Linux I2C裝置驅動2

2021-07-08 17:52:25 字數 1649 閱讀 3440

要想在linux下讀寫晶元的i2c暫存器,一般需要在linux編寫乙份該晶元的i2c驅動,關於linux下如何編寫i2c驅動,前一篇文章《手把手教你寫linux i2c裝置驅動》已經做了初步的介紹,並且留下了兩個疑問尚未解決,第乙個是如何對linux提供的i2c操作函式進行進一步封裝,實現對晶元暫存器的讀寫;另乙個是如何在使用者空間呼叫該i2c驅動**。本文將討論前乙個問題。

首先,我們要了解linux系統提供的i2c操作函式怎麼使用,上篇文章已經提到過,對i2c裝置的讀寫,linux系統提供了多種介面,這些介面可以在核心的 i2c.h 中找到,這裡我主要介紹下面這組讀寫介面:

extern

inti2c_master_send(

struct

i2c_client *,

const

char

* ,int

);    

extern

inti2c_master_recv(

struct

i2c_client *,

char

* ,int

); 

第乙個引數是 i2c_client 物件指標,第二個引數是要傳輸的資料buffer指標,第三個引數為buffer的大小。

介面函式已經有了,下面我們要解決的問題就是以何種形式/規則去使用這些介面才能正確地讀寫晶元的相關暫存器。

首先,我們需要查詢晶元手冊,找到晶元手冊中,關於暫存器的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匯流排上的值。**寫起來也不難,示例如下:

static

inttvp5158_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慢慢一行行的追蹤 肯定是前者更加舒...