BS2, external EEPROM: I need some help understanding.
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!
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