*************************************************************
* ERASE subroutine                                         **
*                                                          **
* TMS320F2XX Flash Utilities.                              **
* Revision: 2.0, 9/10/97                                   **
*                                                          **
* Filename: ERA24_X1.ASM				   **
* Changes: Re-written to include latest flash algorithms.  **
*                                                          **
*                DSP Applications                          **
*                Texas Instruments Inc.                    **
*                                                          **
* Called by : c2xx_bex.asm or flash application programs.  **
*                                                          **
* !!CAUTION - INITIALIZE DP BEFORE CALLING THIS ROUTINE!!  **
*                                                          **
* Function  : Erases one or more contiguos segments of     **
*             flash array 0/1 as specified by the          **
*             following variables.                         **
*             SEG_ST = Segment start address.              **
*             SEG_END= Segment end address.                **
*             PROTECT= Sector protect enable.              **
*                                                           *
* The algorithm used is "XOR-VER1" which means that in      *
* addition to the VER1 readmode, an XOR readback is used to *
* gain more margin. During the read portion of the erase to *
* reads are performed for each address; for the first read  *
* all address bits are complemented using a logical XOR with*
* the array end address. The data read during the first read*
* is discarded and the second read is performed on the      *
* actual address. This scheme simulates the worst-case      *
* branching condition for code executing from the flash     *
* array.                                                    *
* The erase pulse-width is 7ms, and a maximum of 1000 pulses*
* are applied to the array.                                 *
*                                                           *
* The following resources are used for temporary storage:   *
*        AR0  - Used for comparisons.                       *
*        AR1  - Used for erase pulse count.                 *
*        AR2  - Used for main banz loop.                    *
*        AR6  - Parameter passsed to DELAY.                 *
*        B2_0 - Parameter passed to Set_mode.               *
*        B2_1 - Used for flash address.                     *
*        B2_2 - Used for flash data.                        *
*        B2_3 - Used for flash checksum.                    *
*        B2_4 - Used for segment size.                      *
*        B2_5 -                                             *
*        B2_6 -                                             *
*************************************************************
	.include "svar2x.h" ;defines variables for flash0
*
MAX_ER  .set    1000       ;Only allow 1000 erase pulses.
VER1    .set    8          ;VER1 command.
ER_CMND .set    2          ;ERASE COMMAND WORD
ER_EXE  .set    043h       ;ERASE EXEBIN COMMAND WORD
INV_ER  .set    018h       ;INVERSE ERASE COMMAND WORD
FL_WR   .set    6          ;FLASH WRITE COMMAND WORD
FLWR_EX .set    047h       ;FLASH WRITE EXEBIN COMMAND WORD
STOP    .set    0          ;RESET REGISTER COMMAND WORD

	.def	ERASE
;	.ref	PROTECT, SEG_ST,SEG_END
;	.ref	DELAY,REGS,ARRAY

************************************************************
* Code initialization section				   *
* Initialize test loop counters:			   *
*   AR1 is the number of ERASE pulses.                     *
************************************************************
       .sect	".alg"

;GERS:	 SPLK	 #0,IMR 	 ;MASK ALL INTERRUPTS
;	SETC	INTM		;GLOBAL MASK OF INTERRUPTS

ERASE:	LACL	SEG_ST		;Get segment start address.
        AND     #04000h         ;Get array start address.
        SACL    FL_ST           ;Save array start address.
        OR      #03FFFh         ;Get array end address.
        SACL    FL_END          ;Save array end address.

        SPLK    #0,ERROR        ;Reset error flag
        LAR     AR1,#0          ;SET ERASE COUNT = 0
FIRST_SEG
        CALL    XOR_ERASE       ;ERASE FLASH SEGMENT
        CALL    INV_ERASE       ;Check for depletion.
NEXT_SEG
        RET                     ;Return to calling code.

* If here, then an error has occured.
EXIT    SPLK    #1,ERROR                ;Update error flag
        CALL    CLR_CMND                ;Disable any flash cmds.

;	IN	DUMMY, F24X_ACCS	;(DAF)
	CALL	ARRAY			;ACCESS FLASH ARRAY
	RET
;	B	NEXT_SEG		;Get outa here.


