You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@mynewt.apache.org by "paul@wrada.com" <pa...@wrada.com> on 2016/04/19 20:42:09 UTC

i2c HAL API

All,

Please take a look at the i2c HAL api in

https://github.com/apache/incubator-mynewt-core/pull/44

I chose a simple blocking API for now to get some I2C functionality fast.   Its mostly just read/write, with a few other functions.


  1.  probe - I found that immediately after writing this I need some way to discovery what was on the bus.  I wrote this simple function to look for a single address.
  2.  Start/stop - Many devices are just read/write registers so there is no need to control transactions on the bus.  However, for serial eeprom random access, its more efficient to write an address then read the data.  In this case you would issue start,write,read,stop.

Paul

Re: i2c HAL API

Posted by Greg Stein <gs...@gmail.com>.
On Wed, Apr 20, 2016 at 11:01 AM, paul@wrada.com <pa...@wrada.com> wrote:
>...

> What I¹d like to do is address the issues by commenting the API.  I¹ll try
> to do this tomorrow and commit comment changes only to the i2c HAL
> 1) Address the comment errors
> 2) detail the current timeout behavior (describe what it does now).
> 3) detail the usage of start/read/write in combination
>

Sounds great!


> Your other API changes look good, but I need to give them a thorough read
> and test. I will probably not be able to get that into the current
> release.  I¹m shooting for monthly HAL releases, but am trying to build a
> roadmap now.
>

No rush, so get your other stuff done. I'll still be around :-)

I think that we are trying to do two conflicting things with the HAL.
>         1) providing abstracted, but complete, hardware functionality
>         2) creating a simple usable API
>
> These two things may be leading to tradeoffs (simple versus full
> functioning). A new idea (for Mynewt) is to have a hal layer which
> abstracts the hardware at the lowest level possible with a somewhat more
> complicated API, and then a driver level which uses the HAL to provide
> robust user APIs (I2C is a good example).


Gotcha. I can see the tension. I2C might be difficult to create a
low-level, close-to-metal layer. I'm not sure what the various hardware
interfaces look like. I *do* know the Raspberry Pi cannot do repeated
starts, due to a buggy hardware implementation :-( ... I can only imagine
some of the crazy that might be involved at the different hardware
implementations/interfaces. My experience is with "no support at all", so I
bit-bang it on the PIC. Forces you to learn details real quick :-P

I can certainly help with the high-level API, and then when some
implementations are built where I can see the low-level h/w interface, can
help with defining the split.


>   I don¹t know what exactly that
> looks like yet but your expertise is invaluable.  I¹m trying to write up
> my thoughts and the get a concrete example going.  Maybe I2C is the right
> one to start with.
>

As you'd like. I'll keep watching for further commits, and offer reviews.
Might even have to clone me up a local repo ;-)

Cheers,
-g

Re: i2c HAL API

Posted by "paul@wrada.com" <pa...@wrada.com>.
I saw the comments Greg. Thank you so much for sharing that expertise. I
haven¹t had enough experience with I2C; your help is going to make this
great.

Regarding the commentsŠ.  The mynewt team is in release mode today-Friday.
 I¹m on another project today but will get to these comments tomorrow.
What I¹d like to do is address the issues by commenting the API.  I¹ll try
to do this tomorrow and commit comment changes only to the i2c HAL
1) Address the comment errors
2) detail the current timeout behavior (describe what it does now).
3) detail the usage of start/read/write in combination

Your other API changes look good, but I need to give them a thorough read
and test. I will probably not be able to get that into the current
release.  I¹m shooting for monthly HAL releases, but am trying to build a
roadmap now. 

I think that we are trying to do two conflicting things with the HAL.
	1) providing abstracted, but complete, hardware functionality
	2) creating a simple usable API

These two things may be leading to tradeoffs (simple versus full
functioning). A new idea (for Mynewt) is to have a hal layer which
abstracts the hardware at the lowest level possible with a somewhat more
complicated API, and then a driver level which uses the HAL to provide
robust user APIs (I2C is a good example).  I don¹t know what exactly that
looks like yet but your expertise is invaluable.  I¹m trying to write up
my thoughts and the get a concrete example going.  Maybe I2C is the right
one to start with.

Paul



On 4/20/16, 5:01 AM, "Greg Stein" <gs...@gmail.com> wrote:

