How to use S12VR internal eeprom?

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 
已解决

How to use S12VR internal eeprom?

跳至解决方案
1,058 次查看
jtpark
Contributor IV

Hello.

 

I used S12VR.

I want to write or read from internal EEPROM of S12VR.

so,

 

////////////////////////////////////////////////////////////////////////////////////////////////////////////

static volatile word data[] ={0x1234,0x4567,0x6789,0x9123};
word eeprom_address = 0x400 ;

static byte start_flash_command_and_wait[]={
    /*Clear FSTAT*/
    /*BSET FSTAT 0x80*/
    0x1C, 0x01, 0x06, 0x80,
    /*Wait for command to end*/
    /*BRCLR FSTAT 0x80*/
    0x1F, 0x01, 0x06, 0x80, -5,
    /*Return*/
    0x3D
};

 

void main()

{

 

   CPMUOSC_OSCE = 0;    /*Using internal OSC. FREF = 1MHz*/

   CPMUSYNR_SYNDIV = 0x18;  /*FVCO = 50MHz = 2*FREF/(0x18+0x01)*/

   CPMUSYNR_VCOFRQ = 0x01; /*48MHz < fVCO<= 50MHz*/

   while (!CPMUFLG_LOCK){}  /* Wait for PLL to lock */

   CPMUCLKS_PLLSEL = 1;  /* select the PLLCLK/2 as the bus clock */       

   CPMUPOSTDIV = 0;    /*FPLL = FVCO/(POSTDIV + 1) = 50MHz*/

                   /*FBUS = 25MHz*/

   ECLKCTL_NECLK = 0; /*Mirror Bus clock to a PIN...Only use it for reference purposes not to clock another device*/

 

 

    FCCOBIX = 0 ;

    FCCOB = 0x1100 ;

    FCCOBIX = 1 ;

    FCCOB = eeprom_address ;

    eeprom_address+= 8;

    while (!FSTAT_CCIF);

    FSTAT=0x30;

    for (FCCOBIX=2; (FCCOBIX<(4+2)); FCCOBIX++){

     FCCOB = data[FCCOBIX-2];

    }

    FCCOBIX--;

    asm(PSHC);

    asm(SEI);

    asm BSR  start_flash_command_and_wait;

    asm(PULC);   

    for(;;)

 

 

 

 

 

 

 

 

 

 

 

     _FEED_COP(); /* feeds the dog */

     }

 

}

////////////////////////////////////////////////////////////////////////////////////////////////////////////

 

what is wrong?

Do you have an exam code to read or write internal eeprom?

help me plz.

thanks.

标签 (1)
标记 (1)
0 项奖励
1 解答
698 次查看
jtpark
Contributor IV

I solved the problem.

#include <hidef.h>      /* common defines and macros */
#include "derivative.h"      /* derivative-specific definitions */

#define EEPROM_START    0x000400
#define EEPROM_END      0x0007FF
#define EEPROM_SECTOR   0x04

#define OK          0
#define ERASED      1
#define NON_ERASED  2
#define MISALIGNED_ADDRESS  3
#define ACCESS_ERROR        4
#define VERIFICATION_FAILED 5
#define LENGTH_OUT_OF_RANGE 6

void SetPEEmodeBUSCLK(byte _synr, byte _refdv, byte _postdiv);

#pragma CODE_SEG NON_BANKED
interrupt 28 void PLL_LockIsr(void);
#pragma CODE_SEG DEFAULT

byte EEPROM_Erase_Verify_Section(word address, word number_of_words);
byte EEPROM_Program(word int address, word *ptr, byte number_of_words);
byte EEPROM_Erase_Sector(word int address);
word EEPROM_Read_Word(word int address);
void EEPROM_Init(byte fdiv);

word buf[4] = {0xACBD, 0x9812, 0x5678, 0xEF34};
byte err;
byte cnt ;