;	.page
************************************************
* XOR_ERASE: This routine performs an erase to *
* xorver1 level. The Seg to erase is defined by*
* the vars SEG_ST and SEG_END. The following   *
* resources are used for temporary storage:    *
*        AR0  - Used for comparisons.          *
*        AR1  - Used for erase pulse count.    *
*        AR2  - Used for main banz loop.       *
*        B2_0 - Parameter passed to Set_mode.  *
*        B2_1 - Used for flash address.        *
*        B2_2 - Used for flash data.           *
*        B2_3 - Used for flash checksum.       *
*        B2_4 - Used for segment size.         *
************************************************
XOR_ERASE
* COMPUTE CHKSUM ON FLASH1 TO SEE IF ERASED
        CALL    CLR_CMND                ;Disable any flash cmds.
        SPLK    #VER1,B2_0
        CALL    SET_MODE                ;Set VER1 mode.
        SETC    SXM                     ;Enable sign extension.                     
        CLRC    OVM                     ;Disable overflow mode.
        LACC    SEG_END
        SUB     SEG_ST
        SACL    B2_4                    ;Segment length-1.
        LAR     AR2,B2_4                ;load n-1 to loop n times.
        ADD     #1
        SACL    B2_4                    ;Segment length.
        MAR     *,AR2
        BLDD    #SEG_ST,B2_1            ;Segment start address.
        SPLK    #0,B2_3                 ;Clear checksum.
RD1_LOOP                                ;For I = SEG_ST to SEG_END.
        LACC    B2_1                    ;ACC => CURRENT ADDR.
        XOR     FL_END                  ;XOR addr with flash end addr.
        TBLR    B2_2                    ;Dummy Read.
        LACC    B2_1                    ;Get actual addr again.
        TBLR    B2_2                    ;True Read.
        ADD     #1                      ;Increment flash addr.
        SACL    B2_1                    ;Store for next read.
        LACC    B2_3                    ;Get old check sum.
        ADD     B2_2                    ;ACC=>ACC+FL_DATA.
        SACL    B2_3                    ;Save new check sum.
        BANZ    RD1_LOOP,*-
        ADD     B2_4                    ;Should make ACC=0 for erased array.
        BCND    XOR_ERFIN,EQ            ;If B2_3=0 finished.
                
* IF NOT ERASED, PERFORM A FLASH ERASE
        CALL    ERASE_A                 ;Else, pulse it again.
        CALL    INC_ERASE,AR1           ;Inc erase pulse count(AR1).
        B       XOR_ERASE               ;Check again.
XOR_ERFIN
        CALL    CLR_CMND                ;Clear SEG_CTR and Return.
        RET

*************************************************
* INC_ERASE: This routine increments the erase  *
* pulse count and checks against max. The count *
* is passed in AR1, and AR0 is used to check it.*          
*************************************************
INC_ERASE
        MAR     *+                      ;Increment Erase count.
        LAR     AR0,#MAX_ER
        CMPR    2                       ;If AR1>MAX_ER then
        BCND    EXIT,TC                 ;fail, don't continue erasing.
        RET                             ;else return.

*************************************************
* SET_MODE: This routine sets the flash in the  *
* mode specified by the contents of B2_0. This  *
* cam be used for VER0,VER1,AND INVERASE.       *
*************************************************
SET_MODE

;	OUT	DUMMY, F24X_ACCS	;(DAF)
	CALL	REGS		;ACCESS FLASH REGS

        LACL    FL_ST           ;ACC => SEG_CTR.
        TBLW    B2_0            ;Activate MODE.
	RPT	DLY10		;(DAF)
	NOP
;	LAR	AR6,#D10	;SET DELAY
;	CALL	DELAY,*,AR6	;WAIT			  *

;	IN	DUMMY, F24X_ACCS	;(DAF)
	CALL	ARRAY		;ACCESS FLASH ARRAY	  *

	RET


************************************************
* INV_ERASE: This routine is used to check for *
* depletion in the flash array.                *
*        AR2  - Used for main banz loop.       *
*        B2_0 - Parameter passed to Set_mode.  *
*        B2_1 - Used for flash address.        *
*        B2_2 - Used for flash data.           *
************************************************
INV_ERASE
        SPLK    #INV_ER,B2_0
        CALL    SET_MODE        ;Set inverse-erase mode.
        BLDD    #FL_ST,B2_1     ;Array start address.
        LAR     AR2,#31         ;Loop count.
        MAR     *,AR2
