Hello;
I am working on S12XEP100 bootloader from AN4258SW and I have a problem with erasing flash. The program stuck when address of erasing reaches to 0x007D0000. So I wrote a simple application for finding problem. about my app:
-I don't have any interrupt (and ISR) in this app.
-My program resides from 0xB000-0xFFFF to FLASH and 0x3800-0x3FFF to RAM.
-stack pointer to 0x3900.
-IVBR to 0x3F00
here is my app and again it stuck in 0x007D0000:
void main(void) {
PLL_Init(SYNR_VALUE, REFDV_VALUE, POSTDIV_VALUE); //set 50MHz BUSCLK
while((FSTAT & FSTAT_CCIF_MASK) == 0);
FCLKDIV = FLASH_PRESCALER; //set flash prescaler
InterruptModuleSetup();
InitSCI();
//CopyCodeToRAM();
DDRA = 0xff; // all output
DDRM = 0xff; // all output
PORTA = 0x00;
PTM = 0x00;
UINT32 Address;
for(Address = 0x00780000UL; Address < 0x007E0000UL; Address += 0x400)
{
while((FSTAT & FSTAT_CCIF_MASK) == 0); //wait if command in progress
FSTAT = 0x30; //clear ACCERR and PVIOL
FCCOBIX = 0x00; // set FCMD
FCCOBHI = 0x0A;
FCCOB = 0x0A00 | ((Address & 0x00FF0000)>>16);
FCCOBIX = 0x01;
FCCOB = (Address & 0x0000FFF8);
FSTAT = 0x80; //launch command
while((FSTAT & FSTAT_CCIF_MASK) == 0); //wait for done
}
PORTA = 0xff;
PTM = 0xff;
for(;;)
{
}
}
and this is my linker (in IAR Embedded workbench):
-chcs12
//================================================================
// Heap and Stack
//================================================================
// Size of the user stack
-D_CSTACK_SIZE=100
// Size of the heap
-D_HEAP_SIZE=000
//================================================================
// Memory Definitions
//================================================================
// Memory areas available for the application
-D_RAM_BEGIN=03900
-D_RAM_END=03Eff
-D_ROM_BEGIN=B000
-D_ROM_END=FEFF
//================================================================
// Memory Placement
//================================================================
/////////// FLASH
-Z(CODE)INTVEC=3F00-3FFF // interrrupt vectors = 0x3F
-Z(CODE)CODE,EARLYDIFUNCT,DIFUNCT,INITTAB,DATA16_C,DATA8_ID,DATA16_ID,CHECKSUM=_ROM_BEGIN-_ROM_END
//*************************************************************************
////////// RAM
-Z(DATA)DATA8_I,DATA8_Z,DATA8_N=00-FF
-Z(DATA)DATA8_C
-Z(DATA)DATA16_I,DATA16_Z,DATA16_N,HEAP+_HEAP_SIZE=_RAM_BEGIN-_RAM_END
-Z(DATA)CSTACK+_CSTACK_SIZE=3800-38FF //stack placement
//*************************************************************************
regard
Mohammad.
Hi,
Thanks for both answers;
I steel have problem in erasing flash and I wrote a very simple program and I can erase sector from 78 to 7C but I can not erase sector from 7C to 7F, some note about my app:
1-) I don't use any debugger and I check my code with LEDs on or off.
2-) I don't use any interrupt.
3-) I just have a main function and I don't have any other function.
4-) I copy my code to RAM like AN4258SW example.
And this is my code:
#include <iomc9s12xep100.h>
#include <intrinsics.h>
#include "Regdef.h"
#include "Types.h"
#include "Config.h"
void main(void) {
//PLL
PLLCTL = 0x81; //0B10000001 //CME=1,PLLON=0,FM1=0,FM2=0,FSTWKP=0,PRE=0,PCE=0,SCME=1
CLKSEL = 0x03; // 0B00000011; //PLLSEL=0,PSTP=0,PLLWAI=0,RTIWAI=1,COPWAI=1
SYNR = SYNR_VALUE; //Set the multiplier register
REFDV = REFDV_VALUE; //Set the divider register
POSTDIV = POSTDIV_VALUE; //Set the post divider register
PLLCTL |= PLLCTL_PLLON_MASK; //Enable the Phase Lock Loop
//Wait till the PLL VCO is within tolerance
while((CRGFLG & CRGFLG_LOCK_MASK) == 0);
CLKSEL |= CLKSEL_PLLSEL_MASK; //system clocks are derived from PLLCLK
//
//LED
DDRA = 0x80; // all output
DDRM = 0x02; // all output
PORTA = 0x00;
PTM = 0x00;
//
//FLASH SETTING
while((FSTAT & FSTAT_CCIF_MASK) == 0);
FCLKDIV = FLASH_PRESCALER; //set flash prescaler
//
//COPY TO RAM
UINT8 *Src;
UINT8 *Dst;
UINT16 SegSize;
UINT16 x;
src=(UINT8 *)0xFD00;
SegSize = 2; //0xfd00 - 0xfeff
Dst = (UINT8 *)0x3D00;
for (x = 0; x < SegSize; x++) //just copy a byte at a time
*Dst++ = *Src++;
//
//erase
for (UINT32 add = 0x00780000; add<0x007D0000; add+=0x400)
{
while((FSTAT & FSTAT_CCIF_MASK) == 0); //wait if command in progress
FSTAT = 0x30; //clear ACCERR and PVIOL
FCCOBIX = 0x00;
FCCOB = 0x0A00 | ((add & 0x007F0000)>>16);
FCCOBIX = 0x01;
FCCOB = (add & 0x0000FFF8);
FSTAT = 0x80; //launch command
while((FSTAT & FSTAT_CCIF_MASK) == 0); //wait if command in progress
}
//
PORTA = 0x80;
PTM = 0x02;
for(;;)
{
}
}
Best regards,
Mohammad.
Hi,
I would like only to add to previous answer.
You should also keep in mind that the part of the memory which is currently E/W is not allowed to by displayed in the memory window of the debugger. It is also reading of the block which is E/W, which is not allowed..
(The block is not a sector ... also mistake of some customers)
Usual approach is to move critical part of the code to move into RAM to be sure we do not use any part of flash during critical section. (example attached)
Best regards,
Ladislav
Do not execute code (read) from the block being erased.
Interrupt vectors may be located in the block being erased.
Serving interrupts means accessing (reading) vectors.
Disable interrupts.