Re: Question about using I2C_IOCTL_EXEC to read data over I2C

2021-08-17 Thread Dave Tyson
On Tuesday 17 Aug 2021 10:32:50 Jason Thorpe wrote:
> > On Aug 17, 2021, at 10:28 AM, Dave Tyson  wrote:
> > 
> > The device appears at address 0x77 (it's a BMP085) with i2cscan, the data
> > sheet indicates the read address=0xEF/write address=0xEE. I just put 0x77
> > in the address field and assume the read/write bit on the wire is added
> > based on the op code (I2C_OP_WRITE, I2C_OP_READ etc).
> 
> Yes, that's correct.  NetBSD natively addresses i2c devices using the 7-bit
> address **without** the read/write bit on the wire.  As you noted, 0xef and
> 0xee shifted right 1 bit results in 0x77.
> > The device has R/O calibration data in 22 contiguous registers starting at
> > 0xAA->0xBF. Linux programs seem to grab the data in one go starting at
> > 0xAA. The other registers needed to initiate a sensor data grab are R/W -
> > you write a control byte into the 0xF4 register, wait a bit and then read
> > the data from another register set.
> > 
> > A naive attempt to read the calibration data using:
> >command = 0xAA ;
> >iie.iie_op = I2C_OP_READ ;
> >iie.iie_addr = 0x77 ;
> >iie.iie_cmd = &command ;
> >iie.iie_cmdlen = 1 ;
> >iie.iie_buf = &caldata[0] ;
> >iie.iie_buflen = 22;
> >if ((ioctl(iicfd, I2C_IOCTL_EXEC, &iie)) !=0) {
> >
> >printf("read failed %d\n",errno) ;
> >exit(1) ;
> >   
> >   }
> > 
> > actually seemed to work OK, but I don't understand why!
> 
> Looks right to me!  I can explain to you why :-)
> 
> Under the covers, NetBSD did the write and turn-around for you because you
> specified a "cmd".  It performed a START (with the READ bit as 0), wrote
> the command bytes, then performed a REPEATED START with the READ bit set
> and then performed the READ.  You probably should have used
> I2C_OP_READ_WITH_STOP because that was the end of your transaction.
> > I had expected to need a I2C_OP_WRITE first followed by a
> > I2C_OP_READ_STOP.
> > The former would send a start bit, the device addr/write bit and the
> > target
> > register. The latter would send a (re)start bit, device addr/read bit,
> > pull
> > the data back and issue a stop. Maybe because the register I am addressing
> > is R/O there is no need for a write and what I am doing is correct... (or
> > do I need a I2C_OP_READ_STOP)
> 
> > Could someone explain what actually gets sent on the wire for the various 
ops:
> Ok, gotta page this one back into my brain from the archives, but here
> 'goes...
> > I2C_OP_READ
> 
> If a "cmd" is specified, performs a START-WRITE, writes the cmd bytes, then
> performs a REPEATED-START-READ to read the data bytes (and performs a NACK
> after the last byte read).  Errors result in a STOP condition.
> 
> If no "cmd" is specified, similar to above except no START-WRITE is issued
> (REPEATED-START-READ and START-READ are the same on the wire).
> > I2C_OP_READ_WITH_STOP
> 
> As above, but sets a STOP condition afterwards always.
> 
> > I2C_OP_WRITE
> 
> Sends a START-WRITE, then writes "cmd" bytes if provided and then data
> bytes.  Errors result in a STOP condition.
> > I2C_OP_WRITE_WITH_STOP
> 
> As above, but sets a STOP condition afterwards always.
> 
> > I2C_OP_READ_BLOCK
> > I2C_OP_WRITE_BLOCK
> > 
> > and what difference block operations make as man ICC(4) is terse to say
> > the
> > least.
> 
> The BLOCK operations are specific to SMBus block mode transfers.  I don't
> know how much testing actually has been done with it (I know there are
> several i2c controller drivers that do not correctly support it).
> 
> -- thorpej

Thanks Paul and Jason! Great to know how I2C_OP_READ worked behind the scenes 
and that the block operations may not work. 

Cheers,
Dave



Re: Question about using I2C_IOCTL_EXEC to read data over I2C

2021-08-17 Thread Jason Thorpe


