linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
* Problems with I2C reads
@ 2002-08-02 20:36 Keith Outwater
  2002-08-03 20:06 ` bhupinder sahran
  2002-08-05  6:27 ` Murray Jensen
  0 siblings, 2 replies; 5+ messages in thread
From: Keith Outwater @ 2002-08-02 20:36 UTC (permalink / raw)
  To: linuxppc-embedded


Greetings all -

I am trying to talk to an I2C device (Analog Devices AD9888) using the
MPC860 CPM I2C interface from userland.
Writes work fine, but the chip requires a strange write-read sequence
for reading back registers.  For example, to read a register:

Start signal
Slave address (r/w/ bit = write)
Register address
Start signal
Slave address (r/w/ bit = read)
Read register data
Stop signal

Note that there is no stop between the write and the read.  If you put a
stop in, the chip will not acknowledge the read, so using /dev/i2c-0
with write() and read() does not work.

I tried using the ioctl() interface and passed I2C_RDWR to try to
suppress the stop command between messages, but it does not seem to work
(checked it on a scope).
I looked at the ioctl() handler for I2C_RDWR and it was not clear to me
whether that particular ioctl option should work with a write-read
sequence or not.  As far as I can tell it does not work.
I looked for other ways to do this, but found nothing.

Has anyone used I2C like this before? Any hints or suggestions?

Thanks!
Keith

Keith Outwater
Senior Staff Engineer
Microvision, Inc.
(425) 415-6693


** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Problems with I2C reads
  2002-08-02 20:36 Problems with I2C reads Keith Outwater
@ 2002-08-03 20:06 ` bhupinder sahran
  2002-08-05  6:27 ` Murray Jensen
  1 sibling, 0 replies; 5+ messages in thread
From: bhupinder sahran @ 2002-08-03 20:06 UTC (permalink / raw)
  To: Keith Outwater, linuxppc-embedded


hi

I think u r missing onr thing.

sequence should be like this


> Start signal
> Slave address (r/w/ bit = write)
> Register address
> Start signal
> Slave address (r/w/ bit = read)
> Read register data
>NO ack.......................u have to give
> Stop signal


Try to give No ack after reading the register data.

bye
Bhupi
Deep  into silicon with Linux.....
www.gdatech.com

--- Keith Outwater <Keith_Outwater@mvis.com> wrote:
>
> Greetings all -
>
> I am trying to talk to an I2C device (Analog Devices
> AD9888) using the
> MPC860 CPM I2C interface from userland.
> Writes work fine, but the chip requires a strange
> write-read sequence
> for reading back registers.  For example, to read a
> register:
>
> Start signal
> Slave address (r/w/ bit = write)
> Register address
> Start signal
> Slave address (r/w/ bit = read)
> Read register data
> Stop signal
>
> Note that there is no stop between the write and the
> read.  If you put a
> stop in, the chip will not acknowledge the read, so
> using /dev/i2c-0
> with write() and read() does not work.
>
> I tried using the ioctl() interface and passed
> I2C_RDWR to try to
> suppress the stop command between messages, but it
> does not seem to work
> (checked it on a scope).
> I looked at the ioctl() handler for I2C_RDWR and it
> was not clear to me
> whether that particular ioctl option should work
> with a write-read
> sequence or not.  As far as I can tell it does not
> work.
> I looked for other ways to do this, but found
> nothing.
>
> Has anyone used I2C like this before? Any hints or
> suggestions?
>
> Thanks!
> Keith
>
> Keith Outwater
> Senior Staff Engineer
> Microvision, Inc.
> (425) 415-6693
>
>
>


** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Problems with I2C reads
  2002-08-02 20:36 Problems with I2C reads Keith Outwater
  2002-08-03 20:06 ` bhupinder sahran
@ 2002-08-05  6:27 ` Murray Jensen
  1 sibling, 0 replies; 5+ messages in thread
From: Murray Jensen @ 2002-08-05  6:27 UTC (permalink / raw)
  To: Keith Outwater; +Cc: linuxppc-embedded


On Fri, 2 Aug 2002 13:36:13 -0700, "Keith Outwater" <Keith_Outwater@mvis.com> writes:
>I am trying to talk to an I2C device (Analog Devices AD9888) using the
>MPC860 CPM I2C interface from userland.

You should probably state which kernel and i2c driver you are using - there are
a lot of different versions around.

Your message indicates you are using some version of the "drivers/i2c" code, and
that you have correctly surmised the method to use (I2C_RDWR ioctl).

The first thing you should do is to run the command "cat /proc/bus/i2c" and
locate the entry for your i2c bus ("i2c-0" in your case). The second column
should be either "i2c" or "smbus/i2c", which indicates that the algo driver
supports the "master_xfer" routine, which is what the I2C_RDWR ioctl ends up
calling.

