I am trying to program from D-Flash on the MC9S12XET256. I want to use the 1st page (256 bytes worth) of the 1K non-paged eeprom/D-flash memory. Located at 0x0C00 - 0x1000
(the below code isn’t trying to use the fixed window, but we tried for a while)
For some addresses, this code ran without error, but when we looked at the position in memory it did not seem cleared after erasing, nor to contain 0xA5A5 after writing. (I believe this is the case for x10_0100, the address being attempted in the above code). For some other addresses we attempted (there were several- x00_0C00, perhaps? 1F_0C00? x1F_0000?) this resulted in a memory access error (shown by a 1 in the ACCERR bit of the FSTAT register), but I’m fairly sure I am were attempting to read/write areas that weren’t actually DFlash.
If my values are wrong. what are the correct values FCCOBLO FCCOB vto access the 0xC00-0x100 page. Erase it and write to it. Also is it possible to use the other 3 pages in the 1K fixed page as eeprom in the same code?
I appreciate any help with this issue. I have been trying many things to no avail.
Other Info:
Thought perhaps we needed to unprotect flash, tried:
FPROT |= 0xA4; // FPOPEN=1, FPHDIS=1, FPLDIS=1
EPROT |= 0x88; // EPOPEN=1, EPDIS=1
to no avail. (I don’t think this is valid/neccesary, but we tried it because in some derivatives you have to set DFPROT before writing to DFlash)
Code:
// Function to erase Dflash
static void eraseDflash(){
DisableInterrupts;
if ((FSTAT & 0x30) != 0) {
FSTAT |= 0x30; // clear ACCERR or FPVIOL if set
}
FCCOBIX = 0;
FCCOBHI = 0x12; // erase D-flash command
FCCOBLO = 0x10; // global address
FCCOBIX = 1;
FCCOB = 0x0100; // address within sector
FSTAT = 0x80; // initiate flash command
while(!FSTAT_CCIF); // wait for command to complete
EnableInterrupts;
}
// Function to write Dflash
static void writeDflash(UINT16 word_to_write){
DisableInterrupts;
if ((FSTAT & 0x30) != 0) {
FSTAT |= 0x30; // clear ACCERR or FPVIOL if set
}
FCCOBIX = 0;
FCCOBHI = 0x11; // program D-flash command
FCCOBLO = 0x10; // global address
FCCOBIX = 1;
FCCOB = 0x0100; // address within sector
FCCOBIX = 2;
FCCOB = word_to_write;
FSTAT = 0x80; // initiate flash command
while(!FSTAT_CCIF); // wait for command to complete
EnableInterrupts;
}
// Called from main:
eraseDflash();
writeDflash(0xA5A5);
Relevant websites/forum posts:
http://www.freescale.com/files/microcontrollers/doc/data_sheet/MC9S12XEP100RMV1.pdf
https://community.freescale.com/thread/51749
http://www.freescale.com/files/microcontrollers/doc/app_note/AN3743.pdf
http://www.freescale.com/files/microcontrollers/doc/app_note/AN3490.pdf
http://forums.freescale.com/t5/16-Bit-Microcontrollers/Problem-in-using-D-Flash-for-XS128-Need-help/...
At CPU address 0x0C00-0x0FFF there is top most 1kb piece of 256K EEPROM RESOURCES. See Figure 1-2 on page 35.
What is mapped there in 256K EEPROM RESOURCES can be revealed looking into XXXX Kbyte Flash Module chapter. You should look at Table 25-6 on page 901. The top most piece of 256K is the Buffer RAM. So you can't see D-flash at 0xC00, but only buffer RAM or emulated EEPROM. Emulated EEPROM is not enabled by default. To enable it you would need to partition D-flash.
As table 25-6 states, D-flash is at global address 0x100000-0x107FFF 'G. This can be mapped to E-page window at 0x800. EEPAGE's 0 to 31.
You should not mix CPU addresses with global addresses. Compiler may convert far to near or backwards in some cases, but flash controller works only with global addresses.
It is notmal, there's no D-flash at 1F0C00'G. D-flash range is from 0x100000'G to 0x107FFF'G.
Again, there's no D-flash at CPU address 0xC00. At 0xC00 there's either buffer RAM, or EEE.
It makes no sense to try to unprotect flash. In normal modes of operation, only attempts to protect more flash are granted. All attempts to unprotect all or parts of flash are ignored.
You can't do it this way. Instead you need to FSTAT = 0x30
The rest of your routine should work. With address specified 0x100100'G, you should get sector at 0x900 in EEEPAGE = 0 window.erased.