Shop OBEX P1 Docs P2 Docs Learn Events
I2C issues, a propeller unreliability? — Parallax Forums

I2C issues, a propeller unreliability?

4Alex4Alex Posts: 119
edited 2008-10-30 14:31 in Propeller 1
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 mad.gif

Comments

  • Mike HuseltonMike Huselton Posts: 746
    edited 2008-10-29 13:12
    Useless

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    JMH - Electronics: Engineer - Programming: Professional
  • 4Alex4Alex Posts: 119
    edited 2008-10-29 13:20
    @Quantum,

    What is useless?

    Cheers,

    Alex
  • BergamotBergamot Posts: 185
    edited 2008-10-29 13:40
    4Alex said...
    @Quantum,

    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.
  • Beau SchwabeBeau Schwabe Posts: 6,560
    edited 2008-10-29 14:00
    4Alex,

    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.
  • 4Alex4Alex Posts: 119
    edited 2008-10-29 14:02
    @Bergamot:

    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
  • Mike GreenMike Green Posts: 23,101
    edited 2008-10-29 14:03
    1) There are several I2C drivers in the library because several people were independently working on this at the same time and developed routines with different emphases, one on general purpose use (for arbitrary devices with a large set of examples) and one specifically for use with EEPROMs, but with low level routines that allowed other uses. There's a 3rd set of routines in the BS2 Compatibility Library for use with EEPROMs. Since then, various people have modified these for their own specific needs and posted the results for others to share. There's another completely different I2C driver written in assembly language that's part of the FemtoBasic interpreter, but can be used separately.

    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.
  • Mike GreenMike Green Posts: 23,101
    edited 2008-10-29 14:23
    The Spin-only drivers are relatively slow, I'm guessing that they can do maybe 20KHz. The assembly drivers in FemtoBasic can do maybe 300KHz. I know they are not reliable at 400KHz, work with some devices at that speed, but not with others. They're written to be very general purpose and have a lot of overhead internally as a result. They're quite solid at 100KHz (the default setting) with a small selection of I2C devices (PCF8574, PCA9554, MCP23016, various EEPROMs from different manufacturers) with zero, one, or two address (register select) bytes.
  • 4Alex4Alex Posts: 119
    edited 2008-10-29 15:48
    @Bergamot:
    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
  • BradCBradC Posts: 2,601
    edited 2008-10-29 16:11
    4Alex said...
    @Bergamot:
    BTW, what PEBKAC means?

    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!
  • 4Alex4Alex Posts: 119
    edited 2008-10-29 16:34
    @BradC:
    Funny and how accurate! Thanks.

    Cheers,

    Alex
  • agodwinagodwin Posts: 72
    edited 2008-10-29 16:36
    Despite the icon, I took Bergamot's comment to be referring to Quantum's one-word response, not 4Alex's question.

    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.
  • Mike GreenMike Green Posts: 23,101
    edited 2008-10-29 16:44
    The FemtoBasic I2C driver is the file "sdspiFemto.spin". The Spin interface routines only handle the standard EEPROM interfacing with a 2 byte "register" address, but the assembly routines (as described in the comments) do handle a 1 byte "register" address and direct read / write transfers like those for the PCF8574. The Spin interface does no overlapping (buffering) of I/O, but the assembly routines can handle double buffering.

    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
  • 4Alex4Alex Posts: 119
    edited 2008-10-29 19:16
    @Mike:
    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
  • Mike GreenMike Green Posts: 23,101
    edited 2008-10-29 19:28
    There's no fundamental reason why you should have problems with the Propeller. The I/O pin structure is robust 3.3V logic. The underlying speed of the Propeller is more than high enough and this has been demonstrated with a variety of communications protocols and other high speed operations. Perhaps the Propeller is too fast for your device with a clock speed of 80MHz and an instruction time of 50ns. Maybe the signal transitions need to be slowed down a little bit. That's as good a guess as anything. Without hanging a scope and logic analyzer on your setup, it's impossible to tell. Again, the Propeller appears to work well for others in similar circumstances and in circumstances that reasonably would be expected to be troublesome (high speed, tight timing, etc.) What's different about your circumstances and what's actually happening is a question that needs more data.
  • T ChapT Chap Posts: 4,223
    edited 2008-10-29 19:34
    Do you not need a value for ack (0 or 1) in the read data line? 1 = only read one byte.

    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.

    i2c.i2cstart(sclpin)
    i2c.i2cwrite(sclpin, AD5242_Addr)
    i2c.i2cwrite(sclpin, 8)
    i2c.i2cwrite(sclpin, $00)
    i2c.i2cwrite(sclpin, 8)    
    i2c.i2cwrite(sclpin, $00)  'duplicate writes?  device must be auto incrementing a register?
    i2c.i2cwrite(sclpin, 8)
    i2c.i2cstop(sclpin)
    i2c.i2cstart(sclpin)
    i2c.i2cWrite(sclpin , AD5242_Addr+1)   
    'i2c.i2cwrite(sclpin, 8)       'if needed
    numValue := i2c.i2cRead(sclpin, 1)
    i2c.i2cstop(sclpin)
    
    
    
    

    Post Edited (Originator) : 10/29/2008 8:46:58 PM GMT
  • Mike HuseltonMike Huselton Posts: 746
    edited 2008-10-30 00:30
    My sincere apologies. I was responding to another post. However, the response was crass, unkind and just bad manners. Please forgive me.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    JMH - Electronics: Engineer - Programming: Professional
  • 4Alex4Alex Posts: 119
    edited 2008-10-30 11:45
    @Mike:
    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
  • 4Alex4Alex Posts: 119
    edited 2008-10-30 11:51
    @Quantum:
    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
  • JavalinJavalin Posts: 892
    edited 2008-10-30 14:31
    4Alex,

    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
Sign In or Register to comment.