Topics

i2c_burst_write API


Erwan Gouriou
 

Hi all,


I'm having trouble using i2c_burst_write to configure several registers
in one shot in a sensor (using i2c_stm32lx.c driver).

According to API description, it seems to be the adequate use:
" This routine writes multiple bytes to an internal address of an
I2C device synchronously."

Following implementation, it generates 2 messages as follow:
Slave ADdress|Write * SUB-Address (register of the sensor where I'd like to start writing)
Slave ADdress|Write * DATA
It doesn't work for me since sensor is expecting one single message:
SAD|W * SUB * ADD

I've found several examples of sensor supporting the later but not the former.
Though, in Zephyr code, I've found some uses of i2c_burst_write API,
hence I tend to think it should work somehow in some cases.

Hence my questions to you:

Are there actually several ways to address an I2C slave for burst write?
> If yes, I'll just avoid using this API. But it might be worse specifying that
it might not fit all slaves implementations.

Is that due to underlying I2C drivers that do some messages concatenation
magic before sending to slave devices?
> If yes, maybe this is a sign API should be adapted to be more transparent

Any other possibility that I don't have in mind right now?


Thanks
Erwan



 







Piotr Mienkowski
 

Hi Erwan,

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

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

Where:

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.

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].

Cheers,
Piotr


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
 
Where:

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.

Agreed.
 
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 https://goo.gl/sfflM6)

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.

Cheers,
Piotr

_______________________________________________
Zephyr-devel mailing list
Zephyr-devel@lists.zephyrproject.org
https://lists.zephyrproject.org/mailman/listinfo/zephyr-devel


Piotr Mienkowski
 

On 03.04.2017 10:23, Erwan Gouriou wrote:
On 2 April 2017 at 23:52, Piotr Mienkowski <piotr.mienkowski@...> wrote:
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
 
Where:

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.

Agreed.
 
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
Thanks for the correction. Yes, this behavior makes more sense but it is still an invalid implementation on part of the i2c_stm32lx.c driver.
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).
This would be also an invalid behavior and not following the specification. In case of read operation from an internal address the driver must use RESTART.
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.
Yes, I believe we should fix the driver code. The main purpose of i2c_transfer() and all subsequent functions using it, like i2c_burst_write, is to allow generation of these combined messages. Otherwise the i2c_read, i2c_write functions would fully suffice.

--
Piotr


Erwan Gouriou
 



On 3 April 2017 at 11:18, Piotr Mienkowski <piotr.mienkowski@...> wrote:
On 03.04.2017 10:23, Erwan Gouriou wrote:
On 2 April 2017 at 23:52, Piotr Mienkowski <piotr.mienkowski@...> wrote:
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
 
Where:

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.

Agreed.
 
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
Thanks for the correction. Yes, this behavior makes more sense but it is still an invalid implementation on part of the i2c_stm32lx.c driver.

Invalid and not working, it has to be fixed. My issue  is which part
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).
This would be also an invalid behavior and not following the specification. In case of read operation from an internal address the driver must use RESTART.

Agreed. Driver should be fixed to generated RESTART instead of STOP/START.
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.
Yes, I believe we should fix the driver code. The main purpose of i2c_transfer() and all subsequent functions using it, like i2c_burst_write, is to allow generation of these combined messages. Otherwise the i2c_read, i2c_write functions would fully suffice.

Sorry if I missed an element, but I'm not sure to get your point here.
As you described, for burst write operation, only one message has to be sent,
S Addr Wr [A] subAddr [A] Data [A] Data [A] ... [A] Data [A] P
(unlike for burst read where 2 messages are expected).

If we keep the burst write API as is, we define an incorrect sequence of 2 messages:
    msg[0].buf = &start_addr;
    msg[0].len = 1;
    msg[0].flags = I2C_MSG_WRITE;

    msg[1].buf = buf;
    msg[1].len = num_bytes;
    msg[1].flags = I2C_MSG_WRITE | I2C_MSG_STOP;

and then expect the driver to generate a correct single message.
I mean this is doable, but adds unneeded complexity and would require to
explicit the contact in the API.

Erwan

--
Piotr


