Problem on manipulation data on EEPROM without BDM attached.

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Problem on manipulation data on EEPROM without BDM attached.

Jump to solution
2,873 Views
Forsaken
Contributor III

Hi,

 

i'm developing a program that needs saving some data on EEPROM. With BDM attached i don't have any problems saving data on EEPROM (erasing sectors and writing sectors), but when i remove the BDM i can't save nothing on EEPROM. I have checked the register _EPROT.Byte using BDM and not using, this register has the same data on both cases.

 

I have a 4MHz Crystal and i'm setting PLL to reach 40MHz of Bus Clock. Maybe there is something wrong on my code? I put bellow my functions

 

 /* main.c */

init_clock();                                                  /* Set clock @ 40Mhz */

if(ECLKDIV_EDIVLD==0){ ECLKDIV_EDIV=0x14;}  /* If clock not defined, define now */
EPAGE=0xFC;                                                /* Define EEPROM Page */

 

 /* eeprom.c */

 

void PROGRAM_SECTOR_EEPROM(UINT16 Offset, UINT8* pEEPROMAddress)
{
  UINT8   i=0;
  UINT8*  pPointer=pEEPROMAddress;
 

  if(ECLKDIV_EDIVLD==0){ ECLKDIV_EDIV=0x14;}  /* If clock not defined, define now */
  DisableInterrupts;                          /* Disable all interrupts */
  while(ESTAT_CBEIF==0);                      /* Wait for buffer to be empty */
  if(ESTAT_ACCERR==1||ESTAT_PVIOL==1)         /* Clear error flags */
  {
    ESTAT_ACCERR=0;
    ESTAT_PVIOL=0;
  }
  for(i=0; i<EEPROM_SECTOR_WORD_SIZE; i++)
  {
    EDATAHI=*pPointer;
    pPointer++;
    EDATALO=*pPointer;
    pPointer++;
    EADDRHI=(UINT8)(((Offset+i) & 0xFF00)>>8);
    EADDRLO=(UINT8)(((Offset+i) & 0x00FF)>>0);
    ECMD=0x20;                                /* Run Program Command */
    ESTAT_CBEIF=1;                            /* Run command */
    while(ESTAT_CBEIF==0);                    /* Wait for buffer to be empty */
  }
  while(ESTAT_CCIF==0);                       /* Wait for command to completed */ 
  EnableInterrupts;                           /* Enable all interrupts */
}

 

void ERASE_SECTOR_EEPROM(UINT16 Offset)
{

  if(ECLKDIV_EDIVLD==0){ ECLKDIV_EDIV=0x14;}  /* If clock not defined, define now */
  DisableInterrupts;                          /* Disable all interrupts */
  while(ESTAT_CBEIF==0);                      /* Wait for buffer to be empty */
  if(ESTAT_ACCERR==1||ESTAT_PVIOL==1)         /* Clear error flags */
  {
    ESTAT_ACCERR=0;
    ESTAT_PVIOL=0;
  }
  EDATAHI=0x00;
  EDATALO=0x00;
  EADDRHI=(UINT8)((Offset & 0xFF00)>>8);
  EADDRLO=(UINT8)((Offset & 0x00FF)>>0);

  ECMD=0x40;                                  /* Run Sector Erase Command */
  ESTAT_CBEIF=1;                              /* Run command */
  while(ESTAT_CCIF==0);                       /* Wait for command to completed */ 
  EnableInterrupts;                           /* Enable all interrupts */
}

 

Can anyone help me?

Labels (1)
0 Kudos
1 Solution
818 Views
Forsaken
Contributor III

It works!!! Thanks!!! I posted bellow my code, for anyone who wants to use eeprom on NORMAL MODE

 

/*on prm file*/  

EEPROM_FC = NO_INIT     0xFC0800 TO 0xFC0BFF; 

EEPROM_DATA INTO EEPROM_FC;

 

/*main.c*/  

 

 #pragma DATA_SEG EEPROM_DATA
  tEEPROM_DATA            EEPROM_Storage;
#pragma DATA_SEG DEFAULT

 

tEEPROM_DATA      EEPROM_Image;

 

if(ECLKDIV_EDIVLD==0){ ECLKDIV_EDIV=0x14;}/* If clock not defined, define now */

EPAGE=0xFC;                                                /* Define EEPROM Page */

 

/*eeprom.h*/ 

 

#define EEPROM_SECTOR_WORD_SIZE             2
#define EEPROM_SECTOR_BYTE_SIZE               4

 

