I2C是经常使用的一种bus方式,工程师们也经常调试I2C驱动设备;但是总会碰到各种各样的
问题;但是还有一种问题,就是非常小概率问题,又不好重现,怎么处理呢? 好在linux提供一种非常
牛逼的方法,可以在总线被挂住的情况下恢复,然后设备可以继续使用。下面就把相关的代理列举下。
但是你的平台是否配置此功能需要验证下,并打开相关的功能。
Linux I2C 总线驱动恢复机制!从代码看,非常明确的解释了I2C的工作机制和原理。
#define RECOVERY_CLK_CNT 9
static int i2c_generic_recovery(struct i2c_adapter *adap)
{
int i = 0, val = 1, ret = 0;
if (bri->prepare_recovery)
bri->prepare_recovery(adap);
bri->set_scl(adap, val);
ndelay(RECOVERY_NDELAY);
/*
* By this time SCL is high, as we need to give 9 falling-rising edges
*/
while (i++ < RECOVERY_CLK_CNT * 2) {
if (val) {
/* Break if SDA is high */
if (bri->get_sda && bri->get_sda(adap))
break;
/* SCL shouldn't be low here */
if (!bri->get_scl(adap)) {
dev_err(&adap->dev, "SCL is stuck low, exit recovery\n");
ret = -EBUSY;
break;
}
}
val = ! val; ///// 0 1 0 1 波形高低
bri->set_scl(adap, val);
ndelay(RECOVERY_NDELAY);
}
bri->get_sda = get_sda_gpio_value;
bri->get_scl = get_scl_gpio_value;
bri->set_scl = set_scl_gpio_value;
虽然在非不得已情况下,可以使用此方法,但是,最好的办法还是把根本的问题
解决好,这样不会留下什么后遗症。很多情况下是同一组I2C下,挂了多组设备,之间
没有协调好,另外上拉电阻硬件工程师没有算好,在统一大局下,匹配需要调好,多个
上拉电阻就会造成并联,阻值就会变小。