void SetPEEmodeBUSCLK(byte _synr, byte _refdv, byte _postdiv)
{
CPMUSYNR    = _synr;
CPMUREFDIV  = _refdv;
CPMUPOSTDIV = _postdiv;  
 
CPMUOSC_OSCE = 1; //enable external oscillator OSCE
   
while(!CPMUFLG_UPOSC)
  {// you can check for timeot here with error message report
  };   
while(!CPMUFLG_LOCK)
  {// you can check for timeot here with error message report
  };   

  //--- select clocks --------------------
CPMUCLKS = 0B10000011;                   // bus=fPLL/2; COP is clocked from OSCCLK
if(CPMUCLKS != 0B10000011)               // After writing CPMUCLKS register, it is strongly recommended to read 
  {                                       // back CPMUCLKS register to make sure that write of PLLSEL,
     asm nop;                             // RTIOSCSEL, COPOSCSEL0 and COPOSCSEL1 was successful.
  }
//--------------------------------------
}
//******************************************************************************
//EEPROM Send_Command
//******************************************************************************
//this function is stored in RAM memory
//in C language:
//  {
//    FSTAT_CCIF = 1;         //launch command
//    while(FSTAT_CCIF == 0); //wait for done
//  }
static byte Send_Command[]=
{
  0x1C, 0x01, 0x06, 0x80, 0x1F, 0x01, 0x06, 0x80, 0xFB, 0x3D
};

//******************************************************************************
//EEPROM_Erase_Verify_Section
//******************************************************************************
byte EEPROM_Erase_Verify_Section(word address, word number_of_words)
{
  //check if address is aligned (global address [2:0] = 000)
  if((address & 0x0004) != 0)
    return MISALIGNED_ADDRESS;
 
  while(FSTAT_CCIF == 0);   //wait if command in progress
  FSTAT = 0x30;             //clear ACCERR and PVIOL
 
  FCCOBIX = 0x00;
  FCCOB   = 0x1000;
 
  FCCOBIX = 0x01;
  FCCOB   = address;
 
  FCCOBIX = 0x02;
  FCCOB   = number_of_words;
 
  asm JSR Send_Command;
 
  if((FSTAT & (FSTAT_ACCERR_MASK | FSTAT_FPVIOL_MASK)) != 0)
    return ACCESS_ERROR;
 
  //check if phrases are erased and return result
  if(FSTAT_MGSTAT != 0)
    return NON_ERASED;
  else
    return ERASED;
}
//******************************************************************************
//EEPROM_Program
//******************************************************************************
byte EEPROM_Program(word address, word *ptr, byte number_of_words)

  word i;
 
  if((number_of_words < 1) || (number_of_words > 4))
    return LENGTH_OUT_OF_RANGE;
 
  //check if address is aligned (global address [0] != 0)
  if((address & 0x0001) != 0)
    return MISALIGNED_ADDRESS;
 
  //check if the word(s) is/are erased   
  if((EEPROM_Erase_Verify_Section(address, number_of_words)) == NON_ERASED)
    return NON_ERASED; 
   
  while(FSTAT_CCIF == 0);   //wait if command in progress
  FSTAT = 0x30;             //clear ACCERR and PVIOL   
 
  FCCOBIX = 0x00;
  FCCOB   = 0x1100;
 
  FCCOBIX = 0x01;
  FCCOB   = address;
 
 
  for(i=1; i<=number_of_words; i++)  //fill appropriate number of words to FCCOB
  {
    FCCOBIX = i+1;
    FCCOB = *ptr;
    ptr++; 
  }
     
  asm JSR Send_Command;   
 
  if((FSTAT & (FSTAT_ACCERR_MASK | FSTAT_FPVIOL_MASK)) != 0) return ACCESS_ERROR;
  if(FSTAT_MGSTAT != 0) return VERIFICATION_FAILED;   
  return OK;
}
//******************************************************************************
//EEPROM_Erase_Sector
//******************************************************************************
byte EEPROM_Erase_Sector(word address)
{
  //size of sector is 4B
 
  //check if address is aligned (global address [0] != 0) 
  if((address & 0x00000001) != 0)
    return MISALIGNED_ADDRESS;
   
  while(FSTAT_CCIF == 0);   //wait if command in progress
  FSTAT = 0x30;             //clear ACCERR and PVIOL
 
  FCCOBIX = 0x00;
  FCCOB   = 0x12;
 
  FCCOBIX = 0x01;
  FCCOB   = address;
  
  asm JSR Send_Command;
 
  if((FSTAT & (FSTAT_ACCERR_MASK | FSTAT_FPVIOL_MASK)) != 0) return ACCESS_ERROR;
  if(FSTAT_MGSTAT != 0) return VERIFICATION_FAILED;   
  return OK;
}
//******************************************************************************
//PFLASH_Read_Word
//******************************************************************************
word EEPROM_Read_Word(word address)
{
  word data16;
  data16 = *(word *)address;
  return data16;
}

