Flash Programming Not Working on Second Pass

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Flash Programming Not Working on Second Pass

2,382 Views
mjcoury
Contributor I
All -

Here are my erase and write routines -

#pragma CODE_SEG ToCopyToRAM
void EraseFlash(void) {

if ((FSTAT & 0x10) != 0) {
FSTAT |= 0x30;
}
asm {
//LDA #$CC
//STA $1600
LDA #$40
STA FCMD
LDA #$80
STA FSTAT
NOP
NOP
NOP
NOP
WFLOOP:
LDA FSTAT
LSLA
BPL WFLOOP
}
} // end EraseFlash
void WriteFlash(void) {
byte temp = 0x00;
if ((FSTAT & 0x10) != 0) {
FSTAT |= 0x30;
}
asm {
//LDA #$CC
//STA $1600
LDA #$20
STA FCMD
LDA #$80
STA FSTAT
NOP
NOP
NOP
NOP
WFLOOP:
LDA FSTAT
LSLA
BPL WFLOOP
}

// while( (FSTAT & 0x40)!= 1) {
// asm("NOP");
// }
} // end WriteFlash
#pragma CODE_SEG DEFAULT


Here is the routines that call it


int LCDFlashCheck(){
sLCDDataStored_ptr = (lcdram *) LCD_FLASH_START;

if(sLCDDataStored_ptr->iFlashKey == (word) FLASH_SEED) {
sLCDDataActive_ptr->cID = sLCDDataStored_ptr->cID;
sLCDDataActive_ptr->cChannel = sLCDDataStored_ptr->cChannel;
sLCDDataActive_ptr->cEncyptionKey = sLCDDataStored_ptr->cEncyptionKey;
sLCDDataActive_ptr->cPreset1 = sLCDDataStored_ptr->cPreset1;
sLCDDataActive_ptr->cPreset2 = sLCDDataStored_ptr->cPreset2;
sLCDDataActive_ptr->cMode = sLCDDataStored_ptr->cMode;
sLCDDataActive_ptr->cContrast = sLCDDataStored_ptr->cContrast;
sLCDDataActive_ptr->cBacklight = sLCDDataStored_ptr->cBacklight;
return ERROR_NONE;
}else{
sLCDDataActive_ptr->iFlashKey = (word) FLASH_SEED;
sLCDDataActive_ptr->cID = 0;
sLCDDataActive_ptr->cChannel = 5;
sLCDDataActive_ptr->cEncyptionKey = 21;
sLCDDataActive_ptr->cPreset1 = (char) PRESET1;
sLCDDataActive_ptr->cPreset2 = (char) PRESET2;
sLCDDataActive_ptr->cMode = 0;
sLCDDataActive_ptr->cContrast = 0x7F;
sLCDDataActive_ptr->cBacklight = 1;
LCDReWriteFlash();
return ERROR_FLASH_INVALID_KEY;
}
}


int LCDReWriteFlash(void){
char cDummy = 0xFF;
char *cDummy_ptr;
char *cMemory_ptr;
int i;

DisableInterrupts;

//Erase Flash
cMemory_ptr = (char*) LCD_FLASH_START;
*cMemory_ptr = 0xFF;
EraseFlash();

//Write Flash
cDummy_ptr = &(sLCDDataActive);
cMemory_ptr = (char*) LCD_FLASH_START;
for(i=0;i
*cMemory_ptr = *cDummy_ptr;
WriteFlash();
cMemory_ptr++;
cDummy_ptr++;
}

EnableInterrupts;
}

Now when the device is freshly flashed the memory location in question is obviously all 0xFF. The routine works as expected and all the "default" data is stored into FLASH. Now any other write attempts will fail and just not work. When I step through the code at this point

//Erase Flash
cMemory_ptr = (char*) LCD_FLASH_START;
*cMemory_ptr = 0xFF;
EraseFlash();


cMemory_ptr will correctly be addressed at 0x1600. However the next piece of code

*cMemory_ptr = 0xFF;

appears to be "skipped" and because the value at cMemory pointer never changes, the EraseFlash() routine does not correctly erase the page, and of course without the erase there is no write...

Any Ideas?
Labels (1)
0 Kudos
4 Replies

448 Views
jah
Contributor I
i have recently posted some code for the mc9s08rd32dwe processor. not alot of details in your post. the areas i got hung up in are:

-the memory bus is tied up servicing the flash programmer state machine. you need to emulate out of ram while doing your lo level flash programming. put the assembly code to low level program flash in a C language array, make the linker put in ram at processor startup. to flash write it only takes like 30bytes. all this in my semi recent posting, search.
-to program flash you need to consider doing:
1)copy entire page flash to ram
2)modify the ram as needed
3)clear the entire flash page all at once
4)byte by byte copy ram to flash for the entire page
-rember to set the proper flash clock speed for your system in processor startup
-think of testing for proper vcc during flash write.
0 Kudos

448 Views
mjcoury
Contributor I
jah -

to your points

1)copy entire page flash to ram

In my code you can see the #pragma CODE_SEG ToCopyToRAM which, already copies the write and erase routines to flash.

2)modify the ram as needed

Why would I need to modify the ram? I assume you are referring to the memory location to be written / erased. If this is true why does it work once through the process I currently use?

3)clear the entire flash page all at once

If you looked at my routine int LCDReWriteFlash(void){ you can clearly see the routine Erase Flash is called before write flash.

cMemory_ptr = (char*) LCD_FLASH_START;
*cMemory_ptr = 0xFF;
EraseFlash();

The problem is HERE, where the *cMemory_ptr SHOULD be getting the value dummy value of 0xFF - however - since this line gets "skipped" when I step through the code on a second pass - the MCU does not know to erase the page at location cMemory_ptr (in this case $1600)

4)byte by byte copy ram to flash for the entire page

//Write Flash
cDummy_ptr = &(sLCDDataActive);
cMemory_ptr = (char*) LCD_FLASH_START;
for(i=0;i
*cMemory_ptr = *cDummy_ptr;
WriteFlash();
cMemory_ptr++;
cDummy_ptr++;
}

as you can see there is a byte by byte copy ram routine already present. This I assume would work correctly IF i was properly erasing the page - which seems to by why it is not working.
0 Kudos

448 Views
rocco
Senior Contributor II
Hi, mjcoury:

I'm not using the same CPU, but I found that the writing of the address latch, the "*cMemory_ptr = 0xFF;" instruction, had to be executed from ram as well. Otherwise, the fetch of the following instruction caused the address latch to change.

But that was on an HC08, not an S08, so it may not be your problem.
0 Kudos

448 Views
mjcoury
Contributor I
not a bad idea... however, why would it work the first time i run the program from programming and not other attempts?
0 Kudos