Shop OBEX P1 Docs P2 Docs Learn Events
basic i2c driver - write/read data corruption — Parallax Forums

basic i2c driver - write/read data corruption

Richard S.Richard S. Posts: 70
edited 2008-03-19 12:01 in Propeller 1
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

Comments

  • Richard S.Richard S. Posts: 70
    edited 2008-03-19 03:51
    Further testing...reading data into and out of 'buffer' using longmove yields normal results.· Writing data into eeprom from 'buffer', reading data from eeprom into 'buffer', then reading data from 'buffer' into a display reveals corrupted results only with the first eeprom/read-buffer position.·

    Is there a startup-read timing problem?







    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Richard in Michigan
  • stevenmess2004stevenmess2004 Posts: 1,102
    edited 2008-03-19 10:38
    I would say that your problem is that your buffer is declared as bytes but you are using a longmove to move the data. This causes problems with alignment as if you give a longmove an address it just treats the last two bits as 0 which will obviously do bad things.
  • JavalinJavalin Posts: 892
    edited 2008-03-19 12:01
    put a delay in after writing to the eeprom - "waitcnt 400_000 + cnt" should do a 5ms delay at 80mhz - its the max write time on the eeprom!

    J
Sign In or Register to comment.