flash.asm

来自「基于dsp的flash驱动程序」· 汇编 代码 · 共 338 行

ASM
338
字号
*********************************************************************************
*  MEMORY.ASM	v1.00								                            *
*  版权(c) 	2003-		北京合众达电子技术有限责任公司			                *
*  设计者:	段立锋								                                *
*********************************************************************************
		.file	"flash.asm"
		.c_mode
		.mmregs
		

		.copy	"vc5402.inc"	; VC5402 Memory-Mapped	Register Declaration
		.copy   "flash.inc" ; SEED DEC5416 Memory-Mapped Register Declaration
                       
		.def	_flash_erase
		.def	_flash_writes
		.def	_flash_writem
		.def	_flash_reads
		.def	_flash_readm
		
		.text

*********************************************************************************
*	FLASH的操作																	*
*********************************************************************************
*********************************************************************************
*																				*
* 函数定义:uint _flash_erase(uint addr, uint type)		   						*
* 功    能:Flash扇区/块/整片擦除操作											*
*																				*
* 入口参数:A	  ---- 地址addr													*
*		       扇区擦除:Amsb~A11,每个扇区2K   								*
*		       块擦除  :Amsb~A15,每个块32K									*
*		       整片擦除:5555H													*
*		       Amsb:	A16,Flash用SST39VF200时								*
*		       			A17,Flash用SST39VF400时(缺省)						*
*		      			A18,Flash用SST39VF800时								*
*		       Flash定位在程序储存空间0x4000000~401FFFFH                       *
*											   ~403FFFFH(缺省)   				*
*											   ~407FFFFH		                *
*		       地址addr为从0开始的偏移地址,而非Flash的绝对地址					*
*          	   (SP+n) ---- 操作类型type,如果是.far_mode模式则n为2,否则n为1	*
*		       扇区擦除:30H													*
*		       块擦除:  50H													*
*		       整片擦除:10H													*
* 出口参数:A	  ---- 擦除标志													*
*		       未擦干净:00H													*
*		       已擦干净:01H													*
* 资源使用:B,AR0																*
*																				*
*********************************************************************************
_flash_erase:	
				STM	 #SWWSR_VALI,SWWSR	           ; 配置软件等待寄存器
				STM	 #SWCR_VALI,SWCR
				STM	#Flash_base,AH
				PSHM	AL			; 保存地址
				STM	#Flash_5555,AL
				STM	#Flash_UL1,BL
				WRITA	*(BL)			; AAH -> (405555H)
				NOP
				NOP
				STM	#Flash_2AAA,AL
				STM	#Flash_UL2,BL
				WRITA	*(BL)			; 55H -> (402AAAH)
				NOP
				NOP
				STM	#Flash_5555,AL
				STM	#Flash_ERASE,BL
				WRITA	*(BL)			; 80H -> (405555H)
				NOP
				NOP
				STM	#Flash_5555,AL
				STM	#Flash_UL1,BL
				WRITA	*(BL)			; AAH -> (405555H)
				NOP
				NOP
				STM	#Flash_2AAA,AL
				STM	#Flash_UL2,BL
				WRITA	*(BL)			; 55H -> (82AAAH)
				NOP
				NOP
				STM	#Flash_5555,AL
				STM	#10H,BL
				WRITA	*(BL)			; 10H -> (82AAAH)
				NOP
				NOP
		
				POPM	AL			; 恢复地址
				.if	__far_mode
				WRITA	2H			; type -> (addr)
				.else
				WRITA	1H
				.endif
		
erase_poll:		READA	*(BL)
				BITF	*(BL),#Polling_Bit
				BC	erase_poll,NTC		; 查询擦除是否完成?
				
				STM	#00H,AH
				.if	__far_mode
				CMPM	2H,#Flash_SE
				BC	verify_SE,TC		; 扇区擦除时,转verify_SE
				CMPM	2H,#Flash_BE
				BC	verify_BE,TC		; 块擦除时,转verify_BE
				CMPM	2H,#Flash_CE
				BC	verify_CE,TC		; 整片擦除时,转verify_CE
				LD	#0,A			; 不是上述3种擦除操作,则置未擦除干净标志,返回
				FRET
				.else		
				CMPM	1H,#Flash_SE
				BC	verify_SE,TC		; 扇区擦除时,转verify_SE
				CMPM	1H,#Flash_BE
				BC	verify_BE,TC		; 块擦除时,转verify_BE
				CMPM	1H,#Flash_CE
				BC	verify_CE,TC		; 整片擦除时,转verify_CE
				LD	#0,A			; 不是上述3种擦除操作,则置未擦除干净标志,返回
				RET
				.endif
		
