记录说明


原本这么简单的芯片,没有必要做记录,后来发现其中有一颗单独挂在 TWI2 无法通信,而主要原因是最容易忽视的电源域的问题,因此记录一下这件事情。

芯片介绍


MCP3021 是一颗 10BIT 的 ADC 器件,直接通过 I2C 读取两个字节的数据即可获取到 10BIT 的数值。

分析过程


内核版本:Linux version 4.9.56

幸得全志在线的 Syter 提醒了一下,不然估计还得捣鼓一阵,在此感谢 Syter:

  1. 使用 i2cdetect -y 2 无法检测到芯片,意味着无法通信。
  2. TWI2 与其它 TWI 的一样都是通过 10K 上拉到 3.3V,但是测量发现只有 TWI2 是 1.5V。
  3. 通过手动设置 PE14\PE15 为 GPIO 口模式,并设置输入,测量只有 1.5V。
  4. 通过手动设置 PE14\PE15 为 GPIO 口模式,并设置输出高电平,测量只有 1.2V。
  5. 拆除唯一一颗挂在 TWI2 上面的 MCP3021A5T-E 芯片,测试结果和上面一样。
  6. 后发现 TWI2 与 TWI0\TWI1 唯一不同的是不 TWI2 属于 PE 组,其它共属 PH 组。
  7. 测量 PE 组 GPIO 的电源域,只有 1V 左右,通过设置并使能 3.3V VCC-PE,测量上拉电压正常。
  8. 经过测试,可以正常通信,问题得到解决,PE 组没有供电,测量的 1V 应该是通过上拉电阻串进去的电。

如何使能指定组的 GPIO 电源域,取决于实际电路从哪取的电源,如果是 PMU 的某一路电源,只需启用该路电压并设置为 1003300 即可,如:

[power_sply]
......
gpio1_vol                  = 1003300

应用方法


一、确认器件地址

型号 器件地址
MCP3021A0T-E 0x48
MCP3021A1T-E 0x49
MCP3021A2T-E 0x4A
MCP3021A3T-E 0x4B
MCP3021A4T-E 0x4C
MCP3021A5T-E 0x4D
MCP3021A6T-E 0x4E
MCP3021A7T-E 0x4F

二、启用 I2C 控制器

[twi2]
twi2_used        = 1
twi2_scl         = port:PE14<3><default><default><default>
twi2_sda         = port:PE15<3><default><default><default>

[twi2_suspend]
twi2_scl         = port:PE14<7><default><default><default>
twi2_sda         = port:PE15<7><default><default><default>

三、命令行测试验证

数据读取:

root@localhost:~# i2ctransfer -y -f 0 r2@0x4d
0x01 0x2c

数据解析:

1. 高字节:0x01 --> 0000 0001 --> 取低四位:0001 
2. 低字节:0x2c --> 0010 1100 --> 取高六位:0010 11
3. 合并字节:0001 0010 11 --> 0001001011 --> 75
4. 换算电压:75 * 3.3 / (2^10) = 0.24V 与万用表测量电压基本一致。