Hi all
I'm in the process of changing one of our older products and in that process I'm planning to enable the watchdog. My problem is that I get a watchdog timeout when my program erase/write the flash
the erase and write routines looks like they are directly take from the HCS08 Family Reference Manual and looks like the following
FlashErase1:psha lda #(mFPVIOL+mFACCERR) ;mask sta FSTAT ;abort any command and clear errors lda #mPageErase ;$40 mask pattern for page erase command bsr DoOnStack ;finish command from ram-based sub ais #1 rts ;Z = 0 means there was an error;*********************************************************************DoOnStack: pshx pshh ;save pointer to flash psha ;save command on stack ldhx #SpSubEnd ;point at last byte to move to stackSpMoveLoop: lda ,x ;read from flash psha ;move onto stack aix #-1 ;next byte to move cphx #SpSub-1 ;past end? bne SpMoveLoop ;loop till whole sub on stack tsx ;tsx=stack på indexreg.point to sub on stack tpa ;move CCR to A for testing and #$08 ;check the I mask bne I_set ;skip if I already set sei ;block interrupts while FLASH busy lda SpSubSize+6,sp ;preload data for command jsr ,x ;execute the sub on the stack cli ;ok to clear I mask now bra I_cont ;continue to stack de-allocationI_set: lda SpSubSize+6,sp ;preload data for command jsr ,x ;execute the sub on the stackI_cont: ais #low(SpSubSize+3) ;deallocate sub body + H:X + command ;H:X flash pointer OK from SpSub lsla ;A=00 & Z=1 unless PVIOL or ACCERR rts ;to flash where DoOnStack was called ;*********************************************************************SpSub: ldhx low(SpSubSize+4),sp ;get flash address from stack sta 0,x ;write to flash; latch addr and data lda SpSubSize+3,sp ;get flash command sta FCMD ;write the flash command lda #mFCBEF ;mask to initiate command sta FSTAT ;[pwpp] register command nop ;[p] want min 4~ from w cycle to rChkDone: lda FSTAT ;[prpp] so FCCF is valid lsla ;FCCF now in MSB bpl ChkDone ;loop if FCCF = 0SpSubEnd: rts SpSubSize equ *- (SpSub) ;back into DoOnStack in flash ;*********************************************************************FlashProg1: psha ;temporarily save entry data lda #(mFPVIOL+mFACCERR) ;mask sta FSTAT ;abort any command and clear errors lda #mByteProg ;mask pattern for byte prog command bsr DoOnStack ;execute prog code from stack RAM ais #1 ;deallocate data location from stack rts ;Z = 0 means there was an error;*********************************************************************
so my problem is where do I "feed the dog" in this routine so it dont timeout (it need to be feed every 23ms) I guess it needs to be in the subroutine that run in the RAM but I can't really figure out where
hope someone of you can help
best regards
Mikkel
已解决! 转到解答。
SpSub: ldhx low(SpSubSize+4),sp ;get flash address from stack
sta 0,x ;write to flash; latch addr and data
lda SpSubSize+3,sp ;get flash command
sta FCMD ;write the flash command
lda #mFCBEF ;mask to initiate command
sta FSTAT ;[pwpp] register command
nop ;[p] want min 4~ from w cycle to r
ChkDone: lda FSTAT ;[prpp] so FCCF is valid
lsla ;FCCF now in MSB
<<<<<<<<<<<<<<<<<<<<<<<< feed the dog here
bpl ChkDone ;loop if FCCF = 0
SpSubEnd: rts
SpSub: ldhx low(SpSubSize+4),sp ;get flash address from stack
sta 0,x ;write to flash; latch addr and data
lda SpSubSize+3,sp ;get flash command
sta FCMD ;write the flash command
lda #mFCBEF ;mask to initiate command
sta FSTAT ;[pwpp] register command
nop ;[p] want min 4~ from w cycle to r
ChkDone: lda FSTAT ;[prpp] so FCCF is valid
lsla ;FCCF now in MSB
<<<<<<<<<<<<<<<<<<<<<<<< feed the dog here
bpl ChkDone ;loop if FCCF = 0
SpSubEnd: rts
So if you do that like this if there is a probleme with the erase (FCCF never come to '1'). The programm is blocked here.
For software who need a high level of security it's not good.
Somebody has a solution to solve this problem ?
Hello, and welcome to the forum.
It is possible that the COP timer reset process may affect the MCU flags, particularly the Z and N flags. A more suitable position for this code would be immediately following the ChkDone: label. You can then also remove the NOP padding instruction just prior to the label.
As Kef suggests, it is also wise to test the FSTAT register for either of the error flags set, in addtion to the FCCF flag, and exit the loop should any of these flags become set. In fact this seems to be required by the device datasheet / reference manual. The test can be done with a single AND #$70 instruction in lieu of the LSLA. Looping would exit when the result becomes non-zero.
I also notice that the issue of globally disabling interrupts has not been covered by the code. The interrupt vectors also become inaccessible during flash erase and programming. This should be done within the code that calls the 'DoOnStack' routine.
I have used the following RAM based C function to do a similar thing, in a slightly different context. This is the only code that needs to be RAM resident.
void flash_cmd( void)
{
FSTAT = 0x80; // Clear FCBEF bit - activate command
do {
__RESET_WATCHDOG();
} while ((FSTAT & 0x70) == 0); // Wait for command completion or error
}
Regards,
Mac
Mac,
ACCERR and PVIOL in every decent implementation of flash routines are checked before issuing flash command and executing above mentioned doonstack routine. Even if you ignore it, FCCF will stay set.
I took this as something happens like controller gets damaged or doesn't resist nice EMI burst, so that FCCF never comes to 1. If this happens, then checking error bits in a loop most likely won't help. Defensive programming requires timeout for every wait for something loop, especially when this something is external event. I think COP should be reset only in the main application loop or in the lowest prioroty task. Long routine / process, one may have, doesn't justify resetting COP in 2nd place.
Hello Kef,
The issue that I see is that the ACCERR or PVIOL flag may become set during the execution of the flash command, under circumstances where the FCCF bit may not become set. Hence the additional exit conditions for the loop. I seem to recall that this aspect is addressed in the datasheet flow diagrams.
The other issue is that the sector erase period may exceed the COP timeout period, and I assumed that this was the reason for the original query. Clearing the COP timer from outside the loop won't help when this is the case.
Regards,
Mac
Mac,
No, FCCF indicates where flash command is being executed or not. FCCF always is set after command completes, or if command was ignored due to errors.
I looked into S08D, S08GB, and S12C datasheets. All flash diagrams are looping checking only FCCF flag.
Yes, 20ms erase time can be longer than you want for COP timeout. I meant that resetting COP in flash routine is as bad as waiting until FCCF becomes set.
Hello Kef,
kef wrote:
I looked into S08D, S08GB, and S12C datasheets. All flash diagrams are looping checking only FCCF flag.
The flowcharts for the S08 (Fig. 4.2) actually show a separate 'error exit' from the loop, in addition to the normal exit when FCCF becomes set.
I do not know whether you are correct about FCCF also becoming set after an error occurs, but to conform with the datasheet, the error flags should also be tested within the loop. Of course there is no reason why all three flags should not be simultaneously tested, and the error state then separately determined after exit from the loop has occurred.
A minor point - the page erase period may actually extend to about 26 milliseconds at the lower limit of the flash clock frequency (4000 cycles at 150kHz).
Regards,
Mac
I don't know what derivative you are talking about, but all diagrams I saw clearly show only one loop, which is only waiting for FCCF=1. Loop is not entered if eroors occur after or before launching the flash command.
Hello Kef,
I checked the datasheets for the 'QG8, 'SE8 and 'GB60. Fig. 4.2 appears similar for all of them, and is a flow chart showing the erase and programming sequences. Following the launching of the flash command, I see a single wait loop with two exits - an error exit and a normal exit.
Regards,
Mac
Hello Kef,
Agreed that the testing of the error flags, and the error exit, are not part of the wait loop. But it appears these flags still need to be tested after the command is launched (delayed by a few cycles). Actually, in the interests of code size minimisation, it should not matter if the error flags were tested within the wait loop, as I was proposing.
The SpSub routine in the original code snippet did not provide the error flag test afer the command was launched.
Regards,
Mac
Hello,
Subsequent to my previous post, I found that a few devices do not specify the requirement for an error flag check immediately after starting the flash command. After reviewing the Reference manual for quite a few different devices, I found the following exceptions.
AC128, AC60 (but not AC16):
Error check not required for byte programming and sector erase, but still required for burst programming.
DN/DV/DZ series, EL32/SL16:
Error check not required for sector erase, but required for byte or burst programming.
MM128, QE128 only, JE128, and SC4:
No error check required.
All other devices examined specifically required the error check for sector erase, byte program and burst program operations.
I cannot see that there would be any disadvantage in checking the error flags, either prior to or within the wait loop, even if not specifically required. This would make the code more derivative independent.
Interestingly, many of the devices not specifically requiring the error flag test, also have paged flash memory and a MMU module. These must necessarily be coded differently anyway, to make use of the LAP registers, in order to be able to program any flash byte.
Regards,
Mac
Hello,
Thanks for your answer.
Someting like that could be a solution ?
LDHX #$FFFF ;load count value to reset WD
ChkDone: lda FSTAT ;[prpp] so FCCF is valid
lsla ;FCCF now in MSB
AIX #-1
CPHX #0
BEQ NoEraseWD ;if 0 no reset WD
LDA #85 ;for have any Watchdog during erease
STA SRS ;Clear WatchDog counter - first part
LDA #170
STA SRS ;Clear WatchDog counter - second part
NoEraseWD:
bpl ChkDone ;loop if FCCF = 0
SpSubEnd: rts
Hello,
I can see two problems with your proposed code -
The following code is intended to correct these deficiencies. While COP processing occurs, the total loop period will be 29 cycles. This means that COP processing will cease after approximately 1900000 cycles (i.e. 190 milliseconds for 10MHz bus frequency). This compares with a sector erase period of about 25 milliseconds
... LDHX #$FFFFChkDone: CPHX #0 BEQ SkipWD AIX #-1 ; Clear COP timer LDA #$55 STA SRS LDA #$AA STA SRSSkipWD: LDA FSTAT AND #$70 ; Test for command complete or error BEQ ChkDone ; Loop if not RTS
Regards,
Mac
That's another story. Yes, if flash controller hangs, your code will hang there too. To handle flash controller failure, you need to provide your own timeout mechanism, like for every other condition, which you are waiting for and which may never occur.