Jon Medhurst (Tixy) <tixy@...>
 

On Mon, 2017-04-03 at 11:55 +0200, Erwan Gouriou wrote:
[...]
As you described, for burst write operation, only one message has to be
S Addr Wr [A] subAddr [A] Data [A] Data [A] ... [A] Data [A] P
(unlike for burst read where 2 messages are expected).

If we keep the burst write API as is, we define an incorrect sequence of 2
messages:
msg[0].buf = &start_addr;
msg[0].len = 1;
msg[0].flags = I2C_MSG_WRITE;

msg[1].buf = buf;
msg[1].len = num_bytes;
msg[1].flags = I2C_MSG_WRITE | I2C_MSG_STOP;
In what way is that incorrect? msg[0] doesn't have I2C_MSG_STOP and
msg[1] doesn't have I2C_MSG_START or I2C_MSG_RESTART, so that is a
correct way of specifying the single write message you want to appear on
the i2c bus.

and then expect the driver to generate a correct single message.
I mean this is doable, but adds unneeded complexity and would require to
explicit the contact in the API.
If the driver inserts stop/start/restart bits between msg[0] and msg[1]
then it isn't implementing the API correctly and should be fixed.

--
Tixy


Erwan Gouriou
 



On 3 April 2017 at 12:35, Jon Medhurst (Tixy) <tixy@...> wrote:
On Mon, 2017-04-03 at 11:55 +0200, Erwan Gouriou wrote:
[...]
> As you described, for burst write operation, only one message has to be
> S Addr Wr [A] subAddr [A] Data [A] Data [A] ... [A] Data [A] P
> (unlike for burst read where 2 messages are expected).
>
> If we keep the burst write API as is, we define an incorrect sequence of 2
> messages:
>     msg[0].buf = &start_addr;
>     msg[0].len = 1;
>     msg[0].flags = I2C_MSG_WRITE;
>
>     msg[1].buf = buf;
>     msg[1].len = num_bytes;
>     msg[1].flags = I2C_MSG_WRITE | I2C_MSG_STOP;

In what way is that incorrect? msg[0] doesn't have I2C_MSG_STOP and
msg[1] doesn't have I2C_MSG_START or I2C_MSG_RESTART, so that is a
correct way of specifying the single write message you want to appear on
the i2c bus.

My view (but this could be an error from my part), is that defining a message
involves having a header byte (Slave Address | Write) being issued before payload.
Payload being:
*subaddress (or start address) in the first msg[0]
*data in msg[1]

Hence, when we define 2 messages, we get, if we set RESTART correctly
msg[0]: S Addr Wr [A] subAddr [A] RS
msg[1]: Addr Wr [A] Data [A] Data [A] ... [A] Data [A] P

Serialized, this gets:
S Addr Wr [A] subAddr [A] RS Addr Wr [A] Data [A] Data [A] ... [A] Data [A] P

While, as explained by Piotr, expected single message (for a burst write) is:
S Addr Wr [A] subAddr [A] Data [A] Data [A] ... [A] Data [A] P