//******************************************************************************
//PFLASH_Init
//******************************************************************************
void EEPROM_Init(byte fdiv)

  FCLKDIV = fdiv;          
}
//******************************************************************************

static byte start_flash_command_and_wait[]={
    /*Clear FSTAT*/
    /*BSET FSTAT 0x80*/
    0x1C, 0x01, 0x06, 0x80,
    /*Wait for command to end*/
    /*BRCLR FSTAT 0x80*/
    0x1F, 0x01, 0x06, 0x80, -5,
    /*Return*/
    0x3D
};

void delay(unsigned int i)
{
while(i--) ;
}

#pragma CODE_SEG NON_BANKED

__interrupt VectorNumber_Vtimovf void TIM_OVERFLOW(void)
{
 
    TFLG2_TOF = 1 ;
    PTT_PTT0 ^= 1 ;   
  }

__interrupt VectorNumber_Vtimch0 void TIM_CH0(void)
{
 
  TFLG1_C0F = 1 ;
  cnt++ ;

  PTT_PTT0 ^= 1 ;
}

#pragma CODE_SEG DEFAULT

void main(void) {
  /* put your own code here */
 
  unsigned int addr;
 
 
 
CPMUOSC_OSCE = 0;    /*Using internal OSC. FREF = 1MHz*/
CPMUSYNR_SYNDIV = 0x18;  /*FVCO = 50MHz = 2*FREF/(0x18+0x01)*/
CPMUSYNR_VCOFRQ = 0x01; /*48MHz < fVCO<= 50MHz*/
while (!CPMUFLG_LOCK){}  /* Wait for PLL to lock */
CPMUCLKS_PLLSEL = 1;  /* select the PLLCLK/2 as the bus clock */       
CPMUPOSTDIV = 0;    /*FPLL = FVCO/(POSTDIV + 1) = 50MHz*/
                   /*FBUS = 25MHz*/
   ECLKCTL_NECLK = 0; /*Mirror Bus clock to a PIN...Only use it for reference purposes not to clock another device*/


DDRT_DDRT0 = 1 ; // PT0 Output
   PERT_PERT0 = 1 ; //PT0 Pull up
DDRT_DDRT1 = 1 ; // PT1 Output
   PERT_PERT1 = 1 ; //PT1 Pull up


    TSCR2_TOI = 1;            /* Timer overflow interrupt enable */
    TSCR1_TEN = 1;            /* Timer Enable */ 
    TSCR2_PR = 2 ;            /* Timer prescaler select */
   

EnableInterrupts;

//--- PLL Initialization ---------------

  SetPEEmodeBUSCLK(0x01, 0x80, 0x00);     // 16MHz BUSCLK from 8 MHZ oscclk, PEE mode
 
  ECLKCTL_NECLK = 0;                      // enable ECLK output (bus clock is visible on pin PS7)
  //--------------------------------------
  // INITIALIZE THE EEPROM
  //------------------------------
  EEPROM_Init(0x0F);// default settings:
                    // internal oscillator is used = 1MHz => bus clk 8MHz => divide by 0x07
                    // to achieve FCLK 1MHz
                    // Table 15-7. FDIV values for various BUSCLK Frequencies

  //------------------------------
  // check entire EEPROM whether required data are already written
  if( (*(word*)(0x400)) != 0xAABB)
    {
      // the flag at 0x0400 says there are not correct data
      // check the eeprom is erased
      //------------------------------
      if(EEPROM_Erase_Verify_Section(EEPROM_START,512) == NON_ERASED)
        {
          // if no then erase entire EEPROM 
          //------------------------------
          for(addr = EEPROM_START; addr < EEPROM_END; addr+=EEPROM_SECTOR)  
            {
              err = EEPROM_Erase_Sector(addr);
            }
        }

      //...and write required data
      //------------------------------
      err = EEPROM_Program(EEPROM_START, buf, 4);
     
      for(addr = EEPROM_START+8; addr < EEPROM_END; addr+=2)  
        {
          err = EEPROM_Program(addr, &addr, 1);
        }
 
    }

    
    

   

  for(;;) {
    _FEED_COP(); /* feeds the dog */

    PTT_PTT1 ^= 1 ;
    delay(1000) ;
    /*
  err = EEPROM_Program(EEPROM_START, buf, 4);
     
      for(addr = EEPROM_START+8; addr < EEPROM_END; addr+=2)  
        {
          err = EEPROM_Program(addr, &addr, 1);
        }
      */

  
  } /* loop forever */
  /* please make sure that you never leave main */
}

