我有这个电源监视器,我正试图与之交互以检索它的故障日志 LTC2977(数据表:https ://www.analog.com/media/en/technical-documentation/data-sheets/ltc2977.pdf )
我是 i2c / pmbus / smbus 的新手,所以请原谅我糟糕的术语或对事物工作方式的不正确描述。在第 18 页,数据表声明我可以像这样与它进行交互:
LTC2977 是一个从器件。主器件可以使用以下格式与 LTC2977 通信:
- 主发送器,从接收器
- 主接收器,从发射器
支持以下 SMBus 协议:
- 写字节,写字,发送字节
- 读字节、读字、读块
- 警报响应地址
图 1a-12 说明了上述 SMBus 协议。所有事务都支持 PEC(数据包错误检查)和 GCP(组命令协议)。块读取支持 255 字节的返回数据。因此,可以使用 Mfr_config_all_longer_pmbus_timeout 设置延长 PMBus 超时。
可以使用 SMBus (PMBus?) 命令 0xEE 访问相关日志,其中将输出 0xFF 后跟包含日志数据的 255 个字节。现在我可以通过执行查看设备及其所有内部命令/寄存器(?)i2cdump
,同样,如果我这样做,i2cget ... 0xEE
我会得到输出0xff
,这就是日志中的第一个条目应该是什么。我也可以i2cget ... 0xEE w
,所以输出一个单词来获取0x--ff
每次调用i2cget
时“-”的值在哪里发生变化,也许是我的日志数据?
我的问题是我试图将其作为一个块来阅读,就像我在上面所说的文档一样。我不完全确定如何做到这一点,所以我尝试了以下方法:
device = open("/dev/i2c-0", O_RDWR);
ioctl(device, I2C_SLAVE_FORCE, 0x30); //0x30 is the i2c slave address
unsigned char buf[256] = {0};
buf[0] = 0xEE; //the smbus command of the log
write(device, buf, 1);
read(device, buf, 256);
过去我在其他 i2c 设备这样读取它们时取得了成功,首先发出命令,然后读入缓冲区。我之前成功使用过的最大缓冲区是 4 字节缓冲区,所以我认为这不会有什么不同,但是在此操作之后我的缓冲区的内容是现在每个条目都是0xff
我不认为是正确的,因为i2cget ... 0xEE w
有更多不仅仅是0xff
在里面。
接下来我尝试模拟一些我看到其他人使用的功能<smbus.h>
,我没有这个库可供我使用,所以我尝试重新创建 smbus 块读取功能,结果如下:
device = open("/dev/i2c-0", O_RDWR);
ioctl(device, I2C_SLAVE_FORCE, 0x30); //0x30 is the i2c slave address
union i2c_smbus_data data;
struct i2c_smbus_ioctl_data args;
args.read_write = I2C_SMBUS_READ;
args.command = 0xEE; //the smbus command of the log
args.size = I2C_SMBUS_BLOCK_DATA;
args.data = &data;
ioctl(device, I2C_SMBUS, &args);
不幸的是,这根本不起作用,它冻结了我的目标,我不得不重新启动它。我不确定这里出了什么问题,但我相信这是与设备交互的更合适或更正确的方式,如果我能让它工作的话。我注意到的一件事是块数据大小i2c_smbus_data
只有 32 字节,这令人困惑,因为我的数据表似乎表明它将向我发送一个 256 字节的块,这可能是导致它崩溃的原因吗?我读到你可以忽略这个内置的块大小并自己实现它,但我不确定从哪里开始,这和我第一次尝试写入和读取缓冲区不一样吗?
非常感谢任何帮助或了解如何正确使用此 SMBus 或读取日志数据的地方。我相信最坏的情况是我可以在 log 命令上检索一个单词 255 次来构建它,但这似乎是一个非常糟糕的方法