Hello all,
I'm attempting to program an EEPROM word in the MC9S12A32. If I erase the sector that the word is in, then program the word, and check it immediately, I am able to read back the value correctly.
However, if I then power-down and simply try to read back the value, it no longer matches. Instead, it's back to $FFFF.
Here is some pertinent information:
Oscillator = 4MHz
ECLKDIV = $18 (correctly reads $98 after $18 is written)
INITEE = $21 (to move 2K worth of EEPROM to $2000 - $27FF)
ECNFG = default reset value
Here are some snippets of code:
LDX #CALDONE
JSR ERASEE
LDAA #$66
JSR PROGEE
LDD CALDONE (D contains $6600 after PROGEE, but not after power-down)
---
ERASEE
BSET EPROT, $80 ;DISABLE EEPROM PROTECTION
MOVB #$30, ESTAT ;CLEAR ERROR FLAGS
ECHECKCBEIF
BRCLR ESTAT, $80, ECHECKCBEIF ;WAIT FOR BUFFERS TO BE EMPTY
STD 0, X ;WRITE ANY DATA TO EEPROM FOR ERASE
MOVB #$40, ECMD ;PUT ERASE COMMAND IN COMMAND REG
MOVB #$80, ESTAT ;SET CBEIF TO LAUNCH COMMAND
BRSET ESTAT, #$30, ERASEE ;COMMAND FAILED IF EITHER BIT IS SET
ECHECKCCIF
BRCLR ESTAT, #$40, ECHECKCCIF ;WAIT FOR COMMAND TO FINISH
BCLR EPROT, $80 ;ENABLE EEPROM PROTECTION
RTS
---
PROGEE
BSET EPROT, $80 ;DISABLE EEPROM PROTECTION
MOVB #$30, ESTAT ;CLEAR ERROR FLAGS
PCHECKCBEIF
BRCLR ESTAT, $80, PCHECKCBEIF ;WAIT FOR BUFFERS TO BE EMPTY
LDAB #$00 ;WRITE '00' AS 2ND BYTE OF WORD
STD 0, X ;WRITE WORD TO EEPROM
MOVB #$20, ECMD ;PUT PROGRAM COMMAND IN COMMAND REG
MOVB #$80, ESTAT ;SET CBEIF TO LAUNCH COMMAND
BRSET ESTAT, #$30, PROGEE ;COMMAND FAILED IF EITHER BIT IS SET
PCHECKCCIF
BRCLR ESTAT, #$40, PCHECKCCIF ;WAIT FOR COMMAND TO FINISH
BCLR EPROT, $80 ;ENABLE EEPROM PROTECTION
RTS
---
Another strange occurrence is that if I try to read back ESTAT, it shows $C1, which is strange because the LSB should be $0 according to the EEPROM User Guide.
Can anyone offer some pointers on where to look to see why the data isn't surviving power-down? I *think* I have the ECLKDIV setup properly, but if it's not, that could lead to the programming failing and maybe I'm reading back a shadowed RAM value before power-down??
Thanks in advance.
Drew
I see you are toggling EPOPEN bit on and off. Quote from S12EETS1KV1 for S12D64 (A32 EEPROM block should be very similar):
"The EPOPEN and EPDIS bits in the EPROT register can only be written to the protected state (i.e. 0)."
So after you cleared EPOPEN in erase routine, your program routine has no chances to succeed.
Please don't use bit constants in your code. Don't know how others, but I may be too lazy next time and won't check in the docs what $80 means. You can use bit mask defines from Codewarrior MC9S12A32.INC file. mEPROT_EPOPEN stands for $80 bit mask. It is bad C headers use different names, but all bit mask still are available, like EPROT_EPOPEN_MASK.
Thanks for the reply, Kef. That looks like exactly what I was looking for.
Also, thanks for the advice on the bit constants in the code. This was written by another employee and I've been left with the task of porting it to the HC12 family, but I think your suggestion is worth applying to future code. I'm new to Freescale, CodeWarrior, and the HC11/12, and appreciate the help.
Thanks again.
Drew
OK, I've corrected the problem Kef pointed out by removing the writes to EPOPEN and EPDIS, but I still have the same problem: the data that is programmed reads back correctly until power-down, after which it always reads back $FFFF.
So, here's the updated code snippets:
LDX #CALDONE
JSR ERASEE
LDAA #$66
JSR PROGEE
LDD CALDONE
---
PROGEE
MOVB #$30, ESTAT ;CLEAR ERROR FLAGS
PCHECKCBEIF
BRCLR ESTAT, $80, PCHECKCBEIF ;WAIT FOR BUFFERS TO BE EMPTY
LDAB #$00 ;WRITE '00' AS 2ND BYTE OF WORD
STD 0, X ;WRITE WORD TO EEPROM
MOVB #$20, ECMD ;PUT PROGRAM COMMAND IN COMMAND REG
MOVB #$80, ESTAT ;SET CBEIF TO LAUNCH COMMAND
BRSET ESTAT, #$30, PROGEE ;COMMAND FAILED IF EITHER BIT IS SET
PCHECKCCIF
BRCLR ESTAT, #$40, PCHECKCCIF ;WAIT FOR COMMAND TO FINISH
RTS
---
ERASEE
MOVB #$30, ESTAT ;CLEAR ERROR FLAGS
ECHECKCBEIF
BRCLR ESTAT, $80, ECHECKCBEIF ;WAIT FOR BUFFERS TO BE EMPTY
STD 0, X ;WRITE ANY DATA TO EEPROM FOR ERASE
MOVB #$40, ECMD ;PUT ERASE COMMAND IN COMMAND REG
MOVB #$80, ESTAT ;SET CBEIF TO LAUNCH COMMAND
BRSET ESTAT, #$30, ERASEE ;COMMAND FAILED IF EITHER BIT IS SET
ECHECKCCIF
BRCLR ESTAT, #$40, ECHECKCCIF ;WAIT FOR COMMAND TO FINISH
RTS
---
Any other ideas on why the writes to EEPROM won't "survive" power-down? The other pertinent information is still the same as before:
Oscillator = 4MHz
ECLKDIV = $18 (correctly reads $98 after $18 is written)
INITEE = $21 (to move 2K worth of EEPROM to $2000 - $27FF)
ECNFG = default reset value
Thanks.
Drew
OK, I was able to determine the cause of the problem: the EEPROM was being erased when the device was re-programmed with the code to check the contents of EEPROM. I hadn't considered that the EEPROM would be automatically erased during the code re-programming process. The problem is obvious now, but it looked like the data was being "lost" after power-down, when it was actually being erased.
I've seen threads in this forum that discuss AEFSKIPERASING and its use in either the startup.cmd or preload.cmd files. I have a question there now, but I'll move it to a new thread.
Drew
For D64 (should be the same for A32) I added
FLASH AEFSKIPERASING 0
line to this file
\cmd\P&E_Multilink_CyclonePro_Startup.cmd
It should be present in your project folders tree. Command is available only using P&E Multilink BDM connections.