But if you are using the old "8xx" algo driver that is in the vanilla 2_4_devel
source, all the "master_xfer" routine does is call write or read in sequence
depending on the message struct.

>I tried using the ioctl() interface and passed I2C_RDWR to try to
>suppress the stop command between messages, but it does not seem to work
>(checked it on a scope).

Show us some code fragments - what you need is an array of 2 i2c_msg structs
the first with the register address (or "sub-address" in i2c speak) to write,
and the second with the same i2c address and the I2C_M_RD flag set (and with the
buf and len set to valid values).

By the way, there really should be an I2C_M_NOSTOP flag which mirrors the
I2C_M_NOSTART flag - at the moment you just have to assume that you don't
want a stop, otherwise why didn't you just call write followed by read.
I guess this is a reasonable assumption.

>I looked at the ioctl() handler for I2C_RDWR and it was not clear to me
>whether that particular ioctl option should work with a write-read
>sequence or not.  As far as I can tell it does not work.

Depends which driver you are using. I tried to implement this in my version of
the driver, but having no need for it, I never tested it. The vanilla
i2c-algo-8xx.c algorithm driver doesn't support this.

>I looked for other ways to do this, but found nothing.

You found the correct way.

>Has anyone used I2C like this before? Any hints or suggestions?

Try my i2c-algo-cpm.c and i2c-cpm.c drivers - they work as loadable modules (but
unfortunately this needs a patch to commproc.c). This stuff was posted to the
list a while ago, but hasn't made it in yet because it has to go via the i2c
people and I haven't gotten around to it yet. I know of at least one person
who has used it on the 8xx, although not in the way you want. Cheers!
								Murray...
--
Murray Jensen, CSIRO Manufacturing & Infra. Tech.      Phone: +61 3 9662 7763
Locked Bag No. 9, Preston, Vic, 3072, Australia.         Fax: +61 3 9662 7853
Internet: Murray.Jensen@csiro.au

Hymod project: http://www.msa.cmst.csiro.au/projects/Hymod/


** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/

^ permalink raw reply	[flat|nested] 5+ messages in thread

* RE: Problems with I2C reads
@ 2002-08-05 17:39 Keith Outwater
  2002-08-06  4:59 ` Murray Jensen
  0 siblings, 1 reply; 5+ messages in thread
From: Keith Outwater @ 2002-08-05 17:39 UTC (permalink / raw)
  To: linuxppc-embedded


Murray -
Thanks for the info!  Yes, I think that having an I2C_M_NOSTOP option
would do what I want, but that option is not available in the kernel I'm
using.


>
> You should probably state which kernel and i2c driver you are
> using - there are
> a lot of different versions around.

I'm using a 2.4.x kernel snapshot from Denx's CVS.
Wolfgang, can you comment on your kernel's I2C driver?

>
> Your message indicates you are using some version of the
> "drivers/i2c" code, and
> that you have correctly surmised the method to use (I2C_RDWR ioctl).
>
> The first thing you should do is to run the command "cat
> /proc/bus/i2c" and
> locate the entry for your i2c bus ("i2c-0" in your case). The
> second column
> should be either "i2c" or "smbus/i2c", which indicates that
> the algo driver
> supports the "master_xfer" routine, which is what the
> I2C_RDWR ioctl ends up
> calling.

I checked, and it's plain old "i2c"

>
> But if you are using the old "8xx" algo driver that is in the
> vanilla 2_4_devel
> source, all the "master_xfer" routine does is call write or
> read in sequence
> depending on the message struct.
>
> >I tried using the ioctl() interface and passed I2C_RDWR to try to
> >suppress the stop command between messages, but it does not
> seem to work
> >(checked it on a scope).
>
> Show us some code fragments - what you need is an array of 2
> i2c_msg structs
> the first with the register address (or "sub-address" in i2c
> speak) to write,
> and the second with the same i2c address and the I2C_M_RD
> flag set (and with the
> buf and len set to valid values).

Here's the code:

typedef struct {
	struct i2c_msg	*msgs;
	int  nmsgs;
} msgset_t;

extern int i2c_fd;

int
i2c_test(void)
{
	msgset_t			msgset;
	struct	i2c_msg		msg[2];
	char				msg_buf0[2], msg_buf1[2];

	msgset.msgs = msg;
	msgset.nmsgs = 2;

	msg[0].addr = AD9888_I2C_ADDR;
	msg[0].flags = 0;
	msg[0].len = 1;
	msg[0].buf = msg_buf0;

	msg[1].addr = AD9888_I2C_ADDR;
	msg[1].flags = I2C_M_RD;
	msg[1].len = 1;
	msg[1].buf = msg_buf1;

	msg_buf0[0] = 0x1;
	msg_buf1[0] = AD9888_I2C_ADDR;

	set_i2c_slave_address(AD9888_I2C_ADDR);
	ioctl(i2c_fd,I2C_RDWR,&msgset);
	printf("0x%x\n", msg_buf1[0]);
	return 1;
}

msg_buf1[0] is not being updated by the read.  Using a scope I can see
that the AD9888 acks the write but not the read.  There is a stop
interted between the write and the read.

>
> By the way, there really should be an I2C_M_NOSTOP flag which
> mirrors the
> I2C_M_NOSTART flag - at the moment you just have to assume
> that you don't
> want a stop, otherwise why didn't you just call write
> followed by read.
> I guess this is a reasonable assumption.

I grepped the kernel source and there is no I2C_M_NOSTOP flag.  That
seems to be the problem; what I really need is a write followed by a
read without a stop in between.  The sop is causing the chip to ignre
thre read cycle (i.e. not geneate an ack).

>
> >I looked at the ioctl() handler for I2C_RDWR and it was not
> clear to me
> >whether that particular ioctl option should work with a write-read
> >sequence or not.  As far as I can tell it does not work.
>
> Depends which driver you are using. I tried to implement this
> in my version of
> the driver, but having no need for it, I never tested it. The vanilla
> i2c-algo-8xx.c algorithm driver doesn't support this.
>
> >I looked for other ways to do this, but found nothing.
>
> You found the correct way.
>
> >Has anyone used I2C like this before? Any hints or suggestions?
>
> Try my i2c-algo-cpm.c and i2c-cpm.c drivers - they work as
> loadable modules (but
> unfortunately this needs a patch to commproc.c). This stuff
> was posted to the
> list a while ago, but hasn't made it in yet because it has to
> go via the i2c
> people and I haven't gotten around to it yet. I know of at
> least one person
> who has used it on the 8xx, although not in the way you want. Cheers!
>
> Murray...


** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Problems with I2C reads
  2002-08-05 17:39 Keith Outwater
@ 2002-08-06  4:59 ` Murray Jensen
  0 siblings, 0 replies; 5+ messages in thread
