1

我有这个电源监视器,我正试图与之交互以检索它的故障日志 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 次来构建它,但这似乎是一个非常糟糕的方法

4

1 回答 1

0

好的,我已经设法找到了一个解决方案,类似于 2. 的混合设置I2C_SLAVE不再完成(这是否会导致同一 I2C 缓冲区上的其他设备出现问题?我不知道),而是读取直接使用 执行I2C_RDWR,其中传递了 2 个 i2c 消息,第一个使用 smbus 命令/子地址写入,第二个读取那里的数据。

device = open("/dev/i2c-0", O_RDWR);

unsigned char buf[256] = {0};
buf[0] = 0xEE; //the smbus command of the log

struct i2c_msg msgs[2];
msgs[0].addr = 0x30;
msgs[0].flags = 0;
msgs[0].len = 1;
msgs[0].buf = buf;

msgs[1].addr = 0x30;
msgs[1].flags = I2C_M_RD;
msgs[1].len = 256;
msgs[1].buf = buf;

struct i2c_rdwr_ioctl_data args;
args.msgs = msgs;
args.nmsgs = 2;

ioctl(device, I2C_RDWR, &args);

我注意到的一个问题是设备出现了错误的通信错误(尽管为我提供了正确的数据)。数据表指出,这是“非法形成的 i2c/smbus 命令”的全部错误,我猜这意味着我做了一些不太正确的事情。希望对为什么会这样的任何评论

于 2022-01-14T23:01:18.170 回答