MCf51ac128 FLASH sector erase problem.

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

MCf51ac128 FLASH sector erase problem.

1,467 Views
Tom_too
Contributor I
;
;I am working on a small subsystem using the MCF51ac128 chip.
;I have not been able to get the SECTOR ERASE flash command to work.
;CAN ANYONE HELP?
;
;I am running a 20megaHz Bus clock from the PLL
;so I have set the FCDIV register as part of the powerup sequence. 
;20,000,000/8/16 = 156,250Hz.
;
                 MOVE.B  #%01001111,D0    ;the FDIVLD bit sets itself automatically
                 MOVE.B  D0,(FCDIV).L     ;set FLASH clock to an acceptable frequency.
;
;Location 40D, the NVPROT non-volatile register that is copied by silicone
;to the FPROT register on reset, is set in the exec so that there should be no
;FLASHprotected at all:
;
INIT_NVPROT:     DB %11111111             ;40D will be copied to FPROT
;
;I have dumped FCDIV and FPROT and verified that they are correct.
;
;
;The followig subrutine is copied into RAM and executed in an attempt
;to erase the 1K sector at address $1FC00.
;
;Writing a one to the FCBEF bit in FSTAT resets the CPU immediately everytime
;for the sector erase command ($40), and the sector is not erased.
;The exec is burned with each long in the sector at $1FC00 set to $12345678,
;it is not erased to $FFFFFFFF, it is not even changed at all.
;
;NOTE: I tried an erase verify command (5) just to see what wuld happen,
;it did not reset the CPU, and the routine executed to completion.
;
;I have followed the instructions in Chapter 4 and I can't find any other
;documentation on the subject of FLASH for the MCF51ac128/256.
;
SECTOR_ERASE_RAM:
                 MOVE.W   #$2700,SR        ;lock out interrupts
 
                 MOVEA.L  #FSTAT,A6
                 MOVEA.L  #FCMD,A5
                 MOVE.L   #$1FC00,A0       ;addr of sector to erase in A0
 
;;;;                 MOVE.L  #$5,D1             ;erase Verify command.
                 MOVE.L  #$40,D1            ;40hex Sector Erase command.
                 MOVE.B  #$30,(A6)         ;write ones to clear the error bits if any.
                 MOVE.L  #$FFFFFFFF,(A0)   ;write a LONG to the address passed in A0
                 MOVE.B  D1,(A5)           ;write the FLASH command into FCMD register.
   ;The following instruction resets the CPU.
                 MOVE.B  #$80,(A6)         ;write one to FCBEF bit to "launch" command.
   ;It never gets here.
                 MOVE.L  #50,D0            ;;;
TIME_WASTING_LOOP:                         ;
                 NOP                       ;Give the FLASH controller some time
                 SUBQ.L  #1,D0             ;to get going before checking FSTAT.
                 BGT.B   TIME_WASTING_LOOP ;;;
FLASH_CMD_WAIT:
                 MOVE.B  D0,(SRS).L        ;KICK the COP it is defaulted to .512sec.
                 MOVE.B  (A6),D0           ;check FLASH status register
                 ANDI.L  #$40,D0           ;test the FCCF bit
                 BEQ.B   FLASH_CMD_WAIT    ;Wait Loop until the command completes.
                 MOVE.W  #$2000,SR         ;reenable interrupts
                 CMP.L   #$5,D1            ;If the command was verify, report result
                 BEQ.B   TST_FBLANK
                 RTS
TST_FBLANK:                                    ;;;
                 MOVE.B  (A6),D0               ;get the FSTAT register
                 ANDI.L  #$4,D0                ;Strip off the FBLANK bit
                 BEQ.B   NOT_ERASED            ;if FBLANK=0, FLASH array is not erased.
ERASED:          MOVEA.L #ERASED_MSG,A0        ;
                 BRA.B   REPORT_FBLANK         ;
NOT_ERASED:                                    ;
                 MOVEA.L #NOT_ERASED_MSG,A0    ;
REPORT_FBLANK:                                 ;
                 JSR     (SEND_MESSAGE_NOW).L  ;;;
                 RTS                          

NOT_ERASED_MSG:  DB "NOT "
ERASED_MSG:      DB "ERASED",CR,0
 
;Hopefully if I can get a sector erased I will be able to program it.
 
thanks,
Tom_too


Message Edited by Tom_too on 2009-01-22 07:36 PM
Labels (1)
0 Kudos
2 Replies

455 Views
Tom_too
Contributor I
The manual says something about running commands from protected flash,
so I've tried runnning this from protected FLASH as well as RAM.  I have
tried erasing unprotected FLASH, and also securing and then Unsecuring
with the "backdoor" key.  Nothing works.
 
