1. 空閑狀態(tài):SDA和SCL都為高電平。
2. 開(kāi)始條件(S):SCL為高電平時(shí),SDA由高電平向低電平跳變,開(kāi)始傳送數據。
3. 結束條件(P):SCL為低電平時(shí),SDA由低電平向高電平跳變,結束傳送數據。
4. 數據有效:在SCL的高電平期間, SDA保持穩定,數據有效。SDA的改變只能發(fā)生在SCL的底電平期間。
5. ACK信號: 數據傳輸的過(guò)程中,接收器件每接收一個(gè)字節數據要產(chǎn)生一個(gè)ACK信號,向發(fā)送器件發(fā)出特定的低電平脈沖,表示已經(jīng)收到數據。
1.3 I
I
數據傳輸中,首先主器件產(chǎn)生開(kāi)始條件,隨后是器件的控制字節(前七位是從器件的地址,最后一位為讀寫(xiě)位 )。接下來(lái)是讀寫(xiě)操作的數據,以及 ACK響應信號。數據傳輸結束時(shí),主器件產(chǎn)生停止條件
2. Linux I2C 結構分析
2.1 層次分析
1. I2C Core
I2C Core用于維護Linux的I2C核心部分,其中維護了兩個(gè)靜態(tài)的List,分別記錄系統中的I
static LIST_HEAD(adapters);
static LIST_HEAD(drivers);
I
同時(shí)還提供了I
常用的主要是
i2c_master_send()
i2c_master_recv()
i2c_transfer()
2. I2C bus driver
總線(xiàn)驅動(dòng)的職責,是為系統中每個(gè)I
在系統開(kāi)機時(shí),首先裝載的是I
在buses目錄下的i2c-pxa.c中實(shí)現了PXA的I2C總線(xiàn)適配器,I2C adapter 構造一個(gè)對I2Ccore層接口的數據結構,并通過(guò)接口函數向I2C core注冊一個(gè)控制器。I2Cadapter主要實(shí)現對I2C總線(xiàn)訪(fǎng)問(wèn)的算法,iic_xfer() 函數就是I2C adapter底層對I2C總線(xiàn)讀寫(xiě)方法的實(shí)現。同時(shí)I2Cadpter 中還實(shí)現了對I2C控制器中斷的處理函數。
1) i2c-pxa.c定義了i2c_algorithm,并且實(shí)現了master的發(fā)送函數i2c_pxa_xfer(),以及設備查詢(xún)總線(xiàn)的模式的函數i2c_pxa_functionality()
static const struct i2c_algorithm i2c_pxa_algorithm = {
.master_xfer = i2c_pxa_xfer,
.functionality = i2c_pxa_functionality,
};
2) i2c-pxa.c中,實(shí)現了i2c_adapter,主要是在定義pxa-i2c時(shí)進(jìn)行初始化,并且i2c_pxa_probe()中進(jìn)行填充parent指針,并且調用
ret = i2c_add_adapter(&i2c->adap);
進(jìn)行添加。
static struct pxa_i2c i2c_pxa = {
.lock = SPIN_LOCK_UNLOCKED,
.adap = {
.owner = THIS_MODULE,
.algo = &i2c_pxa_algorithm,
.name = "pxa2xx-i2c.0",
.retries = 5,
},
};
總的來(lái)說(shuō),在i2c-pxa中,使用platform驅動(dòng)模型,完成了i2c的總線(xiàn)兩種模塊struct i
3. I2C device driver
I2C只有總線(xiàn)驅動(dòng)是不夠的,必須有設備才能工作。這就是I2C device driver的必要性。I2C的device是有兩個(gè)模塊來(lái)描述的,struct i
在介紹chips目錄下的device driver前有必要介紹一下i2c-dev.c文件。
i2c-dev.c中提供了一個(gè)通用的I2C設備的驅動(dòng)程序,實(shí)現了字符類(lèi)型設備的訪(fǎng)問(wèn)接口,對設備的具體訪(fǎng)問(wèn)是通過(guò)I2C adapter來(lái)實(shí)現的。構造一個(gè)對I2C core層接口的數據結構,通過(guò)接口函數向 I2CCore注冊一個(gè)I2C設備驅動(dòng)。同時(shí)構造一個(gè)對用戶(hù)層接口的數據結構,并通過(guò)接口函數向內核注冊為一個(gè)主設備號為89的字符類(lèi)型設備。
| static struct i2c_driver i2cdev_driver = { struct i2c_dev { |
該文件提供了用戶(hù)層對I2C設備的訪(fǎng)問(wèn),包括open,read,write,ioctl,release等常規文件操作,我們可以通過(guò)open函數打開(kāi)I2C的設備文件,通過(guò)ioctl函數設定要訪(fǎng)問(wèn)從設備的地址,然后就可以通過(guò) read和write函數完成對I2C設備的讀寫(xiě)操作。
| static const struct file_operations i2cdev_fops = { .owner = THIS_MODULE, .llseek = no_llseek, .read = i2cdev_read, .write = i2cdev_write, .ioctl = i2cdev_ioctl, .open = i2cdev_open, .release = i2cdev_release, }; |
注:通過(guò)I2Cdriver提供的通用方法可以訪(fǎng)問(wèn)任何一個(gè)I2C的設備,但是其中實(shí)現的read,write及ioctl等功能完全是基于一般設備的實(shí)現,所有的操作數據都是基于字節流,沒(méi)有明確的格式和意義。為了更方便和有效地使用I2C設備,我們可以為一個(gè)具體的I2C設備開(kāi)發(fā)特定的I2C設備驅動(dòng)程序,在驅動(dòng)中完成對特定的數據格式的解釋以及實(shí)現一些專(zhuān)用的功能。
在chips目錄下包含著(zhù)各種device 的driver,完成各種從設備的注冊。作為一般的I2C設備,使用i2c-dev.c里的操作足夠完成操作了。
當然如果不能完成,則需要獨立完成該驅動(dòng),這就是chips目錄下的代碼。因為i2c-dev.c已經(jīng)實(shí)現了I2C設備的文件操作接口,所以只要實(shí)現structi2c_driver就可以了。對于某些特殊的操作,可以使用command接口進(jìn)行控制。 當然,對于i2接口的fm芯片,則將structi2c_driver放在i2c的chips目錄下,而將另外fm操作相關(guān)的代碼放在了/media/radio目錄下了。在這個(gè)目錄下需要完成讀寫(xiě)接口的完成,這個(gè)大部分使用V4L2架構。
繼續分析中……
聯(lián)系客服