> On Aug 17, 2021, at 10:28 AM, Dave Tyson  wrote:
> 
> The device appears at address 0x77 (it's a BMP085) with i2cscan, the data 
> sheet indicates the read address=0xEF/write address=0xEE. I just put 0x77 in 
> the address field and assume the read/write bit on the wire is added based on 
> the op code (I2C_OP_WRITE, I2C_OP_READ etc).

Yes, that's correct.  NetBSD natively addresses i2c devices using the 7-bit 
address **without** the read/write bit on the wire.  As you noted, 0xef and 
0xee shifted right 1 bit results in 0x77.

> The device has R/O calibration data in 22 contiguous registers starting at 
> 0xAA->0xBF. Linux programs seem to grab the data in one go starting at 0xAA. 
> The other registers needed to initiate a sensor data grab are R/W - you write 
> a control byte into the 0xF4 register, wait a bit and then read the data from 
> another register set.
> 
> A naive attempt to read the calibration data using:
> 
>command = 0xAA ;
>iie.iie_op = I2C_OP_READ ;
>iie.iie_addr = 0x77 ;
>iie.iie_cmd = &command ;
>iie.iie_cmdlen = 1 ;
>iie.iie_buf = &caldata[0] ;
>iie.iie_buflen = 22;
>if ((ioctl(iicfd, I2C_IOCTL_EXEC, &iie)) !=0) {
>printf("read failed %d\n",errno) ;
>exit(1) ;
>   }
> 
> actually seemed to work OK, but I don't understand why!

Looks right to me!  I can explain to you why :-)

Under the covers, NetBSD did the write and turn-around for you because you 
specified a "cmd".  It performed a START (with the READ bit as 0), wrote the 
command bytes, then performed a REPEATED START with the READ bit set and then 
performed the READ.  You probably should have used I2C_OP_READ_WITH_STOP 
because that was the end of your transaction.

> I had expected to need a I2C_OP_WRITE first followed by a I2C_OP_READ_STOP. 
> The former would send a start bit, the device addr/write bit and the target 
> register. The latter would send a (re)start bit, device addr/read bit, pull 
> the data back and issue a stop. Maybe because the register I am addressing is 
> R/O there is no need for a write and what I am doing is correct... (or do I 
> need a I2C_OP_READ_STOP)
> 
> Could someone explain what actually gets sent on the wire for the various ops:

Ok, gotta page this one back into my brain from the archives, but here 'goes...

> I2C_OP_READ

If a "cmd" is specified, performs a START-WRITE, writes the cmd bytes, then 
performs a REPEATED-START-READ to read the data bytes (and performs a NACK 
after the last byte read).  Errors result in a STOP condition.

If no "cmd" is specified, similar to above except no START-WRITE is issued 
(REPEATED-START-READ and START-READ are the same on the wire).

> I2C_OP_READ_WITH_STOP

As above, but sets a STOP condition afterwards always.

> I2C_OP_WRITE

Sends a START-WRITE, then writes "cmd" bytes if provided and then data bytes.  
Errors result in a STOP condition.

> I2C_OP_WRITE_WITH_STOP

As above, but sets a STOP condition afterwards always.

> I2C_OP_READ_BLOCK 
> I2C_OP_WRITE_BLOCK
> 
> and what difference block operations make as man ICC(4) is terse to say the 
> least.

The BLOCK operations are specific to SMBus block mode transfers.  I don't know 
how much testing actually has been done with it (I know there are several i2c 
controller drivers that do not correctly support it).

-- thorpej



Re: Question about using I2C_IOCTL_EXEC to read data over I2C

2021-08-17 Thread Paul Goyette

Dave,

As I recall, our I2C driver does not support block transfers.  It is
necessary to read (or write) one byte at a time.  So you would have
to loop from 0xAA-0xBF.

A long time ago I prepared patches for a small subset of our supported
I2C controllers, but they (the patches) are long gone.

Good luck!


On Tue, 17 Aug 2021, Dave Tyson wrote:


I am trying to get data from a temperature/pressure sensor connected via i2c
to a banana pi running NetBSD current. I understand the I2C protocol but I am
having a bit of difficulty understanding what appears on the wire when the
I2C_IOCTL_EXEC is called with the various op commands. By trial and error I
seem to have been able to read the data, but want to check a few things in
case I am doing it all wrong :-)

