如何debug通訊協議 I2C 子系統
I2C 常見有兩種錯誤:I2C ACK error、I2C timeout
在應該收到 ACK 訊號的時候沒有收到 ACK 訊號,i2c controller 就會產生一個 ACK error 的中斷,告訴 i2c driver 發生了 ACK error。通常情況是 slave 本身的問題。
1、檢查 device 是否存在,i2c bus number 和 device address 是否正確。示例如下:i2c number 為 6,addr 為 0x28:
[31.092951][xxx]i2c i2c-6:addr:0x28,ACK error
2、檢查 device 是否已經上電使能,以及正確的 init。
3、檢查 i2c speed 是否適配,speed 大於 device 支援的 max speed 也會造成 ACK Error。降低速度,如果仍然可以工作的話就說明是 clk 相關問題。
4、檢查 i2c device 訊號電平是否與 AP 匹配。
5、GPIO check 以下幾個部分:
- GPIO 電流驅動能力。
- GPIO 工作模式是否是 I2C 模式。
- GPIO 是否有內部上拉電阻。
- GPIO 預設電平狀態。
從 i2c spec 看,如下情況 NACK 是正常的。
I2C 寫
主機向從機傳送資料時,最後一個 Byte 資料時,從機可能應答也可能非應答,但不怎樣主機都可以產生停止條件,如果主機在向從機傳送資料(甚至包括從機地址在內)時檢測到從機非應答,則會及時停止傳輸。
I2C 讀
主機從從機接收資料時,最後一個 Byte 資料時,主機不回應該從機,即 NACK。
當 I2C 傳輸發生 timeout 時,一般 kernel log 會有類似如下列印:
[48.197718][xxx]i2c i2c-1: addr:0xa,transfer timeout
1、GPIO check 以下幾個部分。
2、排查 slave 順序。
復現問題後,可以手動將相應外設去掉,確認是哪個外設將 i2c bus 拉住,再與供應商溝通,debug 一下該 IC 狀態,理清拉住 i2c bus 原因。
i2c-tools 也很好用,這個工具工具博主上次寫過,參考以下文章:
手把手教你使用 i2c-tools。
(1)相同 address 註冊時衝突.
[2.059184][xxx]i2c i2c-1:Failed to register i2c client 24c02 at 0x51(-16) [2.059189][xxx]i2c i2c-1:Can't create device at 0x51
對應的錯誤碼是 -16。
/kernel-5.10/include/uapi/asm-generic/errno-base.h #define EPERM 1 /* Operation not permitted */ #define ENOENT 2 /* No such file or directory */ #define ESRCH 3 /* No such process */ #define EINTR 4 /* Interrupted system call */ #define EIO 5 /* I/O error */ #define ENXIO 6 /* No such device or address */ #define E2BIG 7 /* Argument list too long */ #define ENOEXEC 8 /* Exec format error */ #define EBADF 9 /* Bad file number */ #define ECHILD 10 /* No child processes */ #define EAGAIN 11 /* Try again */ #define ENOMEM 12 /* Out of memory */ #define EACCES 13 /* Permission denied */ #define EFAULT 14 /* Bad address */ #define ENOTBLK 15 /* Block device required */ #define EBUSY 16 /* Device or resource busy */ ......
可以執行 ls /sys/bus/i2c/devices 檢視對應的 i2c-1 下是否已經有註冊相同的 address 的外設。
若返回 -11,-EAGAIN。代表匯流排正忙,或無法申請到匯流排鎖。如果匯流排正忙,請 retry 等待,或檢視是哪個 device 一直在傳送。如果無法申請到匯流排鎖,請檢視是否在中斷函式或原子上下文呼叫了 i2c_transfer。
(2)隱藏的 i2c address,即外設存在多個 i2c addr 或外設 HW bug,導致 i2c 通訊異常。
示例:eeprom 在 i2c-1 上註冊了 0x50 地址,而 type c 雖然註冊到 0x60 地址,但對 0x50 也能產生響應,type c 拉低了 SDA ,從而 timeout 。
debug 方法:
slave 在第 9 個 clk 產生 ACK 應答後,換成 mater 端來控制時產生的毛刺。此毛刺不會影響 I2C 匯流排讀寫時序,無需處理。
即 slave 和 master 控制匯流排切換間隔,沒有人控制匯流排,帶來的毛刺。
在外接上拉電阻的情況下,有 enable 內部下拉電阻,導致匯流排上有半高電平。
master 端傳送資料時電平拉不到地,可以增大驅動電流或者上拉電阻。
slave 端拉不到地,可以諮詢供應商看是否能增大 slave 端驅動電流或者上拉電阻。
來源於 firefly。
I2C 通訊失敗,出現 log: “timeout, ipd: 0x00, state: 1”
請檢查硬體上拉是否給電。
呼叫 i2c_transfer 返回值為 -6?
返回值為 -6 表示為 NACK 錯誤,即對方裝置無應答響應,這種情況一般為外設的問題,常見的有以下幾種情況:
當外設對於讀時序要求中間是 stop 訊號不是 repeat start 訊號的時候,該如何處理?
這時需要呼叫兩次 i2c_transfer, I2C read 拆分成兩次,修改如下:
static int i2c_read_bytes(struct i2c_client *client, u8 cmd, u8 *data, u8 data_len) {struct i2c_msg msgs[2]; int ret; u8 *buffer; buffer = kzalloc(data_len, GFP_KERNEL); if (!buffer) return -ENOMEM; msgs[0].addr = client->addr; msgs[0].flags = client->flags; msgs[0].len = 1; msgs[0].buf = &cmd; ret = i2c_transfer(client->adapter, msgs, 1); if (ret < 0) { dev_err(&client->adapter->dev, "i2c read failed\n"); kfree(buffer); return ret; } msgs[1].addr = client->addr; msgs[1].flags = client->flags | I2C_M_RD; msgs[1].len = data_len; msgs[1].buf = buffer; ret = i2c_transfer(client->adapter, &msgs[1], 1); if (ret < 0) dev_err(&client->adapter->dev, "i2c read failed\n"); else memcpy(data, buffer, data_len); kfree(buffer); return ret; }
相信以上的 I2C debug 方法已經能為大家解決大部分問題,如果還是沒解決,一般是晶片問題或者原廠底層 code bug,可以找晶片原廠支援。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69901823/viewspace-2903764/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 13. I2C通訊協議協議
- 通訊協議協議
- 5.7.2 ARM微控制器外設:I2C的通訊協議協議
- I2C協議協議
- Redis 通訊協議Redis協議
- HTTP通訊協議HTTP協議
- Mysql通訊協議MySql協議
- MQ通訊協議MQ協議
- web通訊協議Web協議
- modbus通訊協議協議
- 網路通訊協議協議
- Dubbo-通訊協議協議
- 串列埠通訊協議串列埠協議
- 網路通訊協議-ICMP協議詳解!協議
- 網路通訊協議-TCP協議詳解!協議TCP
- 網路通訊協議-HTTP協議詳解!協議HTTP
- 網路通訊協議-SMTP協議詳解!協議
- I2C子系統框架二框架
- 一起玩轉微服務(6)——通訊協議如何統一微服務協議
- 輕量通訊協議 --- MQTT協議MQQT
- HTTP協議的通訊框架HTTP協議框架
- WLAN常用的通訊協議協議
- 通訊協議:HTTP、TCP、UDP協議HTTPTCPUDP
- 15. SPI通訊協議協議
- IIC通訊協議筆記協議筆記
- SPI通訊協議筆記協議筆記
- 如何利用 Netty 實現自定義協議通訊?Netty協議
- 倍福ADS協議通訊協議
- 通訊協議之序列化協議
- 快速理解網路通訊協議協議
- 工業通訊協議(一)- CAN協議
- 通訊協議和網路協議有什麼區別協議
- 如何設計一個好的通訊網路協議協議
- 詳解通訊資料協議ProtoBuf協議
- 物聯網通訊協議介紹協議
- 陌陌通訊協議的學習協議
- 485通訊協議問題淺析協議
- 簡易遊戲通訊協議框架1.0遊戲協議框架