Peder Alm

How do I read and write to EEPROM using S12XD256?

Discussion created by Peder Alm on Mar 15, 2007
Latest reply on Mar 21, 2007 by Peder Alm
I want create a variable in EEPROM, assign a value to the variable in main() and then later on read the value from that variable.
 
I use MC9S12XD256 with a 8Mhz crystal and a busclock at 25MHz, CW5.1 and the SofTec debugger with indart-one.
 
Below is the code I'm trying to use.
 
1) In my *.prm file I changed the EEPROM row...
 
Code:
/* non-paged EEPROM */
      EEPROM        = NO_INIT       0x0C00 TO   0x0FFB;
 
...and added the row inside the PLACEMENT section just after PAGED_RAM:
 
Code:
      EEPROM_DATA INTO EEPROM;

 I left the following lines untouched:
 
Code:
/* paged EEPROM                     0x0800 TO   0x0BFF; addressed through EPAGE */      EEPROM_FC     = READ_ONLY   0xFC0800 TO 0xFC0BFF;      EEPROM_FD     = READ_ONLY   0xFD0800 TO 0xFD0BFF;      EEPROM_FE     = READ_ONLY   0xFE0800 TO 0xFE0BFF;/*    EEPROM_FF     = READ_ONLY   0xFF0800 TO 0xFF0BFF; intentionally not defined: equivalent to EEPROM */

 
 
2) In main.c I added the EEPROM variable...
 
Code:
#pragma CONST_SEG EEPROM_DATA  ushort var1;#pragma CONST_SEG DEFAULT

...and added functions for init eeprom, unprotect, erase, program and protect:
 
Code:
if(eeprom_init(8, 25)==TRUE)  {                                    eeprom_unprotect();    eeprom_erase_sector(&var1);    eeprom_program(&var1, 0x4321);    eeprom_protect();      }

 EEPROM functions:
 
Code:
uchar eeprom_init(uchar oscclk, uchar busclk){  ECNFG = 0x00;                               //no interrupts    if(oscclk==8 && busclk==25)          {    ECLKDIV = 0x00;                           //reset    ECLKDIV |= (ECLKDIV_EDIVLD_MASK | 40);    //EDIVLD must be set after each reset                                       //oscclk*(5+1/busclk)        return TRUE;  }  return NOCASE;}void eeprom_unprotect(void){  EPROT |= EPROT_EPOPEN_MASK;  }void eeprom_protect(void){  EPROT &=~ EPROT_EPOPEN_MASK;  }void eeprom_program(void* address, ushort data){  ushort addr = (ushort)address;    ESTAT |= (ESTAT_PVIOL_MASK | ESTAT_ACCERR_MASK);    while(!(ESTAT & ESTAT_CBEIF_MASK))    ;    ESTAT &=~ (ESTAT_PVIOL_MASK | ESTAT_ACCERR_MASK);    EADDRHI = (addr & 0xFF00) >> 8;  EADDRLO = addr & 0x00FF;    EDATAHI = (data & 0xFF00) >> 8;  EDATALO = data & 0x00FF;    ECMD = ECMD_PROGRAM;            //set command    ESTAT |= ESTAT_CBEIF_MASK;      //start command    while(!(ESTAT&ESTAT_CCIF_MASK)) //wait for command to end    ;                   }      //erases both words in a sectorvoid eeprom_erase_sector(void* address){  ushort addr = (ushort)address;    while(!(ESTAT & ESTAT_CBEIF_MASK))    ;    ESTAT &=~ (ESTAT_PVIOL_MASK | ESTAT_ACCERR_MASK);    EADDRHI = (addr & 0xFF00) >> 8; //write sector address  EADDRLO = addr & 0x00FF;    EDATAHI = 0x00;                 //write dummy data  EDATALO = 0x00;    ECMD = ECMD_SECTOR_ERASE;       //set command    ESTAT |= ESTAT_CBEIF_MASK;      //start command    while(!(ESTAT&ESTAT_CCIF_MASK)) //wait for command to end    ;  }

 
3) To read the variable I just use it as a ordinary variable:
 
Code:
ushort abc = var1;

 

The program after the EEPROM init, unprotect,..... runs fine but the abc variable never gets the value 0x4321. What's wrong?
 
EEPROM section starts at page 1073


 
 
 

Outcomes