The device appears at address 0x77 (it's a BMP085) with i2cscan, the data
sheet indicates the read address=0xEF/write address=0xEE. I just put 0x77 in
the address field and assume the read/write bit on the wire is added based on
the op code (I2C_OP_WRITE, I2C_OP_READ etc).

The device has R/O calibration data in 22 contiguous registers starting at
0xAA->0xBF. Linux programs seem to grab the data in one go starting at 0xAA.
The other registers needed to initiate a sensor data grab are R/W - you write
a control byte into the 0xF4 register, wait a bit and then read the data from
another register set.

A naive attempt to read the calibration data using:

   command = 0xAA ;
   iie.iie_op = I2C_OP_READ ;
   iie.iie_addr = 0x77 ;
   iie.iie_cmd = &command ;
   iie.iie_cmdlen = 1 ;
   iie.iie_buf = &caldata[0] ;
   iie.iie_buflen = 22;
   if ((ioctl(iicfd, I2C_IOCTL_EXEC, &iie)) !=0) {
   printf("read failed %d\n",errno) ;
   exit(1) ;
  }

actually seemed to work OK, but I don't understand why!

I had expected to need a I2C_OP_WRITE first followed by a I2C_OP_READ_STOP.
The former would send a start bit, the device addr/write bit and the target
register. The latter would send a (re)start bit, device addr/read bit, pull
the data back and issue a stop. Maybe because the register I am addressing is
R/O there is no need for a write and what I am doing is correct... (or do I
need a I2C_OP_READ_STOP)

Could someone explain what actually gets sent on the wire for the various ops:

I2C_OP_READ
I2C_OP_READ_WITH_STOP
I2C_OP_WRITE
I2C_OP_WRITE_WITH_STOP
I2C_OP_READ_BLOCK
I2C_OP_WRITE_BLOCK

and what difference block operations make as man ICC(4) is terse to say the
least.

Cheers,
Dave


!DSPAM:611be3ce51591168618607!




++--+--+
| Paul Goyette   | PGP Key fingerprint: | E-mail addresses:|
| (Retired)  | FA29 0E3B 35AF E8AE 6651 | p...@whooppee.com|
| Software Developer | 0786 F758 55DE 53BA 7731 | pgoye...@netbsd.org  |
||  | pgoyett...@gmail.com |
++--+--+


Question about using I2C_IOCTL_EXEC to read data over I2C

2021-08-17 Thread Dave Tyson
I am trying to get data from a temperature/pressure sensor connected via i2c 
to a banana pi running NetBSD current. I understand the I2C protocol but I am 
having a bit of difficulty understanding what appears on the wire when the 
I2C_IOCTL_EXEC is called with the various op commands. By trial and error I 
seem to have been able to read the data, but want to check a few things in 
case I am doing it all wrong :-)

The device appears at address 0x77 (it's a BMP085) with i2cscan, the data 
sheet indicates the read address=0xEF/write address=0xEE. I just put 0x77 in 
the address field and assume the read/write bit on the wire is added based on 
the op code (I2C_OP_WRITE, I2C_OP_READ etc).

The device has R/O calibration data in 22 contiguous registers starting at 
0xAA->0xBF. Linux programs seem to grab the data in one go starting at 0xAA. 
The other registers needed to initiate a sensor data grab are R/W - you write 
a control byte into the 0xF4 register, wait a bit and then read the data from 
another register set.

A naive attempt to read the calibration data using:

command = 0xAA ;
iie.iie_op = I2C_OP_READ ;
iie.iie_addr = 0x77 ;
iie.iie_cmd = &command ;
iie.iie_cmdlen = 1 ;
iie.iie_buf = &caldata[0] ;
iie.iie_buflen = 22;
if ((ioctl(iicfd, I2C_IOCTL_EXEC, &iie)) !=0) {
printf("read failed %d\n",errno) ;
exit(1) ;
   }

actually seemed to work OK, but I don't understand why!

I had expected to need a I2C_OP_WRITE first followed by a I2C_OP_READ_STOP. 
The former would send a start bit, the device addr/write bit and the target 
register. The latter would send a (re)start bit, device addr/read bit, pull 
the data back and issue a stop. Maybe because the register I am addressing is 
R/O there is no need for a write and what I am doing is correct... (or do I 
need a I2C_OP_READ_STOP)

Could someone explain what actually gets sent on the wire for the various ops:

I2C_OP_READ
I2C_OP_READ_WITH_STOP
I2C_OP_WRITE
I2C_OP_WRITE_WITH_STOP
I2C_OP_READ_BLOCK 
I2C_OP_WRITE_BLOCK

and what difference block operations make as man ICC(4) is terse to say the 
least.

Cheers,
Dave