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

[solved] PIC24F32KA304 eeprom_write() addresses off by one?

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



Joined: 25 Apr 2012
Posts: 26

View user's profile Send private message

[solved] PIC24F32KA304 eeprom_write() addresses off by one?
PostPosted: Wed Aug 22, 2012 5:49 pm     Reply with quote

tl;dr version:
Quote:
DON'T USE WRITE_EEPROM=noint!!



I'm using CCS 4.135 and MPLAB 8.84. I'm writing to the on-board EEPROM with the following little test:

Code:

/* tried without this line as well, no change */
#DEVICE WRITE_EEPROM=noint

#define EEPROM_LEN (64)
void eeprom_test(void)
{
   static enum { INIT=0, WRITE, READ, ERASE } state = INIT;
   static int count=0;
   static unsigned int16 pat[EEPROM_LEN];
   unsigned int16 w;
   bool bad;
   int i;

   switch (state) {
   case INIT:
      printf("\r\nNew EEPROM pattern:");
      for (i=0; i<EEPROM_LEN; i++) {
         pat[i] = 0xaa00 + i;
         if ((i % 16) == 0) {
            printf("\r\n");
         }
         printf("%04x ", pat[i]);
      }
      ++count;
      state = WRITE;
      break;

   case WRITE:
#if 1
      for (i=0; i<EEPROM_LEN; i++) {
         write_eeprom(i*2, pat[i], 2);
      }
#else
      write_eeprom(0, &pat[0], sizeof(int16)*EEPROM_LEN);
#endif
      state = READ;
      break;

   case READ:
      bad = FALSE;
      printf("\r\nRead back EEPROM pattern:");
      for (i=0; i<EEPROM_LEN; i++) {
         w = read_eeprom(i*2,2);
//         read_eeprom(i*2, &w);
//         read_eeprom(i*2, &w, 2);
         if ((i % 16) == 0) {
            printf("\r\n");
         }
         printf("%04x ", w);

         if (pat[i] != w) {
            printf("!(%04x) ", pat[i]);
            bad = TRUE;
         }
      }
      if (bad) {
         printf("\r\nFAIL\r\n");
      } else {
         printf("\r\nPASS\r\n");
      }
      state = ERASE;
      break;

   case ERASE:
      for (i=0; i<64; i++) {
         pat[i] = 0xffff;
      }
      write_eeprom(0, &pat[0], sizeof(int16)*EEPROM_LEN);
      state = INIT;

   default:
      state = INIT;
   }
}


This routine is called once a second, just for simplicity. That's plenty of time to write 64 words.

You'll also note that I've tried a few different ways to read, and a couple of different ways to write. The method used doesn't seem to matter.

What I notice is that the EEPROM data is written incorrectly. My serial port output looks like this:

Quote:

New EEPROM pattern:
a000 a101 a202 a303 a404 a505 a606 a707 a808 a909 aa0a ab0b ac0c ad0d ae0e af0f
b010 b111 b212 b313 b414 b515 b616 b717 b818 b919 ba1a bb1b bc1c bd1d be1e bf1f
c020 c121 c222 c323 c424 c525 c626 c727 c828 c929 ca2a cb2b cc2c cd2d ce2e cf2f
d030 d131 d232 d333 d434 d535 d636 d737 d838 d939 da3a db3b dc3c dd3d de3e df3f

Read back EEPROM pattern:
a101 !(a000) a202 !(a101) a303 !(a202) a404 !(a303) a505 !(a404) a606 !(a505) a707 !(a606) a808 !(a707) a909 !(a808) aa0a !(a909) ab0b !(aa0a) ac0c !(ab0b) ad0d !(ac0c) ae0e !(ad0d) af0f !(ae0e) b010 !(af0f)
b111 !(b010) b212 !(b111) b313 !(b212) b414 !(b313) b515 !(b414) b616 !(b515) b717 !(b616) b818 !(b717) b919 !(b818) ba1a !(b919) bb1b !(ba1a) bc1c !(bb1b) bd1d !(bc1c) be1e !(bd1d) bf1f !(be1e) c020 !(bf1f)
c121 !(c020) c222 !(c121) c323 !(c222) c424 !(c323) c525 !(c424) c626 !(c525) c727 !(c626) c828 !(c727) c929 !(c828) ca2a !(c929) cb2b !(ca2a) cc2c !(cb2b) cd2d !(cc2c) ce2e !(cd2d) cf2f !(ce2e) d030 !(cf2f)
d131 !(d030) d232 !(d131) d333 !(d232) d434 !(d333) d535 !(d434) d636 !(d535) d737 !(d636) d838 !(d737) d939 !(d838) da3a !(d939) db3b !(da3a) dc3c !(db3b) dd3d !(dc3c) de3e !(dd3d) df3f !(de3e) df3f
FAIL


So as you can see, my pattern array is correct, and the first word of EEPROM should be 0xa000. If I use MPLAB to read back memory I see the first EEPROM address as 0xa101 (confirming the read is correct):



(picture shows EEPROM window with data starting at address 0x7ffe00: 0xa101 0xa202 0xa303...)

My code is writing to EEPROM location 0, the data it's writing to 0 is 0xa000. I've tried a few different ways to write but the data seems offset by one 16-bit word.

Any ideas?

Update

For those who will complain that my test routine is too long, I wrote a simpler one that shows the same effect:

Code:

void eeprom_test(void)
{
   write_eeprom(0, 0xa000);
   write_eeprom(2, 0xa101);
   write_eeprom(4, 0xa202);
}


The memory dump of the first three words is 0xa101 0xa202 0xa202. Note that the first word is skipped, the second word is written to the first word's address, and the third word is duplicated to the second and third locations.

If I change the addresses to 0,1,2 instead of 0,2,4, I get a compiler error sayign odd addresses aren't allowed. This indicates to me that the addresses are byte addresses, not word addresses.

Update 2
If I use just a single write to address 0, I get the data I was expecting at address 0 (0xa000). If I write to address 2 afterward, address 0 gets written as well as address 2. If I write to address 0 and 4, address 0 and 4 get the same value (0xa101) and address 2 gets left alone (0xffff). I'm erasing the device after every test.

Update 3
It was WRITE_EEPROM=noint after all. I must not have re-built after changing it the first time.

Does this qualify as a bug in CCS?
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Thu Aug 23, 2012 12:02 am     Reply with quote

To give essential help to others, you should post a short and complete example code that allows to reproduce the problem.

A code example is also a good way to report a bug to CCS.
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