Shop OBEX P1 Docs P2 Docs Learn Events
i2c random access reads? — Parallax Forums

i2c random access reads?

Chicago MikeChicago Mike Posts: 88
edited 2007-11-15 18:25 in Propeller 1
I'm using i2c to read from a RTC clock, but I'm having a really interesting issue. I am reading from the same memory address TWICE in·different methods for various reasons, but I'm getting different results? No alteration of this address is occuring (As they are flag bits I'm trying to read). On the first read of this address (See Runonce) I get a result of say %01000101, but reseting the address pointer and reading again (See Runagain), I'm getting %00000010. Clearly there is something I'm missing here in regards to random access reading of i2c devices. Below I've commented the Run once, with what I believe each statements is doing (These methods were taken from James Burrows i2cobject). This was modified from the RTC1307 object to work with a different, but very similar RTC. A lot of code has been removed, (I'm using·i2object, and the lcd4x20 objects)> I did include the methods I am using to print·the bin to the LCD for testing.·I just can't figure why I would get a different response. Its got to have to do with my addressing?

--Mainline Program--
posbin(3,1,Runonce,8)
waitcnt(100_000_000+cnt)
posbin(3,10,Runagain,8)

--- methods---

PUB Runonce : htalarmRecord
· if started == true
··· i2cObject.i2cStart
··· ' Address the device
··· i2cObject.i2cWrite (rtc_Address | 0,8)
··· ' Set the memory pointer to $01 - The register I want to read
··· i2cObject.i2cwrite($01,8)
····i2cObject.i2cStart
··· ' Set the read flag
··· i2cObject.i2cWrite (rtc_Address | 1,8)
··· ' Read the register
··· htalarmRecord := i2cObject.i2cRead(i2cObject#_i2cACK)
··· i2cObject.i2cStop

' Exactly the same as above, but gives a different result
PUB Runagain : htstatus
· if started == true
··· i2cObject.i2cStart
··· i2cObject.i2cWrite (rtc_Address | 0,8)
··· i2cObject.i2cwrite($01,8)
··· i2cObject.i2cStart
··· i2cObject.i2cWrite (rtc_Address | 1,8)
··· htstatus := i2cObject.i2cRead(i2cObject#_i2cACK)
··· i2cObject.i2cStop

PUB posbin(line, column, value, digits)
· pos(line,column)
· bin(value,digits)

PUB bin (value, digits)
· VALUE <<= 32 - DIGITS
· REPEAT DIGITS
··· writeout((VALUE <-= 1) & 1 + "0")

Comments

  • JavalinJavalin Posts: 892
    edited 2007-11-14 16:10
    With the write and directly reading it again - you need to allow at least 5ms between, as this is the time the EEPROM takes to complete the write.

    ie..

    waitcnt(400_000+cnt)

    James
  • Mike GreenMike Green Posts: 23,101
    edited 2007-11-14 16:21
    Without the rest of the code to give a context, it's hard to tell what's going wrong. What you've shown should work as you expect.
    The only thing I can think of is that there's something going on in the device itself that changes the flags that are read. Without
    a datasheet for the device, it's impossible to tell. These devices are RAM based usually and a delay between reads should not be
    necessary.

    Javalin,
    His write cycle is part of the I2C read process.
    You have to use write mode to supply a register address to the device before you can read the register.
  • RaymanRayman Posts: 14,162
    edited 2007-11-14 18:02
    Just FYI:

    I'm also planning on trying out an I2C RTC (maybe today?)...
    Anyway, I'm going to use this stripped down version of Mike Green's I2C code that I previously used for I/O expansion over I2C:

    http://www.rayslogic.com/propeller/Programming/i2c/PCF8574_Demo.zip
  • RaymanRayman Posts: 14,162
    edited 2007-11-14 19:40
    Anybody know what the usual usage of the scratch RAM on the Dallas/Maxim RTC's is? I don't really see the point in using it. Especially, if I'm using a Proto board with 32k of left over EEPROM... Maybe it is for alarms or something?
  • SapiehaSapieha Posts: 2,964
    edited 2007-11-14 20:04
    Hi Rayman.

    It was for systems like PC to hold config data

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Nothing is impossible, there are only different degrees of difficulty.

    Sapieha
  • Chicago MikeChicago Mike Posts: 88
    edited 2007-11-15 01:48
    A little update. I'm trying to use a M41T812S, from st micro. It has generally a similar memory map to the DS1307. (Though I few alterations were needed) and the reason I'm using it is that it has an alarm function on an interrupt pin. Very cool feature.

    After playing around a little more I have realized that regardless of what the second read does it comes back as wrong every time, however on the first call, regardless of the address, the data is correct. I've looked for an offset or something and I can't seem to find a pattern, leaving me with the belief its something in the code above.

    Still looking.
  • JavalinJavalin Posts: 892
    edited 2007-11-15 08:33
    Mike,

    Interesting - sorry didn't really read your first post - hence the EEPROM based response.

    Attached is the beta of my device-objects using Mike Greens "basic_i2c_object" - plus a few bits.· Its not finished but maybe will help?

    Given up on my i2cObject - too messy.

    James
  • Chicago MikeChicago Mike Posts: 88
    edited 2007-11-15 17:33
    I'll give it a shot. Thanks for your object updates. It seems everyone has standardized on Mike's well written, and simple basic_i2cobject.

    Oddly enough with this M41T812S I can do sequential reads without a problem, its just random access reads that seem to be the issue, which the datasheet claims it can do (like most other RTCs I've seen). I have never had this problem with any other i2c devices I've used. Then again all of my experience has been with eeprom or fram i2c devices. Tomorrow I'm going to try another of these M41T812S's to see if thats the problem (Pain because its a SOIC device on a breakout), then I may just order a different RTC that supports I2c to see if its really just this model I'm having problems with, or if its me.

    Anyone has any suggestions for another I2c capable RTC, that has a SOIC form factor available, and had alarm features? (I"m asking a lot, I know, as this was the perfect device for me, and at around $.95, you can't go wrong).

    Thanks,
    Mike.
  • Chicago MikeChicago Mike Posts: 88
    edited 2007-11-15 18:15
    I found it! During a random read, on the final packet read, there is NOACK. Therefor instead of

    htalarmRecord := i2cObject.i2cRead(i2cObject#_i2cACK) which sent sent an ACK (LOW state). I changed it to

    htalarmRecord := i2cObject.i2cRead(1). I'm going to switch my code over to Javalin's new RTC object which use Mike Greens BASIC-i2c_Object tonight for consistency. I noticed that the new RTC objects using BASIC_I2C_Object, reference i2cObject.i2cRead(i2cObject#_i2cNAK) on the final read, which would properly leave the ACK at 1, eliminating this problem.

    Was in my face the entire time on the datasheet, but it took the v2 objects to notice it. Thanks for all the help!
  • JavalinJavalin Posts: 892
    edited 2007-11-15 18:18
    Good catch!

    J
  • ZootZoot Posts: 2,227
    edited 2007-11-15 18:25
    Somebody said...
    Anybody know what the usual usage of the scratch RAM on the Dallas/Maxim RTC's is? I don't really see the point in using it. Especially, if I'm using a Proto board with 32k of left over EEPROM... Maybe it is for alarms or something?

    Generally an RTC has a either a battery backup or a supercap backup (so that time/date and scratch RAM are maintained even when the main system is powered down). Depending on your application it can be cosmically useful to have RAM registers that are stable even after power-off.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    When the going gets weird, the weird turn pro. -- HST
Sign In or Register to comment.