1).?簡介
I2C是嵌入式設(shè)備最為常用的接口之一,常用于如下面這些應(yīng)用場景,因此本文就基于嵌入式Linux演示在User Space進(jìn)行I2C設(shè)備調(diào)試。
- EEPROM
- Real Time Clock
- Touch screen LCD
- Audio codec
本文所演示的平臺來自于Toradex?Apalis iMX6Q?ARM嵌入式平臺,這是一個(gè)基于NXP iMX6Q ARM處理器,支持四核心Cortex-A9。
2.?準(zhǔn)備
a).Apalis iMX6Q ARM核心版配合Apalis?Ixora載板,連接調(diào)試串口UART1到開發(fā)主機(jī)方便調(diào)試,同時(shí)配置好Ubuntu開發(fā)主機(jī)開發(fā)環(huán)境,具體操作方法可以參考這里。
b).Apalis iMX6Q系統(tǒng)使用Toradex Linux Release V2.6.1,下載和更新方法請參考這里。
3). I2C總線user space操作命令測試
a). Apalis iMX6Q核心版默認(rèn)定義提供了三個(gè)I2C總線可供外部使用(i2c-2為核心板內(nèi)部電源管理使用),如下所示,其中i2c-1為通用I2C接口;i2c-0為DDC接口,用于連接HDMI DDC/EDID接口,不能用做通用I2C接口;而i2c-3通常用于連接camera接口使用,不過也可以用做通用I2C接口。
b).?本文演示示例則通過讀寫Apalis Ixora載板連接在i2c-1總線上面的2Kb EEPROM
c). User Space下通過I2C tools直接操作i2c-1總線進(jìn)行訪問EEPROM
./?查看Apalis iMX6Q的所有I2C總線
---------------------------------
root@apalis-imx6:~# ls -l /dev/i2c-*
crw------- 1 root root 89, 0 4??月??26 06:52 /dev/i2c-0
crw------- 1 root root 89, 1 4??月??26 06:52 /dev/i2c-1
crw------- 1 root root 89, 2 4??月??26 06:52 /dev/i2c-2
crw------- 1 root root 89, 3 4??月??26 06:52 /dev/i2c-3
--------------------------------
./?查看i2c-1總線上面的設(shè)備
可以看到在0x50和0x68兩個(gè)地址上面掛有設(shè)備,0x68顯示為UU意味著這個(gè)設(shè)備被kernel driver占用,通常不能從user space探查,這里結(jié)合Apalis iMX6Q手冊可以得知掛載的為外部RTC設(shè)備;而0x50則為我們所需要測試的EEPROM設(shè)備
--------------------------------
--------------------------------
./ dump 0x50 EEPROM全部寄存器地址0-0xff,初始狀態(tài)下每個(gè)寄存器地址保存的數(shù)值都是0xff
--------------------------------
--------------------------------
./使用i2cset和i2cget來寫和讀EEPROM特定寄存器地址
--------------------------------
//?向EEPROM 0x00寄存器地址寫入0x01
root@apalis-imx6:/home# i2cset 1 0x50 0x00 0x01 b??????????????????????????????
WARNING! This program can confuse your I2C bus, cause data loss and worse!?????
DANGEROUS! Writing to a serial EEPROM on a memory DIMM?????????????????????????
may render your memory USELESS and make your system UNBOOTABLE!????????????????
I will write to device file /dev/i2c-1, chip address 0x50, data address????????
0x00, data 0x01, mode byte.????????????????????????????????????????????????????
Continue? [y/N] y??????????????????????????????????????????????????????????????
//?讀取EEPROM 0x00寄存器地址
root@apalis-imx6:/home# i2cget 1 0x50 0x00 b???????????????????????????????????
……????????????????????????????????????????????????????????????
0x01
--------------------------------
d). User Space下通過I2C tools讀取i2c-1總線進(jìn)行訪問RTC芯片
./Apalis Ixora載板外部RTC芯片使用ST m41t00?芯片,其內(nèi)部集成8 byte寄存器用于存儲時(shí)間相關(guān)信息,格式如下:
--------------------------------
1st byte: seconds register
2nd byte: minutes register
3rd byte: century/hours register
4th byte: day register
5th byte: date register
6th byte: month register
7th byte: years register
8th byte: control register
--------------------------------
./ Linux下查看當(dāng)前時(shí)間
--------------------------------
root@apalis-imx6:~# date???????????????????????????????????????????????????????
2017??年?04??月?26??日???星??期??三?08:57:23 UTC
--------------------------------
./ Linux下手動修改當(dāng)前時(shí)間,默認(rèn)當(dāng)設(shè)備聯(lián)網(wǎng)時(shí)候自動聯(lián)網(wǎng)校準(zhǔn)時(shí)間是打開的
--------------------------------
//?關(guān)閉網(wǎng)絡(luò)時(shí)間同步
timedatectl set-ntp 0
//手動設(shè)置時(shí)間并重啟
timedatectl set-time 22:50:11
reboot
--------------------------------
./?利用i2cget –f命令查看RTC寄存器數(shù)值示例
--------------------------------
//?查看當(dāng)前系統(tǒng)時(shí)間設(shè)置
root@apalis-imx6:~# date
2017??年?04??月?26??日???星??期??三?09:02:17 UTC
//?讀取時(shí)數(shù)值
root@apalis-imx6:~# i2cget -f 1 0x68 0x02 b
……
0x09
//?讀取分?jǐn)?shù)值
root@apalis-imx6:~# i2cget -f 1 0x68 0x01 b
……
0x02
//?讀取秒數(shù)值
root@apalis-imx6:~# i2cget -f 1 0x68 0x00 b
……
0x41
--------------------------------
4). I2C總線C程序操作示例
使用C程序打開I2C設(shè)備并進(jìn)行讀寫,這里編寫例程以訪問i2c-1總線上的EEPROM設(shè)備進(jìn)行讀寫操作。
a).?首先以C程序訪問i2C設(shè)備,需要include “i2c-dev.h”這個(gè)頭文件,請注意在Linux中有兩個(gè)同樣名字的頭文件,系統(tǒng)自帶的通常是來自Linux kernel的i2c總線驅(qū)動對應(yīng)的,這個(gè)并不是我們所需要的,而我們所需的是i2c-tools里面提供的這個(gè)“i2c-dev.h”頭文件,這個(gè)文件請見這里:
b).?示例C程序代碼請參考這里,說明如下:
./?首先程序含有輸入變量,i2c總線號碼,設(shè)備地址以及變量X,用于設(shè)置需要讀寫的寄存器地址:0xX0 – 0xXf
./?使用open函數(shù)打開i2c總線
./?使用ioctl函數(shù)設(shè)置設(shè)備地址
./?利用?SMBus?命令或者write函數(shù)向寄存器地址?0xX0 – 0xXf寫入數(shù)據(jù),數(shù)值就是對應(yīng)的寄存器地址
./?利用SMBus命令或者read函數(shù)讀取寄存器地址?0xX0 – 0xXf數(shù)據(jù)并打印出來
./?關(guān)閉i2c總線設(shè)備并退出程序
c).?程序運(yùn)行結(jié)果
--------------------------------
//?寫入并讀出寄存器0x00 – 0x0f
root@apalis-imx6:~# ./i2ctest 1 80 0???????????????????????????????????????????
0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0a 0x0b 0x0c 0x0d 0x0e 0x0f
0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0a 0x0b 0x0c 0x0d 0x0e 0x0f
//?寫入并讀出寄存器0x10 – 0x1f
root@apalis-imx6:~# ./i2ctest 1 80 1???????????????????????????????????????????
0x10 0x11 0x12 0x13 0x14 0x15 0x16 0x17 0x18 0x19 0x1a 0x1b 0x1c 0x1d 0x1e 0x1f
0x10 0x11 0x12 0x13 0x14 0x15 0x16 0x17 0x18 0x19 0x1a 0x1b 0x1c 0x1d 0x1e 0x1f
--------------------------------
這時(shí)dump EEPROM所有寄存器結(jié)果如下
?
評論