BOOL  WRITE_SECTOR_EEPROM(UINT8* far pEEPROMAddress, UINT8* pRAMAddress, INT16 Size);
void    PROGRAM_SECTOR_EEPROM(UINT8* far pEEPROMAddress, UINT8* pRAMAddress);
void    ERASE_SECTOR_EEPROM(UINT8* far pEEPROMAddress);

 

/*eeprom.c*/

 

BOOL WRITE_SECTOR_EEPROM(UINT8* far pEEPROMAddress, UINT8* pRAMAddress, INT16 Size)
{
  UINT8* far pPointerDestination=pEEPROMAddress;
  UINT8*     pPointerOrigin=pRAMAddress;
  UINT16     EndOffset=(((UINT8)pEEPROMAddress+Size) & 0x07FF)/EEPROM_SECTOR_WORD_SIZE;
  UINT16     Offset=((UINT8)pEEPROMAddress & 0x07FF)/EEPROM_SECTOR_WORD_SIZE;

  if((((UINT8)pEEPROMAddress+Size) & 0x07FF)%EEPROM_SECTOR_WORD_SIZE!=0){ return FALSE;}
  if(Size<=0){ return FALSE;}
 
  DisableInterrupts;
  /* Program EEPROM Block */
  while(Offset<EndOffset)
  {
    if(memcmp(pPointerDestination, pPointerOrigin, EEPROM_SECTOR_BYTE_SIZE)!=0)
    {
      /* Erase Sector Procedure */
      ERASE_SECTOR_EEPROM((UINT8*)pPointerDestination);
      /* Program Data Procedure */
      PROGRAM_SECTOR_EEPROM((UINT8*)pPointerDestination, (UINT8*)pPointerOrigin);
    }
    pPointerOrigin+=EEPROM_SECTOR_BYTE_SIZE;
    pPointerDestination+=EEPROM_SECTOR_BYTE_SIZE;
    Offset+=EEPROM_SECTOR_WORD_SIZE;
  }
  EnableInterrupts;
  return TRUE;

}

 

void PROGRAM_SECTOR_EEPROM(UINT8* far pEEPROMAddress, UINT8* pRAMAddress)
{
  UINT8          i=0;
  UINT16* far pEEPROMPointer=(UINT16*)pEEPROMAddress;
  UINT16*      pRAMPointer=(UINT16*)pRAMAddress;


  /* Disable all interrupts */

  DisableInterrupts;                         

  /* Wait for buffer to be empty */
  while(ESTAT_CBEIF==0);                   
  /* Clear error flags */

  if(ESTAT_ACCERR==1||ESTAT_PVIOL==1)        
  {
    ESTAT=(ESTAT_ACCERR_MASK | ESTAT_PVIOL_MASK);
  }
  for(i=0; i<EEPROM_SECTOR_WORD_SIZE; i++)
  {
    *pEEPROMPointer=*pRAMPointer;
    pEEPROMPointer++;
    pRAMPointer++;

    /* Run Program Command */

    ECMD=0x20;                              
    /* Run command */

    ESTAT=ESTAT_CBEIF_MASK;                 
    /* Wait for buffer to be empty */

    while(ESTAT_CBEIF==0);                   
  }
  /* Wait for command to completed */ 

  while(ESTAT_CCIF==0);                     
  /* Enable all interrupts */

  EnableInterrupts;                          
}

 

void ERASE_SECTOR_EEPROM(UINT8* far pEEPROMAddress)
{
  UINT16* far pEEPROMPointer=(UINT16*)pEEPROMAddress;

 

  /* Disable all interrupts */

  DisableInterrupts;                        
  /* Wait for buffer to be empty */

  while(ESTAT_CBEIF==0);                    
  /* Clear error flags */

  if(ESTAT_ACCERR==1||ESTAT_PVIOL==1)        
  {
    ESTAT=(ESTAT_ACCERR_MASK | ESTAT_PVIOL_MASK);
  }
  *pEEPROMPointer=0x0000;
  pEEPROMPointer++;
  /* Run Sector Erase Command */

  ECMD=0x40;                                
  /* Run command */

  ESTAT=ESTAT_CBEIF_MASK;                 

  /* Wait for command to completed */     
  while(ESTAT_CCIF==0);                     
  /* Enable all interrupts */

  EnableInterrupts;                          
}

 

 

Message Edited by Forsaken on 2009-05-21 12:14 PM
Message Edited by Forsaken on 2009-05-21 12:14 PM

