Stamp Manual "I2CIN"/"I2COUT" discrepancy
kelvin_koolohm
Posts: 4
in BASIC Stamp
From the Stamp Manual:
I2COUT Pin,SlaveID,{ Address{\LowAddress},}[ OutputData]
(The discussion is then provided into how to split an address >255 into 2 bytes for the "address \Low Address" format)
But in the following example program, the variable "addr" is defined as a word variable and is used as the incrementer in a "FOR...NEXT" LOOP.
FOR addr = 0 TO 2047 STEP 16 ' loop through all addresses
block = addr.NIB2 << 1 ' calculate block address (addr.NIB2 will range 0 ->7, which is then shifted left once in "block" to insert it into the "SlaveId")
value = addr >> 4 ' create value from upper 8 bits
' write 16 bytes
I2COUT SDA, $A0 | block, addr, [REP value\16]
^
Note that the word variable ^ is then used in the I2C command without breaking it out into the "address \Low Address" format.
Is this legal?
Since the 24LC16 is expecting an 8 bit low address here ( the top 3 bits are included in the SlaveId), what is it receiving from this command?
2nd question: can the "$A0 | block" operation be enclosed in parentheses to make it easier to read?
( the 24LC16 EEPROM being addressed requires that a block address be included in the SlaveId byte to distinguish which one of the 8 blocks of 256 bytes is being addressed)
( they used this method to "OR" the block number into position in the SlaveId )
The makers of the 24LC16 decided to differently use the 3 bits that normally are used to match 3 pins on the chip to help determine chip select.
They decided to use those 3 bits in the SlaveId as the high 3 address bits instead of a two byte address that would waste 5 bits in the high byte address.
Thanks
I2COUT Pin,SlaveID,{ Address{\LowAddress},}[ OutputData]
(The discussion is then provided into how to split an address >255 into 2 bytes for the "address \Low Address" format)
But in the following example program, the variable "addr" is defined as a word variable and is used as the incrementer in a "FOR...NEXT" LOOP.
FOR addr = 0 TO 2047 STEP 16 ' loop through all addresses
block = addr.NIB2 << 1 ' calculate block address (addr.NIB2 will range 0 ->7, which is then shifted left once in "block" to insert it into the "SlaveId")
value = addr >> 4 ' create value from upper 8 bits
' write 16 bytes
I2COUT SDA, $A0 | block, addr, [REP value\16]
^
Note that the word variable ^ is then used in the I2C command without breaking it out into the "address \Low Address" format.
Is this legal?
Since the 24LC16 is expecting an 8 bit low address here ( the top 3 bits are included in the SlaveId), what is it receiving from this command?
2nd question: can the "$A0 | block" operation be enclosed in parentheses to make it easier to read?
( the 24LC16 EEPROM being addressed requires that a block address be included in the SlaveId byte to distinguish which one of the 8 blocks of 256 bytes is being addressed)
( they used this method to "OR" the block number into position in the SlaveId )
The makers of the 24LC16 decided to differently use the 3 bits that normally are used to match 3 pins on the chip to help determine chip select.
They decided to use those 3 bits in the SlaveId as the high 3 address bits instead of a two byte address that would waste 5 bits in the high byte address.
Thanks
Comments
Yes, you can enclose ($A0 | block) in parentheses. Including part of an address in the slave ID is quite common, not so different. The I2C code $A (in 8-bit format) is reserved for memory devices. Or'ing into the device ID is common when it is necessary to select one of several memory chips. Here,
block = addr.NIB2 << 1
shifts the selector bits left by one so that when OR'd with the $A0, the lowest bit is left alone for use as read=%1 (by I2CIN) and write as %0.
The addr is 16 bits, but the I2COUT command, as written, sends only 8 bits, the least significant byte of addr.
I was worried that it might be a typo.
3rd question:
If I'm using a chip that has more than 2K so that the block address
is too big to fit in the 3 bits in the device ID, (so that I'm having
to send the whole address word) will the following code work?
SDA PIN 0
SCL PIN SDA + 1
addr VAR Word
lab var addr.LOWBYTE
hab var addr.HIGHBYTE
(end of declarations)
**************************
FOR addr = 0 to 65535 STEP 16
I2COUT SDA, $A0, hab, \lab, [REP value\16]
NEXT
Or do I have to actually calculate the high address byte and the
low address byte inside the loop?
?