CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

Struct to EEPROM

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Gabriel



Joined: 03 Aug 2009
Posts: 1067
Location: Panama

View user's profile Send private message

Struct to EEPROM
PostPosted: Wed Nov 07, 2018 5:35 am     Reply with quote

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: 19195

View user's profile Send private message

PostPosted: Wed Nov 07, 2018 7:56 am     Reply with quote

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

View user's profile Send private message

PostPosted: Wed Nov 07, 2018 4:46 pm     Reply with quote

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: 19195

View user's profile Send private message

PostPosted: Thu Nov 08, 2018 2:28 am     Reply with quote

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

View user's profile Send private message

PostPosted: Thu Nov 08, 2018 5:58 am     Reply with quote

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: 19195

View user's profile Send private message

PostPosted: Thu Nov 08, 2018 7:33 am     Reply with quote

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. Smile
Gabriel



Joined: 03 Aug 2009
Posts: 1067
Location: Panama

View user's profile Send private message

PostPosted: Thu Nov 08, 2018 7:47 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Sun Jan 27, 2019 8:28 am     Reply with quote

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: 19195

View user's profile Send private message

PostPosted: Sun Jan 27, 2019 9:22 am     Reply with quote

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.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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