verify_SE:		SFTL	A,Flash_SBIT
				OR	#Flash_base,16,A		; A = 被擦除扇区的起始地址
				BD	verify_erase
				LD	#Flash_SSIZE,B		; B = 扇区大小
		
verify_BE:		SFTL	A,Flash_BBIT
				OR	#Flash_base,16,A		; A = 被擦除块的起始地址
				BD	verify_erase
				LD	#Flash_BSIZE,B		; B = 块大小

verify_CE:		LD	#Flash_base,16,A	; A = Flash起始地址
				LD	#Flash_CSIZE,4,B	; B = Flash大小

verify_erase:	READA	*(AR0)
				CMPM	*(AR0),#Flash_BLANK
				BCD	erase_end,NTC
				XC	1,NTC
				LD	#0,A			; 置未擦除干净标志
				ADD	#ONE,A
				SUB	#ONE,B
				BC	verify_erase,BNEQ
				LD	#1,A			; 置擦除干净标志,返回
erase_end:		.if	__far_mode
				FRET
				.else
				RET
				.endif
		
*********************************************************************************
*										*
* 函数定义:uint _flash_writes(ulong addr, uint data)		   		*
* 功    能:将数据data写入addr所指定的Flash单元					*
*										*
* 入口参数:A	  ---- 地址addr,Amsb~A0					*
*		       Amsb:	A16,Flash用SST39VF200时				*
*		       		A17,Flash用SST39VF400时(缺省)			*
*		      		A18,Flash用SST39VF800时				*
*		       Flash定位在程序储存空间80000H~9FFFFH/BFFFFH(缺省)/FFFFFH	*
*		       地址addr为从0开始的偏移地址,而非Flash的绝对地址		*
*          (SP+n) ---- 数据data,如果是.far_mode模式则n为2,否则n为1		*
* 出口参数:A	  ---- 写入标志							*
*		       未写入:00H						*
*		       已写入:01H						*
* 资源使用:B									*
*										*
*********************************************************************************
_flash_writes:	PSHM	AL
		PSHM	AH			; 保存地址
		STM	#Flash_base,AH
		STM	#Flash_5555,AL
		STM	#Flash_UL1,BL
		WRITA	*(BL)			; AAH -> (85555H)
		STM	#Flash_2AAA,AL
		STM	#Flash_UL2,BL
		WRITA	*(BL)			; 55H -> (82AAAH)
		STM	#Flash_5555,AL
		STM	#Flash_PRG,BL
		WRITA	*(BL)			; A0H -> (85555H)
		
		POPM	AH			; 恢复地址 
		POPM	AL
		OR	#Flash_base,16,A
		.if	__far_mode
		WRITA	2H			; data -> (addr)
		.else
		WRITA	1H
		.endif
		
write_poll:	
		nop
		READA	*(BL)
		.if	__far_mode
		XOR	2H,B			; data ^ B
		.else
		XOR	1H,B
		.endif
		BITF	*(BL),#Polling_Bit
		BC	write_poll,TC		; 查询写操作是否完成?
		NOP
		NOP
		STM	#ZERO,BH		; 验证写操作
		LD	#1,A			; 正确,A = 1
		XC	1,BNEQ
;		BD 	write_poll
		LD	#0,A			; 错误,A = 0
		
		.if	__far_mode
		FRET
		.else
		RET
		.endif
		
