PMBus / SMBus / i2c repeated start?

Hi all,

I am implementing a driver for Flex PIM4328PD component.

What function should I use for so-called “Block Write-Block Read Process Call” based communication, such as PMBus, SMBus, or at least i2c repeated start framing ?

Best regards,
Sylvain@LAPP

Hello Sylvain,

you are actually the first user to request PMbus commands. I assume you are referring to the block read/write commands on page 41/42 here:

http://smbus.org/specs/SMBus_3_1_20180319.pdf

In this case you should be able to use the following command for a read:

char i2c_dev_read_reg(unsigned short addr, unsigned char reg, unsigned char *pdata, unsigned char size)

“reg” would be the PMbus command (e.g. MFR_ID) and “size” the expected number of bytes to read from the device. This should be one more than the data size (e.g. 8+1), since the first data byte from the device will contain the number of data bytes.

For a block write you can use the following function, however this should be less common in a sensor driver:

char i2c_dev_write_reg(unsigned short addr, unsigned char reg, unsigned char *pdata, unsigned char size)

Again, “reg” is the PMBus command, “pdata” is a pointer to the data to write and “size” is the number of bytes. The first byte should contain the number of data bytes to be written according to the SMBus specification.

In both cases the “addr” parameter should contain the I2C address of the device (8-bit address format) in the lower byte, the upper byte encodes the I2C bus to use (1 for the MGT bus, 2 for the SNS bus).

Let me know if you have any issues.

Best regards,

Stefan

Hello Sylvain,

just to add that this is assuming the device does not require PEC, but I found no mention of it in the data sheet.

Best regards,

Stefan

Thank you Stefan for your support. I will try your solution ASAP and keep you updated.

Hi Stefan,

Sadly your proposition does not work :frowning:
With this method, the coefficients I get for temperature reading are: 0xFFFFFFFFFF, but they should be 0xFE0000197F.

According to my local expert, and also PMBus and SMBus specifications, an i2c repeated start is mandatory to communicate properly with our PIM.

So what function should I use to do this please ?

Best regards,
Sylvain@LAPP

Hello Sylvain,

I’m afraid there was a misunderstanding, I thought you wanted to do a block read (which should work with the existing functions). However the PMBus COEFFICIENTS command that you apparently want to use is different: the host performs a write cycle with 4 bytes to the slave followed by a repeated start and a read of a given number of bytes. The function I suggested previously only writes a single byte before the repeated start and the read cycle. Could you therefore please try the following function instead:

i2c_dev_read_4bytesReg(unsigned short addr, unsigned int wr_data, unsigned char *rd_data, unsigned char size)

The <wr_data> parameter should be set as follows, where in an unsigned char with the command code according to the PMBus specification.

#define PMBUS_COEFFICIENTS 0x30
unsigned int wr_data = ( 0x1000200 | (cmd << 16) | PMBUS_COEFFICIENTS);

The parameter should be set to one more than the number of bytes than you expect to read (i.e. 6 in the case of the COEFFICIENTS command), or two more in the case there is a PEC byte. The fist byte in <rd_data> will be the number of bytes output from the device (i.e. 5) followed by the coefficients data and possibly a PEC byte.

Could you please give this a try? I hope there is no mistake, but we do unfortunately not have any board with a device that supports the PMBus COEFFICIENTS command, so we can’t really test it.

cheers,

Stefan

1 Like

Hooray I now receive my coef !
Thank you again.

It was really not obvious to me that i2c_dev_read_4bytesReg(…) was doing just that under the hood.

Hello Sylvain,

glad to hear that it worked.