⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mpc_sm.asm

📁 8051 mp3 very good for using
💻 ASM
字号:
;-----------------------------------------------;
; SM - Get SM type and initialize SM properties
;
; Call: none
; Ret:  C=0: successful, SmPages are valid
;       C=1: unknown type

sm_gettype:
	ldiw	Y,SmSign	; Y = Pointer to SM property structure
	cbi	PORTC,CE	; CE="L"
	sbi	PORTC,CLE	; Command Phase: CLE="H", ALE="L"
	cbi	PORTC,ALE	; /
	ldi	r16,C_ID	; Cmd: Read ID
	 rcall	sm_write	; /
	cbi	PORTC,CLE	; Address Phase: CLE="L", ALE="H"
	sbi	PORTC,ALE	; /
	ldi	r16,0x00	; Addr: 0
	 rcall	sm_write	; /
	cbi	PORTC,ALE	; Data Phase: CLE="L", ALE="L"
	outi	DDRA,0		; Disable data out
	outi	PORTA,-1	; Pull-up
	 rcall	sm_read		; Read mfr code
	st	Y+,r16		; /
	 rcall	sm_read		; Read device code
	st	Y+,r16		; /
	sbi	PORTC,CE	; CE = "H"

	cpi	r16,Sign8	; Is device size 8MB ?
	brne	PC+8		;  no, skip
	sti	Y+,byte2(Pages8); Initialize as 8MB
	sti	Y+,byte3(Pages8); 
	sti	Y+,Blkp8-1	; 
	ret			; /

	cpi	r16,Sign16	; Is device size 16MB ?
	brne	PC+8		;  no, skip
	sti	Y+,byte2(Pages16); Initialize as 16MB
	sti	Y+,byte3(Pages16); 
	sti	Y+,Blkp16-1	; 
	ret			; /

	cpi	r16,Sign32	; Is device size 32MB ?
	brne	PC+8		;  no, skip
	sti	Y+,byte2(Pages32); Initialize as 32MB
	sti	Y+,byte3(Pages32); 
	sti	Y+,Blkp32-1	; 
	ret			; /

	cpi	r16,Sign64	; Is device size 64MB ?
	brne	PC+8		;  no, skip
	sti	Y+,byte2(Pages64); Initialize as 64MB
	sti	Y+,byte3(Pages64); 
	sti	Y+,Blkp64-1	; 
	ret			; /

	cpi	r16,Sign128	; Is device size 128MB ?
	brne	PC+8		;  no, skip
	sti	Y+,byte2(Pages128); Initialize as 128MB
	sti	Y+,byte3(Pages128); 
	sti	Y+,Blkp128-1	; 
	ret			; /

	ret			; Unknown device type



;-----------------------------------------------;
; SM - Test and erase current block
;
; Call: _PageX = Page(block) to be checked
; Ret:  r16,r17,r18,r19,_Loop = broken
;       C=0 : Successful, Block is erased.
;       C=1 : Bad block.

sm_chk_blk:
	 rcall	sm_erase	; Erase
	brcs	sc_ret		; /
	ldi	r19,0x55	; Write 0x55,0xAA....
	 rcall	sc_fill		; 
	brcs	sc_ret		; /
	 rcall	sc_chk		; Verify
	brcs	sc_ret		; /
	 rcall	sm_erase	; Erase
	brcs	sc_ret		; /
	ldi	r19,0xaa	; Write 0xAA,0x55....
	 rcall	sc_fill		; 
	brcs	sc_ret		; /
	 rcall	sc_chk		; Verify
	brcs	sc_ret		; /
	 rcall	sm_erase	; Erase
sc_ret:	sbi	PORTC,CE	; CE = "H"
	ret

sc_fill:
	push	_PageL
	push	_PageM
	push	_PageH
	lds	_Loop,SmPPB	; Block count
	inc	_Loop		;
scf_sl:	 rcall	sm_wr_set	;---- Block filling loop
	ldi	r18,512/2	; Page count
	out	PORTA,r19	;---- Page filling loop
	cbi	PORTC,WE	; Write Even byte
	sbi	PORTC,WE	; /
	com	r19		; P = !P
	out	PORTA,r19	; Write Odd byte
	cbi	PORTC,WE	; 
	sbi	PORTC,WE	; /
	com	r19		; P = !P
	dec	r18		; End of page ?
	brne	PC-9		;  no, continue
	 rcall	sm_wr_start	; Start to write
	brcs	scf_err		; /
	 rcall	next_page	; Page ++
	dec	_Loop		; End of block ?
	brne	scf_sl		;  no, continue
	clc
	rjmp	PC+2
scf_err:sec
	pop	_PageH
	pop	_PageM
	pop	_PageL
	ret

