HCS08 Flash routine for dummies

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

HCS08 Flash routine for dummies

1,039 Views
danielhembree
Contributor III

I know this subject has been covered many times in this forum, and I have looked at many of the posts to try and figure out how to accomplish this, but I can't seem to get a handle on it. It seems like a fairly straightforward procedure, which is all the more frustrating. I am using an MC9S08GB60A and Codewarrior 5.9.0. All I want to do is write a single flash memory location with a byte that represents the last state of an input port so that when the system is next powered on, the input state is recalled.

 

I am by no means an expert at this so please forgive...

 

 

Code is below:

 

// Flash write from RAM.MCP

 

#include <hidef.h> /* for EnableInterrupts macro */

#include "derivative.h" /* include peripheral declarations */

 

int address;

unsigned char data;

 

unsigned char FLASH_CMD[] @0x1040={

0x87,0xC6,0x18,0x25,0xA5,0x10,0x27,0x08,0xC6,0x18,0x25,0xAA,0x10,0xC7,0x18,0x25,

0x9E,0xE6,0x01,0xF7,0xA6,0x20,0xC7,0x18,0x26,0x45,0x18,0x25,0xF6,0xAA,0x80,0xF7,

0x9D,0x9D,0x9D,0x9D,0x45,0x18,0x25,0xF6,0xF7,0xF6,0xA5,0x30,0x27,0x04,0xA6,0xFF,

0x20,0x07,0xC6,0x18,0x25,0xA5,0x40,0x27,0xF9,0x8A,0x81};

 

 

// Function Prototypes

void Write_byte(int Address, unsigned char data);

 

void main(void) {

  DisableInterrupts;                     // Disable interupts

  SOPT_COPE = 0;                    // Disable COP

  ICGC1 = 0x28;                          // Configure Fbus = 5MHz

  ICGC2 = 0x72;

 

  if(FSTAT_FACCERR == 1)          // Check FACCERR Flag, clear if set

      {

          FSTAT_FACCERR = 1;

      }

 

  FCDIV = 0x18;                          // Configure Fclk (5MHz/(24+1)=200KHz)

  address = 0x2000;                    // Flash memory location

  data = 0x01;                             // Data (dummy)

 

  for(;;)

   {

           Write_byte(address, data);       // Call writing function

           data++;                                  // Next (dummy) data value

   

    __RESET_WATCHDOG(); /* feeds the dog */

  } /* loop forever */

 

}

 

 

void Write_byte(address, data)

    {

    asm jsr 0x1040;                    // Flash write routine from code

    }                                          // example in HCS08QRUG, opcode

                                               // contained within array located

                                               // at RAM mem location $1040 .

 

*******************************************************************************

 

 

Below is the excerpt from HSC08QRUQ (p93) that the opcode in the array is based on:

 

//Array of opcode instructions of the Erase/Program function

//Element 0x14 of the array is: (command 0x20 to program a byte, 0x40 to erase a page)

unsigned char FLASH_CMD[] {

0x87,0xC6,0x18,0x25,0xA5,0x10,0x27,0x08,0xC6,0x18,0x25,0xAA,0x10,0xC7,0x18,0x25,

0x9E,0xE6,0x01,0xF7,0xA6,0x20,0xC7,0x18,0x26,0x45,0x18,0x25,0xF6,0xAA,0x80,0xF7,

0x9D,0x9D,0x9D,0x9D,0x45,0x18,0x25,0xF6,0xF7,0xF6,0xA5,0x30,0x27,0x04,0xA6,0xFF,

0x20,0x07,0xC6,0x18,0x25,0xA5,0x40,0x27,0xF9,0x8A,0x81};

/* The opcode above represents this set of instructions

if (FSTAT&0x10){ //Check to see if FACCERR is set

FSTAT = FSTAT | 0x10; //write a 1 to FACCERR to clear

}

(*((volatile unsigned char *)(Address))) = data; //write to somewhere in flash

FCMD = 0x20; //set command type.

FSTAT = FSTAT | 0x80; //Put FCBEF at 1.

_asm NOP; //Wait 4 cycles

_asm NOP;

_asm NOP;

_asm NOP;

if (FSTAT&0x30){ //check to see if FACCERR or FVIOL are set

return 0xFF; //if so, error.

}

while ((FSTAT&0x40)==0){ //else wait for command to complete

;

}*/


 


Labels (1)
0 Kudos
2 Replies

360 Views
weapon
Senior Contributor I

Hi Hembree,

the flash should be in erased state before it can be programmed.  In your code, you always reprogram a same place without erasing it firstly.

there should be some error.

However, please don't use a loop forever  to program flash, the flash edurance is around 100,000 cycles. if you use loop forever,

the lifetime of  this sector of flash is easy to be used up. Actually, I am a little worried that somewhere of the flash of the MCU you are using is invalid.

  for(;;)

   {

           Write_byte(address, data);       // Call writing function

           data++;                                  // Next (dummy) data value

   

    __RESET_WATCHDOG(); /* feeds the dog */

  } /* loop forever

  for(;;)

   {

          Erase_byte();  // erase the location firstly

           Write_byte(address, data);       // Call writing function

           data++;                                  // Next (dummy) data value

   

    __RESET_WATCHDOG(); /* feeds the dog */

  } /* loop forever

0 Kudos

360 Views
danielhembree
Contributor III

Mr. Weiping Xu,

I am now understanding that it is necessary to erase the flash before it can be written to and now have some code that I believe has me on the right track.

When complete my program not use the forever loop. That was implemented as a test and since my flash writing routine was not functioning I believe the flash memory should be unaffected. Thanks for pointing that fact out to me though.

Dan

0 Kudos