Problem with I2CCmd()

Discussion about the ZBasic language including the System Library. If you're not sure where to post your message, do it here. However, do not make test posts here; that's the purpose of the Sandbox.
spamiam
Posts: 739
Joined: 13 November 2005, 6:39 AM

Problem with I2CCmd()

Post by spamiam »

I am updating some old software to the newest compiler capabilities.

I am trying to get a Devantech SRF08 ultrasonic ranger to work.

After sending the ranging command and waiting the requisite >65mS, I then try to read the data.

If I use the following command:

Code: Select all

Ret_Val = I2CCmd(1,SRF08_ADDRESS, 1,LdrReg,1,Light)
It does not read the data and further ranging commands are ignored for some reason.

If I do it using low level commands it works fine:

Code: Select all

		Call I2CStart(1)
		Ans = I2CPutByte(1,SRF08_ADDRESS)
		Ans = I2CPutByte(1,LdrReg)
		Call I2CStart(1)
		Ans = I2CPutByte(1,SRF08_ADDRESS+1)
		Light = I2CGetByte(1,False)
In what way does the highlevel I2CCmd() differ from the low level commands that I show? I suspect that it is the I2CStart() in the middle of the low level code. I am confused by this because I was under the impression that the Devantech device conformed to the I2C standard.

-Tony
dkinzer
Site Admin
Posts: 3120
Joined: 03 September 2005, 13:53 PM
Location: Portland, OR

Re: Problem with I2CCmd()

Post by dkinzer »

spamiam wrote:In what way does the highlevel I2CCmd() differ from the low level commands that I show?
The only difference that I'm aware of is that I2CCmd() performs an I2CStop() at the end of the sequence that you gave. The I2CStart() is necessary, according to the standard, between the "transmit" portion and the "receive" portion of the transaction. In that situation, it is rightly called a "repeated start" in contrast to the initial use where it establishes an I2C start condition.
- Don Kinzer
mikep
Posts: 796
Joined: 24 September 2005, 15:54 PM

Post by mikep »

I just tried the example source code from Application Note AN208 and it worked fine on the following devices ZX-24e, ZX-1281e, ZX-24ne. What device are you using?

I tried it with a SRF08 software version 8. The same one that I used to create the original application note.
Mike Perks
spamiam
Posts: 739
Joined: 13 November 2005, 6:39 AM

Post by spamiam »

The only difference that I'm aware of is that I2CCmd() performs an I2CStop() at the end of the sequence that you gave
Actually, I had accidentally omitted the I2CStop() at the end. I placed it there and the functionality of the low-level technique was unchanged.

I had suspected that the low-level code I used was completely replicating the functions of the I2CCMD(), but I was not sure.

I will try slowing down the I2C speed and see if that makes a difference.
I just tried the example source code from Application Note AN208 and it worked fine on the following devices ZX-24e, ZX-1281e, ZX-24ne. What device are you using?

I tried it with a SRF08 software version 8. The same one that I used to create the original application note.
The device I am using is a Devantech SRF08, but it is not new. I think it is about 3 years old, maybe 4. I am not sure of the software version of the SRF08. Is this read from byte 0?

-Tony

EDIT: I am using a ZX-24 for this project. Actually, it the Beta device that I had been given a long time ago. It is nearly identical to the current production units. Since the low-level interfacing works, then I do not think that it is a hardware problem at all.

EDIT(2): My SRF08 is using version 5 firmware.
Last edited by spamiam on 02 October 2008, 18:39 PM, edited 2 times in total.
spamiam
Posts: 739
Joined: 13 November 2005, 6:39 AM

Post by spamiam »

mikep wrote:I just tried the example source code from Application Note AN208 and it worked fine on the following devices ZX-24e, ZX-1281e, ZX-24ne. What device are you using?

I tried it with a SRF08 software version 8. The same one that I used to create the original application note.
Mike, thanks for pointing me to the code. For some reason, I thought it was SRF10 specific and it was not an exact match for the SRF08 in its details.

Two things that you are doing differently from my code. 1) your code is much more thorough. Mine is very barebones and bug prone since I just wrote it last night. 2) You are using the hardware I2C. I am using channel 1, one of the software-driven I2C channels. Maybe this is an issue.

Can you re-run your code, and just change the channel from 0 to 1? This will test the software I2C functionality. I can't use the hardware I2C because one of the pins is used for something else, and on this device, I can't reassign some of the pins (not easily, anyway).


-Tony
spamiam
Posts: 739
Joined: 13 November 2005, 6:39 AM

Post by spamiam »

I did more work with tracing down the I2CCmd() issue. I switched around some processors so that I have a recent model ZX24 (instead of a beta device), and a ZX24n.

I used Mike Perk's SRF08 ultrasonic ranger code modified to use a software channel, and use pins 12 and 13. For the ZX24n the compiler told me that it needs at least 140 bytes of task stack, so I made that modification too.

The program works fine on the ZX24n.

It does not work on the ZX24. This was for the same program, just compiled for the 24 vs 24n.

I am pretty sure there is a compiler bug in the code for the software I2C operation of I2CCmd() which is not present in the version of the 24n.

-Tony
dkinzer
Site Admin
Posts: 3120
Joined: 03 September 2005, 13:53 PM
Location: Portland, OR

Post by dkinzer »

spamiam wrote:I am pretty sure there is a compiler bug in the code for the software I2C operation of I2CCmd() which is not present in the version of the 24n.
More likely is a problem in the VM. The code generated by the compiler is identical (except for the channel number) between the hardware channel and the software channels.

