關於 K210 MaixPy 的 I2C 讀取設備,搜索不到設備,通信失敗的一些原因以及解決方案。


近來對 amigo 開發期間的遇到 I2C 問題做一下總結。

我們發現有一些 I2C 設備搜索不到,主要原因是 DATA 的信號衰減,也可能是 I2C 的總線被拉住了。

軟件層面的問題

例如在實現 Amigo 音頻設備,錄音與播放切換和重入功能實現,主要問題是 I2C 的傳輸超時問題。

如 amigo 的 ES8374 在通過 I2C 配置設備播放后,一條 4 設備的 I2C 變得很不穩定,排查后,發現通信失敗后, SDA 腳失敗后持續為低,理論上 I2C 驅動應該在判斷接收數據失敗后,恢復為 高, 但實際上沒有,所以現在的解決方法是重新配置為 GPIO 后手動拉高,然后就可以重新繼續工作了。

這個問題是因為 I2C 從機端 K210 給出數據,從機應答了,並且拉低的數據線表示我知道了,要返回數據,但實際上並沒有返回,而造成的結果就是,主機在等待從機的應答數據,從機也在等待主機的下一次讀取請求,但誰也沒辦法繼續運行了,理論上 K210 端在發現超時退出后應當恢復 I2C 總線的現場准備下一次的請求讀取,但實際並沒有進行這樣預期的處理,所以臨時的修復方案可以如下圖。

附帶代碼:


    # read reg value
    def _readReg(self, regAddr):
        while True:
            try:
                self.i2c_bus.writeto(self.i2c_addr, bytes([regAddr]))
                return (self.i2c_bus.readfrom(self.i2c_addr, 1))[0]
            except OSError as e:
                #print(e)
                from fpioa_manager import fm
                from Maix import GPIO
                tmp = fm.fpioa.get_Pin_num(fm.fpioa.I2C1_SDA)
                fm.register(tmp, fm.fpioa.GPIOHS15)
                sda = GPIO(GPIO.GPIOHS15, GPIO.OUT)
                sda.value(1)
                fm.register(tmp, fm.fpioa.I2C1_SDA, force=True)

    # write value to reg
    def _writeReg(self, regAddr, data):
        while True:
            try:
                return self.i2c_bus.writeto_mem(self.i2c_addr, regAddr, data, mem_size=8)
            except OSError as e:
                #print(e)
                from fpioa_manager import fm
                from Maix import GPIO
                tmp = fm.fpioa.get_Pin_num(fm.fpioa.I2C1_SDA)
                fm.register(tmp, fm.fpioa.GPIOHS15)
                sda = GPIO(GPIO.GPIOHS15, GPIO.OUT)
                sda.value(1)
                fm.register(tmp, fm.fpioa.I2C1_SDA, force=True)


需要注意的是,這個問題,應該遲早要在 BSP SDK 層面得到解決,內部的資源執行方式出了問題,考慮不周全。

硬件層面的問題

剛才我們說的是從軟件的角度發現問題,而另一種情況是完全於軟件無關的情況。

同一份代碼,如下讀取 RGB Sensor 的代碼,在 ESP32 上可以正常工作,但在 K210 上則無法正常工作,操作邏輯保持一致,也不受到執行時序的影響,從邏輯分析上出現的結果如下圖。

可以看到后者 K210 的信號發出后,從機並沒有做出 ACK 操作 DATA 線的應答,那此時的問題會是什么呢?

我們接一台示波器就可以發現了,主要原因是實際的信號有差異。

嗯,衰減的那個就是 K210 的(時好時壞),這種信號從機芯片不一定可以識別得到,實際輸出的信號與 下方 ESP32 輸出的信號對比一下就存在差距。

剩下就自己想想有什么辦法了,通常來說芯片 IO 上拉能力不夠可能會有這種現象,但實際是不是這樣呢?我們還是得檢討一下硬件線路和軟件IO配置才能解決具體的問題了,這已經超過了我對本質問題的理解,等我之后能完美解決再做出解答吧。

補 2020年9月9日

注意,最近得到了解到 I2C 的總線上存在上拉電阻的差異,通常 I2C 都是開漏輸出,所以需要一個外部的弱上拉電阻,那上拉電阻應該要多少呢,這里有一個參考 IIC為什么絕大多數時候都是帶有上拉電阻呢? , 這件事早在 STM32 時期就存在這些現象了,大多數人不會用硬件的 I2C ,然后都用 軟 I2C 的 GPIO 的推挽輸出來解決問題了,但實際上只是不了解應該要如何配合那個硬 I2C 的上拉。

如果使用 GPIO 上拉就可以將它恢復到最開始的狀態。

下次再說說 SPI 存在的問題吧~。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM