Hello everybody, I have a question related to using flash on HCS08 devices.
I would like to use a whole flash page to store a set of informations that are crucial to my tasks.
I already integrated the source code provided with AN3942.pdf.
It works fine, but as far as I understood it allows only saving 256 byte using the FlashProgBurst routine (the size subroutine parameter is an unsigned char).
So I don't understand how can I use the whole flash page, that is the 512 bytes.
When I use the FlashErase, I erase the whole page, but when I use the FlashProgBurst I'm able to write only half a page.
Any hint will be appreciated.
Solved! Go to Solution.
Hello Giovanni,
Both burst programming and byte-by-byte programming require a similar sequence and actions.
The main difference is that, for burst programming, the next address and byte value is written to flash memory after FSTAT_FCBEF flag becomes set, indicating that the buffer is ready the new data. At this point, the programming voltage is still present on the flash row, and the flash array remains inaccessible to read operations. This means that the code to increment the address, and write the new address and data value, must also reside within RAM, perhaps on the stack, along with code to launch the programming command and test the flags.
For byte-by-byte programming the programming process for the current byte is completed when FSTAT_FCCF flag becomes set. This happens some time after FSTAT_FCBEF becomes set, which accounts for the additional time taken. At this point, the programming voltage has been removed from the flash array, so is now available for read operations. This means that code to increment the address, and write the new address and data value, may reside within flash memory, in the normal manner. Only the code to launch the programming command and test the flags need reside within RAM, requiring many fewer bytes of RAM resident code.
For programming each 32 bytes, there will be the following timing differences for the total programming time, ignoring code execution overheads. The range of values takes into account the allowable limits for the flash clock frequency (150 - 200 kHz).
Burst programming 690 - 920 microseconds
Byte-by-byte programming 1440 - 1920 microseconds
Page erase time 20 - 27 milliseconds
Since you are not restricted to a single row for the byte-by-byte programming, the address sequence can be totally random, and does not need to commence at a row boundary.
If you are storing the current flash data page in RAM, and then erasing the page, at this point you are vulnerable to power failure occurring, and the loss of the current data. One method to counter this is to store the same data within two different flash pages, then erase and program one page at a time. You may want to include a CRC check value within your data so that you know the page programming is complete and intact.
Regards,
Mac
Hello Bigmac.
Thanks you for your help, I'm late in my reply because I was on a business trip.
You are right, my 512 byte are are in RAM (or better, I have to add 32 bit at time to a array that at most will be 512 byte so I have to dump in RAM the previously stored array, add 32 bit and then store it again in flash).
I will give a try to the idea of byte by byte write.
If I understood your suggestion I have to act like this:
erase 512 byte page
write byte 1
write byte 2
....
write byte 511
Am I right?
Giovanni
Hello Giovanni,
Both burst programming and byte-by-byte programming require a similar sequence and actions.
The main difference is that, for burst programming, the next address and byte value is written to flash memory after FSTAT_FCBEF flag becomes set, indicating that the buffer is ready the new data. At this point, the programming voltage is still present on the flash row, and the flash array remains inaccessible to read operations. This means that the code to increment the address, and write the new address and data value, must also reside within RAM, perhaps on the stack, along with code to launch the programming command and test the flags.
For byte-by-byte programming the programming process for the current byte is completed when FSTAT_FCCF flag becomes set. This happens some time after FSTAT_FCBEF becomes set, which accounts for the additional time taken. At this point, the programming voltage has been removed from the flash array, so is now available for read operations. This means that code to increment the address, and write the new address and data value, may reside within flash memory, in the normal manner. Only the code to launch the programming command and test the flags need reside within RAM, requiring many fewer bytes of RAM resident code.
For programming each 32 bytes, there will be the following timing differences for the total programming time, ignoring code execution overheads. The range of values takes into account the allowable limits for the flash clock frequency (150 - 200 kHz).
Burst programming 690 - 920 microseconds
Byte-by-byte programming 1440 - 1920 microseconds
Page erase time 20 - 27 milliseconds
Since you are not restricted to a single row for the byte-by-byte programming, the address sequence can be totally random, and does not need to commence at a row boundary.
If you are storing the current flash data page in RAM, and then erasing the page, at this point you are vulnerable to power failure occurring, and the loss of the current data. One method to counter this is to store the same data within two different flash pages, then erase and program one page at a time. You may want to include a CRC check value within your data so that you know the page programming is complete and intact.
Regards,
Mac
Hi bigmac. Thanks a lot for your great help. About the ping pong buffering, I already implemented it because of the power failure problem. I will try using the FlashProg function instead of the FlashProgBurst, since, as you suggested, there won't be a big time difference. I hope everything will works fine. Thanks again, Giovanni
Good morning bigmac, I continued working on the topic of this forum thread but I have a problem.
I'm using a QE16 device.
Everything worked fine when I tried writing to address 0xC000 and 0xC2000.
As soon as I write to addresses 0xF200 I see no changes in ROM, using Memory tools in Codewarrior.
The sourcecode that I use is the following one:
void writeDataOnFlash(uint8_t* pRomInfo, uint16_t sizeToSave, uint8_t* addressSelect) {
uint8_t * volatile pRomInfoCurrent = (unsigned char *) pRomInfo;
uint8_t * volatile pRomStart = (unsigned char *) (addressSelect);
uint16_t i =0;
DisableInterrupts;
// Cancello la pagina di flash sulla quale andro' a scrivere adesso
FlashErase(pRomStart);
for(i=0;i<sizeToSave;i++)
{
FlashProg(pRomStart+i, pRomInfoCurrent[i]);
}
EnableInterrupts;
}
The size of the buffer (sizeToSave) equals 508 bytes (so under the page size).
I defined in a similar way the ROM memory zones in prm file:
I'm sorry I had some problem adding the lines of prm:
Is there anyone able to find my fault? I don't understand what happens? Can I monitor some CPU register looking for access errors?
Giovanni
I found it, my fault I didn't update NVPROT register so the page that I was accessign was protected.
Giovanni
Hello Giovanni,
Burst programming mode actually applies to only a single flash row at a time, likely to consist of 32 or 64 bytes, depending on MCU type. When the programming of each row is competed, a new burst programming sequence will need to be initiated. This means that the programming of a whole flash page of 512 bytes will require 8 or 16 burst programming sequences.
I assume that you have all 512 bytes of data already present in RAM prior to the commencement of programming. Using an 8-bit index value, the data will need to be split into two separate 256 byte tables. Alternatively, you can use a 16-bit index value.
The additional complexity of tracking the row position can be avoided by the use of byte-by-byte programming, in lieu of burst programming mode. This will take a marginally longer period to complete, but this is trivial compared with the page erase duration.
Regards,
Mac