在原帖中查看解决方案

0 项奖励
2 回复数
699 次查看
jtpark
Contributor IV

I solved the problem.

#include <hidef.h>      /* common defines and macros */
#include "derivative.h"      /* derivative-specific definitions */

#define EEPROM_START    0x000400
#define EEPROM_END      0x0007FF
#define EEPROM_SECTOR   0x04

#define OK          0
#define ERASED      1
#define NON_ERASED  2
#define MISALIGNED_ADDRESS  3
#define ACCESS_ERROR        4
#define VERIFICATION_FAILED 5
#define LENGTH_OUT_OF_RANGE 6

void SetPEEmodeBUSCLK(byte _synr, byte _refdv, byte _postdiv);

#pragma CODE_SEG NON_BANKED
interrupt 28 void PLL_LockIsr(void);
#pragma CODE_SEG DEFAULT

byte EEPROM_Erase_Verify_Section(word address, word number_of_words);
byte EEPROM_Program(word int address, word *ptr, byte number_of_words);
byte EEPROM_Erase_Sector(word int address);
word EEPROM_Read_Word(word int address);
void EEPROM_Init(byte fdiv);

word buf[4] = {0xACBD, 0x9812, 0x5678, 0xEF34};
byte err;
byte cnt ;

void SetPEEmodeBUSCLK(byte _synr, byte _refdv, byte _postdiv)
{
CPMUSYNR    = _synr;
CPMUREFDIV  = _refdv;
CPMUPOSTDIV = _postdiv;  
 
CPMUOSC_OSCE = 1; //enable external oscillator OSCE
   
while(!CPMUFLG_UPOSC)
  {// you can check for timeot here with error message report
  };   
while(!CPMUFLG_LOCK)
  {// you can check for timeot here with error message report
  };   

  //--- select clocks --------------------
CPMUCLKS = 0B10000011;                   // bus=fPLL/2; COP is clocked from OSCCLK
if(CPMUCLKS != 0B10000011)               // After writing CPMUCLKS register, it is strongly recommended to read 
  {                                       // back CPMUCLKS register to make sure that write of PLLSEL,
     asm nop;                             // RTIOSCSEL, COPOSCSEL0 and COPOSCSEL1 was successful.
  }
//--------------------------------------
}
//******************************************************************************
//EEPROM Send_Command
//******************************************************************************
//this function is stored in RAM memory
//in C language:
//  {
//    FSTAT_CCIF = 1;         //launch command
//    while(FSTAT_CCIF == 0); //wait for done
//  }
static byte Send_Command[]=
{
  0x1C, 0x01, 0x06, 0x80, 0x1F, 0x01, 0x06, 0x80, 0xFB, 0x3D
};

