I implemented the flash routines for the S12 and it works fine.
Now I have a new project with HCS12XEP and have to adapt the flash routines. Is it correct that I can write to a flash block while code fetching from a different flash block? Or is it the same like S12 (flash routines in RAM and no IRQ while flash access)? I didn't find an answer in the datasheet.
Thanks!
Mark
Yes, you should disable interrupts and run code from memory, which is readable and not from which you are erasing/programming. Those MCU's, which don't require disable of interrupts or running from RAM, have CPU halted while flash is being erased or programmed. Yes, you may run from one flash block (block is not the same like page), while other is being programmed.
Thanks for your answer!
I have an other question: I'm trying to write to Flash page E0. What I have to define in prm?
NO_INIT?
.prm:
SEGMENTS
PAGE_E0 = NO_INIT DATA_FAR IBCC_FAR 0xE08000 TO 0xE0BFFF;
:
PLACEMENT
NON_VOLATILE_STORAGE INTO PAGE_E0;
Flash.c:
#pragma CONST_SEG NON_VOLATILE_STORAGE
const char __far non_volatile_data[] = { 0xFFFF };
#pragma CONST_SEG DEFAULT
Thank you!
Mark
Either NO_INIT or READ_ONLY. READ_ONLY for settings defined in your code, and implicit zeros for not initialized settings. NO_INIT for not initialized data.
I'm using NO_INIT, because READ_ONLY makes all data reset with data from S-records file, when upgrading firmware using bootloader. I think that old settings should survive firmware upgrade.
Thanks for your help!
I actually have a very strange problem. If I run my flash write routine in debug mode (single step), it works. In normal mode (continue) the write access fails with ACCERR=1. Seems I have to look for the error for a while...
Mark
That code (HCS12XDP512) runs in debug mode (single step) fine but not in contiues mode. Any idea where the error could be? Thanks a lot!
#pragma CODE_SEG .data
static void LaunchCommand(void)
{
// launch flash command
FSTAT_CBEIF = 1;
// wait for command completion
do
{
} while (!FSTAT_CCIF);
}
#pragma CODE_SEG NON_BANKED
:
:
UInt16 *pDestination = (UInt16 *)0x8000;
PPAGE = 0xE0;
FSTAT = 0x32; // clear error flags
*pDestination = *pSource; // write data to address
FCMD = 0x20; // program command
__asm SEI; // disable interrupts
LaunchCommand(); // call routine in RAM
__asm CLI; // enable interrupts
pSource++;
pDestination++;
:
#pragma CODE_SEG DEFAULT
Hm, should work. But are you running it really on S12XD and not on S12XE?
FSTAT_CBEIF = 1;
^^ it shouldn't cause your problem, but this code is clearing not just CBEIF, but also all other FSTAT flags. You know it, right?
I'm running on S12XD right now because I only have such a hardware. Later in the project we'll change to S12XE. That means I have to chage my flash routines again right? :smileywink:
The problem of the flash write access in continues mode was no code problem. It was a problem of the debugger not refreshed the memory data properly. :smileysad:
> FSTAT_CBEIF = 1;
>
> ^^ it shouldn't cause your
> problem, but this code is
> clearing not just CBEIF,
> but also all other FSTAT
> flags. You know it, right?
I don't understand...what I have to change...?
Thank you very much for your help!
Mark
Right, S12XE has different type of flash and requires different program/erase routines. But this doesn't happen too often. From ancient HC12 until now this is only 4th or so version of flash.
Regarding debugger. It doesn't update read only memories, unless you edit memory mapping in debugger to refresh memory when halting. See in P&E Multilnk menu in debugger.
> FSTAT_CBEIF = 1;
Ok. Let consider more dangerous line:
FSTAT_PVIOL = 1;
Looks like innocent attempt to clear PVIOL flag. But in fact this is an attempt to clear all FSTAT flags, including CBEIF! You are launching flash command here. Don't you see how? The answer is in how C bitfields (see how FSTAT_PVIOL is defined in headers) are working. PVIOL bit like other bitfields members not addresseable. You can address only whole bytes, belonging to bitfield struct. So how you or compiler can change just one bit? Only reading whole byte, manipulating read bit pattern, then writing resulting bitpattern back to byte in memory. This is exactly what happens in our example. FSTAT is read with PVIOL set or not, but with CBEIF most likely set. Whatever you do to PVIOL bit in read bit pattern, all other bits are preserved, including CBEIF=1. So you get a write of one to CBEIF, which is an attempt to launch flash command. :smileyhappy:
What to do? Don't use bitfields with flags. Below red lines are wrong. Use green lines
FSTAT |= FSTAT_PVIOL_MASK; // clears all FSTAT flags
FSTAT &= ~FSTAT_PVIOL_MASK; // clears all FSTAT flags except PVIOL
FSTAT_PVIOL = 1; // clears all FSTAT flags
FSTAT_PVIOL = 0; // clears all FSTAT flags except PVIOL
FSTAT = FSTAT_PVIOL_MASK;
FSTAT &= FSTAT_PVIOL_MASK; // note no ~