Unable to detect the FPVIOL flag when trying to erase/write a FLASH protected block on HCS08GT60A

I have a problem to detect the FPVIOL flag in the FSTAT register when I try to erase or write a protected FLASH block on a HCS08GT60A chip.

My FLASH register configuration is the following:

FOPT = 0x42 (No Backdoor key, No vector redirection, Unsecured mode)

FPROT = 0xA0 (FLASH blocks from 0xE000 to 0xFFFF are protected)

In my test, I try to erase or programm the 0xF000 address with the algorithm decribed in the Data sheet. The Erase or Write action is not executed (no changes in the FLASH) but the FPVIOL flag is not set ???

My FLASH driver is written in C language and in the algorithm provided in the data sheet , we have to clear the FCBEF bit in the FSTAT register to launch the required command on the FLASH. In my FLASH driver, this was done by setting to 1 the FCBEF like "FSTAT_FCBEF = TRUE" with FSTAT_FCBEF is equivalent to the MSB of a bit field. With this code, the compiler gets the FSTAT value, does an OR with 0x80 and writes the result to FSTAT. Doing this, if the FPVIOL or the FACCERR bits of the FSTAT are set, they are reset by the las write to FSTAT (if they are set, with the OR, they stay to 1 and then they are written to one which leads to resetting them), so it is not possible to detects them ....

So I replace the "FSTAT_FCBEF = TRUE" by "FSTAT = 0x80" and all is working well.

Interresting what you say regarding the FACCERR & FPVIOL bits. I was under the impression that these bits were set only after the command was registered by writing to the FCBEF bit.

I look at the SpSub code (reproduced below, this code is from the reference manual & monitor program), and the FCBEF bit is set by a STA instruction which would overwrite all other bits in FSTAT.

When the program returns to DoOnStack A is shifted left 1 bit which would normally put FPVIOL & FACCERR at bits 7 & 6 repectively. If what you say is true, then a check for these error flags should be done immediately after storing the data to the flash address (sta ,x).

Can anyone confirm or deny this?

JC

;********************************************************************************;* SpSub - This variation of SpSub performs all of the steps for;* programming or erasing flash from RAM. SpSub is copied onto the;* stack, SP is copied to H:X, and then the copy of SpSub in RAM is;* called using a JSR 0,X instruction.;*;* At the time SpSub is called, the data to be programmed (dummy data;* for an erase command), is in A and the flash address is on the;* stack above SpSub. After return, PVIOL and ACCERR flags are in bits;* 6 and 5 of A. If A is shifted left by one bit after return, it;* should be zero unless there was a flash error.;*;* Uses 24 bytes on stack + 2 bytes if a BSR/JSR calls it;********************************************************************************

The FPVIOL and FACCERR are really set only after the FCBEF bit writing. Your SpSub code is right because even if the STA instruction overwrite all other bits in the FSTAT register, these bits are overwritten with a null value ("mFCBEF: equ %10000000").

If you look at the datasheet you will see that writing with a null value to all FSTAT bits except FCBEF have no effect (the FPVIOL and FACCERR are not modified by this write).

This is another instance where side effects have been caused by the use of a read-modify-write sequence. Unfortunately, in this case the data sheet does not give a specific warning for the FSTAT register. The same warning would also apply to any other register that contains bits that are cleared by writing a one.

As Johan has observed, FSTAT_FCBEF = 1 is such a sequence, although this fact may not be immediately obvious. A possible drawback with programming in C, versus assembler.

If you think about it, the setting or clearing of a single bit would always be read-modify-write, since a read is first required to determine the state of the other (unaltered) bits in the register. Since this is a problem only for certain hardware registers that contain flags, it is really up to the programmer to realize each special case, where operations on a single bit may cause problems. The compiler has no knowledge of such cases, since it does not know anything about operation of the hardware.

I think you're right, each time a problem occurs really close to hardware it is a good practice to look at disassembly of the code. The more compilers are complicated the more we lose sight of the hardware target we use .