HCS12XA - Flash Mass Erase (Bootloader)

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

HCS12XA - Flash Mass Erase (Bootloader)

Jump to solution
1,124 Views
sebasira
Senior Contributor I

Hello, I'm porting the bootloader from AN3275 to the HCS12XA.

For now, the only problem that I've encountered is that I don't understand what does or should the bootloader erase. And that's why I cannot modify the mass erase routine in order to work with the S12XA. I know it should erase everything but the bootloader memory area.

 

I don't want it to be portable for any other devices, and will only be need for the S12XA256, so every control regarding block size, pages per block, etc won't be needed.

Block size is 1024 (0x400) can anyone guide/help me on how to modify this routine in order to do that?

 

Here's the code that set the addresses to be erased, that's what I want to modify.

void near vfnFlashMassEraseCmd(void){    /*     * Total Flash Pages     * MEMSIZ1 (1:0) = 0:0  128K = 8 Pages (0<<3)     * MEMSIZ1 (1:0) = 0:1  256K = 16Pages (1<<3)     * MEMSIZ1 (1:0) = 1:0  512K = 32Pages (2<<3)     * MEMSIZ1 (1:0) = 1:1 1024K = 64Pages (3<<3)     *     * As the HCS12XA does not have the MEMSIZ1 then its defined as "1" becasuse     * it has 256KB of Flash Memory     */    uint16 li16BlockZeroStart,li16BootAddressPointer,li16PageAddressPointer;    uint8 li8FlashPagesPerBlock = ui8fnFindFlashPagesPerBlock();    uint8 li8Page = 0x3f - li8FlashPagesPerBlock;    uint8 li8BlockSearch = 8<<(MEMSIZ1 & 3);        li8BlockSearch = (uint8) (li8BlockSearch/li8FlashPagesPerBlock);  //Number of Blocks        /***** PART 1 *****/
    li16BlockZeroStart = 0x3f -  li8FlashPagesPerBlock;    /*Mass Erase Blocks from Block 1 To Block N, Block 0 must be erased page by page*/    while (--li8BlockSearch){      gi32FlashAddressH = ((uint16) (0x3f - (li8FlashPagesPerBlock * li8BlockSearch)));      gi32FlashAddressL = 0x8000;      gi8FlashBlock = li8BlockSearch;      gi16FlashDataCounter = 1;      if (vfnFlash_Cmd(FMassErase)){        // SEND ERROR MESSAGE        return;      }    }            /***** PART 2 *****/    gi8FlashBlock = 0;    for(gi32FlashAddress=0xEF00;gi32FlashAddressL>=0xC000;gi32FlashAddressL-=0x200){      gi16FlashDataCounter = 1;      if (vfnFlash_Cmd(FErase)){        // SEND ERROR MESSAGE        return;      }    }            /***** PART 3 *****/    PPAGE=0x3E;    li16PageAddressPointer=0xBFFF;    li16BootAddressPointer = 0xFFFF;    while(PPAGE>li8Page){      if(*(uint8 *)(li16BootAddressPointer) != *(uint8 *)(li16PageAddressPointer)){       /* Erase Paged Memory */        gi32FlashAddressH = PPAGE;        for(gi32FlashAddressL=0xBF00;gi32FlashAddressL>=0x8000;gi32FlashAddressL-=0x200){          gi16FlashDataCounter = 1;          if (vfnFlash_Cmd(FErase)){            // SEND ERROR MESSAGE            return;          }        }        PPAGE--;        li16PageAddressPointer = 0xC000;        li16BootAddressPointer = 0x0000;      }      li16BootAddressPointer--;      li16PageAddressPointer--;      /***** PART 4 *****/      if(li16BootAddressPointer<0xF000){        PPAGE = 0x36;      }      }    FlashSectorBackup();    FlashSectorRestore();  }

 

I point out four parts, wich I think are the "skeleton" of the routine, I'd like to know what does/should do each part so I can understand it better.

 

Thanks for taking the time to read!!

In case anyone want/need the entire project, I'll attach it here.

Labels (1)
Tags (1)
0 Kudos
Reply
1 Solution
827 Views
kef
Specialist I

Yes, MEMSIZ registers are not present  on S12XD/XA. Indstead you should use PARTID to determine the amount of flash blocks available.

 

PART1 is erasing memory blocks, not occupied by bootloader. Executing mass erase command is faster than erasing sector by sector. But yYou can't use PART1 on S12X, because mass erase command is erasing all the flash, not just single flash block.

 

PART2 seems erasing nonbanked 0xC000-0xEFFF sector by sector

 

PART3 seems erasing flash not erased in PART1 and PART2.

 

Purpose of PART4 is not clear.

 

These snipets may help you. I can't provide all the code, because  mix of asm and C. FlashSectorProgrammed routine is not verified.

 

#define MINPAGE 0xE0    // min page on S12XD/XA#define MAXPAGE 0xFF    // max page#define LOUNPAGED 0xFD  // page of unpaged 0x4000#define HIUNPAGED 0xFF  // page of unpaged 0xC000#define BOOTLOADRSIZE 0x2000 // 0x2000 for bootloader at 0xE000-0xFFFF#define SECTORSIZE  1024#define SECTORSIZEW (SECTORSIZE/2) // sector size, 16bit wordsenum {xd128=0,xd256,xd512} device;// Pages not available on S12X. 0 - no page to skip.                            //xd128 xd256 xd512const char EXCLUDEPAGELO[] = {0xE4, 0xE8,  0}; // const char EXCLUDEPAGEHI[] = {0xFB, 0xF7,  0};///  device can be determined like this   switch(PARTID & ~3)   {      case 0xC410:         device = xd512;         break;      case 0xC000:         device = xd256;         break;      default:         device = xd128;         break;   }//////////////////// NOT VERIFIED. Should return 0 for blank sector and 1 for programmed sectorint FlashSectorProgrammed(unsigned short * ptr){int rv = 0;int i;   for(int i = 0; i < SECTORSIZEW; i++, ptr++)   {      if(*ptr != 0xFFFF)      {         rv = 1;         break;      }   }   return rv;}////////// Erase all sectors /////   int pp;   unsigned int *mp;      // erase vectors first, so that bootloader      // won't launch app in case reset happens sooner than       // flash is erased      if(FlashSectorProgrammed((void*)(0-BOOTLOADRSIZE-SECTORSIZE))      {//         printf("\r\n  Erasing dc00");         FlashSectorErase((void*)((void*)(0-BOOTLOADRSIZE-SECTORSIZE));      }      for(pp=MINPAGE; pp<=MAXPAGE; pp++)      {         if(   pp >= EXCLUDEPAGELO[device]  // skip pages on <512kB devices            && pp <= EXCLUDEPAGEHI[device])            continue;         PPAGE=pp;         for(mp=(unsigned int*)0x8000u;mp<(unsigned int*)0xC000u;mp+=SECTORSIZEW)         {            if(FlashSectorProgrammed(mp))            {//               printf("\r\n  Erasing %2x:%4x",pp,mp);               FlashSectorErase(mp);            }            ARMCOP=0x55;            ARMCOP=0xAA;            // end of erase            if((pp==MAXPAGE) && (mp==(unsigned int*)(0xC000-BOOTLOADRSIZE-SECTORSIZE)) ) break;          }      }///////////

 

 

View solution in original post

0 Kudos
Reply
1 Reply
828 Views
kef
Specialist I

Yes, MEMSIZ registers are not present  on S12XD/XA. Indstead you should use PARTID to determine the amount of flash blocks available.

 

PART1 is erasing memory blocks, not occupied by bootloader. Executing mass erase command is faster than erasing sector by sector. But yYou can't use PART1 on S12X, because mass erase command is erasing all the flash, not just single flash block.

 

PART2 seems erasing nonbanked 0xC000-0xEFFF sector by sector

 

PART3 seems erasing flash not erased in PART1 and PART2.

 

Purpose of PART4 is not clear.

 

These snipets may help you. I can't provide all the code, because  mix of asm and C. FlashSectorProgrammed routine is not verified.

 

#define MINPAGE 0xE0    // min page on S12XD/XA#define MAXPAGE 0xFF    // max page#define LOUNPAGED 0xFD  // page of unpaged 0x4000#define HIUNPAGED 0xFF  // page of unpaged 0xC000#define BOOTLOADRSIZE 0x2000 // 0x2000 for bootloader at 0xE000-0xFFFF#define SECTORSIZE  1024#define SECTORSIZEW (SECTORSIZE/2) // sector size, 16bit wordsenum {xd128=0,xd256,xd512} device;// Pages not available on S12X. 0 - no page to skip.                            //xd128 xd256 xd512const char EXCLUDEPAGELO[] = {0xE4, 0xE8,  0}; // const char EXCLUDEPAGEHI[] = {0xFB, 0xF7,  0};///  device can be determined like this   switch(PARTID & ~3)   {      case 0xC410:         device = xd512;         break;      case 0xC000:         device = xd256;         break;      default:         device = xd128;         break;   }//////////////////// NOT VERIFIED. Should return 0 for blank sector and 1 for programmed sectorint FlashSectorProgrammed(unsigned short * ptr){int rv = 0;int i;   for(int i = 0; i < SECTORSIZEW; i++, ptr++)   {      if(*ptr != 0xFFFF)      {         rv = 1;         break;      }   }   return rv;}////////// Erase all sectors /////   int pp;   unsigned int *mp;      // erase vectors first, so that bootloader      // won't launch app in case reset happens sooner than       // flash is erased      if(FlashSectorProgrammed((void*)(0-BOOTLOADRSIZE-SECTORSIZE))      {//         printf("\r\n  Erasing dc00");         FlashSectorErase((void*)((void*)(0-BOOTLOADRSIZE-SECTORSIZE));      }      for(pp=MINPAGE; pp<=MAXPAGE; pp++)      {         if(   pp >= EXCLUDEPAGELO[device]  // skip pages on <512kB devices            && pp <= EXCLUDEPAGEHI[device])            continue;         PPAGE=pp;         for(mp=(unsigned int*)0x8000u;mp<(unsigned int*)0xC000u;mp+=SECTORSIZEW)         {            if(FlashSectorProgrammed(mp))            {//               printf("\r\n  Erasing %2x:%4x",pp,mp);               FlashSectorErase(mp);            }            ARMCOP=0x55;            ARMCOP=0xAA;            // end of erase            if((pp==MAXPAGE) && (mp==(unsigned int*)(0xC000-BOOTLOADRSIZE-SECTORSIZE)) ) break;          }      }///////////

 

 

0 Kudos
Reply