Shop OBEX P1 Docs P2 Docs Learn Events
I2C Questions — Parallax Forums

I2C Questions

crgwbrcrgwbr Posts: 614
edited 2007-03-11 01:13 in Propeller 1
I'm trying to write to an eeprom with Mike Green's Minimal I2C routines (I know there are several thread's about this, my question is different though).· Basically, I have never used I2C before, and am quite confused about many of the terms.· In the "I2Cwritepage" routine the following terms are used; i2cSCL, i2cAddr, addrReg, dataPtr, and count.· Can someone post a definition of these terms?··In fact, just explaining I2C would be great.

Thanks,
Craig

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
NerdMaster
For
Life

Comments

  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2007-03-10 02:55
    Craig,
    You only need to google "I2C specification" and you will find the information on the first link. The names of the routines should always be self-explanatory if you understand what needs to be achieved. Also download the datasheet on the eeprom so you can understand the writepage operation as well.

    Take note that I2C is really a very simple protocol if you only consider it in the context of single master as it is generally used. Multiple master I2C is used where multiple micros may share the same I2C peripherals and need to be able to handle conflicts, but don't worry about that.

    RTM RTM RTM

    *Peter*
  • Mike GreenMike Green Posts: 23,101
    edited 2007-03-10 04:44
    i2cSCL is the (even numbered) pin number where the SCL (serial clock) is connected. addrReg is the EEPROM address and consists of a 3 bit device address and a 16 bit address within the device (some devices use multiple device addresses). dataPtr is the address in main memory of the area containing the data, and count is the number of bytes to write.

    i2cAddr I think I now call devSel and is the basic device select code (usually provided in the datasheet for the device). For EEPROMs, it's normally $A0.

    The Basic I2C routines take care of the I2C protocol details in terms of addressing the device, sending any EEPROM address bytes, re-addressing the device if you're trying to read from it, and transferring possibly multiple data bytes.
  • T ChapT Chap Posts: 4,223
    edited 2007-03-10 10:22
    said...
    consists of a 3 bit device address and a 16 bit address within the device (some devices use multiple device addresses)


    Can these be mixed? Say 2 devices that are 3 bit address:

    %000
    %001
    %010

    then a 2 bit addressed device:

    %11

    and a 4th device at 4 bits

    %0100

    If it does not see it's own device type, will it ignore the start byte which may contain 2, 3, or 4 bit addresses?
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2007-03-10 11:32
    originator,

    I had just done up a rather involved explanation of the use of device addresses + modifier bits but then my browser crashed.

    I think you are getting confused with the use of n-bit addresses as this is referring to the pins that allow you to select the lsbs of a fixed device address. Eeproms such as the 24LC256 will have a 3-bit chip address input that can modify the base address from $A0 to $AE. The lsb is not actually an address bit but a read/write select. Each and every I2C device must end up (your responsibility) with a unique address otherwise you will have contention. Does that sort of answer your question?

    *Peter*
  • crgwbrcrgwbr Posts: 614
    edited 2007-03-10 13:05
    ok; I read some of the data sheet.·I attached·the diagram of the device addressing code.· Acording to it I need to send:

    1. Start bit (i2cStart(SCL))
    2. 4 bit binary control code
    3. 3 bit binary chip select (A0, A1 A2)
    4. Read/Write bit
    5. Acknowledgement bit

    I'm guessing data comes after the acknowledgement bit.

    Anyway, for a 2 byte pagewrite to the boot eeprom and the last internal data address, I think·it would be like this:

    i2cSCL - 28
    i2cAddr - $A0
    addrReg - %0000111111111111111 ($7FFF = %0111111111111111)
    dataPtr - @variable
    count - 2

    Question: Do I have to use the binary internal address, can I put it in hexidecimal instead?· ($7FFF instead of %0111111111111111)

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    NerdMaster
    For
    Life


    Post Edited (crgwbr) : 3/10/2007 1:30:56 PM GMT
    512 x 384 - 15K
    i2c.JPG 14.7K
  • Mike GreenMike Green Posts: 23,101
    edited 2007-03-10 15:39
    crgwbr,
    What you've got looks like it would work except that you're trying to write 2 bytes to the last data address (it'll wrap around to the start of the last "page"). Don't forget to either wait 5ms after the write or use writeWait to make sure the write has completed before you try to write anything else or read from the EEPROM. Regarding the binary vs. hexadecimal question. The Spin compiler translates all numbers into the same 32 bit numeric values regardless of whether they're written in decimal, binary, hexadecimal or 2-bit form (%%2310).

    For data address, use $7FFE with a count of 2.

    Again, the I2C object takes care of the start condition, sending the proper device address when it needs to be sent (including the read/write bit), any address or data bytes, and the stop condition.

    By the way, don't include the read/write bit in the device address byte ... the routines do that for you.

    Post Edited (Mike Green) : 3/10/2007 3:44:29 PM GMT
  • T ChapT Chap Posts: 4,223
    edited 2007-03-10 19:22
    There are i2c devices that use 2, 3 and 4 bit fixed address schemes, the EEPROM on the Prop uses 3 pins for example. There are other devices I want to add to the existing i2c pins to avoid using extra pins (SDA and SCL), for example I am looking to add a 12 bit I2C ADC on the bus with the EEPROM. I am still searching, but here is a BB/TI that looks like what I want, nobody has them in stock, it is just an example. It uses 2 address pins.

    What I notice about the address byte is, it has a 5 bit device length versus 4 on the EEPROM.

    MSB 6   5   4    3    2    1     LSB
      1   0    0   1    0   A1  A0    R/W
    
    



    This leads me to belive that it can be used with the EEPROM lines, since they have adjusted the device type bit length to compensate for the shorter address bits.

    focus.ti.com/lit/ds/symlink/ads7828.pdf

    Post Edited (originator) : 3/10/2007 7:30:41 PM GMT
  • Mike GreenMike Green Posts: 23,101
    edited 2007-03-10 20:26
    originator,
    If you look at the upper 4 bits for different kinds of devices, they have different codes. EEPROMs are $Ax, the I/O expanders are $40 or $70. The A-D/D-As as you've noticed are $90. This is done so the devices can be mixed. Your ADC can be used with an EEPROM.
  • T ChapT Chap Posts: 4,223
    edited 2007-03-10 23:06
    Thanks for the clarification. Using assembly, what is the fastest rate at which a "highspeed" i2c device can be read by the Propeller? I have not yet found an ADC that has a feature to write into it a threshold to trigger an alarm on a separate pin, similar to some i2c temp devices that are on the market. To monitor the ADC for a threshold, the device will have to be read in a loop, and the code would consist of the start byte to init the device, followed by the read loop checking the level, and acting at a set point. There may be a better way that what I described, but fast read/response is desired.
  • Paul BakerPaul Baker Posts: 6,351
    edited 2007-03-10 23:32
    Originator, it the only function you are using the ADC for is a threshold function? If so, you really should use an analog comparator instead.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Paul Baker
    Propeller Applications Engineer

    Parallax, Inc.
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2007-03-10 23:39
    Yeah, my lost detailed reply covered all this. BTW, I don't know if the I2C routines check the ack bit after the control byte (address+r/w) is sent but that is the easy way to see if the device is ready. So eeprom access routines would normally keep polling the address until they receive an ack to indicate eeprom is ready and no longer programming. All transfers are byte sized and include an ack bit from the recipient of the byte. That is why the device address is only 7-bits so that a single bit can be allocated for read/write.

    Typical 27lc256 eeprom write and read access.
    START
    %1010000    7-bit device address     ; The device address is always 7-bits while the lsbs may be user selectable if address select pins are available.
    %0          1-bit read/write         ; 0 indicates that the master will be writing further data bytes (not to be confused with writing memory locations)
    <-- ack                              ; the receiving chip pulls the sda line low during the ack clock if it's address matches the device address and it is ready.
    
    $00         addrh                    ; the address high byte which is 'written' to the eeproms address register (only 7-bits are significant on the 27lc256)
    <-- ack                              ; the receiving chip acks the byte written to it
    
    $C0         addrl                    ; the address low byte which is 'written' to the eeproms address register
    <-- ack
    
    $12         memory data              ; data "to be" written to the memory location pointed to by the auto-incrementing address register
    ack
    STOP                                 ; it is at this point that the eeprom will program the data byte or bytes as in the case of a page write.
    
    ; now a bit more tersely...
    
    START                                ; ok now we want to read that data back but first we have to write the memory address register first to point to the data
    $A0         eeprom+write             ; device address with address bytes to follow
    <-- ack                              ; if there is no ack then keep on reissuing a START+DEVADDR+R/W (normally done with each control byte)
    $00         addrh
    <-- ack
    $C0         addrl                    ; if we didn't do this the location that would be accessed would actually be $C1 as the memory address register auto-increments
    <-- ack
    STOP                                 ; optional as a START will always reset the I2C state machine
    START
    $A1         eeprom+read
    <-- ack
    <-- $12     memory data              ; ahhh, there it is
    nack                                 ; normally thank the eeprom very much with an ack but since we have had enough say no more thanks.
    STOP
    
    



    The datasheet does detail this in timing diagrams but maybe this makes it a bit easier to see for some. Hope it helps.

    *Peter*
  • T ChapT Chap Posts: 4,223
    edited 2007-03-10 23:43
    True, that's what I am doing currently. The 8 input chips seemed like something to explore to reduce pin counts while getting 8 ADC's.
  • Paul BakerPaul Baker Posts: 6,351
    edited 2007-03-10 23:56
    Then perhaps you should use 8 analog comparators with an I2C port expander. That way you'll get the entire bank of thresholds at once.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Paul Baker
    Propeller Applications Engineer

    Parallax, Inc.
  • T ChapT Chap Posts: 4,223
    edited 2007-03-11 01:13
    Peter I missed your deatils earlier somehow, thanks for taking the time out, that is beneficial info. Nothing worse than writing a long detailed response and crashing. I have done that a few times, now I would do a long answer in a text editor with frequent saves.

    Paul, in the case of the expander, that is a very good point, since the PCF8575 has an Interrupt output that fires on any received input to the ports (if in the correct mode). A simple Spin waitpne that starts a Read on the I2C bus could be fast enough. My guess is that the from the time a trigger happens, and the INT hits the Propeller that initiates the read, the info shoud still be present when it gets read.
Sign In or Register to comment.