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 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
> 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
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
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