sc_chk:
	push	_PageL
	push	_PageM
	push	_PageH
	lds	_Loop,SmPPB	; Block count
	inc	_Loop		;
	com	r19		; P = !P
scc_sl:	 rcall	sm_rd_page	;---- Block compare loop
	ldi	r18,512/2	; Page count
	cbi	PORTC,RE	;---- Page compare loop 
	com	r19		; P = !P
	in	r16,PINA	; Read Even byte
	sbi	PORTC,RE	; /
	cp	r16,r19		; 
	brne	scc_err		; 
	cbi	PORTC,RE	; Read Odd byte
	com	r19		; P = !P
	in	r16,PINA	; 
	sbi	PORTC,RE	; /
	cp	r16,r19		; 
	brne	scc_err		; 
	dec	r18		; End of page ?
	brne	PC-13		;  no, continue
	 rcall	next_page	; Page ++
	dec	_Loop		; End of block ?
	brne	scc_sl		;  no, continue
	clc
	rjmp	PC+2
scc_err:sec
	pop	_PageH
	pop	_PageM
	pop	_PageL
	ret


;-----------------------------------------------;
; SM - Receive 512 bytes of page data from HOST into SM
;
; Call: none
; Ret:  r16-r19 = broken
;
;SCK  ______---___---___---___---______
;MOSI -----000111222333444555666777----

sm_rcv512:
	ldi	r18,low(511)
	ldi	r19,high(511)
rcv1:	in	r16,PINB	; b0
	bst	r16,SCK
	brtc	PC-2
	bst	r16,MOSI
	bld	r17,0
	in	r16,PINB	; b1
	bst	r16,SCK
	brts	PC-2
	bst	r16,MOSI
	bld	r17,1
	in	r16,PINB	; b2
	bst	r16,SCK
	brtc	PC-2
	bst	r16,MOSI
	bld	r17,2
	in	r16,PINB	; b3
	bst	r16,SCK
	brts	PC-2
	bst	r16,MOSI
	bld	r17,3
	in	r16,PINB	; b4
	bst	r16,SCK
	brtc	PC-2
	bst	r16,MOSI
	bld	r17,4
	in	r16,PINB	; b5
	bst	r16,SCK
	brts	PC-2
	bst	r16,MOSI
	bld	r17,5
	in	r16,PINB	; b6
	bst	r16,SCK
	brtc	PC-2
	bst	r16,MOSI
	bld	r17,6
	in	r16,PINB	; b7
	bst	r16,SCK
	brts	PC-2
	bst	r16,MOSI
	bld	r17,7
	out	PORTA,r17	; Write into SM
	cbi	PORTC,WE	; 
	sbi	PORTC,WE	; /
	subi	r18,1		; End of page ?
	sbci	r19,0		;  no, continue
	brcc	rcv1		; /
	ret



;-----------------------------------------------;
; SM - Reset device
;
; Call: none
; Ret:  r16 = broken

sm_reset:
	cbi	PORTC,CE	; CE="L"
	sbi	PORTC,CLE	; Command Phase: CLE="H", ALE="L"
	cbi	PORTC,ALE	; /
	ldi	r16,C_RES	; Cmd: Reset
	 rcall	sm_write	; /
	sbis	PINC,BSY	; Wait for ready
	rjmp	PC-1		; /
	sbi	PORTC,CE	; CE="H"
	ret



;-----------------------------------------------;
; SM - Erase current block
;
; Call: _PageX = Page(Block) for erase
; Ret:  r16 = broken
;       C = 0:Successful, 1:error

sm_erase:
	cbi	PORTC,CE	; CE="L"
	sbi	PORTC,CLE	; Command Phase: CLE="H", ALE="L"
	cbi	PORTC,ALE	; /
	ldi	r16,C_ERA1	; Cmd: Erase 1
	 rcall	sm_write	; /
	cbi	PORTC,CLE	; Address Phase: CLE="L", ALE="H"
	sbi	PORTC,ALE	; /
	mov	r16,_PageL	; Addr 1
	 rcall	sm_write	; /
	mov	r16,_PageM	; Addr 2
	 rcall	sm_write	; /
	mov	r16,_PageH	; Addr 3 (will be ignored at 32M or below SMs)
	 rcall	sm_write	; /
	sbi	PORTC,CLE	; Command Phase: CLE="H", ALE="L"
	cbi	PORTC,ALE	; /
	ldi	r16,C_ERA2	; Cmd: Erase 2
	 rcall	sm_write	; /
	sbis	PINC,BSY	; Wait for end of erase
	rjmp	PC-1		; /
	ldi	r16,C_STA	; Cmd: Status
	 rcall	sm_write	; /
	cbi	PORTC,CLE	; Data Phase: CLE="L", ALE="L"
	 rcall	sm_read		; Read status into C
	lsr	r16		; /
	ret



