Flash1 Mass erase on the MC68HC908GZ60

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

Flash1 Mass erase on the MC68HC908GZ60

1,994 Views
CyrilG_
Contributor I
Hello, I am trying to erase Flash 1 on the MC68HC908GZ60 using the Flash 1 CTRL Register but I am having some issues. After a mass erase, the uC resets even if i clear the watchdog at every step. Here is my function to do a mass erase:
 
void EraseFlash1()
{
unsigned char ucTemp;
unsigned char *pFlash1;
unsigned int uiCounter;
 
FL1BPR=0xFE; //Protect FL1BPR and Interrupt Vectors
FL1CR = 0x06;
ucTemp = FL1BPR; //Read FL1BPR as described in the datasheet
pFlash1 = (unsigned char*)0x8000;
*pFlash1 = 0x00;

// wait minimum 10µs
for(uiCounter = 0; uiCounter < 20; uiCounter++) //Wait double of the required time
   __RESET_WATCHDOG();
FL1CR = 0x0E;
// wait minimum 4ms
for(uiCounter = 0; uiCounter < 8000; uiCounter++) //Wait double of the required time
   __RESET_WATCHDOG();
FL1CR = 0x08;
// wait minimum 100µs
for(uiCounter = 0; uiCounter < 200; uiCounter++) //Wait double of the required time
   __RESET_WATCHDOG();
 
FL1CR = 0x00;
}
 
For information, my quartz is at 1Mhz so I am pretty sure my sleep time between steps is correct. I made sure that my code was located in flash2 otherwise I know i would erase myself. The beginning of my file looks like this
#pragma CONST_SEG SPECIAL_CONST
#pragma CODE_SEG SPECIAL_ROM
#pragma DATA_SEG SPECIAL_RAM
 
and the memory map looks like this:
 
SEGMENTS /* here all RAM/ROM areas of the device are listed. Used in PLACEMENT below. */
  Z_RAM           = READ_WRITE 0x0040 TO 0x00FF;
  RAM1            = READ_WRITE 0x0100 TO 0x03CF;
  RAM1_SPECIAL    = READ_WRITE 0x03D0 TO 0x043F;    // part of RAM1 - used for CodeLoader
  RAM2            = READ_WRITE 0x0580 TO 0x097F;
  FLASH2A         = READ_ONLY  0x0462 TO 0x04FF;
  FLASH2B         = READ_ONLY  0x0980 TO 0x1B7F;
  FLASH2C         = READ_ONLY  0x1E20 TO 0x7FFF;  // used for CodeLoader
  FLASH1          = READ_ONLY  0x8000 TO 0xDFFF;
  FLASH1_SPECIAL1 = READ_ONLY  0xE000 TO 0xEFFF;
  FLASH1_SPECIAL2 = READ_ONLY  0xF000 TO 0xFDFF;
  VECTOR1         = READ_ONLY  0xFFCC TO 0xFFFF;
//  VECTOR2         = READ_ONLY  0xEFCC TO 0xEFFF;
END
PLACEMENT /* here all predefined and user segments are placed into the SEGMENTS defined above. */
  DEFAULT_ROM                   INTO FLASH1;
  SPECIAL_ROM                   INTO FLASH2C;
  SPECIAL_CONST                 INTO FLASH2B;//FLASH1_SPECIAL2;
  DEFAULT_RAM                   INTO RAM1;
  SSTACK                        INTO RAM1;
  SPECIAL_RAM          INTO RAM1_SPECIAL;
  RAM2                          INTO RAM2;
//  PARAMETER_FLASH               INTO FLASH2B;
  _DATA_ZEROPAGE                INTO Z_RAM;
  VECTOR_TABLE_1                INTO VECTOR1;
//  VECTOR_TABLE_2                INTO VECTOR2;
END
 
