S12G Program/Erase flash problem

cancel
Showing results for 
Search instead for 
Did you mean: 

S12G Program/Erase flash problem

Jump to solution
679 Views
zaeuiezaonje
Contributor I

Hi,

 

I try to erase or program flash on a S12G MCU but I've a trouble. The code running without error (ACCERR and FPVIOL bits still at 0) but the flash still in the same state.

 

I've tried the following code given as example without sucess :

 

tU16 FLASH_addr(tU08 type)

{

    tU16 base, addr, j;

    tU32 i;

    // Fill the range with its address

    asm BGND;   /* Software Breakpoint 3 - by running to here the erase,

                   erase verify and program commands have all been launched.

                   The P-flash has now been programmed with the addresses as

                   shown in the memory maps */ 

                 

    base = FlashStartAddrGL[type];

    for (i = 0; i < FlashSectNum[type]; i++)

    {

        if(LaunchFlashCommand(2, EraseFlashSector[type], FlashStartAddrGH[type], base, 0, 0, 0, 0) != CCIF_MASK) /* erase the flash block again*/

            return FLASH_ACCESS_ERROR;     

        if(LaunchFlashCommand(3, EraseVerifyFlashSector[type], FlashStartAddrGH[type], base, FlashSectSize[type]>>(type+(2^type)-1), 0, 0, 0) != CCIF_MASK) /* timing sector erase command */

            return FLASH_ACCESS_ERROR;

 

        addr = base;

        for (j = 0; j < FlashSectSize[type]; j+=8)

        {

            if(LaunchFlashCommand(2*(2+type), ProgramFlash[type], FlashStartAddrGH[type], addr, addr, addr+2, addr+4, addr+6) != CCIF_MASK) /* timing 1 word program command */

            return FLASH_ACCESS_ERROR;

            addr += 8;

        }

        base += FlashSectSize[type];

    }

    return FLASH_OK;

}

 

tU08 LaunchFlashCommand(char params, tU08 command, tU08 ccob0, tU16 ccob1, tU16 ccob2, tU16 ccob3, tU16 ccob4, tU16 ccob5)

{

    if(FSTAT_CCIF == 1)

    {

        /* Clear any error flags*/

        FSTAT = (FPVIOL_MASK | ACCERR_MASK);

 

        /* Write the command id / ccob0 */

        FCCOBIX = 0;

        FCCOBHI = command;

        FCCOBLO = ccob0;

 

        if(++FCCOBIX != params)

        {

            FCCOB = ccob1;                /* Write next data word to CCOB buffer. */

            if(++FCCOBIX != params)

            {

                FCCOB = ccob2;             /* Write next data word to CCOB buffer. */

                if(++FCCOBIX != params)

                {

                    FCCOB = ccob3;        /* Write next data word to CCOB buffer. */

                    if(++FCCOBIX != params)

                    {

                        FCCOB = ccob4;    /* Write next data word to CCOB buffer. */

                        if(++FCCOBIX != params)

                            FCCOB = ccob5;          /* Write next data word to CCOB buffer. */

                    }

                } 

            }

        }

        FCCOBIX = params-1;

 

        /* Clear command buffer empty flag by writing a 1 to it */

        FSTAT = CCIF_MASK;

        while (!FSTAT_CCIF) {     /* wait for the command to complete */

        /* Return status. */

        }

        return(FSTAT);     /* command completed */

    }

 

    return(FLASH_BUSY); /* state machine busy */

}

I've also heared that the CCIF clearing and the wait have to be in RAM, so I've put the previous red section of code in RAM but this handling have no effects...

Do you know where can be the mistake ?

Thank you very much for any help.

Labels (1)
0 Kudos
1 Solution
201 Views
kef2
Senior Contributor IV
  • static const U8 testByte@0x38000 = 0x9A;

0x38000 above means banked address, PPAGE=3, CPU address = 0x8000

