Shop OBEX P1 Docs P2 Docs Learn Events
BS2, external EEPROM: I need some help understanding. — Parallax Forums

BS2, external EEPROM: I need some help understanding.

LMMLMM Posts: 1
edited 2008-03-09 23:30 in BASIC Stamp
Ok, so I have a BS2OEM with a 24LC16B in it. What I'm wanting to do is read the first few bits off an EEPROM (a second 24LC16B) with SDA on pin 4 and SCL on pin 5, store them into a variable, and be able to compare said variable with one that's already on the BS2OEM's EEPROM. I looked quite heavily last night for example code that allowed BS2 to read I2C EEPROMs connected to 2 pins, and did in fact find I2C_Essentials.BS2 by Jon Williams. I've modified it in order to use it with the 2nd EEPROM, mainly changing values sent to the 2nd EEPROM to match the control codes off the 24LC16B's spec. sheet I found online.

The problem is I don't think I'm doing it right... The command code that should be sent is: 1010ABC0, where ABC is the block select bits. What ARE the block select bits I need to put there? On the 2nd EEPROM I wrote "1245" to the very beginning of it using "DATA 1234" on a 2nd BS2 before removing it and attempting to read it from the 1st BS2.

For quick reference, here's a PDF link to the EEPROM's spec. sheet I've been using: ww1.microchip.com/downloads/en/DeviceDoc/21703G.pdf. The info I've been looking at most is on page 9 and the 2nd graph labeled "Figure 7-2: Random Read" on page 10.

Here is my code. It's quite sloppy (for instance the I2C_Stop subroutine isn't even being used, as the EEPROM's spec. sheet said it doesn't need to be used in random reading), so feel free to kick it around to your liking. I'm not asking for anyone to fix it (this is a school project, after all) but I would LOVE a push in the right direction!

' =========================================================================
'
'   File....... I2C_Essentials.BS2
'   Purpose.... I2C Interface Routines
'   Author..... Jon Williams, Parallax
'   E-mail..... jwilliams@parallax.com
'   Started.... 20 MAR 2002
'   Updated.... 18 AUG 2004
'
'   {$STAMP BS2}
'   {$PBASIC 2.5}
'
' =========================================================================


' -----[noparse][[/noparse] Program Description ]---------------------------------------------
'
' Generic I2C code for non-BS2p/BS2pe modules.


' -----[noparse][[/noparse] Revision History ]------------------------------------------------
'
' 18 AUG 2004 - Updated and made routines completely generic


' -----[noparse][[/noparse] I/O Definitions ]-------------------------------------------------

SDA             PIN     4                       ' I2C serial data line
SCL             PIN     5                       ' I2C serial clock line


' -----[noparse][[/noparse] Constants ]-------------------------------------------------------

Ack             CON     0                       ' acknowledge bit
Nak             CON     1                       ' no ack bit


' -----[noparse][[/noparse] Variables ]-------------------------------------------------------

slvAddr         VAR     Byte                    ' slave address
devNum          VAR     Nib                     ' device number (0 - 7)
addrLen         VAR     Nib                     ' 0, 1 or 2
devAddr         VAR     Word                    ' address in device
results         VAR     Word

i2cData         VAR     Byte                    ' data to/from device
i2cWork         VAR     Byte                    ' work byte for TX routine
i2cAck          VAR     Bit                     ' Ack bit from device



Main:
DEBUG "program started",CR
GOTO read_byte
stopmaybe:
 DEBUG "results = ", HEX results, CR, "devaddr.LOWBYTE = ", DEC devaddr.LOWBYTE, CR, "devaddr.HIGHBYTE = ", DEC devaddr.HIGHBYTE, CR, "i2cdata = ", DEC i2cdata, CR, "i2cwork = ", DEC i2cwork, CR
 STOP
 END

' -----[noparse][[/noparse] Subroutines ]-----------------------------------------------------



' -----[noparse][[/noparse] High Level I2C Subroutines]---------------------------------------