What version of the ZX-24 VM are you using? There was a problem in the I2C software channels that was fixed in v1.3.0 (August 2006). It is possible that another, heretofore undiscovered, problem remains.

Do you have access to a logic analyzer?
- Don Kinzer
mikep
Posts: 796
Joined: 24 September 2005, 15:54 PM

Post by mikep »

Here is what my experiments show:
  1. Doesn't fail with channel 0 only on some devices with channel 1.
  2. Doesn't fail on ZX-24ne and ZX-1281e. It does fail on ZX-24e.
I haven't yet tried a ZX-24ae or ZX-24pe.

All tests with ZBasic compiler, ZVM or zxLib version 2.6
Mike Perks
spamiam
Posts: 739
Joined: 13 November 2005, 6:39 AM

Post by spamiam »

dkinzer wrote:What version of the ZX-24 VM are you using? There was a problem in the I2C software channels that was fixed in v1.3.0 (August 2006). It is possible that another, heretofore undiscovered, problem remains.

Do you have access to a logic analyzer?
I was using version 2.5.x at first, then I loaded the newest VM with the same results.

Unfortunately, I don't have a logic analyzer. And my scope is just a simple analog 100MHz type, so I can't do any storage. In debugging the issue, all I can really do is to issue a specific command repetetively, with the scope sweep slow enough to capture the entire train, and then try to start a new data train soon after the sweep finishes, triggering on the first new bit of the next train.

-Tony
spamiam
Posts: 739
Joined: 13 November 2005, 6:39 AM

Post by spamiam »

I did some checking to see what problems other people had communicating with the Devantech ranger family. I found this:
Q. My software master I2C code does not read correct data from the SRF08, but its works fine with an I2C EEPROM
chip. Why is this?
A. The most likely cause is the master code not waiting for the I2C bus hold. This is where the slave can hold the
SCL line low until it is ready. When the master releases SCL (remember it's a passive pull-up, not driven high) the
slave may still be holding it low. The master code should then wait until it actually does go high before proceeding
I suspect that this does not apply to the current bug, but maybe it does. Just FYI.

-Tony
dkinzer
Site Admin
Posts: 3120
Joined: 03 September 2005, 13:53 PM
Location: Portland, OR

Post by dkinzer »

spamiam wrote:the slave can hold the SCL line low until it is ready.
This is called "slave clock stretching" and I believe that it is implemented correctly.

It is interesting that only the ZX-24 and ZX-24e appear to have the problem. These mega32-based devices use the original ZX code base. Since v1.5, all other devices (native and VM) have used the ZX Lib code base which is derived from but not identical to the original ZX code base.
- Don Kinzer
spamiam
Posts: 739
Joined: 13 November 2005, 6:39 AM

Post by spamiam »

dkinzer wrote:
spamiam wrote:the slave can hold the SCL line low until it is ready.
This is called "slave clock stretching" and I believe that it is implemented correctly.

It is interesting that only the ZX-24 and ZX-24e appear to have the problem. These mega32-based devices use the original ZX code base. Since v1.5, all other devices (native and VM) have used the ZX Lib code base which is derived from but not identical to the original ZX code base.
As I thought about it, I concluded that the slave clock stretching is not the issue. I had slowed the ranging commands to much slower than the recommended 65mS. By the time I try to read the registers, the ranging should be long since complete.

It seems that the VM is the culprit. Interestingly, I think that at one time I had written some code to use the I2CCmd() and it was successful. I looked for that code but did not find it immediately. It might have been for an I2C RTC instead. Most likely I was using the low level I2C commands instead of bit-banging the interface.

I did try slowing the I2C clock to 50KHz, with no success. I think I can go slower. The I2C documentation in the Zbasic Library manual does not indicate (or I did not see) the SLOWEST possible settings for the I2C interface (hardware or software).

-Tony
dkinzer
Site Admin
Posts: 3120
Joined: 03 September 2005, 13:53 PM
Location: Portland, OR

Post by dkinzer »

spamiam wrote:It seems that the VM is the culprit. Interestingly, I think that at one time I had written some code to use the I2CCmd() and it was successful.
The source of the problem has been found and corrected. It was also confirmed that the problem is limited to mega32-based devices (i.e., those built using the original ZX code base). It appears to have been introduced between the v2.3.1 and v2.5.0 releases.

You can try out a pre-release of the v2.6.1 VM for the ZX-24 using this link:
http://www.zbasic.net/download/zvm/2.6/zx24_2-6-1.zvm

The correction of this problem is the only change from v2.6.0.
- Don Kinzer
spamiam
Posts: 739
Joined: 13 November 2005, 6:39 AM

Post by spamiam »

dkinzer wrote:The source of the problem has been found and corrected.
I will try it when I get home. What was the actual problem with the code? The problem seemed odd. If I sent data, but did not read data, then it seemed to work fine. When I tried to read data, then it did not seem to send or read afterward. I tried sending an extra I2CStop() command but that did not seem to do the job.

-Tony
dkinzer
Site Admin
Posts: 3120
Joined: 03 September 2005, 13:53 PM
Location: Portland, OR

Post by dkinzer »

spamiam wrote:What was the actual problem with the code?
The pointer for where the data read was to be stored was clobbered during the preparation for the I2C operation. Consequently, the returned data was written to memory other than where it should have been written. This would cause unpredictable results, of course.
- Don Kinzer
Post Reply