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



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 | paul%whooppee.com@localhost    |
| Software Developer | 0786 F758 55DE 53BA 7731 | pgoyette%netbsd.org@localhost  |
|                    |                          | pgoyette99%gmail.com@localhost |
+--------------------+--------------------------+----------------------+


Home | Main Index | Thread Index | Old Index