Access to flash memory

Started by montserret_maxime January 12, 2006
Hi,

I've a problem on MSC9S12DG256 chip.
I try to write a word in flash memory. I write the code in flash.
I copy it into RAM and I execute it in RAM.
My code is that :

static bool ProgData(void)
{
unsigned short * sectAddr = (unsigned short *)0x8000;
B = 0x34;
PPAGE = B;
B = B >> 2;
B = ~B;
B &= 0x3;
FCNFG = B;

*sectAddr = 0xABAB;

FCMD = PROG;

FSTAT |= FSTAT_CBEIF_MASK;
if (FSTAT_ACCERR) {return 0;}
if (FSTAT_PVIOL) {return 0;}
asm nop;
asm nop;
asm nop;
asm nop;
asm nop;
while(FSTAT_CBEIF == 0);

while(FSTAT_CCIF == 0);
}

The code is executed without error or crash.
But the data is not written in Flash

Have you got an idea about my problem.

Thanks in advance for your help.



Hi Maxime.

You apparently forgot to set FCLKDIV.

You can have a look in the "P&E_ICD_Erase_unsecure_hcs12.cmd" of your project.

Here is the code I tested successfully. Note the "NON_BANKED" pragma.

Regards,
Gilles static volatile unsigned char B;

#pragma CODE_SEG NON_BANKED
static Bool ProgData(void)
{
unsigned short * sectAddr = (unsigned short *)0x8000;

FPROT = 0xFF;

// XTAL :
// 16 MHz $49
// 8 MHz $27
// 4 MHz $13
// 2 MHz $9
// 1 MHz $4

FCLKDIV = 0x49;

B = 0x34;
PPAGE = B;
B = B >> 2;
B = ~B;
B &= 0x3;
FCNFG = B; *sectAddr = 0xABAB;

FCMD = 0x20; //PROG;

FSTAT |= FSTAT_CBEIF_MASK;
if (FSTAT_ACCERR) {return 0;}
if (FSTAT_PVIOL) {return 0;}
asm nop;
asm nop;
asm nop;
asm nop;
asm nop;
while(FSTAT_CBEIF == 0); while(FSTAT_CCIF == 0);
}

void main(void) {
/* put your own code here */
EnableInterrupts;

ProgData();

for(;;) {} /* wait forever */
/* please make sure that you never leave this function */
}
At 11:29 AM 1/12/2006, you wrote:
>Hi,
>
>I've a problem on MSC9S12DG256 chip.
>I try to write a word in flash memory. I write the code in flash.
>I copy it into RAM and I execute it in RAM.
>My code is that :
>
>static bool ProgData(void)
>{
> unsigned short * sectAddr = (unsigned short *)0x8000;
> B = 0x34;
> PPAGE = B;
> B = B >> 2;
> B = ~B;
> B &= 0x3;
> FCNFG = B;
>
> *sectAddr = 0xABAB;
>
> FCMD = PROG;
>
> FSTAT |= FSTAT_CBEIF_MASK;
> if (FSTAT_ACCERR) {return 0;}
> if (FSTAT_PVIOL) {return 0;}
> asm nop;
> asm nop;
> asm nop;
> asm nop;
> asm nop;
> while(FSTAT_CBEIF == 0);
>
> while(FSTAT_CCIF == 0);
>}
>
>The code is executed without error or crash.
>But the data is not written in Flash
>
>Have you got an idea about my problem.
>
>Thanks in advance for your help. >Yahoo! Groups Links >
>




Thanks a lot. Now it's working. The problem was FCLKDIV register.
Now , I want to erase a page. For that, my code is :

static void EraseFlash(void)
{
unsigned short * addr = (unsigned short *)0x8000;
FCLKDIV = 0x49;
B = 0x34;
PPAGE = B; B = B >> 2;
B = ~B;
B &= 0x3;
FCNFG = B;
cmd = ERASE + MASS;
asm nop;
if (EraseCmd(cmd, addr) == 0)
{
bError = 1;
}
cmd = ERVER + MASS;
if (EraseCmd(cmd, addr) == 0)
{
bError = 1;
}
if (FSTAT_BLANK)
{
bError = 1;
}
FCNFG = FSTAT_BLANK_MASK;
}

static bool EraseCmd(unsigned short cmd, unsigned short * addr)
{
asm nop;
asm nop;
*addr = 0xFFFF;
*(addr+1) = 0xFFFF;
FCMD = cmd;
FSTAT = FSTAT_CBEIF_MASK;
if (FSTAT_ACCERR) {return 0;}
if (FSTAT_PVIOL) {return 0;}
EraseCmdOK();
return 1;
}

