basic i2c driver - write/read data corruption
Below is a portion of my program that·writes a list of values to eeprom and then reads them from the eeprom.
[noparse][[/noparse]code]
CON
· _clkmode······· = xtal1 + pll16x·················································
· _xinfreq······· = 5_000_000
· eepromAddress·· = $8000
OBJ
····
· i2c···· : "basic_I2C_Driver"
· kb····· : "keyboard"
· text··· : "vga_text"··
·
VAR
·
· long··············· offset[noparse][[/noparse]8]····················
· long··············· cpu[noparse][[/noparse]8]······················
· long··············· sign[noparse][[/noparse]8]······························
· long··············· units[noparse][[/noparse]8]····················
· long··············· pos[noparse][[/noparse]4]······················
· long··············· cal_x[noparse][[/noparse]4]····················
· long··············· cal_y[noparse][[/noparse]4]····················
· long··············· cal_z[noparse][[/noparse]4]····················
· long··············· cal_a[noparse][[/noparse]4]····················
· long··············· dp_cnt······················
· long··············· dp_deg······················
· long··············· dp_in·······················
· long··············· dp_mm·······················
· byte··············· d_p[noparse][[/noparse]8]······················
· byte··············· display_type
· byte··············· buffer[noparse][[/noparse]128]················
PUB Start
· initialize_variables
· kb.startx(26, 27, %1_111_110, %11_11100)
·
· i2c.initialize(28)·················· ' initialize basic_i2c_driver
· i2c.start(28)······················· ' start basic_i2c_driver
· file_menu
PUB Initialize_variables
·
· repeat index from 0 to 7 step 1
··· d_p[noparse][[/noparse]index]··· := 4
··· offset[noparse][[/noparse]index] := 8.0
··· sign[noparse][[/noparse]index]·· := 1.0
··· cpu[noparse][[/noparse]index]··· := 5080.0
··· units[noparse][[/noparse]index]· := @in_ptr
· repeat index from 0 to 3 step 1
··· pos[noparse][[/noparse]index]·· := 20320
··· cal_x[noparse][[/noparse]index] := 200.0
··· cal_y[noparse][[/noparse]index] := 200.0
··· cal_z[noparse][[/noparse]index] := 200.0
··· cal_a[noparse][[/noparse]index] := 200.0
···
· dp_cnt := 1
· dp_deg := 2
· dp_in· := 4
· dp_mm· := 3
·
· display_type := 1
···········
PUB File_menu
· file_screen·
· repeat
··· input := kb.getkey
··· case input···
····· $31:························· ' 1 ... write values to disk
······· write_buffer
······· EEPROM_read_write_screen
······· file_screen
····· $32:························· ' 2 ... read values from disk
······· read_buffer
······· EEPROM_read_write_screen
······· file_screen
····· $33:························· ' 3 ... go to display_values_screen
······· display_screen·············
······· file_screen
····· $30:························· ' 0 ... to main_menu
······· abort········
····· other:······················· ' wrong command
······· wrong_command_screen
······· file_screen
PUB Write_buffer
'' Write_buffer will write to location (eepromAddress + (128*block))
'' Block is set to 1 or 2 for the different 128 bytes blocks of eeprom used
' Write the 1st 128 byte block of memory
· block := 1
·
· longmove(@buffer,@offset,8)······ ' load long values into buffer
· longmove(@buffer+32,@cpu,8)······
· longmove(@buffer+64,@sign,8)
· longmove(@buffer+96,@units,8)
· writeit·························· ' write buffer data to 1st 128 byte block
' Write the 2nd 128 byte block of memory
·
· block := block + 1··············
·
· longmove(@buffer,@pos,4)········· ' load long and byte values into buffer
· longmove(@buffer+16,@cal_x,4)
· longmove(@buffer+32,@cal_y,4)
· longmove(@buffer+48,@cal_z,4)
· longmove(@buffer+64,@cal_a,4)
·
· longmove(@buffer+80,@dp_cnt,1)
· longmove(@buffer+84,@dp_deg,1)
· longmove(@buffer+88,@dp_in,1)
· longmove(@buffer+92,@dp_mm,1)
·
· bytemove(@buffer+96,@d_p,8)
· bytemove(@buffer+104,@display_type,1)
·
· writeit·························· ' write buffer data to 2nd 128 byte block
PUB Read_buffer
'' Fill write buffer with data saved at location (eepromAddress + (128*block))
'' Block is set to 1 or 2 for the different 128 bytes blocks of eeprom used
' Read the 1st 128 byte block of memory
· block := 1
·
· readit··························· ' read 1st 128 byte block into buffer
·
· longmove(@offset,@buffer,8)······ ' move buffer data into variables
· longmove(@cpu,@buffer+32,8)·
· longmove(@sign,@buffer+64,8)
· longmove(@units,@buffer+96,8)
·
' Read the 2nd 128 byte block of memory
· block := 1 + block
·
· readit··························· ' read 2nd 128 byte block into buffer
··
· longmove(@pos,@buffer,4)········· ' move buffer data into variables
· longmove(@cal_x,@buffer+16,4)·
· longmove(@cal_y,@buffer+32,4)
· longmove(@cal_z,@buffer+48,4)
· longmove(@cal_a,@buffer+64,4)
·
· longmove(@dp_cnt,@buffer+80,1)
· longmove(@dp_deg,@buffer+84,1)
· longmove(@dp_in,@buffer+88,1)
· longmove(@dp_mm,@buffer+92,1)
·
· bytemove(@d_p,@buffer+96,8)
· bytemove(@display_type,@buffer+104,1)
''
''
''·· I2C EEPROM
''
''
PRI ReadIt
'' Method that calls i2c_driver to read string from eeprom
· if i2c.Readpage(i2c#BootPin, i2c#EEPROM, eepromAddress+(128*block), @buffer, 128)
··· EEPROM_error_screen ' an error occurred during the read
···
PRI WriteIt | startTime
'' Method that calls i2c_driver to write string to eeprom
· if i2c.Writepage(i2c#BootPin, i2c#EEPROM, eepromAddress+(128*block), @buffer, 128)
··· EEPROM_error_screen ' an error occured during the write
·······
· startTime := cnt ' prepare to check for a timeout
···
· repeat while i2c.WriteWait(i2c#BootPin, i2c#EEPROM, eepromAddress+(128*block))
··· if cnt - startTime > clkfreq / 10
····· EEPROM_error_screen ' waited more than a 1/10 second for the write to finish
''
''
''·· SCREENS
''
''
PUB Display_values_screen
'' Displays values stored in eeprom in a variety of formats
'' Formats include integer, floating point decimal, string
PUB File_screen················
'' File read/write screen
·
· text.str(string($A,7,$B,2,"‣▶ LOAD/STORE SETTINGS ◀‣"))
· text.str(string($A,8,$B,4,"1▶ SAVE VALUES"))
· text.str(string($A,8,$B,5,"2▶ READ VALUES"))
· text.str(string($A,8,$B,6,"3▶ DISPLAY VALUES"))
· text.str(string($A,8,$B,7,"0▶ MAIN MENU"))
PUB Wrong_command_screen
·
· text.str(string($A,4,$B,5,"‣▶ INVALID COMMAND ◀‣"))
PUB EEPROM_read_write_screen
· text.str(string($A,8,$B,9,"‣▶ FILE READ/WRITE ◀‣"))
· text.str(string($A,8,$B,11,"··· PLEASE WAIT...·· "))
··
PUB EEPROM_error_screen
·
· text.str(string($A,4,$B,3,"‣▶ FILE READ/WRITE ERROR ◀‣"))
· text.str(string($A,4,$B,5,"······· TRY AGAIN········· "))
[noparse][[/noparse]/code]
There are two blocks of values, each totaling 128 bytes.· The read/write buffer is 128 bytes.· When I save the two blocks of data, and then read them back in, all the data appears correct witht he exception of 'offset' and 'pos'.· These two long variables seem to interact, giving incorrect results to the 'offset' value.· It appears to be predictable...for a given value saved in 'pos' and certain but incorrect value appears in 'offset'.· When I move the position of 'offset' and 'pos' to another line (hence another position in the read/write buffer) the error is different but still predictable and reproducible.
If either block 1 or block 2 are commented out, data is written/read without error.· It is only when I have 2 blocks of data to write and read that the error occurs.· Note that the 'offset' and 'pos' variables are at the top of each block to be written/read.
I believe the problem to be somehow connected with the way I have written the routines to write/read but it is not clear as to what.· Comments are welcomed!
Thanx!
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Richard in Michigan
Post Edited (Richard S.) : 3/18/2008 11:59:48 PM GMT
[noparse][[/noparse]code]
CON
· _clkmode······· = xtal1 + pll16x·················································
· _xinfreq······· = 5_000_000
· eepromAddress·· = $8000
OBJ
····
· i2c···· : "basic_I2C_Driver"
· kb····· : "keyboard"
· text··· : "vga_text"··
·
VAR
·
· long··············· offset[noparse][[/noparse]8]····················
· long··············· cpu[noparse][[/noparse]8]······················
· long··············· sign[noparse][[/noparse]8]······························
· long··············· units[noparse][[/noparse]8]····················
· long··············· pos[noparse][[/noparse]4]······················
· long··············· cal_x[noparse][[/noparse]4]····················
· long··············· cal_y[noparse][[/noparse]4]····················
· long··············· cal_z[noparse][[/noparse]4]····················
· long··············· cal_a[noparse][[/noparse]4]····················
· long··············· dp_cnt······················
· long··············· dp_deg······················
· long··············· dp_in·······················
· long··············· dp_mm·······················
· byte··············· d_p[noparse][[/noparse]8]······················
· byte··············· display_type
· byte··············· buffer[noparse][[/noparse]128]················
PUB Start
· initialize_variables
· kb.startx(26, 27, %1_111_110, %11_11100)
·
· i2c.initialize(28)·················· ' initialize basic_i2c_driver
· i2c.start(28)······················· ' start basic_i2c_driver
· file_menu
PUB Initialize_variables
·
· repeat index from 0 to 7 step 1
··· d_p[noparse][[/noparse]index]··· := 4
··· offset[noparse][[/noparse]index] := 8.0
··· sign[noparse][[/noparse]index]·· := 1.0
··· cpu[noparse][[/noparse]index]··· := 5080.0
··· units[noparse][[/noparse]index]· := @in_ptr
· repeat index from 0 to 3 step 1
··· pos[noparse][[/noparse]index]·· := 20320
··· cal_x[noparse][[/noparse]index] := 200.0
··· cal_y[noparse][[/noparse]index] := 200.0
··· cal_z[noparse][[/noparse]index] := 200.0
··· cal_a[noparse][[/noparse]index] := 200.0
···
· dp_cnt := 1
· dp_deg := 2
· dp_in· := 4
· dp_mm· := 3
·
· display_type := 1
···········
PUB File_menu
· file_screen·
· repeat
··· input := kb.getkey
··· case input···
····· $31:························· ' 1 ... write values to disk
······· write_buffer
······· EEPROM_read_write_screen
······· file_screen
····· $32:························· ' 2 ... read values from disk
······· read_buffer
······· EEPROM_read_write_screen
······· file_screen
····· $33:························· ' 3 ... go to display_values_screen
······· display_screen·············
······· file_screen
····· $30:························· ' 0 ... to main_menu
······· abort········
····· other:······················· ' wrong command
······· wrong_command_screen
······· file_screen
PUB Write_buffer
'' Write_buffer will write to location (eepromAddress + (128*block))
'' Block is set to 1 or 2 for the different 128 bytes blocks of eeprom used
' Write the 1st 128 byte block of memory
· block := 1
·
· longmove(@buffer,@offset,8)······ ' load long values into buffer
· longmove(@buffer+32,@cpu,8)······
· longmove(@buffer+64,@sign,8)
· longmove(@buffer+96,@units,8)
· writeit·························· ' write buffer data to 1st 128 byte block
' Write the 2nd 128 byte block of memory
·
· block := block + 1··············
·
· longmove(@buffer,@pos,4)········· ' load long and byte values into buffer
· longmove(@buffer+16,@cal_x,4)
· longmove(@buffer+32,@cal_y,4)
· longmove(@buffer+48,@cal_z,4)
· longmove(@buffer+64,@cal_a,4)
·
· longmove(@buffer+80,@dp_cnt,1)
· longmove(@buffer+84,@dp_deg,1)
· longmove(@buffer+88,@dp_in,1)
· longmove(@buffer+92,@dp_mm,1)
·
· bytemove(@buffer+96,@d_p,8)
· bytemove(@buffer+104,@display_type,1)
·
· writeit·························· ' write buffer data to 2nd 128 byte block
PUB Read_buffer
'' Fill write buffer with data saved at location (eepromAddress + (128*block))
'' Block is set to 1 or 2 for the different 128 bytes blocks of eeprom used
' Read the 1st 128 byte block of memory
· block := 1
·
· readit··························· ' read 1st 128 byte block into buffer
·
· longmove(@offset,@buffer,8)······ ' move buffer data into variables
· longmove(@cpu,@buffer+32,8)·
· longmove(@sign,@buffer+64,8)
· longmove(@units,@buffer+96,8)
·
' Read the 2nd 128 byte block of memory
· block := 1 + block
·
· readit··························· ' read 2nd 128 byte block into buffer
··
· longmove(@pos,@buffer,4)········· ' move buffer data into variables
· longmove(@cal_x,@buffer+16,4)·
· longmove(@cal_y,@buffer+32,4)
· longmove(@cal_z,@buffer+48,4)
· longmove(@cal_a,@buffer+64,4)
·
· longmove(@dp_cnt,@buffer+80,1)
· longmove(@dp_deg,@buffer+84,1)
· longmove(@dp_in,@buffer+88,1)
· longmove(@dp_mm,@buffer+92,1)
·
· bytemove(@d_p,@buffer+96,8)
· bytemove(@display_type,@buffer+104,1)
''
''
''·· I2C EEPROM
''
''
PRI ReadIt
'' Method that calls i2c_driver to read string from eeprom
· if i2c.Readpage(i2c#BootPin, i2c#EEPROM, eepromAddress+(128*block), @buffer, 128)
··· EEPROM_error_screen ' an error occurred during the read
···
PRI WriteIt | startTime
'' Method that calls i2c_driver to write string to eeprom
· if i2c.Writepage(i2c#BootPin, i2c#EEPROM, eepromAddress+(128*block), @buffer, 128)
··· EEPROM_error_screen ' an error occured during the write
·······
· startTime := cnt ' prepare to check for a timeout
···
· repeat while i2c.WriteWait(i2c#BootPin, i2c#EEPROM, eepromAddress+(128*block))
··· if cnt - startTime > clkfreq / 10
····· EEPROM_error_screen ' waited more than a 1/10 second for the write to finish
''
''
''·· SCREENS
''
''
PUB Display_values_screen
'' Displays values stored in eeprom in a variety of formats
'' Formats include integer, floating point decimal, string
PUB File_screen················
'' File read/write screen
·
· text.str(string($A,7,$B,2,"‣▶ LOAD/STORE SETTINGS ◀‣"))
· text.str(string($A,8,$B,4,"1▶ SAVE VALUES"))
· text.str(string($A,8,$B,5,"2▶ READ VALUES"))
· text.str(string($A,8,$B,6,"3▶ DISPLAY VALUES"))
· text.str(string($A,8,$B,7,"0▶ MAIN MENU"))
PUB Wrong_command_screen
·
· text.str(string($A,4,$B,5,"‣▶ INVALID COMMAND ◀‣"))
PUB EEPROM_read_write_screen
· text.str(string($A,8,$B,9,"‣▶ FILE READ/WRITE ◀‣"))
· text.str(string($A,8,$B,11,"··· PLEASE WAIT...·· "))
··
PUB EEPROM_error_screen
·
· text.str(string($A,4,$B,3,"‣▶ FILE READ/WRITE ERROR ◀‣"))
· text.str(string($A,4,$B,5,"······· TRY AGAIN········· "))
[noparse][[/noparse]/code]
There are two blocks of values, each totaling 128 bytes.· The read/write buffer is 128 bytes.· When I save the two blocks of data, and then read them back in, all the data appears correct witht he exception of 'offset' and 'pos'.· These two long variables seem to interact, giving incorrect results to the 'offset' value.· It appears to be predictable...for a given value saved in 'pos' and certain but incorrect value appears in 'offset'.· When I move the position of 'offset' and 'pos' to another line (hence another position in the read/write buffer) the error is different but still predictable and reproducible.
If either block 1 or block 2 are commented out, data is written/read without error.· It is only when I have 2 blocks of data to write and read that the error occurs.· Note that the 'offset' and 'pos' variables are at the top of each block to be written/read.
I believe the problem to be somehow connected with the way I have written the routines to write/read but it is not clear as to what.· Comments are welcomed!
Thanx!
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Richard in Michigan
Post Edited (Richard S.) : 3/18/2008 11:59:48 PM GMT
spin
![](/plugins/FileUpload/images/file.png)
13K
Comments
Is there a startup-read timing problem?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Richard in Michigan
J