Current-Users archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: Question about using I2C_IOCTL_EXEC to read data over I2C



On Tuesday 17 Aug 2021 10:32:50 Jason Thorpe wrote:
> > On Aug 17, 2021, at 10:28 AM, Dave Tyson <dtyson%anduin.org.uk@localhost> 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



Home | Main Index | Thread Index | Old Index