//******************************************************************************
//EEPROM_Erase_Verify_Section
//******************************************************************************
byte EEPROM_Erase_Verify_Section(word address, word number_of_words)
{
  //check if address is aligned (global address [2:0] = 000)
  if((address & 0x0004) != 0)
    return MISALIGNED_ADDRESS;
 
  while(FSTAT_CCIF == 0);   //wait if command in progress
  FSTAT = 0x30;             //clear ACCERR and PVIOL
 
  FCCOBIX = 0x00;
  FCCOB   = 0x1000;
 
  FCCOBIX = 0x01;
  FCCOB   = address;
 
  FCCOBIX = 0x02;
  FCCOB   = number_of_words;
 
  asm JSR Send_Command;
 
  if((FSTAT & (FSTAT_ACCERR_MASK | FSTAT_FPVIOL_MASK)) != 0)
    return ACCESS_ERROR;
 
  //check if phrases are erased and return result
  if(FSTAT_MGSTAT != 0)
    return NON_ERASED;
  else
    return ERASED;
}
//******************************************************************************
//EEPROM_Program
//******************************************************************************
byte EEPROM_Program(word address, word *ptr, byte number_of_words)

  word i;
 
  if((number_of_words < 1) || (number_of_words > 4))
    return LENGTH_OUT_OF_RANGE;
 
  //check if address is aligned (global address [0] != 0)
  if((address & 0x0001) != 0)
    return MISALIGNED_ADDRESS;
 
  //check if the word(s) is/are erased   
  if((EEPROM_Erase_Verify_Section(address, number_of_words)) == NON_ERASED)
    return NON_ERASED; 
   
  while(FSTAT_CCIF == 0);   //wait if command in progress
  FSTAT = 0x30;             //clear ACCERR and PVIOL   
 
  FCCOBIX = 0x00;
  FCCOB   = 0x1100;
 
  FCCOBIX = 0x01;
  FCCOB   = address;
 
 
  for(i=1; i<=number_of_words; i++)  //fill appropriate number of words to FCCOB
  {
    FCCOBIX = i+1;
    FCCOB = *ptr;
    ptr++; 
  }
     
  asm JSR Send_Command;   
 
  if((FSTAT & (FSTAT_ACCERR_MASK | FSTAT_FPVIOL_MASK)) != 0) return ACCESS_ERROR;
  if(FSTAT_MGSTAT != 0) return VERIFICATION_FAILED;   
  return OK;
}
//******************************************************************************
//EEPROM_Erase_Sector
//******************************************************************************
byte EEPROM_Erase_Sector(word address)
{
  //size of sector is 4B
 
  //check if address is aligned (global address [0] != 0) 
  if((address & 0x00000001) != 0)
    return MISALIGNED_ADDRESS;
   
  while(FSTAT_CCIF == 0);   //wait if command in progress
  FSTAT = 0x30;             //clear ACCERR and PVIOL
 
  FCCOBIX = 0x00;
  FCCOB   = 0x12;
 
  FCCOBIX = 0x01;
  FCCOB   = address;
  
  asm JSR Send_Command;
 
  if((FSTAT & (FSTAT_ACCERR_MASK | FSTAT_FPVIOL_MASK)) != 0) return ACCESS_ERROR;
  if(FSTAT_MGSTAT != 0) return VERIFICATION_FAILED;   
  return OK;
}
//******************************************************************************
//PFLASH_Read_Word
//******************************************************************************
word EEPROM_Read_Word(word address)
{
  word data16;
  data16 = *(word *)address;
  return data16;
}

//******************************************************************************
//PFLASH_Init
//******************************************************************************
void EEPROM_Init(byte fdiv)

  FCLKDIV = fdiv;          
}
//******************************************************************************

static byte start_flash_command_and_wait[]={
    /*Clear FSTAT*/
    /*BSET FSTAT 0x80*/
    0x1C, 0x01, 0x06, 0x80,
    /*Wait for command to end*/
    /*BRCLR FSTAT 0x80*/
    0x1F, 0x01, 0x06, 0x80, -5,
    /*Return*/
    0x3D
};

void delay(unsigned int i)
{
while(i--) ;
}

#pragma CODE_SEG NON_BANKED

__interrupt VectorNumber_Vtimovf void TIM_OVERFLOW(void)
{
 
    TFLG2_TOF = 1 ;
    PTT_PTT0 ^= 1 ;   
  }