My only issue/question is the message header of the second message that
does not seem to fit the expected sequence (detailed here for instance:
 §5.1.1 in https://goo.gl/sfflM6). And even if we set the correct RESTART
flag, it is not expected by slave (unlike a burst read sequence)
Or there are other possible sequences that I am not aware of.

> and then expect the driver to generate a correct single message.
> I mean this is doable, but adds unneeded complexity and would require to
> explicit the contact in the API.

If the driver inserts stop/start/restart bits between msg[0] and msg[1]
then it isn't implementing the API correctly and should be fixed.

I agree driver should insert START/STOP/RESTART as defined by API and
specification or be fixed otherwise.


--
Tixy


Jon Medhurst (Tixy) <tixy@...>
 

On Mon, 2017-04-03 at 13:39 +0200, Erwan Gouriou wrote:
On 3 April 2017 at 12:35, Jon Medhurst (Tixy) <tixy@linaro.org> wrote:

On Mon, 2017-04-03 at 11:55 +0200, Erwan Gouriou wrote:
[...]
As you described, for burst write operation, only one message has to be
S Addr Wr [A] subAddr [A] Data [A] Data [A] ... [A] Data [A] P
(unlike for burst read where 2 messages are expected).

If we keep the burst write API as is, we define an incorrect sequence of
2
messages:
msg[0].buf = &start_addr;
msg[0].len = 1;
msg[0].flags = I2C_MSG_WRITE;

msg[1].buf = buf;
msg[1].len = num_bytes;
msg[1].flags = I2C_MSG_WRITE | I2C_MSG_STOP;
In what way is that incorrect? msg[0] doesn't have I2C_MSG_STOP and
msg[1] doesn't have I2C_MSG_START or I2C_MSG_RESTART, so that is a
correct way of specifying the single write message you want to appear on
the i2c bus.

My view (but this could be an error from my part), is that defining a
message
involves having a header byte (Slave Address | Write) being issued before
payload.
Payload being:
*subaddress (or start address) in the first msg[0]
*data in msg[1]

Hence, when we define 2 messages, we get, if we set RESTART correctly
msg[0]: S Addr Wr [A] subAddr [A] RS
msg[1]: Addr Wr [A] Data [A] Data [A] ... [A] Data [A] P
Why do you want to send a RESTART? In the doc you link to, in 
Table 13 "Transfer when master is writing multiple bytes to slave",
it doesn't specify a restart. It lists the same sequence as Zephyr's
i2c_burst_write() function implements.

A restart is needed for reads (Table 15) because you need a way of
changing from write mode (sending address) to read mode (reading bytes).
And that's what i2c_burst_read() does.

Serialized, this gets:
S Addr Wr [A] subAddr [A] RS *Addr Wr [A]* Data [A] Data [A] ... [A] Data
[A] P
And in message after your restart, the i2c device will possibly use the
first Data byte as the 'subAddr' to use, and then write your second Data
byte to that address, which is probably not what you want.

While, as explained by Piotr, expected single message (for a burst write)
is:
S Addr Wr [A] subAddr [A] Data [A] Data [A] ... [A] Data [A] P
Which is the same as the document for your device specifies (Table 13
again).

--
Tixy


Erwan Gouriou
 



On 3 April 2017 at 17:53, Jon Medhurst (Tixy) <tixy@...> wrote:
On Mon, 2017-04-03 at 13:39 +0200, Erwan Gouriou wrote:
> On 3 April 2017 at 12:35, Jon Medhurst (Tixy) <tixy@...> wrote:
>
> > On Mon, 2017-04-03 at 11:55 +0200, Erwan Gouriou wrote:
> > [...]
> > > As you described, for burst write operation, only one message has to be
> > > S Addr Wr [A] subAddr [A] Data [A] Data [A] ... [A] Data [A] P
> > > (unlike for burst read where 2 messages are expected).
> > >
> > > If we keep the burst write API as is, we define an incorrect sequence of
> >
> > 2
> > > messages:
> > >     msg[0].buf = &start_addr;
> > >     msg[0].len = 1;
> > >     msg[0].flags = I2C_MSG_WRITE;
> > >
> > >     msg[1].buf = buf;
> > >     msg[1].len = num_bytes;
> > >     msg[1].flags = I2C_MSG_WRITE | I2C_MSG_STOP;
> >
> > In what way is that incorrect? msg[0] doesn't have I2C_MSG_STOP and
> > msg[1] doesn't have I2C_MSG_START or I2C_MSG_RESTART, so that is a
> > correct way of specifying the single write message you want to appear on
> > the i2c bus.
> >
> > My view (but this could be an error from my part), is that defining a
>
> message
> involves having a header byte (Slave Address | Write) being issued before
> payload.
> Payload being:
> *subaddress (or start address) in the first msg[0]
> *data in msg[1]
>
> Hence, when we define 2 messages, we get, if we set RESTART correctly
> msg[0]: S Addr Wr [A] subAddr [A] RS
> msg[1]: Addr Wr [A] Data [A] Data [A] ... [A] Data [A] P

Why do you want to send a RESTART? In the doc you link to, in 
Table 13 "Transfer when master is writing multiple bytes to slave",
it doesn't specify a restart. It lists the same sequence as Zephyr's
i2c_burst_write() function implements.

A restart is needed for reads (Table 15) because you need a way of
changing from write mode (sending address) to read mode (reading bytes).
And that's what i2c_burst_read() does.

> Serialized, this gets:
> S Addr Wr [A] subAddr [A] RS *Addr Wr [A]* Data [A] Data [A] ... [A] Data
> [A] P

And in message after your restart, the i2c device will possibly use the
first Data byte as the 'subAddr' to use, and then write your second Data
byte to that address, which is probably not what you want.

> While, as explained by Piotr, expected single message (for a burst write)
> is:
> S Addr Wr [A] subAddr [A] Data [A] Data [A] ... [A] Data [A] P

Which is the same as the document for your device specifies (Table 13
again).

Exact, I just don't see why we specify 2 messages in API (msg[0] and msg[1]),
if we want driver to send one single message.
There should be a reason, but I don't get it, and this was basically my initial
question (sorry if this was not clear enough).


--
Tixy


Jon Medhurst (Tixy) <tixy@...>
 

On Mon, 2017-04-03 at 18:10 +0200, Erwan Gouriou wrote:
On 3 April 2017 at 17:53, Jon Medhurst (Tixy) <tixy@linaro.org> wrote:

On Mon, 2017-04-03 at 13:39 +0200, Erwan Gouriou wrote:
On 3 April 2017 at 12:35, Jon Medhurst (Tixy) <tixy@linaro.org> wrote:

On Mon, 2017-04-03 at 11:55 +0200, Erwan Gouriou wrote:
[...]
As you described, for burst write operation, only one message has to
be
S Addr Wr [A] subAddr [A] Data [A] Data [A] ... [A] Data [A] P
(unlike for burst read where 2 messages are expected).

If we keep the burst write API as is, we define an incorrect
sequence of

2
messages:
msg[0].buf = &start_addr;
msg[0].len = 1;
msg[0].flags = I2C_MSG_WRITE;

msg[1].buf = buf;
msg[1].len = num_bytes;
msg[1].flags = I2C_MSG_WRITE | I2C_MSG_STOP;
In what way is that incorrect? msg[0] doesn't have I2C_MSG_STOP and
msg[1] doesn't have I2C_MSG_START or I2C_MSG_RESTART, so that is a
correct way of specifying the single write message you want to appear
on
the i2c bus.

My view (but this could be an error from my part), is that defining a
message
involves having a header byte (Slave Address | Write) being issued before
payload.
Payload being:
*subaddress (or start address) in the first msg[0]
*data in msg[1]

Hence, when we define 2 messages, we get, if we set RESTART correctly
msg[0]: S Addr Wr [A] subAddr [A] RS
msg[1]: Addr Wr [A] Data [A] Data [A] ... [A] Data [A] P
Why do you want to send a RESTART? In the doc you link to, in
Table 13 "Transfer when master is writing multiple bytes to slave",
it doesn't specify a restart. It lists the same sequence as Zephyr's
i2c_burst_write() function implements.

A restart is needed for reads (Table 15) because you need a way of
changing from write mode (sending address) to read mode (reading bytes).
And that's what i2c_burst_read() does.

Serialized, this gets:
S Addr Wr [A] subAddr [A] RS *Addr Wr [A]* Data [A] Data [A] ... [A] Data
[A] P
And in message after your restart, the i2c device will possibly use the
first Data byte as the 'subAddr' to use, and then write your second Data
byte to that address, which is probably not what you want.

While, as explained by Piotr, expected single message (for a burst write)
is:
S Addr Wr [A] subAddr [A] Data [A] Data [A] ... [A] Data [A] P
Which is the same as the document for your device specifies (Table 13
again).

Exact, I just don't see why we specify 2 messages in API (msg[0] and
msg[1]),
if we want driver to send one single message.
There should be a reason, but I don't get it, and this was basically my
initial
question (sorry if this was not clear enough).
I expect the message is specified in two parts so we don't have to
create a buffer of arbitrary length and copy the data to it just so we
can prepend the address byte. (The SPI API has that flaw, and several
months ago there was an RFC to fix that, but I've not seen anything
since.)