static void EraseCmdOK(void)
{
while(FSTAT_CCIF == 0);
}

This code doesn't work.

Any idea ???

Thanks in advance.



Yes,
I did not try your code this time.
But apparently you forgot to unprotect the flash.
Check my previously sent code: FPROT = 0xFF; /* to unprotect all blocks */

Also, why do you have:

*addr = 0xFFFF;
*(addr+1) = 0xFFFF; ??

the second line is useless, to my opinion.

Regards,
Gilles At 02:23 PM 1/12/2006, montserret_maxime wrote:
>Thanks a lot. Now it's working. The problem was FCLKDIV register.
>Now , I want to erase a page. For that, my code is :
>
>static void EraseFlash(void)
>{
> unsigned short * addr = (unsigned short *)0x8000;
> FCLKDIV = 0x49;
> B = 0x34;
> PPAGE =
> B; B = B >> 2;
> B = ~B;
> B &= 0x3;
> FCNFG = B;
> cmd = ERASE + MASS;
> asm nop;
> if (EraseCmd(cmd, addr) == 0)
> {
> bError = 1;
> }
> cmd = ERVER + MASS;
> if (EraseCmd(cmd, addr) == 0)
> {
> bError = 1;
> }
> if (FSTAT_BLANK)
> {
> bError = 1;
> }
> FCNFG = FSTAT_BLANK_MASK;
>}
>
>static bool EraseCmd(unsigned short cmd, unsigned short * addr)
>{
> asm nop;
> asm nop;
> *addr = 0xFFFF;
> *(addr+1) = 0xFFFF;
> FCMD = cmd;
> FSTAT = FSTAT_CBEIF_MASK;
> if (FSTAT_ACCERR) {return 0;}
> if (FSTAT_PVIOL) {return 0;}
> EraseCmdOK();
> return 1;
>}
>
>static void EraseCmdOK(void)
>{
> while(FSTAT_CCIF == 0);
>}
>
>This code doesn't work.
>
>Any idea ???
>
>Thanks in advance. >
>
>Yahoo! Groups Links >
>




I add command "FPROT = 0xFF;" before doing other thing.
And I suppressed command "*(addr+1) = 0xFFFF;"
But it's not working also. --- In 68HC12@68HC..., Gilles Blanquin <gilles.blanquin@f...>
wrote:
>
>
> Yes,
> I did not try your code this time.
> But apparently you forgot to unprotect the flash.
> Check my previously sent code: FPROT = 0xFF; /* to unprotect all
blocks */
>
> Also, why do you have:
>
> *addr = 0xFFFF;
> *(addr+1) = 0xFFFF; ??
>
> the second line is useless, to my opinion.
>
> Regards,
> Gilles > At 02:23 PM 1/12/2006, montserret_maxime wrote:
> >Thanks a lot. Now it's working. The problem was FCLKDIV register.
> >Now , I want to erase a page. For that, my code is :
> >
> >static void EraseFlash(void)
> >{
> > unsigned short * addr = (unsigned short *)0x8000;
> > FCLKDIV = 0x49;
> > B = 0x34;
> > PPAGE =
> > B; B
= B >> 2;
> > B = ~B;
> > B &= 0x3;
> > FCNFG = B;
> > cmd = ERASE + MASS;
> > asm nop;
> > if (EraseCmd(cmd, addr) == 0)
> > {
> > bError = 1;
> > }
> > cmd = ERVER + MASS;
> > if (EraseCmd(cmd, addr) == 0)
> > {
> > bError = 1;
> > }
> > if (FSTAT_BLANK)
> > {
> > bError = 1;
> > }
> > FCNFG = FSTAT_BLANK_MASK;
> >}
> >
> >static bool EraseCmd(unsigned short cmd, unsigned short * addr)
> >{
> > asm nop;
> > asm nop;
> > *addr = 0xFFFF;
> > *(addr+1) = 0xFFFF;
> > FCMD = cmd;
> > FSTAT = FSTAT_CBEIF_MASK;
> > if (FSTAT_ACCERR) {return 0;}
> > if (FSTAT_PVIOL) {return 0;}
> > EraseCmdOK();
> > return 1;
> >}
> >
> >static void EraseCmdOK(void)
> >{
> > while(FSTAT_CCIF == 0);
> >}
> >
> >This code doesn't work.
> >
> >Any idea ???
> >
> >Thanks in advance.
> >
> >
> >
> >
> >
> >
> >
> >Yahoo! Groups Links
> >
> >
> >
> >
>