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.
Solved! Go to Solution.
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; } }///////////
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; } }///////////