Hi,
I am writing boot loader code for MC9S12DP256 micro-controller. So for this I have written FLASH erase sector/mass, program routines. Now I am facing some problem with the sector erase/program on non-PAGED (i.e PAGE =0x3e and 0x3f). But I am succeeding on PAGED windows erase/program from PAGE= 0x30 to 0x3d and also the mass erase on all the block of the pages(including PAGE=0x3e and 0x3f). I have OSC frequency of 48MHz on board and bus clock of 24MHz. I have initialized the FCLKDIV = 0x5e before going to call the FLASH related routines. The FLASH related routines are copied into RAM and executing.
I will put my code here:
#define FLASH_MASS_ERASE | 0x41 |
#define FLASH_SECTOR_ERASE | 0x40 |
#define FLASH_WRITE | 0x20 |
#define FLASH_VERIFY | 0x05 |
void ClearFlashErr()
{
volatile char i=0;
for(i=0;i<4;i++)
{
FCNFG = i;/* Bank select from 0 - 3*/
FSTAT |=(ACCERR | PVIOL | BLANK);
}
_asm("nop");
return;
}
char FlashCommands(const volatile char cmd, const volatile char page, const volatile int addr, const volatile int data)
{
char error_flash=0;
char i=0;
ClearFlashErr();
FCNFG = /*(FCNFG & 0xcc) | */(~(page >> 2 )) & 0x03;//BKSEL select block
if(FSTAT & CBEIF)
{
PPAGE = page;
DISABLE_INTERRUPTS();
FDATA = data;
FADDR = addr;
FCMD = cmd;// 41-mass erase, 40-512b sector erase, 20-progam 1 word, 05-erase verify
FSTAT = CBEIF;
ENABLE_INTERRUPTS();
while(((FSTAT & (CCIF | ACCERR | PVIOL)) == 0x0) || ((FSTAT & CBEIF) == 0x00))
{
_asm("nop");
i++;
if(i>200)
{
error_flash =1;
break;
}
}
if((FSTAT & ACCERR)||(FSTAT & PVIOL))
{
error_flash = 1;
}
_asm("nop");
}
return(error_flash);
}
Parameters passed for erasing,
* When I call to sector erase(command 0x40) on PAGE 0x3e, passed the address of 0x4000
* When I call to sector erase on PAGE 0x3f, passed the address of 0xC000
* Even I have tried to pass the page window address(0x8000) along with the PAGE
Some observation from my side:
* After mass erase on all the blocks of FLASH, I am able to program/write on the PAGE=0x3e from 0x4000. but not even single location on the PAGE=0x3f
Please can anybody let me know and guide me what may be the wrong?
Waiting....
Regards,
Ganesh
Hi, Edward is correct in his answer and I would like to add for you support files which can help you in your design.
1) The example code for flash E/W using array in the RAM for execution of critical phase of the flas EW process is attached.
2) link to the all access bootloader which can help you in your design.
http://www.freescale.com/files/microcontrollers/doc/app_note/AN3275.pdf
The source SW files can be downloaded from http://tinyurl.com/qct4uxf
Best regards,
Ladislav
FSTAT |=(ACCERR | PVIOL | BLANK); |
^^ serious bug here. FSTAT bits are cleared writing ones to flag. I you think a bit, you will see that this code tries to clear all FSTAT flags that are set, including CBEIF! Either do
FSTAT = ACCERR|PVIOL|BLANK;
or
FSTAT &= ACCERR|PVIOL|BLANK; // NO '~' to the right from &=
FDATA = data;
FADDR = addr;
^^ second serious bug. FDATA and FADDR registers are of interest only for BDM programmers. In normal operation modes these registers are not accessible. You need to write directly to flash array to latch address and data to be programmed. Instead of these ^^ two lines you need to *(short*)addr = data;