[En-Nut-Discussion] Missing possibility in the I2CBUS API
Uwe Bonnes
bon at elektron.ikp.physik.tu-darmstadt.de
Tue Feb 19 16:34:00 CET 2013
>>>>> "Harald" == Harald Kipp <harald.kipp at egnite.de> writes:
Harald> Hi Uwe, On 19.02.2013 12:29, Uwe Bonnes wrote:
>> while most devices allow to read multiple I2C registers with some
>> auto-increment scheme, Maxim for it's MAX44009 ambient light sensor
>> decided to require another sequence: Start- Chip Address/Write -
>> Write Register number - repeated start - Chip Address/Read - Read
>> register content- Start- Chip Address/Write - Write Register next
>> number - repeated start - Chip Address/Read - Read register content -
>> Stop. This means multiple transactions without STOP during the
>> sequence of transactions.
Harald> There is even more: PMBus allows to change the slave address
Harald> after a repeated start (see chapter 9 of the I2C specs.).
Harald> I assume, that not all I2C master hardware is able to support
Harald> this, neither the Maxim nor the PMBus scheme.
>> The i2cbus API implemented in dev/i2cbus.c so long doesn't allow such
>> a sequence, to my understanding. Should we extend the API?
Harald> For the Maxim, we could argue: "Well, use two separate
Harald> transactions in that case." But for the PMBus we are busted in
Harald> any case.
Sorry, forgot to mention that it is about atomic access to a two byte
variable of the MAX44009 that gets updated by the MAX44009 when no I2C
access is going on, that means a I2C-Stop has been issued.
Harald> I do not have the right idea now, but we better change the API
Harald> soon, before running into similar backward compatibility issues
Harald> as before.
Harald> I remember a different approach I saw somewhere else, where a
Harald> list of transactions was passed to the driver. May be that is
Harald> more difficult to use, but would more closely reflect the design
Harald> of the I2C bus. E.g.
Harald> list[0].sla = 0x22; list[0].txlen = 1; list[0].txbuf = ®_num;
Harald> list[0].rxlen = 0; list[0].rxbuf = NULL;
Harald> list[1].sla = 0x22; list[1].txlen = 0; list[1].txbuf = NULL;
Harald> list[1].rxlen = 1; list[1].rxbuf = ®_val;
Harald> ....
Harald> list[n].sla = 0x55;
Harald> ...
Harald> NutI2cBusTransact(bus, list, list_len)
Harald> If the hardware is able to do this in one transaction, it can be
Harald> done. Otherwise the driver must use several start-stop
Harald> transactions to execute the list.
Yes, I think we need to be able to (also) supply a list of transactions.
What about adding
NutI2cBusTransact(bus, list, list_len)
and keeping
NutI2cMasterTransceive(NUTI2C_SLAVE *slave, const void *wdat, int wlen,\
void *rdat, int rsiz)
which would set up the arguments to finally call NutI2cBusTransact()?
Otherwise, is there a reason you do
(*bus->bus_transceive) (slave, &msg);
/* Release the bus. */
NutEventPost(&bus->bus_mutex);
/* Return the number of bytes received. */
rc = msg.msg_ridx;
}
return rc;
and not
rc = (*bus->bus_transceive) (slave, &msg);
/* Release the bus. */
NutEventPost(&bus->bus_mutex);
/* Return the number of bytes received. */
if (rc == 0)
rc = msg.msg_ridx;
}
return rc;
In your approach, the device driver in the case of failure must write
the failurereason to msg.msg_ridx and so we loose the number of bytes
successfully transferred.
Bye
--
Uwe Bonnes bon at elektron.ikp.physik.tu-darmstadt.de
Institut fuer Kernphysik Schlossgartenstrasse 9 64289 Darmstadt
--------- Tel. 06151 162516 -------- Fax. 06151 164321 ----------
More information about the En-Nut-Discussion
mailing list