本来觉得I2C设备并没有什么好写的,直接把I2C设备往板子上一怼就是了,结果ls dev/* 一下发现只有一个i2c-2,也就是twi2
再观察一下原理图,
TWI只引出到了显示屏的接口上。FPC排线接口那么密,为了保护眼睛,肯定是不能直接飞线的。
硬的不行只能来软的了。
首先我们知道,D1有好几个I2C(TWI)接口,系统上只看到一个肯定是由于设备树上没有使能,那么我们只要在设备树里使能一下不就完了。
注意到板子上有4列 2.54的拓展插针接口,观察一下这些拓展接口有哪些可以复用为I2C,观察一下原理图,还真有:
可以看到B4 B5 / B3 B2 都可以,好的,那么接下来着手修改设备树就可以了。
<span>vim tina/device/config/chips/d1-h/configs/nezha/board.dts</span>
这里以nezha 作为例子,如果需要使用nezha_min请自行修改
找到twi1将其状态修改为okay
<span>&twi1 {
clock-frequency = <400000>;
pinctrl-0 = <&twi1_pins_a>;
pinctrl-1 = <&twi1_pins_b>;
pinctrl-names = default, sleep;
status = okay;
};</span>
如果要使用twi0, 需要修改GPIO为B3/B2, 默认twi0的GPIO不是这俩。
修改完后,重新编译打包,烧录,兴冲冲一测试:
<span>i2cdetect -y -a 1</span>
结果输出了一堆:
<span>[ 253.507438] sunxi_i2c_do_xfer()1816 - [i2c1] incomplete xfer (status: 0x20, dev addr: 0x0)
-- [ 253.589885] twi_stop()478 - [i2c1] STOP can't sendout!
[ 253.595653] sunxi_i2c_core_process()1632 - [i2c1] STOP failed!
[ 253.602359] sunxi_i2c_do_xfer()1816 - [i2c1] incomplete xfer (status: 0x20, dev addr: 0x1)
-- [ 253.684285] twi_stop()478 - [i2c1] STOP can't sendout!
[ 253.690051] sunxi_i2c_core_process()1632 - [i2c1] STOP failed!
[ 253.696786] sunxi_i2c_do_xfer()1816 - [i2c1] incomplete xfer (status: 0x20, dev addr: 0x2)
-- [ 253.779930] twi_stop()478 - [i2c1] STOP can't sendout!
[ 253.785696] sunxi_i2c_core_process()1632 - [i2c1] STOP failed!
[ 253.792433] sunxi_i2c_do_xfer()1816 - [i2c1] incomplete xfer (status: 0x20, dev addr: 0x3)
-- [ 253.875845] twi_stop()478 - [i2c1] STOP can't sendout!
[ 253.881611] sunxi_i2c_core_process()1632 - [i2c1] STOP failed!
[ 253.888371] sunxi_i2c_do_xfer()1816 - [i2c1] incomplete xfer (status: 0x20, dev addr: 0x4)
-- [ 253.967612] twi_stop()478 - [i2c1] STOP can't sendout!
[ 253.973380] sunxi_i2c_core_process()1632 - [i2c1] STOP failed!
[ 253.980128] sunxi_i2c_do_xfer()1816 - [i2c1] incomplete xfer (status: 0x20, dev addr: 0x5)
-- [ 254.062125] twi_stop()478 - [i2c1] STOP can't sendout!
[ 254.067891] sunxi_i2c_core_process()1632 - [i2c1] STOP failed!
[ 254.074621] sunxi_i2c_do_xfer()1816 - [i2c1] incomplete xfer (status: 0x20, dev addr: 0x6)
-- [ 254.156403] twi_stop()478 - [i2c1] STOP can't sendout!
[ 254.162169] sunxi_i2c_core_process()1632 - [i2c1] STOP failed!
[ 254.168921] sunxi_i2c_do_xfer()1816 - [i2c1] incomplete xfer (status: 0x20, dev addr: 0x7)
-- [ 254.251204] twi_stop()478 - [i2c1] STOP can't sendout!
[ 254.256970] sunxi_i2c_core_process()1632 - [i2c1] STOP failed!
[ 254.263702] sunxi_i2c_do_xfer()1816 - [i2c1] incomplete xfer (status: 0x20, dev addr: 0x8)
-- [ 254.343745] twi_stop()478 - [i2c1] STOP can't sendout!
[ 254.349513] sunxi_i2c_core_process()1632 - [i2c1] STOP failed!
[ 254.356258] sunxi_i2c_do_xfer()1816 - [i2c1] incomplete xfer (status: 0x20, dev addr: 0x9)</span>
虽然可以看出确实是在遍历了,但总感觉哪里不对。仔细看了下报错内容,说I2C无法发送STOP信号。
想了一下,I2C的STOP信号其实就是把SDA拉高,那么显然是SDA无法拉高。为什么SDA无法拉高呢?
众所周知I2C是OD输出,OD输出只能通过上拉电阻拉高,而我没有接传感器(一般传感器会在I2C接口接上拉电阻,防止你不懂得接上拉电阻用不了然后说他卖假货23333),且这个板子也没给这两个引脚接上拉电阻,所以SDA无法拉高是正常的。
好了,那么接下来接上设备试试,特地仔细观察了一下我这个I2C 设备,人家确实是有上拉电阻的,如果还不行可能不能甩锅了。
我使用的芯片是ADS1015,手册ADS1015 数据表、产品信息和支持 | 德州仪器 TI.com.cn, ADDR为 0x48 (ADR脚接地)
可以看到正常探测到0x48了,不过这个输出跟一般的i2cdetect不太一样,如我的其他板子:
主要的区别其实就是多打印了一些东西,这个应该是编译内核的默认设置不同,这里就不管了。