|
|
View previous topic :: View next topic |
Author |
Message |
Gabriel
Joined: 03 Aug 2009 Posts: 1067 Location: Panama
|
Struct to EEPROM |
Posted: Wed Nov 07, 2018 5:35 am |
|
|
Hi all..
I have an array of structs... each struct is 32bytes the array is size 4 thus its 128 bytes total.
This is purposely done so that when the array fills up with 4 data points (struct) i can make a single page write to an 24LC512 EEPROM....
The problem is that prior to this all my eeprom usage has been single byte writes.
How do i dump a struct to EEPROM comprising of several floats and misc. Bytes?
I would appreciate some direction or related post.
Thanks.
G. _________________ CCS PCM 5.078 & CCS PCH 5.093 |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19499
|
|
Posted: Wed Nov 07, 2018 7:56 am |
|
|
Yes, bytes.
Key to remember is that everything in memory is bytes. If you have the address of the start of your first array in a pointer, and cast this to be to an int8 (or byte), then if points to the first byte. Increment it, and you are accessing the second, etc. etc..
Now the 'page write', will need a routine like:
Code: |
//Needs #use I2C, setup with stream==EEPROM, and
//CHIP_ADDR_W/ADDR_R defined
void wait_ext_eeprom(void)
{
int1 status;
i2c_start(EEPROM);
status=i2c_write(EEPROM,CHIP_ADDR_W);
while(status==1)
{
i2c_start(EEPROM);
status=i2c_write(EEPROM,CHIP_ADDR_W);
}
i2c_stop(EEPROM);
}
//modified for 24512. Not tested....
void write_to_eeprom(char *data, unsigned int8 len, unsigned int16 address)
/* pointer to the block of data to write */
/* number of bytes to write */
/* EEPROM address to write data */
{
unsigned int16 lastpage;
unsigned int16 page;
/* Wait until our device is ready */
wait_ext_eeprom();
/* Select device */
i2c_start(EEPROM);
i2c_write(EEPROM,CHIP_ADDR_W));
i2c_write(EEPROM,make8(address,1));
i2c_write(EEPROM,make8(address,0));
page = address >> 7; //128 byte page on this chip
lastpage = page;
while (len) //loop for all bytes
{
if (page != lastpage)
{
/* Issuing a STOP will start the physical write sequence */
i2c_stop(EEPROM);
delay_us(1);
lastpage = page;
/* Wait until our device is ready */
wait_ext_eeprom();
/* Re-select and re-set the address pointer in the device */
i2c_start(EEPROM);
i2c_write(EEPROM,CHIP_ADDR_W));
i2c_write(EEPROM,make8(address,1));
i2c_write(EEPROM,make8(address,0));
}
i2c_write(EEPROM, *data); //write the bytes
data++;
address++;
/* The 24C512 has a 128 byte page for writing. */
page = address >> 7;
len--;
}
i2c_stop(EEPROM);
delay_us(1);
wait_ext_eeprom();
}
|
Call 'write_to_eeprom', with the address of the first byte of your structures, the length of the data (128), and the address you want to save the data to.
This automatically handles page writing to the eeprom, and restarts if a page boundary is crossed. |
|
|
Gabriel
Joined: 03 Aug 2009 Posts: 1067 Location: Panama
|
|
Posted: Wed Nov 07, 2018 4:46 pm |
|
|
Hi Ttelmah,
Thank you for your response.
looks simple enough.
one question regarding the code presented above:
If a boundary is crossed, lets say i would have a total length of 132 by some error, instead of the page 128, the code does the physical write to eeprom and the additional 4 bytes are rewritten at the beginning of the same page, and the physical write done again over the same page.
This would create a totally unreadable page in my application as the expected struct cant be reconstructed when i read back into the struct since the bytes are out of order and the first 4 bytes overwritten by the last 4....
or am i missing something?
Kind regards,
G _________________ CCS PCM 5.078 & CCS PCH 5.093 |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19499
|
|
Posted: Thu Nov 08, 2018 2:28 am |
|
|
That's totally down to _you_.....
Check your address is to a page boundary, and ensure your data size is 128 or less.
The layout of the data is your responsibility. The code will handle switching across pages, since it was designed for the situation where you might well be saving 'odd size' blocks to the EEPROM, and as a result boundaries may be crossed... |
|
|
Gabriel
Joined: 03 Aug 2009 Posts: 1067 Location: Panama
|
|
Posted: Thu Nov 08, 2018 5:58 am |
|
|
Quote: | That's totally down to _you_..... |
I know... thats why I'm trying to understand your code so that i can make my adjustments.
I don't like to copy/paste or use code i don't fully understand.
Thank you so much for your help on this.
G. _________________ CCS PCM 5.078 & CCS PCH 5.093 |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19499
|
|
Posted: Thu Nov 08, 2018 7:33 am |
|
|
Key thing is this:
page = address >> 7
This calculates a page number from an address. Now since pages are 128 bytes on this chip if you have an address like 0x4534, this is byte 0x34, in page 0x8A. The page number is the top 9bits of the address.
The standard exit is at the bottom of the loop, where the 'stop' triggers the write.
However, if the page number changes while it is looping, it instead triggers the same 'stop', but then loads the new address to carry on from. So long as the page number does not change, this part of the code won't get used, and all the loop does it write successive bytes. |
|
|
Gabriel
Joined: 03 Aug 2009 Posts: 1067 Location: Panama
|
|
Posted: Thu Nov 08, 2018 7:47 pm |
|
|
Thank you for the explanation.
Its pretty clear now.
G. _________________ CCS PCM 5.078 & CCS PCH 5.093 |
|
|
Gabriel
Joined: 03 Aug 2009 Posts: 1067 Location: Panama
|
|
Posted: Sun Jan 27, 2019 8:28 am |
|
|
Hi All,
Finally got around to this.
Got this working nicely now but I have a doubt.
During a Page write, if something goes wrong, and I issue a i2c_stop(), i will trigger the write cycle.
Is there any way to abort a page write gracefully?
I can't find anything about aborting on the datasheet.
I figured that if during a write, i Re-issue a Start command, and then the Stop command, the write cycle would be aborted because the EEPROM would quit the page write and follow what ever the new Start command wants to do, which in my case would be simply to stop, but hopefully this would avoid triggering the page write.
At this point i don't really think it matters if i waste a write cycle on an eventual error, especially if i can recognize an error. I just want to know if my conclusion was right.
G. _________________ CCS PCM 5.078 & CCS PCH 5.093 |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19499
|
|
Posted: Sun Jan 27, 2019 9:22 am |
|
|
What sort of thing do you visualise 'going wrong'?.
If the CPU has an issue, it is not going to be able to send a stop.
If the write has an issue, you are not going to know about it till the error
has occurred.
If power fails during the write, data may have been written of not. This is
why if you want security, you checksum data actually written.
The one situation where an abort is used in flash operations, is if
(for instance), you have a power fail during a write, and have power
fail detection, so add an abort to the code for this, so the physical write can
be suspended in a 'civilised' manner. Some EEPROM's do support an abort
instruction for this. However most assume that your hardware will be
designed to ensure that power can be maintained for the erase cycle
time, so this is not needed.
The chip you are using will not respond to commands during the write cycle.
So you can't use this to stop the write. Even the WP line is ignored after
the write is triggered. All you can really do is ensure your supply is
guaranteed to remain 'good' for the duration of the cycle, and test before starting. |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|