I2C issues, a propeller unreliability?
4Alex
Posts: 119
Hi all,
I am migrating new and previous designs from PICs to propeller. Accordingly, I've been using several different kind of I2C devices lately (read: about 2 dozens) and I noticed that quite a few don't respond well to I2C spins (or at least, in an uncomplicated manner). I'm using the James Burrows May 2006 Version 1.3 spin but I've used other variants as well including the Basic_I2C as modified by Tim Moore. Same issues.
Could someone kindly explain to me why is that there are several I2C spins available (why not just one, after all, there's only one standard) and why not all of them can properly address all of the I2C devices found out there. One variant works better with one kind of devices but not others and vice versa for the other variants. Sometime ReadLocation works some other time you need the convoluted i2cWrite/i2cRead form. This is nuts. I've programmed other microcontrollers for years and I've never encountered, not even once, the kind of erratic behaviour than I am experiencing with the Propeller. Is this a propeller issue, then?
For example, I am trying to address a very common digital potentiometer. Ultra-simple to operate. Its the AD5242 (256-steps pot). A very straight forward I2C device. Used it all the time with PICs. First try to migrate it on a propeller design. Doesn't work. Period. The fartest I can go is a device_present confirmation, which I got right away from minute 1.
'get wiper position value (1 byte) (datasheet p.6)
i2c.i2cstart
i2c.i2cwrite(AD5242_Addr,8) 'Frame #1 add=$58, confirmed by device_present
i2c.i2cwrite($00,8) 'Frame #2, instruction=$00, read reg. for wiper 1
i2c.i2cwrite($00,8) 'Frame #3, data=$00, could be ignored
i2c.i2cstop
i2c.i2cstart
i2c.i2cWrite(AD5242_Addr+1, 8) 'slave address
numValue := i2c.i2cRead(i2c#_i2cNAK)
i2c.i2cstop
This code (and several other variants) results in junk, when not 0. At power-on, value should be 127 (mid-course between 0 and 255 steps). The device is functional and responsive when tested with a PIC.
For convenience, I have attached the datasheet.
Any help would be greatly appreciated.
Cheers,
Alex
I am migrating new and previous designs from PICs to propeller. Accordingly, I've been using several different kind of I2C devices lately (read: about 2 dozens) and I noticed that quite a few don't respond well to I2C spins (or at least, in an uncomplicated manner). I'm using the James Burrows May 2006 Version 1.3 spin but I've used other variants as well including the Basic_I2C as modified by Tim Moore. Same issues.
Could someone kindly explain to me why is that there are several I2C spins available (why not just one, after all, there's only one standard) and why not all of them can properly address all of the I2C devices found out there. One variant works better with one kind of devices but not others and vice versa for the other variants. Sometime ReadLocation works some other time you need the convoluted i2cWrite/i2cRead form. This is nuts. I've programmed other microcontrollers for years and I've never encountered, not even once, the kind of erratic behaviour than I am experiencing with the Propeller. Is this a propeller issue, then?
For example, I am trying to address a very common digital potentiometer. Ultra-simple to operate. Its the AD5242 (256-steps pot). A very straight forward I2C device. Used it all the time with PICs. First try to migrate it on a propeller design. Doesn't work. Period. The fartest I can go is a device_present confirmation, which I got right away from minute 1.
'get wiper position value (1 byte) (datasheet p.6)
i2c.i2cstart
i2c.i2cwrite(AD5242_Addr,8) 'Frame #1 add=$58, confirmed by device_present
i2c.i2cwrite($00,8) 'Frame #2, instruction=$00, read reg. for wiper 1
i2c.i2cwrite($00,8) 'Frame #3, data=$00, could be ignored
i2c.i2cstop
i2c.i2cstart
i2c.i2cWrite(AD5242_Addr+1, 8) 'slave address
numValue := i2c.i2cRead(i2c#_i2cNAK)
i2c.i2cstop
This code (and several other variants) results in junk, when not 0. At power-on, value should be 127 (mid-course between 0 and 255 steps). The device is functional and responsive when tested with a PIC.
For convenience, I have attached the datasheet.
Any help would be greatly appreciated.
Cheers,
Alex
pdf
395K
Comments
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
JMH - Electronics: Engineer - Programming: Professional
What is useless?
Cheers,
Alex
Yeah, I'd like to know too.
The guy seems to have a legitimate problem. It's probably PEBKAC, but until we know that it would be nice to not make him any angrier than he already is.
I wouldn't say that this is a Propeller issue as much as it is a software issue and possibly a hardware conflict.· At least one of the I2C sources you named does not handle the SDA and·SCL signals correctly.· From my own findings·the·signals are not·properly driven as open collector.· Keep in mind also that the Propeller is 3.3V, which means that some I2C devices that are 5V may be sensitive to this difference and you need to design accordingly.
I'm not familiar with the AD5242 or I would gladly provide you with code that I know for sure will work.
Here is an excellent source for I2C specifications: http://www.nxp.com/acrobat_download/usermanuals/UM10204_3.pdf
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Beau Schwabe
IC Layout Engineer
Parallax, Inc.
Thanks for your good words. I'm not the least bit angry, actually. Sorry for the icon, I must have clicked it accidentally when doing the attachment. The issues ARE real. I've asked some assistance in the past on rather complex ICs, and fortunately the solutions kindly offered worked. However, it's never a consistent solution from one I2C problem to another. There's something wrong somewhere. I do get the speed issue (most ICs do work up to 400kHz, though), and at the rigueur the clock stretching (to a point) but this should be it. And it's not. I have successfully used all these ICs on a PIC (mostly 16 and 18F series up to 40MHz) and I never even needed the so-called clock stretching. So, this is why I am humbly asking if there is an I2C issue with the propeller that I should be aware of. I am usually prompt to blame myself of having a senior moment (I'm at that age) but... Sorry if this sounds whiny, it's not intended to be.
Thanks all for your patience.
Cheers,
Alex
2) James Burrows' driver had problems with the standard Propeller I2C bus on I/O pins 28/29 used with the EEPROM. This only has a pullup on SDA and the SCL line is normally driven high and low. If you're using these lines for your AD5242, you may need to add a pullup to SCL or use the posted Version 2 of this driver which uses a different low level driver that takes care of this.
3) What you've written looks like it ought to work (other than always setting the pot to zero). Since it doesn't, there must be something you're not showing us that's causing problems. There may be something else in your program or in the wiring that's causing the problem.
BTW, what PEBKAC means?
@Beau:
Thanks for your reply. I use only 3v3 compatible ICs with the propeller. It simplifies my designs and they are usually more 'modern'. The AD5242 is rated from 2v7 to 5v. This is a breadboard implementation so the only other I2C is the SEEPROM. Thanks for the link but I had already downloaded that *precious* document.
@ Mike:
As always, thanks for your reply. I consistently pull-up both lines in every designs, as I experienced unstabilities in the past. The code is short and sweet since I tend to test things on a breadboard before going any further with an untested IC/Code combo. The only thing missing in the code snippet is the init and the device_present calls: they work since I get the device_present confirmation.
1. I have replaced the spin with just downloaded version Basic_I2C Version 2.1 (still listed as version 1.1 in comments, though). Very same code as above worked right away. I can now read back all the preset values I want. So, it was a version issue, this time. Thanks for pointing me to a more recent version.
2. My understanding of I2C is that you can run at pretty much any speed as long as you don't exceed the rated value (100kHz or 400kHz). I am I correct on this one? If such is the case (and it should obviiously be since I can read/write with a slow spin driver), then speed is not an issue. So why clock stretching would be necessary?
3. I have downloaded the femtobasic zip file. I can't see any I2C driver. In any case, can we use this driver the same way as I use the other spin object, I mean, just adding a file (and referencing it) along with all the other spins?
Many thanks for all your help.
Cheers,
Alex
Oooooo! let me answer this one. It's the cause of almost all my woes regarding anything I touch.
PEBKAC
Problem
Exists
Between
Keyboard
And
Chair
ie. Me [noparse]:)[/noparse]
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Pull my finger!
Funny and how accurate! Thanks.
Cheers,
Alex
I started off with Tim's code (I think) but while I found it dealt fine with eeproms, including the boot eeprom, it wouldn't work with a MAX1139 ADC which stretches the clock.I did some changes but Spin still makes it too slow, and I shall have a look at Mike's femtobasic ones too, or write my own.
Neither the "simple" I2C Spin routines nor the FemtoBasic routines can handle clock stretching. The "standard" hardware without the SCL pullup can't handle clock stretching anyway since the SCL line has to be actively driven high. You could certainly modify the Spin routines to do this, but the assembly routines would have to be completely rewritten to add this.
Post Edited (Mike Green) : 10/29/2008 4:52:29 PM GMT
First, thanks a lot for your time and much valued assistance. This posting is not about some sort of PEBKAC (couldn't resist to use it at least once), though I am first to seriously consider this possibility before posting. Trust me.
So, back under the hood. According to the UM10204 (p. 25) expertly referred to by Beau, the speeds for the I2C are:
• Standard-mode (Sm), with a bit rate up to 100 kbit/s
• Fast-mode (Fm), with a bit rate up to 400 kbit/s
• Fast-mode Plus (Fm+), with a bit rate up to 1 Mbit/s
• High-speed mode (Hs-mode), with a bit rate up to 3.4 Mbit/s.
My understanding from your reply is that under spin the bus runs at 20kHz (or so). Then, speed shouldn't be a concern for ANY I2C devices at all. Signalling is rather straighforward so it should always work. The words "Consistently across I2C devices" also comes to mind. How is it then that it's still difficult (sometime impossible) to communicate with some I2C devices (like in the reply of agodwin) even though electronics and signalling are correct. Moreover, it always work with a PIC, typically running in the range of 20-40MHz. I had some hands-on experience with BS2 (long, long time ago), and I don't recall having any problem then. How is it that the problems starts when using the propeller? I may be obtuse but I still don't get it.
In any case, thanks all for your patience. Hope this thread won't get me booted off the island.
Cheers,
Alex
Typically you would use the format (sclpin, 1) for reading 1 byte.
Check to see if the i2c variant of read you are using does include a field for ack.
Also, the i2c versions I use (minimal I2C, BasicI2c) require i2cstart, i2cstop, write, readdata to use the scl_pin.
Test this with minimal i2c driver, not sure what the '8' is, but I put it on a new line.
Post Edited (Originator) : 10/29/2008 8:46:58 PM GMT
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
JMH - Electronics: Engineer - Programming: Professional
I agree with you on the robustness of the propeller. It is really a great processor to work with, and I'm often amazed at how simple it is to implement complex designs compared to PICs.
You have a good point in looking at the signal transition & timings: I have a logic analyzer and I intend to do some work on this. I'm a bit tied up right now but I will check into that. Perhaps some devices are more susceptible than others to glitches on the lines and similar issues. In a previous post, I asked about the maximum number of I2C devices on a single line primarily because I have experienced communication problems with a combo of ICs that used to work individually. It turned out that noise was the problem.
Again, many thanks for your help.
@Originator:
Thanks for your reply. The code posted above now work properly as it is listed. I also tried the i2c_basic version modified by Tim Moore (Aug 08) and it works too.
Cheers,
Alex
No need for apologies, I never considered your posting rude, I was just wondering which part was useless. Nevertheless, the mere fact that you care means that I am replying to a gentleman.
Cheers,
Alex
Glad you got it working - version 1.X was a bit weird in some ways. It assumed (correctly) that the SCL & SDA both had pull ups - the SDA (I think) doesn't on the prop dev board, also the number of bits/bytes/longs etc wasn't as nice as Mikes way. Mikes Basic_i2c_driver.spin was a very tidy improvement - so has been used in v2.X
I'll correct the version comments in it.
Cheers,
James