[En-Nut-Discussion] Missing possibility in the I2CBUS API

Ulrich Prinz ulrich.prinz at googlemail.com
Mon May 6 14:00:15 CEST 2013


For the return codes I had the original intention to return
0 for success ( for functions without transfer)
>0 for number of tranceived bytes
<0 for error codes

But I did not completely implement it as it was not truly compatible
to the original implementation.
In many cases NutOS just returns -1 in case of error and then leaves
it to the user to find the right variables to query for detailed error
information.

There are some traps with using this rule:
You need to limit the maximum byte count to a value that guarantees to
be less then the negative roll over value caused by bit-width of your
return variable. For ARM 32 bits and Cortex 16 bits are fine as you
will not send a block of more than 32767 bytes through I2C in one
transfer. But with 8 bit platforms you need to declare return values
as int (preciesly int16_t) or limit transfer to 127 bytes in one
transfer.
If you then try to make most serial interfaces behave the same, and
you adopt the mechanism for SPI... I already used SPI several times
with transfers larger than 32k if you think of colourful LCD/OLED
displays.

Regards
Ulrich


2013/5/3 Harald Kipp <harald.kipp at egnite.de>:
> Hi Uwe,
>
> On 19.02.2013 16:34, Uwe Bonnes wrote:
>>>>>>> "Harald" == Harald Kipp <harald.kipp at egnite.de> writes:
>
>>     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()?
>
> Looks promising to me.
>
>
>>         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.
>
> Looks more correct to me than the current implementation. I think I also
> already stumbled here, but hasn't got time to fix it.
>
> As I tried to express in my response to Ulrich, the i2cbus interface is
> quite new and probably not in wide use right now. That's our chance to
> make it fit to various requirements before we enter the "backward
> compatibility maintenance hell". I'm ready to test any of your changes.
>
> Regards,
>
> Harald
>
> _______________________________________________
> http://lists.egnite.de/mailman/listinfo/en-nut-discussion


More information about the En-Nut-Discussion mailing list