*********************************************************************************
*										*
* 函数定义:uint _flash_writem(ulong addr, uint * ptr, uint length)   		*
* 功    能:将ptr所指向的数据缓冲区中的length个数据写入addr所指定的Flash单元	*
*										*
* 入口参数:A	  ---- 地址addr,Amsb~A0					*
*		       Amsb:	A16,Flash用SST39VF200时				*
*		       		A17,Flash用SST39VF400时(缺省)			*
*		      		A18,Flash用SST39VF800时				*
*		       Flash定位在程序储存空间80000H~9FFFFH/BFFFFH(缺省)/FFFFFH	*
*		       地址addr为从0开始的偏移地址,而非Flash的绝对地址		*
*          (SP+n) ---- 数据缓冲区起始地址ptr,如果是.far_mode模式则n为2,否则n为1	*
*          (SP+m) ---- 数据长度lrngth,如果是.far_mode模式则m为3,否则m为2	*
* 出口参数:A	  ---- 写入标志							*
*		       未写入:00H						*
*		       已写入:01H						*
* 资源使用:B,AR0								*
*										*
*********************************************************************************
_flash_writem:	.if	__far_mode
		LDU	2H,B
		.else
		LDU	1H,B
		.endif
		STLM	B,AR0			; AR0 ← 数据起始地址
writem_loop:	PSHM	AL			; 保存地址
		PSHM	AH
		.if	__far_mode
		FRAME	-2
		LDU	*AR0+,B			; 取数据
		STL	B,0H			; 传递数据
		FCALL	_flash_writes
		RC	AEQ			; 未写入,则A = 0,返回
		FRAME	2
		POPM	AH
		POPM	AL
		ADD	#ONE,A			; Flash地址+1
		ADDM	#-1,3H
		CMPM	3H,#ZERO
		.else
		FRAME	-1
		LDU	*AR0+,B			; 取数据
		STL	B,0H			; 传递数据
		CALL	_flash_writes
;		RC	AEQ			; 未写入,则A = 0,返回
		FRAME	1
		POPM	AH
		POPM	AL
		ADD	#ONE,A			; Flash地址+1
		ADDM	#-1,2H
		CMPM	2H,#ZERO
		.endif
		BC	writem_loop,NTC
		LD	#1,A			; 已写入,则A = 1,返回
		
		.if	__far_mode
		FRET
		.else
		RET
		.endif
		
*********************************************************************************
*										*
* 函数定义:uint _flash_reads(ulong addr)			   		*
* 功    能:从addr指定的Flash单元中读出一个数据					*
*										*
* 入口参数:A	  ---- 地址addr,Amsb~A0					*
*		       Amsb:	A16,Flash用SST39VF200时				*
*		       		A17,Flash用SST39VF400时(缺省)			*
*		      		A18,Flash用SST39VF800时				*
*		       Flash定位在程序储存空间80000H~9FFFFH/BFFFFH(缺省)/FFFFFH	*
*		       地址addr为从0开始的偏移地址,而非Flash的绝对地址		*
* 出口参数:A	  ---- 读出数据							*
* 资源使用:A									*
*										*
*********************************************************************************
_flash_reads:	OR	#Flash_base,16,A
		READA	*(AL)
		.if	__far_mode
		FRET
		.else
		RET
		.endif
		
*********************************************************************************
*										*
* 函数定义:void _flash_readm(ulong addr, uint * ptr, uint length)   		*
* 功    能:从addr指定的Flash单元中读出length数据到ptr所指向的数据缓冲区中		*
*										*
* 入口参数:A	  ---- 地址addr,Amsb~A0					*
*		       Amsb:	A16,Flash用SST39VF200时				*
*		       		A17,Flash用SST39VF400时(缺省)			*
*		      		A18,Flash用SST39VF800时				*
*		       Flash定位在程序储存空间80000H~9FFFFH/BFFFFH(缺省)/FFFFFH	*
*		       地址addr为从0开始的偏移地址,而非Flash的绝对地址		*
*          (SP+n) ---- 数据缓冲区起始地址ptr,如果是.far_mode模式则n为2,否则n为1	*
*          (SP+m) ---- 数据长度length,如果是.far_mode模式则m为3,否则m为2	*
* 出口参数:A	  ---- 读出数据							*
* 资源使用:B,AR0								*
*										*
*********************************************************************************
_flash_readm:	OR	#Flash_base,16,A
		.if	__far_mode
		LDU	2H,B
		.else
		LDU	1H,B
		.endif
		STLM	B,AR0			; AR0 ← 数据起始地址
		
readm_loop:	READA	*AR0+
		ADD	#ONE,A			; Flash地址+1
		.if	__far_mode
		ADDM	#-1,3H
		CMPM	3H,#ZERO
		.else
		ADDM	#-1,2H
		CMPM	2H,#ZERO
		.endif
		BC	readm_loop,NTC
		
		.if	__far_mode
		FRET
		.else
		RET
		.endif

		.end

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?