wolwil, Here it is again incase you didn't find it. Maxpages is set for 1023 x the number of 24LC1025's you have connected. The routine saves the last storage pointer in the last 2 locations of the last 24LC1025. Block is incremented once for each page. Before you start a clean write you would set block to 0 which is the first page. When you want to read back the data then you would call READ_WRITE_BLK1025 and block would have the last address written..
This routine is rock solid and I use it for accessing 4 x 24LC1025's for a total of over 4 gigabits of memoy to record Azmnuth,Elevation,East/West/Up/Down Sensor data and control flag information for about 2 months at 1 minute intervals... I hope this helps...
Code:
CNTRL_BYTE CON $A0 'CONTROL BYTE FOR 24LC1025 I2C EEPROM MEMORY (A0/A1 USED FOR CHIP SELECT)
MAX_PAGES CON 4095 'MAXIMUM MEMORY STORAGE PAGES,(32 BYTES/MINUTE x 4 MINUTES x PAGES = TOTAL MINUTES)
'*********************************************************************
RW_EEPROM1025: 'READ FROM or WRITE TO SERIAL EEPROM
'*********************************************************************
IF READ_WRITE = 1 THEN 'WRITE 128 BYTE BLOCK TO EEPROM
IF BLOCK <> 0 THEN 'IF STARTING NEW PASS DON'T READ OLD LOCATION
READ_WRITE = 0 'SET FOR BLOCK READ
GOSUB READ_WRITE_BLK1025 'READ FROM SERIAL EEPROM NEXT AVAILABLE STORAGE BLOCK
READ_WRITE = 1 'SET FOR BLOCK WRITE
ENDIF
DEVICE = BLOCK / 512 'SELECT WHICH PHYSICAL ADDRESS BOUNDRY & EEPROM
ADDRESS = BLOCK << 7 'CALCULATE 12C ADDRESS TO STORE DATA TO
CNTROL_BYTE = CNTRL_BYTE 'COPY CONTROL BYTE
CNTROL_BYTE.1 = DEVICE.1 'SET LSB OF HARDWARE ADDRESS
CNTROL_BYTE.2 = DEVICE.2 'SET MSB OF HARDWARE ADDRESS
CNTROL_BYTE.3 = DEVICE.0 'SET 64K BLOCK BIT
INTCON.7 = 0 'CLEAR GLOBAL INTERRUPT
I2CWRITE SDA,SCL,CNTROL_BYTE,ADDRESS,[STR STOR_DATA\128] 'SAVE DATA TO 12C
WRITEOCCURED = 1
INTCON.7 = 1 'SET GLOBAL INTERRUPT
PAUSE 6 'ALLOW TIME FOR I2C WRITE ~5Ms.
BLOCK = BLOCK + 1 'INCREMENT FOR NEXT AVAILABLE BLOCK TO WRITE
BLOCK = BLOCK MIN MAX_PAGES 'LIMIT TO n BLOCKS OF 128 BYTES
GOSUB READ_WRITE_BLK1025 'WRITE TO or READ FROM SERIAL EEPROM LAST STORAGE BLOCK
ELSE
DEVICE = BLOCK / 512 'SELECT WHICH PHYSICAL ADDRESS BOUNDRY & EEPROM
ADDRESS = BLOCK << 7 'CALCULATE 12C ADDRESS TO STORE DATA TO
CNTROL_BYTE = CNTRL_BYTE 'COPY CONTROL BYTE
CNTROL_BYTE.1 = DEVICE.1 'SET LSB OF HARDWARE ADDRESS
CNTROL_BYTE.2 = DEVICE.2 'SET MSB OF HARDWARE ADDRESS
CNTROL_BYTE.3 = DEVICE.0 'SET 64K BLOCK BIT
INTCON.7 = 0 'CLEAR GLOBAL INTERRUPT
I2CREAD SDA,SCL,CNTROL_BYTE,ADDRESS,[STR READ_DATA\128] 'LOAD IN ENTIRE BLOCK
WRITEOCCURED = 1
INTCON.7 = 1 'SET GLOBAL INTERRUPT
ENDIF
RETURN
'*********************************************************************
READ_WRITE_BLK1025: 'WRITE TO or READ FROM SERIAL EEPROM NEXT AVAILABLE STORAGE BLOCK
'*********************************************************************
ADDRESS = 65534 'POINT TO LAST STORED DATA(WORD) ADDRESS
DEVICE = MAX_PAGES / 512 'SELECT WHICH PHYSICAL ADDRESS BOUNDRY & EEPROM
CNTROL_BYTE = CNTRL_BYTE 'COPY CONTROL BYTE
CNTROL_BYTE.1 = DEVICE.1 'SET LSB OF HARDWARE ADDRESS
CNTROL_BYTE.2 = DEVICE.2 'SET MSB OF HARDWARE ADDRESS
CNTROL_BYTE.3 = DEVICE.0 'SET 64K BLOCK BIT
IF READ_WRITE = 1 THEN
INTCON.7 = 0 'CLEAR GLOBAL INTERRUPT
I2CWRITE SDA,SCL,CNTROL_BYTE,ADDRESS,[BLOCK.LOWBYTE,BLOCK.HIGHBYTE] 'WRITE DATA POINTER TO 12C
WRITEOCCURED = 1
INTCON.7 = 1 'SET GLOBAL INTERRUPT
PAUSE 6 'ALLOW TIME FOR I2C WRITE ~5Ms.
ELSE
INTCON.7 = 0 'CLEAR GLOBAL INTERRUPT
I2CREAD SDA,SCL,CNTROL_BYTE,ADDRESS,[BLOCK.LOWBYTE,BLOCK.HIGHBYTE] 'READ DATA POINTER FROM 12C
WRITEOCCURED = 1
INTCON.7 = 1 'SET GLOBAL INTERRUPT
ENDIF
RETURN
Dave Purola,
N8NTA
Bookmarks