Re: i2c_burst_write API

Erwan Gouriou

Hi Piotr,

On 2 April 2017 at 23:52, Piotr Mienkowski <piotr.mienkowski@...> wrote:
Hi Erwan,

You may have solved your problem already, if not maybe you'll find the
following comment useful.

Sure, I'm glad to be able to discuss this topic.

The proper way to write data to an i2c device with a one byte internal
address (on a bus level) is as follows:

S Addr Wr [A] subAddr [A] Data [A] Data [A] ... [A] Data [A] P

S     (1 bit) : Start bit
P     (1 bit) : Stop bit
Rd/Wr (1 bit) : Read/Write bit. Rd equals 1, Wr equals 0.
A (1 bit) : Acknowledge bit.
Addr  (7 bits): I2C 7 bit device address.
subAddr  (8 bits): Internal address
Data  (8 bits): A plain data byte.

Which is what your sensor is expecting. If i2c_burst_write as
implemented by i2c_stm32lx.c driver generates

S Addr Wr [A] subAddr [A] S Addr Wr [A] Data [A] Data [A] ... [A] Data
[A] P

that's wrong. I don't have an STM32 MCU device to try it out but if I
look at the driver's code it seems to confuse I2C_MSG_STOP and
I2C_MSG_RESTART flags. The I2C_MSG_STOP flag is missing completely from
the source code and the decision whether to generate the stop bit is
based on I2C_MSG_RESTART flag. That feels wrong and would result exactly
in the kind of behavior you described.

Problem is actually a bit different.
Generated message is as follows (2 separated messages actually)
S Addr Wr [A] subAddr [A] P
S Addr Wr [A] Data [A] Data [A] ... [A] Data [A] P
I agree it could be optimized with a RESTART instead of the STOP/START sequence.
Though, it is still valid from I2C bus point of view, while not understood by sensor
"protocol" implementation (cf §5.1.1 in

For instance, for burst_read operation, same 2 messages sequence is
generated (second message being a read instruction)
S Addr Wr [A] subAddr [A] P
S Addr Rr [A] Data [A] Data [A] ... [A] Data [A] P
This sequence is correctly treated y sensor, even if the use of RESTART had
been a nicer of doing it (and with better performance on a loaded I2C bus).

I think the issue is, even if we replace STOP/START, having 2 messages
gets the driver generating (S address Wr) before data, and this is not expected by sensor.
S Addr Wr [A] subAddr [A] RS S Addr Wr [A] Data [A] Data [A] ... [A] Data
[A] P

If we agree the brust_write should generated the correct message you described,
I'm not sure this is up to driver to modify the 2 messages so we get the correct
single message.

It would be best to fix the driver code but a quick workaround is to use
i2c_write() function. The i2c device internal address subAddr should be
sent as buf[0] and the first data byte should be sent as buf[1].

Indeed, I've chosen this option in order to progress, and this just works.


Zephyr-devel mailing list

Join to automatically receive all group messages.