And your flash routine needs to be supplied with global address, which for S12G family is PPAGE*0x4000 + (CPU address - 0x8000) = 0x00C000, where 0x4000 is size of PPAGE window and 0x8000 is PPAGE window offset in CPU address space.

View solution in original post

0 Kudos
7 Replies
201 Views
zaeuiezaonje
Contributor I

Here are some further details :


I've correctly initialize the flash clock according to my bus clock (24MHz) :

FSTAT_FPVIOL = 1;

FSTAT_ACCERR = 1;
while(FSTAT_ACCERR);
FCLKDIV_FDIV = 0x17U;

I've write again the erase function like this, to be more concise :

U1 u1HAL_MEMORY_ErasePage(dword addr)

{      

  if (BlockOutOfRange(addr, addr)) {   /* Check range of address */

    return(FALSE);

  }

  ClearFlags();                                 /* Clear all flags */

  if (FSTAT_CCIF == 0U) {              /* Is command buffer full ? */

    return FALSE;                             /* If yes then error */

  }

  FCCOBIX = 0U;                             /* Clear index register */

  FCCOBHI = 0x0AU;                       /* Erase P-Flash sector command */

  FCCOBLO = (byte)(addr >> 16U);     /* High address word */

  FCCOBIX++;                                   /* Shift index register */

  FCCOB = (word)(addr & 0xFFFFFFF8UL);      /* Low address word aligned to 8 byte phrase*/

  CallFnCmdInRam();                                   /* Copy Wait in RAM routine to stack and launch the flash process */

 

  for (i=0; i<100; i++);

 

  if (FSTAT_FPVIOL == 1U) {            /* Is protection violation detected ? */

    return FALSE;                              /* If yes then error */

  }

  if (FSTAT_ACCERR == 1U) {            /* Is acces error detected ? */

    return FALSE;                                   /* If yes then error */

  }

  if (FSTAT_MGSTAT) {                  /* Was attempt to erase the sector errorneous? */

    return FALSE;                            /* If yes then error */

  }

  return TRUE;                                 /* OK

}

CallFnCmdInRam copy in RAM the following routine to stack :

static void FnCmdInRam_(void)

{

  FSTAT = 0x80U;                              /* Clear flag command buffer empty */

  while (FSTAT_CCIF == 0U) {}          /* Wait to command complete */

  return;

}



In order to do my test, I've set a byte at the address 0x38000, and I try to erase it then I read it value :

static const U8 testByte@0x38000 = 0x9A;

...                                                        <------------ The read value of the test byte = 0x9A

status = erasePage(0x38000);

...                                                       <------------ The read value of the test byte = 0x9A,  status = OK (no error flag)



I think I tried everything that was possible to do, and I've no more idea :/
Do you have any suggestion ?



0 Kudos
201 Views
kef2
Senior Contributor IV

How do verify that flash contents doesn't change? If it's Codewarrior debugger, you should keep in mind that by default it caches flash and EEPROM contents and doesn't display actual flash contents, unless you make modifications to debugger memory map (in debugger go to Multtilink menu, and/or search forums for more information).

0 Kudos
201 Views
zaeuiezaonje
Contributor I

Thank you for your help.
Actually, I read the bytes then I send them by CAN, so I think that the verification is correct.

0 Kudos
202 Views
kef2
Senior Contributor IV
  • static const U8 testByte@0x38000 = 0x9A;

0x38000 above means banked address, PPAGE=3, CPU address = 0x8000

And your flash routine needs to be supplied with global address, which for S12G family is PPAGE*0x4000 + (CPU address - 0x8000) = 0x00C000, where 0x4000 is size of PPAGE window and 0x8000 is PPAGE window offset in CPU address space.

View solution in original post

0 Kudos
201 Views
zaeuiezaonje
Contributor I

Thank you very much for your help.
Indeed I confused banked address and global address.

0 Kudos
201 Views
ushacy
Contributor I

You can actually erase the flash of a s12 board using a secure tool.

0 Kudos
201 Views
zaeuiezaonje
Contributor I

Yes but I try to erase and program flash programmatically.

0 Kudos