;-----------------------------------------------;
; SM - Set ready to write
;
; Call: _PageX = Page for write
; Ret:  r16 = broken

sm_wr_set:
	cbi	PORTC,CE	; CE="L"
	sbi	PORTC,CLE	; Command Phase: CLE="H", ALE="L"
	cbi	PORTC,ALE	; /
	ldi	r16,C_RD0	; Cmd: Cancel RD2 cmd
	 rcall	sm_write	; /
	ldi	r16,C_WR	; Cmd: Write set
	 rcall	sm_write	; /
	cbi	PORTC,CLE	; Address Phase: CLE="L", ALE="H"
	sbi	PORTC,ALE	; /
	ldi	r16,0x00	; Addr 0
	 rcall	sm_write	; /
	mov	r16,_PageL	; Addr 1
	 rcall	sm_write	; /
	mov	r16,_PageM	; Addr 2
	 rcall	sm_write	; /
	mov	r16,_PageH	; Addr 3 (will be ignored at 32M/16M SMs)
	 rcall	sm_write	; /
	cbi	PORTC,ALE	; Data Phase: CLE="L", ALE="L"
	ret



;-----------------------------------------------;
; SM - Write intrenal buffer into memory array
;
; Call: none
; Ret:  C=0 : Successful
; 	C=1 : Error

sm_wr_start:
	sbi	PORTC,CLE	; Command Phase: CLE="H", ALE="L"
	cbi	PORTC,ALE	; /
	ldi	r16,C_PRG	; Cmd: Write start
	 rcall	sm_write	; /
	sbis	PINC,BSY	; Wait for ready
	rjmp	PC-1		; /
	ldi	r16,C_STA	; Cmd: Read status
	 rcall	sm_write	; /
	cbi	PORTC,CLE	; Data Phase: CLE="L", ALE="L"
	 rcall	sm_read		; Read data
	sbi	PORTC,CE	; CE = "H"
	lsr	r16		; Read status into C
	ret



;-----------------------------------------------;
; SM - Read out a page data from memory array
;      into transfer buffer
;
; Call: _PageX = Page# for read
; Ret:  r16 = broken
;
; NOTE1: AT 32MB MEDIUM OR BELOW.
; The read transfer cycle is initiated after Addr2, following Addr3 will 
; be ignored. But if Addr3 is given at the read transfer cycle has been 
; completed, read data can become wrong. An interrupt between Addr2 and
; Addr3 will cause this problem. Therefore, all interrupts must be disabled 
; during this routine is executed in order to avoid data collaption.
; NOTE2: Above problem has been fixed at this routine :-)

sm_rd_page2:			; Read a page and set pointer to offset 512
	ldi	r16,C_RD2	; Cmd: Read2
	rjmp	PC+2		; 
sm_rd_page:			; Read a page and set pointer to offset 0
	ldi	r16,C_RD0	; Cmd: Read
	in	_SrgTmp2,SREG	; Save I flag 
	cli			; Disable interrupts (TO AVOID DATA COLLAPTION)
	cbi	PORTC,CE	; CE="L"
	sbi	PORTC,CLE	; Command Phase: CLE="H", ALE="L"
	cbi	PORTC,ALE	; /
	 rcall	sm_write	; Command
	cbi	PORTC,CLE	; Address Phase: CLE="L", ALE="H"
	sbi	PORTC,ALE	; /
	ldi	r16,0x00	; Addr 0
	 rcall	sm_write	; /
	mov	r16,_PageL	; Addr 1
	 rcall	sm_write	; /
	mov	r16,_PageM	; Addr 2
	 rcall	sm_write	; /
	mov	r16,_PageH	; Addr 3 (will be ignored at < 64M media)
	 rcall	sm_write	; /
	cbi	PORTC,ALE	; Data Phase: CLE="L", ALE="L"
	outi	DDRA,0x00	; Disable data out
	outi	PORTA,-1	; Pull-up
	out	SREG,_SrgTmp2	; Restore I flag
	sbis	PINC,BSY	; Wait for ready
	rjmp	PC-1		; /
	ret



;-----------------------------------------------;
; SM - Read/Write byte
;
; Call: r16 = data for write
; Ret:  r16 = read data

sm_write:
	out	PORTA,r16	; Set data for write
	outi	DDRA,0xff	; Enable data out
	cbi	PORTC,WE	; WE="L"
	sbi	PORTC,WE	; WE="H"
	ret

sm_read:
	cbi	PORTC,RE	; RE="L"
	nop			; 
	in	r16,PINA	; Read
	sbi	PORTC,RE	; RE="H"
	ret



⌨️ 快捷键说明

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