View solution in original post

0 Kudos
6 Replies
819 Views
Forsaken
Contributor III

It works!!! Thanks!!! I posted bellow my code, for anyone who wants to use eeprom on NORMAL MODE

 

/*on prm file*/  

EEPROM_FC = NO_INIT     0xFC0800 TO 0xFC0BFF; 

EEPROM_DATA INTO EEPROM_FC;

 

/*main.c*/  

 

 #pragma DATA_SEG EEPROM_DATA
  tEEPROM_DATA            EEPROM_Storage;
#pragma DATA_SEG DEFAULT

 

tEEPROM_DATA      EEPROM_Image;

 

if(ECLKDIV_EDIVLD==0){ ECLKDIV_EDIV=0x14;}/* If clock not defined, define now */

EPAGE=0xFC;                                                /* Define EEPROM Page */

 

/*eeprom.h*/ 

 

#define EEPROM_SECTOR_WORD_SIZE             2
#define EEPROM_SECTOR_BYTE_SIZE               4

 

BOOL  WRITE_SECTOR_EEPROM(UINT8* far pEEPROMAddress, UINT8* pRAMAddress, INT16 Size);
void    PROGRAM_SECTOR_EEPROM(UINT8* far pEEPROMAddress, UINT8* pRAMAddress);
void    ERASE_SECTOR_EEPROM(UINT8* far pEEPROMAddress);

 

/*eeprom.c*/

 

BOOL WRITE_SECTOR_EEPROM(UINT8* far pEEPROMAddress, UINT8* pRAMAddress, INT16 Size)
{
  UINT8* far pPointerDestination=pEEPROMAddress;
  UINT8*     pPointerOrigin=pRAMAddress;
  UINT16     EndOffset=(((UINT8)pEEPROMAddress+Size) & 0x07FF)/EEPROM_SECTOR_WORD_SIZE;
  UINT16     Offset=((UINT8)pEEPROMAddress & 0x07FF)/EEPROM_SECTOR_WORD_SIZE;

  if((((UINT8)pEEPROMAddress+Size) & 0x07FF)%EEPROM_SECTOR_WORD_SIZE!=0){ return FALSE;}
  if(Size<=0){ return FALSE;}
 
  DisableInterrupts;
  /* Program EEPROM Block */
  while(Offset<EndOffset)
  {
    if(memcmp(pPointerDestination, pPointerOrigin, EEPROM_SECTOR_BYTE_SIZE)!=0)
    {
      /* Erase Sector Procedure */
      ERASE_SECTOR_EEPROM((UINT8*)pPointerDestination);
      /* Program Data Procedure */
      PROGRAM_SECTOR_EEPROM((UINT8*)pPointerDestination, (UINT8*)pPointerOrigin);
    }
    pPointerOrigin+=EEPROM_SECTOR_BYTE_SIZE;
    pPointerDestination+=EEPROM_SECTOR_BYTE_SIZE;
    Offset+=EEPROM_SECTOR_WORD_SIZE;
  }
  EnableInterrupts;
  return TRUE;

}

 

void PROGRAM_SECTOR_EEPROM(UINT8* far pEEPROMAddress, UINT8* pRAMAddress)
{
  UINT8          i=0;
  UINT16* far pEEPROMPointer=(UINT16*)pEEPROMAddress;
  UINT16*      pRAMPointer=(UINT16*)pRAMAddress;


  /* Disable all interrupts */

  DisableInterrupts;                         

  /* Wait for buffer to be empty */
  while(ESTAT_CBEIF==0);                   
  /* Clear error flags */

  if(ESTAT_ACCERR==1||ESTAT_PVIOL==1)        
  {
    ESTAT=(ESTAT_ACCERR_MASK | ESTAT_PVIOL_MASK);
  }
  for(i=0; i<EEPROM_SECTOR_WORD_SIZE; i++)
  {
    *pEEPROMPointer=*pRAMPointer;
    pEEPROMPointer++;
    pRAMPointer++;

    /* Run Program Command */

    ECMD=0x20;                              
    /* Run command */

    ESTAT=ESTAT_CBEIF_MASK;                 
    /* Wait for buffer to be empty */

    while(ESTAT_CBEIF==0);                   
  }
  /* Wait for command to completed */ 

  while(ESTAT_CCIF==0);                     
  /* Enable all interrupts */

  EnableInterrupts;                          
}

 