The i2c interface at least has total flexibility on how you construct
messages.

--
Tixy


Erwan Gouriou
 



On 3 April 2017 at 18:19, Jon Medhurst (Tixy) <tixy@...> wrote:
On Mon, 2017-04-03 at 18:10 +0200, Erwan Gouriou wrote:
> On 3 April 2017 at 17:53, Jon Medhurst (Tixy) <tixy@...> wrote:
>
> > On Mon, 2017-04-03 at 13:39 +0200, Erwan Gouriou wrote:
> > > On 3 April 2017 at 12:35, Jon Medhurst (Tixy) <tixy@...> wrote:
> > >
> > > > On Mon, 2017-04-03 at 11:55 +0200, Erwan Gouriou wrote:
> > > > [...]
> > > > > As you described, for burst write operation, only one message has to
> >
> > be
> > > > > S Addr Wr [A] subAddr [A] Data [A] Data [A] ... [A] Data [A] P
> > > > > (unlike for burst read where 2 messages are expected).
> > > > >
> > > > > If we keep the burst write API as is, we define an incorrect
> >
> > sequence of
> > > >
> > > > 2
> > > > > messages:
> > > > >     msg[0].buf = &start_addr;
> > > > >     msg[0].len = 1;
> > > > >     msg[0].flags = I2C_MSG_WRITE;
> > > > >
> > > > >     msg[1].buf = buf;
> > > > >     msg[1].len = num_bytes;
> > > > >     msg[1].flags = I2C_MSG_WRITE | I2C_MSG_STOP;
> > > >
> > > > In what way is that incorrect? msg[0] doesn't have I2C_MSG_STOP and
> > > > msg[1] doesn't have I2C_MSG_START or I2C_MSG_RESTART, so that is a
> > > > correct way of specifying the single write message you want to appear
> >
> > on
> > > > the i2c bus.
> > > >
> > > > My view (but this could be an error from my part), is that defining a
> > >
> > > message
> > > involves having a header byte (Slave Address | Write) being issued before
> > > payload.
> > > Payload being:
> > > *subaddress (or start address) in the first msg[0]
> > > *data in msg[1]
> > >
> > > Hence, when we define 2 messages, we get, if we set RESTART correctly
> > > msg[0]: S Addr Wr [A] subAddr [A] RS
> > > msg[1]: Addr Wr [A] Data [A] Data [A] ... [A] Data [A] P
> >
> > Why do you want to send a RESTART? In the doc you link to, in
> > Table 13 "Transfer when master is writing multiple bytes to slave",
> > it doesn't specify a restart. It lists the same sequence as Zephyr's
> > i2c_burst_write() function implements.
> >
> > A restart is needed for reads (Table 15) because you need a way of
> > changing from write mode (sending address) to read mode (reading bytes).
> > And that's what i2c_burst_read() does.
>
>
> > > Serialized, this gets:
> > > S Addr Wr [A] subAddr [A] RS *Addr Wr [A]* Data [A] Data [A] ... [A] Data
> > > [A] P
> >
> > And in message after your restart, the i2c device will possibly use the
> > first Data byte as the 'subAddr' to use, and then write your second Data
> > byte to that address, which is probably not what you want.
>
>
> > > While, as explained by Piotr, expected single message (for a burst write)
> > > is:
> > > S Addr Wr [A] subAddr [A] Data [A] Data [A] ... [A] Data [A] P
> >
> > Which is the same as the document for your device specifies (Table 13
> > again).
>
>
> Exact, I just don't see why we specify 2 messages in API (msg[0] and
> msg[1]),
> if we want driver to send one single message.
> There should be a reason, but I don't get it, and this was basically my
> initial
> question (sorry if this was not clear enough).

I expect the message is specified in two parts so we don't have to
create a buffer of arbitrary length and copy the data to it just so we
can prepend the address byte. (The SPI API has that flaw, and several
months ago there was an RFC to fix that, but I've not seen anything
since.)

The i2c interface at least has total flexibility on how you construct
messages.

Hi Jon
 
Ok, This is indeed a valid reason, even if a bit confusing.
What about making this explicit in the API?

Thanks anyway for the input.