NEXT_IVERS
        LACL    B2_1            ;Get address.
        TBLR    B2_2            ;Dummy read.
        TBLR    B2_2            ;Read data.
        ADD     #1              ;Increment address.
        SACL    B2_1            ;Save address.
        ZAC
        ADD     B2_2            ;Add data.
        BCND    EXIT, NEQ       ;If ACC<>0, then fail.
*Else continue, until until done with row.
        BANZ    NEXT_IVERS      ;Loop 32 times.
        CALL    CLR_CMND        ;Disable flash commands.
        RET                     ;If here then test passed.
        .page
************RDP***************


ERASE_A
* SETUP FLASH ERASE COMMANDS FOR PROTECT MASK DEFINED IN  **
* LINK COMMAND FILE.					  **
        LACL    PROTECT         ;GET SEGMENT PROTECT MASK **
        OR      #ER_CMND        ;OR IN ERASE COMMAND      **
	SACL	B2_5		;B2_5 = ERASE COMMAND	  **
        OR      #ER_EXE         ;OR IN EXEBIN COMMAND     **
	SACL	B2_6		;B2_6 = ERASE EXE COMMAND **

* MUST LOAD WDATA WITH FFFF AS DESCRIBED IN STEP xx IN	  **
* TABLE 9.						  **
	SPLK	#0FFFFh,B2_3	;WDATA VALUE FOR ERASE
        LACC    FL_ST           ;ACC => FLASH             **
	TBLW	B2_3		;SET WDATA = FFFF	   *

* THIS SECTION ACTIVATES THE WRITE COMMAND AS DESCRIBED
* IN STEPS xx/xx IN TABLE 9.
	CALL	CLR_CMND	;CLEAR EXISTING CONDITION

;	OUT	DUMMY, F24X_ACCS	;(DAF)
	CALL	REGS		;ACCESS FLASH REGS
	LACC	FL_ST		;ACC => FLASH
	TBLW	B2_5		;ACTIVATE ERASE
	RPT	DLY10		;(DAF)
	NOP
;	LAR	AR6,#D10	;SET DELAY
;	CALL	DELAY,*,AR6	;WAIT

; THIS SECTION ACTIVATES THE EXEBIN COMMAND AS DESCRIBED
; IN STEPS xx/xx IN TABLE 9.
	TBLW	B2_6		;START ERASURE
	RPT	DLY3K3		;(DAF) 3.3mS delay
	NOP
	RPT	DLY3K3		;(DAF) 3.3mS delay
	NOP
;	LAR	AR6,#D7K	;SET DELAY to 7ms
;	CALL	DELAY,*,AR6	;WAIT
	CALL	CLR_CMND	;DEACTIVATE COMMAND
	RET			;RETURN TO CALLING SEQUENCE

CLR_CMND
; THIS SECTION DE-ACTIVATES ERASE OPERATION AS DESCRIBED  **
; IN STEPS xx/xx IN TABLE 9.				  **
	

;	OUT	DUMMY, F24X_ACCS	;(DAF)
	CALL	REGS		;ACCESS FLASH REGISTERS   **
        LACC    FL_ST
	SPLK	#0,B2_0 	;STOP ERASE COMMAND	  **
	TBLW	B2_0		;STOP ERASURE		  **
	TBLW	B2_0		;STOP ERASURE AGAIN	  **
	RPT	DLY10		;(DAF)
	NOP
;	LAR	AR6,#D10	;SET DELAY		  **
;	CALL	DELAY,*,AR6	;WAIT			  **


;	IN	DUMMY, F24X_ACCS	;(DAF)
	CALL	ARRAY		;ACCESS FLASH ARRAY	  **
	RET		;RETURN TO CALLING SEQUENCE	  **

ARRAY:	IN	DUMMY, F24X_ACCS
;	LDP	#0E0H
;	SPLK	#0,7018H
;	LDP	#6
	RET

REGS:	OUT	DUMMY, F24X_ACCS
;	LDP	#0E0H
;	SPLK	#0800H,7018H
;	LDP	#6
	RET

	.end