>Sorry I missed this conversation ... I've commented on the recent commit.
>Please see my feedback there. I can chat about I2C for hours :-)
>
>On Tue, Apr 19, 2016 at 1:42 PM, paul@wrada.com <pa...@wrada.com> wrote:
>
>> All,
>>
>> Please take a look at the i2c HAL api in
>>
>> https://github.com/apache/incubator-mynewt-core/pull/44
>>
>> I chose a simple blocking API for now to get some I2C functionality
>>fast.
>>  Its mostly just read/write, with a few other functions.
>>
>>
>>   1.  probe - I found that immediately after writing this I need some
>>way
>> to discovery what was on the bus.  I wrote this simple function to look
>>for
>> a single address.
>>   2.  Start/stop - Many devices are just read/write registers so there
>>is
>> no need to control transactions on the bus.  However, for serial eeprom
>> random access, its more efficient to write an address then read the
>>data.
>> In this case you would issue start,write,read,stop.
>>
>> Paul
>>


Re: i2c HAL API

Posted by Greg Stein <gs...@gmail.com>.
Sorry I missed this conversation ... I've commented on the recent commit.
Please see my feedback there. I can chat about I2C for hours :-)

On Tue, Apr 19, 2016 at 1:42 PM, paul@wrada.com <pa...@wrada.com> wrote:

> All,
>
> Please take a look at the i2c HAL api in
>
> https://github.com/apache/incubator-mynewt-core/pull/44
>
> I chose a simple blocking API for now to get some I2C functionality fast.
>  Its mostly just read/write, with a few other functions.
>
>
>   1.  probe - I found that immediately after writing this I need some way
> to discovery what was on the bus.  I wrote this simple function to look for
> a single address.
>   2.  Start/stop - Many devices are just read/write registers so there is
> no need to control transactions on the bus.  However, for serial eeprom
> random access, its more efficient to write an address then read the data.
> In this case you would issue start,write,read,stop.
>
> Paul
>

Re: i2c HAL API

Posted by marko kiiskila <ma...@runtime.io>.
Ah yes. Sorry, I forgot that every transaction starts with an address.
Not just after start condition.

Yes, I think the API is OK as is.

> On Apr 19, 2016, at 12:46 PM, paul@wrada.com wrote:
> 
> Thanks Marko.
> 
> Regarding the address, that is what I was originally thinking, but the
> protocol sends the address in every read or write, so I would have to
> ³store² it in the driver state. Its just another byte, but I suspect the
> application is already storing it anyway.  If you don¹t mind the extra
> byte of storage I could move it to the start command.
> 
> OhŠ It may be a bit confusing, but take the i2c serial eeprom example
> where this is a device address and a memory address.
> 
> To do a random access read, you write the memory address into the chip,
> then read back the number of bytes (auto-increment).
> Both the write and the read commands take the device address. This is
> because the low bit of the address field in the protocol specifies the
> direction of the command (R/W).
> 
> If the device is not there there is a timeout as there are rules about the
> ack speed (next clock).
> If the device is misfired, you typically cannot issue a start condition,
> so the read/writes fail. I only tested this condition when there are no
> suitable pull-ups on the bus.
> 
> 
> 
> 
> On 4/19/16, 12:13 PM, "marko kiiskila" <marko@runtime.io <ma...@runtime.io>> wrote:
> 
>> Hi Paul,
>> 
>>> On Apr 19, 2016, at 11:42 AM, paul@wrada.com wrote:
>>> 
>>> All,
>>> 
>>> Please take a look at the i2c HAL api in
>>> 
>>> https://github.com/apache/incubator-mynewt-core/pull/44
>>> 
>>> I chose a simple blocking API for now to get some I2C functionality
>>> fast.   Its mostly just read/write, with a few other functions.
>>> 
>>> 
>>> 1.  probe - I found that immediately after writing this I need some
>>> way to discovery what was on the bus.  I wrote this simple function to
>>> look for a single address.
>>> 2.  Start/stop - Many devices are just read/write registers so there
>>> is no need to control transactions on the bus.  However, for serial
>>> eeprom random access, its more efficient to write an address then read
>>> the data.  In this case you would issue start,write,read,stop.
>> 
>> 
>> What¹s a bit confusing about the API is that the i2c address is present
>> in argument for both read and write operation. To me it would make
>> sense to include the i2c address in the call to start(), but not to
>> read()/write().
>> 
>> Let¹s say I have device with i2c address X. And what I need to do
>> is write 2 bytes of address to it, followed by read of 1024 bytes.
>> So the transaction would look like : start - send address - write 2 bytes
>> - read 1024 bytes - stop.
>> 
>> Also, if i2c bus is busy/miswired is there a way to time-out during start?
>> I think I also want a timeout when sending i2c address; in case the
>> device is
>> not there.
>> 
>> Hope this helps,
>> M