__interrupt VectorNumber_Vtimch0 void TIM_CH0(void)
{
 
  TFLG1_C0F = 1 ;
  cnt++ ;

  PTT_PTT0 ^= 1 ;
}

#pragma CODE_SEG DEFAULT

void main(void) {
  /* put your own code here */
 
  unsigned int addr;
 
 
 
CPMUOSC_OSCE = 0;    /*Using internal OSC. FREF = 1MHz*/
CPMUSYNR_SYNDIV = 0x18;  /*FVCO = 50MHz = 2*FREF/(0x18+0x01)*/
CPMUSYNR_VCOFRQ = 0x01; /*48MHz < fVCO<= 50MHz*/
while (!CPMUFLG_LOCK){}  /* Wait for PLL to lock */
CPMUCLKS_PLLSEL = 1;  /* select the PLLCLK/2 as the bus clock */       
CPMUPOSTDIV = 0;    /*FPLL = FVCO/(POSTDIV + 1) = 50MHz*/
                   /*FBUS = 25MHz*/
   ECLKCTL_NECLK = 0; /*Mirror Bus clock to a PIN...Only use it for reference purposes not to clock another device*/


DDRT_DDRT0 = 1 ; // PT0 Output
   PERT_PERT0 = 1 ; //PT0 Pull up
DDRT_DDRT1 = 1 ; // PT1 Output
   PERT_PERT1 = 1 ; //PT1 Pull up


    TSCR2_TOI = 1;            /* Timer overflow interrupt enable */
    TSCR1_TEN = 1;            /* Timer Enable */ 
    TSCR2_PR = 2 ;            /* Timer prescaler select */
   

EnableInterrupts;

//--- PLL Initialization ---------------

  SetPEEmodeBUSCLK(0x01, 0x80, 0x00);     // 16MHz BUSCLK from 8 MHZ oscclk, PEE mode
 
  ECLKCTL_NECLK = 0;                      // enable ECLK output (bus clock is visible on pin PS7)
  //--------------------------------------
  // INITIALIZE THE EEPROM
  //------------------------------
  EEPROM_Init(0x0F);// default settings:
                    // internal oscillator is used = 1MHz => bus clk 8MHz => divide by 0x07
                    // to achieve FCLK 1MHz
                    // Table 15-7. FDIV values for various BUSCLK Frequencies

  //------------------------------
  // check entire EEPROM whether required data are already written
  if( (*(word*)(0x400)) != 0xAABB)
    {
      // the flag at 0x0400 says there are not correct data
      // check the eeprom is erased
      //------------------------------
      if(EEPROM_Erase_Verify_Section(EEPROM_START,512) == NON_ERASED)
        {
          // if no then erase entire EEPROM 
          //------------------------------
          for(addr = EEPROM_START; addr < EEPROM_END; addr+=EEPROM_SECTOR)  
            {
              err = EEPROM_Erase_Sector(addr);
            }
        }

      //...and write required data
      //------------------------------
      err = EEPROM_Program(EEPROM_START, buf, 4);
     
      for(addr = EEPROM_START+8; addr < EEPROM_END; addr+=2)  
        {
          err = EEPROM_Program(addr, &addr, 1);
        }
 
    }

    
    

   

  for(;;) {
    _FEED_COP(); /* feeds the dog */

    PTT_PTT1 ^= 1 ;
    delay(1000) ;
    /*
  err = EEPROM_Program(EEPROM_START, buf, 4);
     
      for(addr = EEPROM_START+8; addr < EEPROM_END; addr+=2)  
        {
          err = EEPROM_Program(addr, &addr, 1);
        }
      */

  
  } /* loop forever */
  /* please make sure that you never leave main */
}

0 项奖励
698 次查看
iggi
NXP Employee
NXP Employee

Hi,

an example code you can find in the appnote AN4448:

MC9S12VR Family Demonstration Lab Training

AN4448SW

Inside the SW pack, there is a demo project for Flash (both Program and Data  (EEPROM)). In the flash.c you can find the routines.

Regards,

iggi

0 项奖励