void ERASE_SECTOR_EEPROM(UINT8* far pEEPROMAddress)
{
  UINT16* far pEEPROMPointer=(UINT16*)pEEPROMAddress;

 

  /* Disable all interrupts */

  DisableInterrupts;                        
  /* Wait for buffer to be empty */

  while(ESTAT_CBEIF==0);                    
  /* Clear error flags */

  if(ESTAT_ACCERR==1||ESTAT_PVIOL==1)        
  {
    ESTAT=(ESTAT_ACCERR_MASK | ESTAT_PVIOL_MASK);
  }
  *pEEPROMPointer=0x0000;
  pEEPROMPointer++;
  /* Run Sector Erase Command */

  ECMD=0x40;                                
  /* Run command */

  ESTAT=ESTAT_CBEIF_MASK;                 

  /* Wait for command to completed */     
  while(ESTAT_CCIF==0);                     
  /* Enable all interrupts */

  EnableInterrupts;                          
}

 

 

Message Edited by Forsaken on 2009-05-21 12:14 PM
Message Edited by Forsaken on 2009-05-21 12:14 PM
0 Kudos
818 Views
albuquerque
Contributor I

Hello , I have the same problem as you  , I copy your code but this still the same when I power down and power up again my eeprom variables are lost. Have some different initializantion too.Can you send me your init code for eeprom. Thanks

0 Kudos
818 Views
kef
Specialist I

What derivative you are using? This thread doesn't apply to newer derivatives EEPROM like S12XE or S12XS.

 

Initialization is simple, just write proper clock divider to ECLKDIV.

 

By default using P&E target, debugger is caching contents of NV memory. You may need to adjust Debugging Memory Map to make debugger updating EEPROM locations.

0 Kudos
818 Views
Forsaken
Contributor III

I have change my write function, as you said i belive. Can you check? I have a doubt, how can i erase a sector on normal mode, if i can not use EADDR and EADATA??

 

 

void PROGRAM_SECTOR_EEPROM(UINT8* far pEEPROMAddress, UINT8* pRAMAddress)
{
  UINT8       i=0;
  UINT16* far pEEPROMPointer=(UINT16*)pEEPROMAddress;
  UINT16*     pRAMPointer=(UINT16*)pRAMAddress;
 
  DisableInterrupts;                          /* Disable all interrupts */
  while(ESTAT_CBEIF==0);                      /* Wait for buffer to be empty */
  if(ESTAT_ACCERR==1||ESTAT_PVIOL==1)         /* Clear error flags */
  {
    ESTAT=(ESTAT_ACCERR_MASK | ESTAT_PVIOL_MASK);
  }
  for(i=0; i<EEPROM_SECTOR_WORD_SIZE; i++)
  {
    *pEEPROMPointer=*pRAMPointer;
    pEEPROMPointer++;
    pRAMPointer++;
    ECMD=0x20;                                /* Run Program Command */
    ESTAT_CBEIF=ESTAT_CBEIF_MASK;             /* Run command */
    while(ESTAT_CBEIF==0);                    /* Wait for buffer to be empty */
  }
  while(ESTAT_CCIF==0);                       /* Wait for command to completed */ 
  EnableInterrupts;                           /* Enable all interrupts */
}

0 Kudos
818 Views
kef
Specialist I

*pEEPROMPointer=*pRAMPointer; should work. The same should work for your erase routine, the only difference is that you may write anything to *pEEPROMPointer, for example *pEEPROMPointer=0.

 

 

    ESTAT_CBEIF=ESTAT_CBEIF_MASK;             /* Run command */

 

Red part should be removed

0 Kudos
818 Views
kef
Specialist I

1) 

   ESTAT_ACCERR=0;

^^ this is wrong. You should not write access CW defined flags bitfields. Since ACCERR is cleared writing '1' to it, above line will clear all set ESTAT flags except ACCERR. ACCERR won't clear because write 0 doesn't do anything.

 

    ESTAT_PVIOL=0;

  

Same here. Correct code is this

 

   ESTAT &= ESTAT_PVIOL_MASK;  // please note no ~ before ESTAT_PVIOL_MASK

or this

 

   ESTAT = ESTAT_PVIOL_MASK;

 

And same here

 

   ESTAT_CBEIF=1;                            /* Run command */
 

 

 

2) EADDR and EDATA registers are not writeable in normal chip modes (without BDM connected). These registers can be used to program EEPROM via BDM. But in normal mode, to latch word to be programmed, you should write not EADDR and EDATA, but EEPROM directly, via some pointer.

 

0 Kudos