mt6762在连接一些外设时,i2c在低电平会拉不低的情况,最低电平在0.4V左右.这时需要去掉外设的上拉电阻或调整硬件i2c的驱动电流.
修改文件路径:
vendor/mediatek/proprietary/bootable/bootloader/preloader/platform/mt6765/src/drivers/i2c.c
修改函数:
int i2c_hw_init(void)
1 修改上拉电阻
/* Switch internal resistor */
/* 0x0:75k 0x1:5k */
/* 0x2:15k 0x3:1k */
/*I2C0,1*/
I2C_SET_REG32(0x10002a00 + 0x70, 0xFF, 0xFF);
/*I2C2,4*/
I2C_SET_REG32(0x10002800 + 0xA0, 0xFF, 0xFF);
/*I2C6*/
I2C_SET_REG32(0x10002c00 + 0x70, 0xF, 0xF);
/*I2C3,5*/
I2C_SET_REG32(0x10002600 + 0xb0, 0xFF, 0xFF);
2修改驱动电流
/* Just for MT6765/MT6762, config driving set EH2,EH1= 2'b01 */
/* EH: 1, i2c mode;0, GPIO mode */
/* [EH2,EH1]: 2'b00,0.31;2'b01,0.61;2'b10,1.1;2'b11,1.41 单位为mA*/
/* [EH,EH2,EH1] = [bit2,bit1,bit0] */
/*I2C0,1*/
I2C_SET_REG32((0x10002a00 + 0x20), 0x0FFF, 0x0B6D);
/*I2C2,4*/
I2C_SET_REG32((0x10002800 + 0x20), 0x0FFF, 0x0B6D);
/*I2C6*/
I2C_SET_REG32((0x10002c00 + 0x20), 0x3F, 0x2D);
/*I2C3,5*/
I2C_SET_REG32((0x10002600 + 0x20), 0x0FFF, 0x0B6D);
3我们以i2c4为例,修改其内部上拉电阻与驱动电流看波形有哪些影响.
设置i2c4,DWS i2c4配置为Pull&Push En打勾
(1)上拉电阻为1K,2b'11
/*I2C2,4*/
I2C_SET_REG32(0x10002800 + 0xA0, 0xFF, 0xFF);
驱动电流为1.1mA,[EH,EH2,EH1] = 2b'110
/*I2C2,4*/
I2C_SET_REG32((0x10002800 + 0x20), 0x0FFF, 0x0B6D);
对应波形如下
可见i2c第九个clk为读取ACK的电平没有完全拉地低.
(2)上拉电阻为1K,2b'11
/*I2C2,4*/
I2C_SET_REG32(0x10002800 + 0xA0, 0xFF, 0xFF);
驱动电流为1.41mA,[EH,EH2,EH1] = 2b'111
/*I2C2,4*/
I2C_SET_REG32((0x10002800 + 0x20), 0x0FFF, 0x0FFF);
对应波形如下
可见驱动电流增加波形没改善.
(3)上拉电阻为15K,2b'10
/*I2C2,4*/
I2C_SET_REG32(0x10002800 + 0xA0, 0xFF, 0xAA);
驱动电流为1.41mA,[EH,EH2,EH1] = 2b'111
/*I2C2,4*/
I2C_SET_REG32((0x10002800 + 0x20), 0x0FFF, 0x0FFF);
对应波形如下
可见增大上拉电阻,2c第九个clk为读取ACK的电平完全拉低,但是第9个CLK后高电平建立时间变长.
(4)上拉电阻为75K,2b'00
/*I2C2,4*/
I2C_SET_REG32(0x10002800 + 0xA0, 0xFF, 0x00);
驱动电流为1.41mA,[EH,EH2,EH1] = 2b'111
/*I2C2,4*/
I2C_SET_REG32((0x10002800 + 0x20), 0x0FFF, 0x0FFF);
对应波形如下
可见上拉电阻越大,第9个CLK后高电平建立时间越长.
4 如果直接把DWS i2c4配置为Pull&Push En打勾去掉
高低电平建立的时间会变长,波形有畸变,如下图
5 总结,
mt6762在连接一些外设时,i2c在低电平会拉不低的情况时,可以尝试从外部更改外部上拉电阻,i2c内部上拉电阻,以及寄存器修改驱动电流三个方面去优化i2c的波形,适配对应外设i2c波形,达到满足i2c数据通行的要求.