' Random location read
' -- pass device slave address in "slvAddr"
' -- pass address bytes (0, 1 or 2) in "addrLen"
' -- register address passed in "devAddr"
' -- data byte read is returned in "i2cData"

Read_Byte:
  GOSUB I2C_Start
  DEBUG "sent Start",CR
    i2cWork = %10100000               ' send slave ID (write)
    GOSUB I2C_TX_Byte
    DEBUG "sent control byte, got an ack",CR
    DEBUG "mem's all good, sending word address #1",CR
    GOTO i2c_start2
    continue:
    DEBUG "start condition set", CR
      i2cWork = %10100001                   ' send word address (1)
      GOSUB I2C_TX_Byte
      DEBUG "read control byte sent", CR
    SHIFTIN sda, scl, MSBFIRST, [noparse][[/noparse]results\8]                     ' send word address (0)
    DEBUG "results received!", CR
'    GOSUB I2C_TX_Byte
'    DEBUG "bytes sent, going back to I2C_Start to send start command",CR
'    GOSUB I2C_Start
'  DEBUG "sending slave address to read",CR
'  i2cWork = slvAddr | %00000001          ' send slave ID (read)
'  GOSUB I2C_TX_Byte
'  DEBUG "sent! begin receiving...",CR
'  GOSUB I2C_RX_Byte_Nak
'  DEBUG "receiving...",CR
'  GOSUB I2C_Stop
'  i2cData = i2cWork
  GOTO STOPmaybe
'  DEBUG devaddr, CR
  RETURN


' -----[noparse][[/noparse] Low Level I2C Subroutines]----------------------------------------

' *** Start Sequence ***

I2C_Start:                                      ' I2C start bit sequence
DEBUG "input sda...",CR
  INPUT SDA
  DEBUG "input scl...",CR
  INPUT SCL
  DEBUG "low sda...",CR
  LOW SDA
  RETURN

  I2C_Start2:                                      ' I2C start bit sequence
DEBUG "input sda...",CR
  INPUT SDA
  DEBUG "input scl...",CR
  INPUT SCL
  DEBUG "low sda...",CR
  LOW SDA
GOTO continue

Clock_Hold:
  DEBUG "waiting for the clock"
  DO : LOOP UNTIL (SCL = 1)                     ' wait for clock release
  RETURN


' *** Transmit Byte ***

I2C_TX_Byte:
DEBUG "sending I2C_TX_byte...",CR
  SHIFTOUT SDA, SCL, MSBFIRST, [noparse][[/noparse]i2cWork\8]      ' send byte to device
  DEBUG "shiftout sent!", CR
  SHIFTIN SDA, SCL, MSBPRE, [noparse][[/noparse]i2cAck\1]          ' get acknowledge bit
  IF i2cack = 0  THEN
  DEBUG "ack received!",CR
  ELSEIF i2cack <> 0 THEN: DO : LOOP UNTIL (i2cack = 0)
  ENDIF
  RETURN


' *** Receive Byte ***

I2C_RX_Byte_Nak:
  i2cAck = Nak                                  ' no Ack = high
  GOTO I2C_RX
  RETURN

I2C_RX_Byte:
  i2cAck = Ack                                  ' Ack = low

I2C_RX:
  SHIFTIN SDA, SCL, MSBPRE, [noparse][[/noparse]i2cWork\8]         ' get byte from device
  DEBUG "got byte from device", CR
  SHIFTOUT SDA, SCL, LSBFIRST, [noparse][[/noparse]i2cAck\1]       ' send ack or nak
  DEBUG "send ack" ,CR

  RETURN


' *** Stop Sequence ***

I2C_Stop:                                       ' I2C stop bit sequence
DEBUG "beginning stop command", CR
  LOW SDA
  INPUT SCL
  INPUT SDA
  DEBUG "stop command finished!" ,CR
  RETURN
Sign In or Register to comment.