The only indication that a FLASH controller exists in the silicon is that
when I protect the flash sector to be erased, this will execute to completion
and the privelidge violation bit will be set.
Any other situation produces a reset interrupt immediately when the
erase command is "launched".
 
The hardware information register (table 7-11) shows "CF100029".
Indicating Cold Fire V1 revision zero.
Is there a more recent revision of the MCF51ac128 silicon since rev zero?
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
                 align.w
ERASE_FLASH:
                 MOVE.W  #$2700,SR              ;lock out interrupts
FLASH_BUSY:
                 MOVE.B  (FSTAT).L,D0           ;check FLASH status register
                 BTST.L   #7,D0                         ;check command buffer empty bit
                 BEQ.W   FLASH_BUSY           ;0=busy, 1=ready for a new command
 
                 MOVE.B  #$30,D0
                 MOVE.B  D0,(FSTAT).L           ;write ones to clear the error bits if any.
 
                 MOVE.L  #$FFFFFFFF,D0                                            ;write a LONG to the
                 MOVE.L  D0,(FLASH_CONFIGURATION_DATA).L ;address of sector to erase
 
                 MOVE.B  #$40,D0                   ;40hex is the "SECTOR ERASE" command
                 MOVE.B  D0,(FCMD).L           ;write command into the FLASH command register.
                    
                 MOVE.B  #$80,D0
                 MOVE.B  D0,(FSTAT).L           ;write a one to the FCBEF bit in the
                                                                    ;FLASH status register to "launch" the command.
                 NOP
                 NOP
                 NOP
                 NOP
                 NOP
FLASH_CMD_WAIT:
                 MOVE.B  D0,(SRS).L                 ;KICK the COP it defaults to .512 seconds
                 MOVE.B  (FSTAT).L,D0             ;check FLASH status register
                 ANDI.L     #$40,D0                      ;test the FCCF bit in the FLASH status register
                 BEQ.B    FLASH_CMD_WAIT
                 RTS
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Please help,
Tom _too
0 Kudos

455 Views
Tom_too
Contributor I
I managed to erase a sector of FLASH!
(I was not particularly surprised to find that erased 2K bytes instead
of the 1K Bytes described in the manual).
I'm still not sure exactly what made it start to work, but for the  benefit of any one else using the MCF51ac128, here's what I did:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;This part of the erase sector is executed in FLASH.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
                 align.w
ERASE_FLASH_SECTOR:
FLASH_BUSY:
                 MOVE.B  (FSTAT).L,D0          ;check FLASH status register
                 BTST.L  #7,D0                        ;check command buffer empty bit
                 BEQ.W   FLASH_BUSY         ;0=busy, 1=ready for a new command.
                 JSR     (COPY_CMD_LAUNCHER_TO_RAM).L
            
                 MOVE.W  #$2700,SR             ;lock out interrupts
                 MOVE.B  #$30,D0            
                 MOVE.B  D0,(FSTAT).L          ;write ones to clear the error bits if any.
                 MOVE.L  #$FFFFFFFF,D0                                        ;write a LONG to the
                 MOVE.L  D0,(FLASH_CONFIGURATION_DATA).L ;address of sector to erase
 
                 MOVE.B  #$40,D0                                         ;40hex i "SECTOR ERASE" command                  
                 JSR     (CMD_LAUNCHER_IN_RAM).L         ;Launch the command from RAM.
                 MOVE.W  #$2000,SR                                   ;re-enable interrupts
                 MOVE.B  (FSTAT).L,D0                                ; FLASH status register
                 RTS
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;This section of code is copied to RAM and executed in RAM as a subroutine.
;
;INPUTS: The FLASH command code byte is passed to this subroutine in D0
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
                 align.w
FLASH_LUANCH_CMD:
                 MOVE.B  D0,(FCMD).L          ;write the FLASH command into the FLASH command register.
                    
                 MOVE.B  #$80,D0                  ;write a one to the FCBEF bit in the FLASH status register
                 MOVE.B  D0,(FSTAT).L         ;to "launch" the command.
                 NOP
                 NOP
RAM_FLASH_CMD_WAIT:
                 MOVE.B  D0,(SRS).L             ;KICK the COP it defaults to .512 seconds on reset
 
                 MOVE.B  (FSTAT).L,D0
                 ANDI.L  #$30,D0                     ;If there was an error return immediately
                 BNE.B   RAM_RETURN
                 MOVE.B  (FSTAT).L,D0         ;check FLASH status register
                 ANDI.L  #$40,D0                    ;test the FCCF bit in the FLASH status register
                 BEQ.B   RAM_FLASH_CMD_WAIT
RAM_RETURN:
                 RTS                                        ;return when its done.
0 Kudos