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 CCS Technical Support

EEPROM writing problem

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



Joined: 15 Jan 2007
Posts: 11
Location: Germany

View user's profile Send private message

EEPROM writing problem
PostPosted: Fri Jul 13, 2007 4:50 am     Reply with quote

Hello

I want to write a couple of bytes into the internal EEPROM from my 18F8722 with compiler version 4.042.
When I call the function Internal_EEPROM with 0x00 as data and write one byte it works ok but when writing two bytes it stores only the first. The second stays 0xFF. When writing 3 bytes the first and third become 0x00 and the second stays at 0xFF.
This was verified in the simulator and in real life.

Any suggestions? Thanks for your help.

Code:

/******************************************************************************
*                                                                             *
*   Access to the internal EEPROM of the Microcontroller                      *
*                                                                             *
*    R_W         -> 0..read, 1..write                                         *
*    Base_Address-> internal EEPROM address                                   *
*    Data        -> data to read from/write into internal EEPROM              *
*    Length      -> how long is variable ( 8..8 bit,  16..16 bit,             *
*                                         24..24 bit, 32..32 bit)             *
*    Returns     -> 1..everything OK, 0..EEPROM write failed                  *
*                                                                             *
******************************************************************************/
#SEPARATE int1 Internal_EEPROM(int1 R_W, int Base_Address ,int32& Data, int Length)
{
   int   j, i, loop_end;
   int32 ReRead;

   loop_end = Length/8;                            // determine how many bytes need to be read/written
   switch (R_W)
      {
      case 0:                                      // Read from internal EEPROM
         Data = 0x00;
         for(i=0; i <  loop_end; i++)
         {
            *(((int8 *)&Data)+loop_end-i-1) = Read_EEPROM(Base_Address + i);     // from CCS Support
         }
         return(OK);
         break;
      case 1:                                      // Write to internal EEPROM
         for (j = 0; j < INT_ROM_RETRY; j++)       // write until error exceeds threshold
            {
            ReRead = 0x00;
            for(i=1; i <= loop_end; i++)
               Write_EEPROM(Base_Address+i-1, *(&Data + loop_end - i)); // write data
            for(i=0; i <  loop_end; i++)
               *(&ReRead+loop_end-i-1) = Read_EEPROM(Base_Address + i); // read written data
            if (ReRead != Data) { continue; } else return(OK);
            }
//         PIC_Fehler(Error_Internal_ROM);
         return(FAILURE);
         break;
      }
}


/******************************************************************************
*                                                                             *
*   Set the EEPROM registers to their init values at first startup            *
*   Assumes that this is the first start of this µC and the internal EEPROM   *
*   is not yet initialised.                                                   *
*                                                                             *
*    Returns     -> 1..everything OK, 0..EEPROM write failed                  *
*                                                                             *
******************************************************************************/
int1 EEPROM_Setup()
{
   int fail = 0;                                   // problem with writing to the EEPROM?

   EEPROM_data = IF_PIC_REV;
   Internal_EEPROM(1, Addr_IF_PIC_REV,  EEPROM_data,  8);
   EEPROM_data = 0x30;
   Internal_EEPROM(1, Addr_Digital_Poti,EEPROM_data,  8); LCD_Contrast = 0x30;
   EEPROM_data = 0x00;
   if (Internal_EEPROM(1, Addr_S1_MBST, EEPROM_data, 16) != OK) fail++;
      GMBST_S1 = 0x00;
   if (Internal_EEPROM(1, Addr_S2_MBST, EEPROM_data, 16) != OK) fail++;
      GMBST_S2 = 0x00;
   if (Internal_EEPROM(1, Addr_M1_MBST, EEPROM_data, 16) != OK) fail++;
      GMBST_M1 = 0x00;
   if (Internal_EEPROM(1, Addr_M2_MBST, EEPROM_data, 16) != OK) fail++;
      GMBST_M2 = 0x00;
   if (Internal_EEPROM(1, Addr_M3_MBST, EEPROM_data, 16) != OK) fail++;
      GMBST_M3 = 0x00;
   if (Internal_EEPROM(1, Addr_L_MBST, EEPROM_data, 16) != OK) fail++;
      GMBST_L  = 0x00;
   if (Internal_EEPROM(1, Addr_Operating_Time, EEPROM_data, 24) != OK) fail++;
      GOperating_Time    = 0x00;
   if (Internal_EEPROM(1, Addr_Magnetron_On_Time, EEPROM_data, 24) != OK) fail++;
      GMagnetron_On_Time = 0x00;
   if (fail > 0)
      return (failure);
   else
      return (OK);
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Jul 13, 2007 2:17 pm     Reply with quote

I didn't try to understand your whole program, but you've got at least
two places in your code where you're making the assumption that
pointer arithmetic will be done as if all pointers are byte pointers.
CCS used to operate that way, but not anymore, since vs. 4.021.

For example, this expression,
Code:
*(&Data + loop_end - i));

needs to be modified to look like this:
Code:
*(&(int8 *)Data + loop_end - i));


Also fix this one:
Code:
 *(&ReRead+loop_end-i-1)


Here's a test program that will let you see the difference. Compile this
code and run it in MPLAB simulator and view the results in the Output
window. Setup the MPLAB simulator to use 'UART1' for output.
Code:

#include <18F452.h>
#fuses XT,NOWDT,NOPROTECT,BROWNOUT,PUT,NOLVP
#use delay(clock=4000000) 
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)

//===========================
void main()
{
int32 Data;
int i, loop_end;
int8 *Ptr;

loop_end = 2;
i = 0;

Ptr = &Data + loop_end - i;
printf("&Data = %LX\n\r", &Data);
printf("Ptr = %LX \n\r", Ptr);

// This time, cast 'Data' to a char ptr before
// doing pointer arithmetic.
Ptr = &(char *)Data + loop_end - i;
printf("&Data = %LX\n\r", &Data);
printf("New Ptr = %LX \n\r", Ptr);

while(1);
}


Here are the results:
Quote:

&Data = 0006

Ptr = 000E

&Data = 0006

New Ptr = 0008
marc10k



Joined: 15 Jan 2007
Posts: 11
Location: Germany

View user's profile Send private message

PostPosted: Mon Jul 16, 2007 12:20 am     Reply with quote

Thanks PCM Programmer

It worked fine after I moved the '&' from your first example in front of DATA.
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