From: Murray Jensen @ 2002-08-06  4:59 UTC (permalink / raw)
  To: Keith Outwater; +Cc: linuxppc-embedded


On Mon, 5 Aug 2002 10:39:02 -0700, "Keith Outwater" <Keith_Outwater@mvis.com> writes:
>
>Murray -
>Thanks for the info!  Yes, I think that having an I2C_M_NOSTOP option
>would do what I want, but that option is not available in the kernel I'm
>using.

No, my comment was that for completeness there should be an I2C_M_NOSTOP flag,
but it isn't necessary because you simply assume that if you provide a set of
i2c_msg's which consists of a write followed by a read, it is assumed that you
don't want the STOP in between them. This is how I interpreted things in my
version of the driver.

>I checked, and it's plain old "i2c"

I'm not sure about the "plain old" - but "i2c" is enough for it to work, as
long as your "algo" driver supports the transfers as I outlined above.

>Here's the code:

The code looks correct to me. If you try my version of the driver, posted to
this list recently, it should at least attempt to do the right thing. The
stock standard linuxppc_2_4_devel driver/i2c/i2c-algo-8xx.c will not do what
you want - it will simply do a write followed by a read, with a STOP in
between.

>msg_buf1[0] is not being updated by the read.  Using a scope I can see
>that the AD9888 acks the write but not the read.  There is a stop
>interted between the write and the read.

Looks like Wolfgang's code base has the original "i2c-algo-8xx.c" algo driver.

>I grepped the kernel source and there is no I2C_M_NOSTOP flag.  That
>seems to be the problem; what I really need is a write followed by a
>read without a stop in between.  The sop is causing the chip to ignre
>thre read cycle (i.e. not geneate an ack).

See comment above - the NOSTOP is assumed in my version of the driver. If you
want to think about it another way, the stock standard 8xx algo driver assumes
that you want a STOP between the messages, and my version assumes the opposite.
Cheers!
								Murray...
--
Murray Jensen, CSIRO Manufacturing & Infra. Tech.      Phone: +61 3 9662 7763
Locked Bag No. 9, Preston, Vic, 3072, Australia.         Fax: +61 3 9662 7853
Internet: Murray.Jensen@csiro.au

Hymod project: http://www.msa.cmst.csiro.au/projects/Hymod/


** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2002-08-06  4:59 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2002-08-02 20:36 Problems with I2C reads Keith Outwater
2002-08-03 20:06 ` bhupinder sahran
2002-08-05  6:27 ` Murray Jensen
  -- strict thread matches above, loose matches on Subject: below --
2002-08-05 17:39 Keith Outwater
2002-08-06  4:59 ` Murray Jensen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).