Finally the function calling the Mass erase function looks like this:
 
 
void ProgramuCCodeBis()
{
 
#ifdef __HIWARE__ //to disable the interrupts
    asm TPA;
    asm PSHA;
    asm SEI;
#else
    #pragma asm
    TPA
    PSHA
    SEI
    #pragma endasm
#endif
 
EraseFlash1();  //calling the mass erase function
//make a led blink to see if the uC resets or not
for (;:smileywink:
{
  for (i=0;i<0xFFFF;i++)
  {
        PTB_PTB1 = 1;
        asm sta COPCTL;     //Clearing the watchdog
  }     
  for (i=0;i<0xFFFF;i++)
  {
        PTB_PTB1 = 0;
        asm sta COPCTL;
  }
}
#ifdef __HIWARE__ //Enabling interrupts
    asm PULA;
    asm TAP;
#else
    #pragma asm
    PULA
    TAP
    #pragma endasm
#endif
   
}
The next step after the mass erase will be to program flash 1 with a source code received on the CAN Bus previously and stored on a external RAM.
Does anybody see something wrong in the code or give a hint how to debug this? I have been stuck for a week on this .
Thank you very much for your help
Cyril G.
 
PS: I attached Codeloader.c and codeloader.h containing all the functions and prototypes
Labels (1)
0 Kudos
7 Replies

602 Views
kook
Contributor I

I'm refreshing this topic, because I have the same problem on the DZ60. The simulator says that a  COP reset occurs during the mass erase operation, even when it is disabled (writing #$08 to FSTAT register). At the exact cycle that the mass erase should be completed (20000 cycles @192.3kHz) COP reset occurs. Everithing is OK if I execute 128 subsequent sector erases, completely erasing it step by step.

 

Why the COP reset occurs when it is disabled in the initialization process, way before the main program???????

Why I have no problem performing 128 subsequent erases instead????

 

It is not a vector erasing problem, because I'm trying to erase EEPROM;  it has a separate array from Flash and them "erase independently of each other".

 

Can anyone help me to find out the solution at this little dilemma :smileyvery-happy:?

0 Kudos

602 Views
bigmac
Specialist III

Hello,

 

I question whether FCS mode is capable of simulating any of the flash operations.

 

Regards,

Mac

 

0 Kudos

602 Views
Ake
Contributor II
Hello,
As the COP reset lies at 0xffff on the HC908GZ60, it means that a COP reset is actually writing to an Flash EPROM address. If this is done during erasure/programming, the data and addresses to the Flash EPROM are destroyed.
So move the COP reset till before and after each operation instead.
 
Regards,
Ake
0 Kudos

602 Views
CyrilG_
Contributor I
Thank you very much for your prompt response. I tried to move the COP clear before and after and still have the same problem. So to pinpoint the problem, i tried to erase only one page at a time . It works somewhat better. But I am able to erase only the first page. If I delete two pages in a row, the uC resets.
The pages are 128 bytes long no?
Here the updated version of my code:

//Calling the erase page function 2 in a row
  EraseFlash1(0x8000); //0x8000 represents the start address of the page
  COPCTL =0x01; //Clear watchdog
  EraseFlash1(0x8000);
  COPCTL =0x01; //Clear watchdog


//Led blinking to make sure that the uC didn't reset
for (;:smileywink:
{
  for (i=0;i<0x1FFF;i++)
  {
        PTB_PTB1 = 1;
        COPCTL =0x01; //Clear watchdog
  }     
  for (i=0;i<0x1FFF;i++)
  {
        PTB_PTB1 = 0;
        COPCTL =0x01; //Clear watchdog
  }
 
 //-------------------- Function to erase one page at a time ----------------////

void EraseFlash1(unsigned int startAddress)
{
unsigned char ucTemp;
unsigned char *pFlash1;
unsigned int uiCounter;

FL1CR = 0x02;
ucTemp = FL1BPR;
pFlash1 = (unsigned char*)startAddress;
*pFlash1 = 0x01;

// wait minimum 10µs
for(uiCounter = 0; uiCounter < 10; uiCounter++);
FL1CR = 0x0A;

// wait minimum 4ms
for(uiCounter = 0; uiCounter < 4000; uiCounter++);
FL1CR = 0x08;

// wait minimum 100µs
for(uiCounter = 0; uiCounter < 100; uiCounter++);
FL1CR = 0x00;

for(uiCounter = 0; uiCounter < 2; uiCounter++);

}



0 Kudos

602 Views
bigmac
Specialist III
Hello,
 
I assume that the original EraseFlash1() function does actually reside within Flash2.  Have you configured the COP timeout period for the longer duration?  Does the mass erase successfully complete if the COP timer is disabled?
 
For mass erase of Flash1, it would seem that whether or not clearing the COP timer occurs within the erase procedure should not matter.  Since the vectors are within Flash1, they would be erased anyhow.  Surely this vector erasure would represent a rather precarious situation?
 
Perhaps the updatable portion of the program should reside in Flash2, rather than Flash1.  Then a mass erase would not affect the reset vector (and other vectors), and the COP reset operation would have no effect on the erasure process.
 
Regards,
Mac
 
0 Kudos

602 Views
CyrilG_
Contributor I
Hello,
 
I double checked and the EraseFlash1 function does reside in Flash2 and I set up the COP Timeout to the longer position.  Since I removed the COP reset from the Erase sequence, I am able to erase one line at a time (but only one). However, now you mention it, I tried to disable the COP and the program seems to hang somewhere so I don't know if the Flash 1 has been successfully erased or not. Is there a bit I can check for successful mass erase?
When you say that vector erasure would be a rather precarious situation, do you mean that we can not erase and reprogram them? If not, i have to rethink my in-chip programmability.
Unfortunately, I can't move the updatable portion of the code to flash2 because I have to update most of the source code ( including the interrupts vectors if possible) and it wouldn't fit in  flash 2. 
Thank you for your help.
Regards,
Cyril G.  
0 Kudos

602 Views
bigmac
Specialist III
Hello Cyril,


Cyril G. wrote:
When you say that vector erasure would be a rather precarious situation, do you mean that we can not erase and reprogram them? If not, i have to rethink my in-chip programmability.
Unfortunately, I can't move the updatable portion of the code to flash2 because I have to update most of the source code ( including the interrupts vectors if possible) and it wouldn't fit in  flash 2. 


What I meant is that, once the reset vector was erased, the situation would remain precarious until the reset vector was re-programmed.  If a reset should occur for any reason during this interval, perhaps due a power outage, the bootloader would become inoperable.
 
A safer approach would be to leave all vectors intact, with the reset vector pointing to the bootloader code within the upper pages of the flash1 array.  The other vectors might point to fixed locations within flash2, or lower pages in flash1.  At each fixed location, the interrupt vector could then be re-directed to the new code, simply using a jump instruction.
 
The implication of this approach would be that each flash1 page required for the updated code would need to be individually erased (with the vectors and bootloader code remaining write protected).  The code for page erase or program would need to be run from flash2, as you currently have (or alternatively from RAM).
 
If necessary, flash2 array could still be mass erased using code within the bootloader area.
 
Your code must be very tight since there is less than 3K size difference between the two flash arrays.  Perhaps the solution may be to use flash2 array first, an then use the flash1 pages that immediately follow flash2, for the overflow.  This would minimize the number of pages that would need to be individually erased, and potentially speed up the erase process.
 
I cannot explain your current problems with respect to mass erase.  You might try a mass erase of flash2, with the mass erase function re-positioned to the flash1 array, to see if the problem persists with the reset vector now remaining intact.
 
Regards,
Mac
 

It just occurred to me that, within the mass erase function, you appear to be restoring the interrupt enable state that existed prior to calling the function.  This could be bad news if previously the interrupts had been enabled.  Surely interrupts should remain disabled untill after re-programming takes place, and the interrupt vectors are re-programmed.


 



Message Edited by bigmac on 2008-06-07 12:17 AM
0 Kudos