I am working flash program and erase in MC9S12DP256 controller.
i am not able write in flash area , but i am using same command state machine.
i have attached my code give below ,i am using code worrier tool.
can u give some solution?
progAdr=(unsigned short int *) 0xC000;
bufferPtr=&buffer;
FCLKDIV = 0x49;
FCNFG=3;
FSTAT_PVIOL=1;
FSTAT_ACCERR=1;
FCNFG=2;
FSTAT_PVIOL=1;
FSTAT_ACCERR=1;
FCNFG=1;
FSTAT_PVIOL=1;
FSTAT_ACCERR=1;
FCNFG=0;
FSTAT_PVIOL=1;
FSTAT_ACCERR=1;
for(i=0;i<5;i++){
if(FSTAT_CBEIF == 1) {
*progAdr++ = *bufferPtr++;
FCMD =0x20;
FSTAT_CBEIF=1;
if((FSTAT_PVIOL==1)||(FSTAT_ACCERR==1)) {
return;
}
}
while(FSTAT_CCIF!=1){
}
Wrong:
FSTAT_PVIOL=1;
wrong:
FSTAT_ACCERR=1;
FSTAT register contains bits, that are cleared writing "1" to them. Since CPU can address bytes, words, but not single bits, to do FSTAT_PVIOL=1, CPU has to 1) read FSTAT, 2) do bitwise or with PVIOL bit mask, 3) write result back to FSTAT.
At 1 step CBEIF is brobably set. What happens at step 3 is you write 1 not only to PVIOL, but also to CBEIF. You are trying to launch flash command. Don't use bitfields with such flags registers.
Dear Kef,
Thanks for your reply,
FSTAT register internally create one structure .
That structure is contain all the bit field in code warrior header file (mc9s12dp256.h).
that struct assign FSTAT address . If I want to access individual bit means directly assign to bit
compiler is take care bit processing (FSTAT_PVIOL)So both are same operation.
Can u check attachment file?
In codewarrior linker file I need change any code segment address?
Shall I need to open any backdoor key for erasing and programming?
Shall I need to consider any security register?
--Dalmeida
I know Codewarrior header files have bitfields defined for every register bit. But still you can't clear single flag bit properly using these bit defines. It is impossible. Any write access to such flag via bitfield structure, either flagbit=0 or flagbit=1, unavoidable write ones to flags that are set. The same applies not only to FSTAT register, but also to timer flags register, CAN status register and many other flags registers.
Again, in case CBEIF is set and you are trying to clear PVIOL or ACCERR like this FSTAT_PVIOL=1 or FSTAT_PVIOL=0 etc, you make "1" written also to CBEIF flag, because when accessing some bitfield, you have to preserve contents of "not accessed" bitfields from the same bitfields structure. CBEIF was "1", you preserve it rewriting it with "1"; so you are trying to launch some flash command.
Compiler can't care about hardware nuissances. I believe those bitfields should be removed from Codewarrior headers. If not all, then at least those dangerous defines for flags registers.
Security enabled doesn't mean flash write protection. Secured flash still can be erased/programmed from your code, so you don't need to backdoor unsecure your flash.
I have change in code your way (byte access FAST reg),But that code also not working .
I have attached below code.
unsigned short int buffer[]={0x0046,0x0047,0x0048,0x0049,0x004A};
unsigned short int *progAdr;
int i;
progAdr=(unsigned short int *) 0xc000;
FCLKDIV = 0x49;
if(FCLKDIV_FDIVLD == 0){
return;
}
FCNFG=3;
FSTAT|=(PVIOL | ACCERR);
//FSTAT_ACCERR=1;
FCNFG=2;
FSTAT|=(PVIOL | ACCERR);
// FSTAT_PVIOL=1;
// FSTAT_ACCERR=1;
FCNFG=1;
FSTAT|=(PVIOL | ACCERR);
//FSTAT_PVIOL=1;
//FSTAT_ACCERR=1;
FCNFG=0;
FSTAT|=(PVIOL | ACCERR);
for(i=0;I<5;I++){
if(FSTAT_CBEIF == 1) {
*progAdr = buffer[i];
FCMD =0x20;
// (void)DoOnStack(far_address); // just passed for PPAGE
FSTAT_CBEIF=1;
if((FSTAT & PVIOL)||(FSTAT & ACCERR)) {
return;
}
while(FSTAT_CBEIF == 0);
progAdr++;
}
while(FSTAT_CCIF!=1){
}
}
i am using Normal Single Chip Mode in MC9S12DP256.
In Normal mode ,some registers and bits are protected
against accidental changes.
Can u confirm u are using normal mode or special mode?
This is also wrong:
FSTAT|=(PVIOL | ACCERR);
I don't know how PVIOL is defined in your code. Is it the defined the same like FSTAT_PVIOL_MASK from DP256 header file? It is the same like setting PVIOL and ACCERR via bitfields.
1) FSTAT reads with CBEIF == 1
2) you OR that with FSTAT_PVIOL_MASK and FSTAT_ACCERR_MASK
3) you write resulting value back to FSTAT with CBEIF=1. You are trying to launch flash command here!
It is not clear:
1) how does your code deal with the fact that flash memory is not readable while any flash command is being executed. That means also that you can't execute code while some flash command is in progress.
2) P&E Multilink/cyclone connection by default caches flash memory contents. Isn't it the case that program/erase succeeds but you simply see no changes in the memory? In hiwave debugger go to debugging memory map and check update memory checkbox for relevant memory blocks.
Hi kef,
I am tried but I am not able to launch that command.
can u confirm it is work in normal mode in mc9s12dp256?
below details are contain in mc9s12dp256 dataseet:
There are two basic types of operating modes:
Normal modes — some registers and bits are protected
against accidental changes.
Special modes — allow greater access to protected control
registers and bits for special purposes such as testing.
What's maskset of your MC9S12DP256? For example 1K79X has a bug that prevents flash and eeprom operations while chip is secured. Unsecured 1K79X is programmable in all operating modes. Other masksets that don't have these erratas are programmable and eraseable in all operating modes, both secured and unsecured.
Here you can find D family erratas: erratas
Hi Kef,
I have load flash driver program in $4000 location . I need to program and erase location $8000 .
Is it properly work ? I have attached my code below .
Please some idea kef....
unsigned short int *progAdr;
int i;
progAdr=(unsigned short int *) 0xC000;
FCLKDIV = 0x49;
FSTAT|=(FSTAT_ACCERR_MASK | FSTAT_PVIOL_MASK);
if(FCLKDIV_FDIVLD == 0){
return;
}
for(i=0;i<5;i++){
if(FSTAT_CBEIF == 1) {
*progAdr = 0x55;
FCMD =0x20;
// (void)DoOnStack(far_address); // just passed for PPAGE
FSTAT |= FSTAT_CBEIF_MASK;
if((FSTAT_PVIOL == 1)||(FSTAT_ACCERR == 1)) {
return;
}
while(FSTAT_CBEIF == 0);
while(FSTAT_CCIF!=1){
}
progAdr++;
}
}
1. You say you are programming 0x8000. But your code clearly uses 0xC000 as a destination address.
2. Programming 0x8000 with driver code at 0x4000 will succeed only for PPAGE settings <=0x3B. This is because pages 0x3C to 0x3F form single flash bank. 0x4000 belongs to PPAGE==0x3E. And code can't run in the same flash bank that is being programmed. Your code needs to execute from different flash bank, from EEPROM, from RAM or from external memory.
3. Programming 0xC000 with driver at 0x4000 also will fail. Because 0xC000 is PPAGE==0x3F. 0x4000 is PPAGE=0x3E. Both pages belong to the same flash bank.
4. Again, this your piece of code is WRONG:
FSTAT|=(FSTAT_ACCERR_MASK | FSTAT_PVIOL_MASK);
^^ this code clears ACCERR, PVIOL bits and most likely writes "1' also to CBEIF, trying to launch flash command. Since FCMD is probably not loaded at this point, some error (PVIOL I think) will be triggered again. Please remove red symbol. I wrote already why bitfields are wrong. You do the same what compiler does for FSTAT_ACCERR=1 and FSTAT_PVIOL=1;. I'm afraid my explanation doesn't help you to understand why it's wrong.
5. This is also not right piece of code:
FSTAT |= FSTAT_CBEIF_MASK;
^^ here you are not only launching flash command, but also clearing ACCERR and PVIOL.
6. Don't forget to set up BKSEL bits in FCNFG register. 00 for pages 3C to 3F, 01 for 38-3B etc.
After fixing these issues code should start working. Of course with restrictions specified in 2 and 3, unless you move your code to RAM.
Hi Kef
i have understand ur point and change my code but still not working .
i have attached below .
unsigned short int *progAdr;
int i;
progAdr=(unsigned short int *) 0x4000;
FCLKDIV = 0x49;
if(FCLKDIV_FDIVLD == 0){
return;
}
FCNFG=3;
FSTAT =(FSTAT_ACCERR_MASK | FSTAT_PVIOL_MASK);
FCNFG=2;
FSTAT =(FSTAT_ACCERR_MASK | FSTAT_PVIOL_MASK);
FCNFG=1;
FSTAT =(FSTAT_ACCERR_MASK | FSTAT_PVIOL_MASK);
FCNFG=0;
FSTAT =(FSTAT_ACCERR_MASK | FSTAT_PVIOL_MASK);
for(i=0;i<5;i++){
if(FSTAT_CBEIF == 1) {
*progAdr = 0x41;
FCMD =0x20;
FSTAT = FSTAT_CBEIF_MASK;
if((FSTAT_PVIOL == 1)||(FSTAT_ACCERR == 1)) {
return;
}
while(FSTAT_CBEIF == 0);
progAdr++;
}
}
while(FSTAT_CCIF!=1){}
Start_up code available in Unbanked Flash ROM $C000
flash driver program available in banked Flash ROM $30 to $3D
i am trying write at unbanked ROM S4000 .Is it possible?
Can u confirm it is working or not?
Please refer attachment file
Can u give some solution?
Your code is working. But programming 0x4000, driver code can not be placed in pages 0x3C..0x3F, because 0x4000 and pages 3C..3D are flash bank0.
Alsoo since interrupt vectors at 0xFFxx also to bank0, you should disable interrupts while erasing/programming.
Did you make debugger updating flash at 0x4000? HCSMultilinkCyclonePro->Debugging Memory Map...->Unbanked Flash 4000->refresh memory when halting?
Hi Kef,
I have disable all the interrupt. I have changed location also .
Still that program is problem(illegal_BP) in execution time
i have attached my program below .this program stored in $30 area.i am using same lier file
unsigned short int *progAdr;
int i;
progAdr=(unsigned short int *) 0xD000;
DisableInterrupts;
FCLKDIV = 0x49;
if(FCLKDIV_FDIVLD == 0){
return;
}
FCNFG=3;
FSTAT =(FSTAT_ACCERR_MASK | FSTAT_PVIOL_MASK);
FCNFG=2;
FSTAT =(FSTAT_ACCERR_MASK | FSTAT_PVIOL_MASK);
FCNFG=1;
FSTAT =(FSTAT_ACCERR_MASK | FSTAT_PVIOL_MASK);
FCNFG=0;
FSTAT =(FSTAT_ACCERR_MASK | FSTAT_PVIOL_MASK);
for(i=0;i<5;i++){
if(FSTAT_CBEIF == 1) {
*progAdr = 0x4141;
FCMD =0x20;
FSTAT = FSTAT_CBEIF_MASK;
if((FSTAT_PVIOL == 1)||(FSTAT_ACCERR == 1)) {
return;
}
while(FSTAT_CBEIF == 0);
progAdr++;
}
}
while(FSTAT_CCIF!=1){}