Shop OBEX P1 Docs P2 Docs Learn Events
Writing/Reading via I2C to boot eeprom — Parallax Forums

Writing/Reading via I2C to boot eeprom

TE44TE44 Posts: 42
edited 2007-01-23 13:28 in Propeller 1
Not having great success writing/reading to/from the Boot EEprom on a demo board - can some one show me an example ?

e.g a decimal value eg '1234' ?

·

Comments

  • Mike GreenMike Green Posts: 23,101
    edited 2007-01-21 22:28
    What are you using? What are you trying to do?

    Attached is a set of routines to do this with some comments on their use. You can also use the I2C object in the Propeller Object Exchange.
  • TE44TE44 Posts: 42
    edited 2007-01-21 23:03
    Mike,
    Trying to write a 4 digit decimal ('1234') to the end of the boot eeprom and read it back - thought it would be straight forward but I am having difficulty -I am using the Demo Board Rev C - loads of I2C routines out there but an example using the one you attached would be nice. I can see you are well up there on this aspect of things.

    TE
  • Mike GreenMike Green Posts: 23,101
    edited 2007-01-21 23:45
    Where do you have the decimal characters? Would you rather write the binary? You can take the example in the comments in the routines I posted, just use the bytes where you have the character string and a length of 4. If you want to write a binary word, just provide the address of the word and a length of 2.

    You'll have to give more specific information about what you're trying to do if the above isn't enough.
  • TE44TE44 Posts: 42
    edited 2007-01-22 00:19
    Mike,
    All I want to do is write a value eg '1234' to Boot EEprom and recall it after a power cycle.

    i.e without code -

    i2c.i2cstart
    i2c.I2cwrite(28,???)
    waitcnt (500_000)
    i2c.i2cread(28,???)



    - assign the 'read in' value to an assigned var
  • Mike GreenMike Green Posts: 23,101
    edited 2007-01-22 00:30
    If you have a word variable "foo", you can do the following:
    i2cWritePage(28,$A0,$7FFC,@foo,2)
    waitcnt(clkfreq / 200 + cnt)
    


    To read it back in do:
    i2cReadPage(28,$A0,$7FFC,@foo,2)
    


    This doesn't do any checking. You can follow the examples in the source comments for that. If you want to use a long instead of a word, just use a size of 4 instead of 2. I didn't write the routines to be used as an object. Just cut and paste them into your program.

    Note: The kind of Start/Write/Read stuff you've hinted at in your posting won't work. Look at datasheets for EEPROMs to see the kinds of sequences needed. You have to write a device select code, then a 16 bit address, then some data. For reading, you have to write the select code and the address, then re-select the device for reading and read your data.
  • Luis DigitalLuis Digital Posts: 371
    edited 2007-01-22 00:36
    Pull-up resistor in SDA and SCL pins?

    idea.gif
  • TE44TE44 Posts: 42
    edited 2007-01-22 01:20
    Mike,
    That worked perfectly - thank you ...

    TE
  • Mike GreenMike Green Posts: 23,101
    edited 2007-01-22 01:21
    Luis,
    The I2C specification (from Philips) requires pull-up resistors (about 4.7K) between each of the SCL and SDA pins and the +5V or +3.3V supply so that the signal lines are high if no devices are driving them so. Where there is only one possible bus master (like with the boot EEPROM on the Propeller), you can dispense with the SCL pull-up since only the Propeller will transmit a clock and can drive the line both low and high. You still need the pull-up on the SDA line to keep the line in a high state as the EEPROM and Propeller take turns transmitting data and there may be some overlap. If one of them drove the line high and low, there might be a brief short circuit that could damage one of them. By using a pull-up and only driving the line low, there can't be a short.
  • Luis DigitalLuis Digital Posts: 371
    edited 2007-01-22 01:36
    Mike,

    "i2c Object library v1.3 for the Propeller" only reads (no write) if does not have a resistance in SCL.
  • Mike GreenMike Green Posts: 23,101
    edited 2007-01-22 01:48
    Yes. The current version of the I2C Object Library is supposed to have fixed this. There is an additional parameter (to the init routine) that is supposed to cause the routines to actively drive the SCL line both high and low. I've had some problems with this working which is why I wrote my own. They're simple, but they do work with or without the pullup on SCL so they will work with the boot EEPROM on the Parallax boards.
  • TE44TE44 Posts: 42
    edited 2007-01-22 21:17
    Mike,
    While the example works out great - when I power cycle I get an odd character back - If I write the value '1234' - when pin6 goes from low - high -low (010) it reads it back fine ... then after a power cycle it throws back an odd char - i believe chr 210...?

    here is the sample -


    VAR
    word buffer
    word old

    CON
    _clkmode = xtal1 + pll16x
    _xinfreq = 5_000_000

    obj
    ee: "minimal_i2c_driver"
    text: "vga_text"

    Pub Main
    buffer := 1234
    text.start(16)

    dira[noparse][[/noparse]0..7] := %0000000 'set p1 to p7 as inputs

    old :=0

    ' set a pattern '010'on pin6 before write is called
    ' to ensure write is not called numerous times in the loop
    repeat
    if ina[noparse][[/noparse]6] ==0 and old ==1
    old :=0

    if ina[noparse][[/noparse]6] == 1 and old == 0
    write
    old :=1
    else
    read

    pub write

    ee.i2cWritepage(28,$A0,$7000,@buffer,2)
    waitcnt(clkfreq / 200 + cnt)
    text.out($00)
    text.str(string("Wrote : "))
    text.dec(buffer)
    waitcnt(2_000)
    pub read
    ee.i2cReadPage(28, $A0, $7000, @buffer, 2)
    waitcnt(clkfreq / 200 + cnt)
    text.out($00)
    text.str(string("Read : "))
    if buffer
    text.dec(buffer)
  • Mike GreenMike Green Posts: 23,101
    edited 2007-01-22 22:21
    I don't see anything obviously wrong with your example. It turns out that you don't need the waitcnt after the i2cReadPage, but that extra delay won't hurt anything. It may be that the Propeller boot loader leaves the EEPROM in an odd state and it needs to be reset prior to the first read or write. Try putting this in your initialization code:
      outa[noparse][[/noparse]28] := 1 ' set SCL high
      dira[noparse][[/noparse]28] := 1
      dira[noparse][[/noparse]29] := 0 ' set SDA as input
      repeat 9 ' up to 9 cycles
        outa[noparse][[/noparse]28] := 0 ' put out a clock pulse
        outa[noparse][[/noparse]28] := 1
        if ina[noparse][[/noparse]29] ' if SDA is not high, repeat
          quit
    


    Do be sure to clear "buffer" before reading it just to make sure it's read.
    It may be that neither the write nor read is actually happening. Both
    the i2cReadPage and i2cWritePage will return non-zero if an error
    occurred and you could display a message if so.
  • TE44TE44 Posts: 42
    edited 2007-01-23 10:43
    as per usual you were right mike....need I say any more ?
  • QuattroRS4QuattroRS4 Posts: 916
    edited 2007-01-23 13:28
    Read this thread very interesting ! Already have a use for something quite similar ..
Sign In or Register to comment.