Re: i2c HAL API

Posted by "paul@wrada.com" <pa...@wrada.com>.
Thanks Marko.

Regarding the address, that is what I was originally thinking, but the
protocol sends the address in every read or write, so I would have to
³store² it in the driver state. Its just another byte, but I suspect the
application is already storing it anyway.  If you don¹t mind the extra
byte of storage I could move it to the start command.

OhŠ It may be a bit confusing, but take the i2c serial eeprom example
where this is a device address and a memory address.

To do a random access read, you write the memory address into the chip,
then read back the number of bytes (auto-increment).
Both the write and the read commands take the device address. This is
because the low bit of the address field in the protocol specifies the
direction of the command (R/W).

If the device is not there there is a timeout as there are rules about the
ack speed (next clock).
If the device is misfired, you typically cannot issue a start condition,
so the read/writes fail. I only tested this condition when there are no
suitable pull-ups on the bus.




On 4/19/16, 12:13 PM, "marko kiiskila" <ma...@runtime.io> wrote:

>Hi Paul,
>
>> On Apr 19, 2016, at 11:42 AM, paul@wrada.com wrote:
>> 
>> All,
>> 
>> Please take a look at the i2c HAL api in
>> 
>> https://github.com/apache/incubator-mynewt-core/pull/44
>> 
>> I chose a simple blocking API for now to get some I2C functionality
>>fast.   Its mostly just read/write, with a few other functions.
>> 
>> 
>>  1.  probe - I found that immediately after writing this I need some
>>way to discovery what was on the bus.  I wrote this simple function to
>>look for a single address.
>>  2.  Start/stop - Many devices are just read/write registers so there
>>is no need to control transactions on the bus.  However, for serial
>>eeprom random access, its more efficient to write an address then read
>>the data.  In this case you would issue start,write,read,stop.
>
>
>What¹s a bit confusing about the API is that the i2c address is present
>in argument for both read and write operation. To me it would make
>sense to include the i2c address in the call to start(), but not to
>read()/write().
>
>Let¹s say I have device with i2c address X. And what I need to do
>is write 2 bytes of address to it, followed by read of 1024 bytes.
>So the transaction would look like : start - send address - write 2 bytes
>- read 1024 bytes - stop.
>
>Also, if i2c bus is busy/miswired is there a way to time-out during start?
>I think I also want a timeout when sending i2c address; in case the
>device is
>not there.
>
>Hope this helps,
>M


Re: i2c HAL API

Posted by marko kiiskila <ma...@runtime.io>.
Hi Paul,

> On Apr 19, 2016, at 11:42 AM, paul@wrada.com wrote:
> 
> All,
> 
> Please take a look at the i2c HAL api in
> 
> https://github.com/apache/incubator-mynewt-core/pull/44
> 
> I chose a simple blocking API for now to get some I2C functionality fast.   Its mostly just read/write, with a few other functions.
> 
> 
>  1.  probe - I found that immediately after writing this I need some way to discovery what was on the bus.  I wrote this simple function to look for a single address.
>  2.  Start/stop - Many devices are just read/write registers so there is no need to control transactions on the bus.  However, for serial eeprom random access, its more efficient to write an address then read the data.  In this case you would issue start,write,read,stop.


What’s a bit confusing about the API is that the i2c address is present
in argument for both read and write operation. To me it would make
sense to include the i2c address in the call to start(), but not to read()/write().

Let’s say I have device with i2c address X. And what I need to do
is write 2 bytes of address to it, followed by read of 1024 bytes.
So the transaction would look like : start - send address - write 2 bytes - read 1024 bytes - stop.

Also, if i2c bus is busy/miswired is there a way to time-out during start?
I think I also want a timeout when sending i2c address; in case the device is
not there.

Hope this helps,
M