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

📄 sb_eeprogram.asm

📁 DSP56300显示程序,用于显示LED的工作关态
💻 ASM
字号:
;**************************************************************************
;***
;***	Copyright 2007, Freescale, Inc.  All rights reserved.
;***
;**************************************************************************
;***
;***	I2C EEPROM programing routines for making SoundBite self boot
;***
;***	This code writes the I2C EEPROM attached to the 56371 in the format
;***	required for self-booting in mode 9
;***
;**************************************************************************

	section soundbite_eeprogram

	nolist
	include "..\dsp56371.equ"			; generic 56371 equates
	include "..\soundbite.equ"			; SoundBite specific equates
	include "..\soundbite_macros.equ"	; macros for sb_leds.asm and sb_switches.asm
	list	


;**************************************************************************
; reference external symbols for LED control
;**************************************************************************
	xref	SETUP_LEDS,SET_LEDS	


;**************************************************************************
; define default start addresses and lengths of uploads for EEPROM...
;**************************************************************************
PSTART_CODE	equ	0			; this is always 0 for non-SA self-boot
XSTART		equ	0			; this is typically always 0
YSTART		equ	0			; this is typically always 0
PLENGTH		equ	$450		; length of P code
XLENGTH		equ	$40			; length of X data
YLENGTH		equ	$40			; length of Y data
PSTART_EXEC	equ	$0			; begin execution here after download done
EEPROM_STRT equ $0			; default start address in EEPROM
;**************************************************************************


;**************************************************************************
; define symbols used for progress indication via LEDs
;**************************************************************************
TOTAL_BYTES	equ 3*(12+PLENGTH+XLENGTH+YLENGTH)	; total bytes to upload to EEPROM
PROGRESS	equ	@CVI($FE0000/TOTAL_BYTES)		; increment to show 8 bits of 
												; progress in LEDs when complete


	org p:		
;*************************************************************************
; entry point to EEPROM programming routine to make SoundBite self boot
;*************************************************************************
e2prog:
	ori		#$03,mr				; guarantee that interrupts are masked 
	movep	#$0,X:M_HCSR		; turn off/reset SHI

;*** Set DSP core clock rate ***
	movep   #$04401d,x:$FFFFFD	; assumes 24.576 MHz DSP core clock
								; programming routine won't work otherwise
	rep 	#$FFF				; wait for PLL to settle
	nop

;*** Set SHI clock Rate ***
	movep	#$000040,X:M_HCKR	; /64 for crystal value (i.e. 25MHz/(8*8) = 390625 Hz

;*** Setup SHI: Master Mode, 8 bit data, I2C protocol ***
	movep	#$008242,X:M_HCSR	; write register leaving SHI disabled...
	bset 	#0,x:M_HCSR			; enable the SHI after register programmed...

;*** set M registers for pointers to guarantee linear addressing
	move	#$FFFFFF,m0			; set linear addressing mode for r0,r1,r2
	move	m0,m1
	move	m1,m2

;*** setup progress indication (binary counter)
	move	#0,r7				; counter used for indicating 8 bits of progress (LEDs)
	move	#PROGRESS,n7		; increment and show progress by displaying uppermost byte

	bsr	SETUP_LEDS				; setup LEDs for use


;*** load y0 and y1 with I2C device select write/read bytes
;*** 	this allows changing device select on the fly, if desired
	move	#$A00000,y0			; I2C EEPROM device select, write bit clear
	move	#$A10000,y1			; I2C EEPROM device select, read bit set

;*** load core registers with all upload parameters, allowing for easy change with debugger
	move 	#EEPROM_STRT,r1		; r1 = EEPROM internal start address
	move	#>PSTART_CODE,r4	; r4 = P code start address
	move	#>XSTART,r5			; r5 = X data start address
	move	#>YSTART,r6			; r6 = Y data start address
	move	#>PLENGTH,m4		; m4 = P code length
	move	#>XLENGTH,m5		; m5 = X data length
	move	#>YLENGTH,m6		; m6 = Y data length
	move	#>PSTART_EXEC,n0	; n0 = P addr at which to start executing


;*********************************************************************
;*** stop here and wait to enable user to change upload paramters
;*** comment this out for production SoundBite programming...
;*********************************************************************
;	DEBUG		; change upload paramters now, if desired/required
;*********************************************************************
	nop
	nop
	nop


; write table of start addresses and lengths to EEPROM; 18 bytes total
	move	r4,b1			; write start address for P code data to EEPROM
	bsr		WRITE_word
	move	r5,b1			; write start address for X data to EEPROM
	bsr		WRITE_word
	move	r6,b1			; write start address for Y data to EEPROM
	bsr		WRITE_word
	move	m4,b1			; write length of P code to EEPROM
	bsr		WRITE_word
	move	m5,b1			; write length of X data to EEPROM
	bsr		WRITE_word
	move	m6,b1			; write length of Y data to EEPROM
	bsr		WRITE_word


; write P code data to EEPROM
	move	r1,n4				; store EEPROM addres for beginning of P data
	move	r4,r2				; r2 points to P start address
	move	m4,r3				; r3 contains length of data to upload
	do r3,Pdataloop
		move	p:(r2)+,b1		; read word from P memory
		bsr		WRITE_word		; write it to EEPROM
		nop
Pdataloop:
	nop


; write X data to EEPROM
	move	r1,n5				; store EEPROM addres for beginning of X data
	move	r5,r2				; r2 points to X start address
	move	m5,r3				; r3 contains length of data to upload
	do r3,Xdataloop
		move	x:(r2)+,b1		; read word from X memory
		bsr		WRITE_word		; write it to EEPROM
		nop
Xdataloop:
	nop


; write Y data to EEPROM
	move	r1,n6				; store EEPROM addres for beginning of Y data
	move	r6,r2				; r2 points to Y start address
	move	m6,r3				; r3 contains length of data to upload
	do r3,Ydataloop
		move	y:(r2)+,b1		; read word from Y memory
		bsr		WRITE_word		; write it to EEPROM
		nop
Ydataloop:
	nop

; write address to start execution when download completes
	move	r1,n7				; store EEPROM addres for start of execution
	move	n0,b1				; P address at which to start execution
	bsr		WRITE_word
	nop

	move	#>$FF,a1			; turn on all LEDs to indicate completion 
	bsr		SET_LEDS			; while turning off GPLED9


;*********************************************************************
;*** EEPROM programming is now complete...  Data in EEPROM may be inspected, if desired
;*********************************************************************

	DEBUG		; stop here.  EEPROM should now be programmed...
				; Nx registers n4,n5,n6,n7 contain the EEPROM addresses
				; of the respective P, X, Y data and P exec. start addresses.
				; These may be inspected using the READ_TEST routine below.


	jmp READ_TEST	; resume here to check EEPROM (for checking by hand only)

	jmp *			; stop here



;*********************************************************************
;*** EEPROM programming/reading subroutines
;*********************************************************************

;*********************************************************************
;*** Write 3 bytes of a 24-bit word to EEPROM, LSB first
;***
;***	b1: contains word to write
;***	r1: contains address to write to in EEPROM
;***	r7: contains the visual progress counter (displays $FF when complete)
;***	clobbers a and x0
;***
;***	calls WRITE_byte subroutine
;*********************************************************************
WRITE_word:
	do #3,wordloop			; loop over 3 bytes of 24-bit word
	asr		#8,b,b			; shift LSB of B1 to MSB of b0
	move	b0,x0			; move b0 to x0, argument for WRITE_byte
	bsr		WRITE_byte		; write this to EEPROM
	nop
	move	r7,a1			; put progress counter into A
	lsr		#16,a			; shift A right by 16 bits
	bsr		SET_LEDS		; display status in lower 8 LEDs
	nop
wordloop:
	nop
	rts


;*********************************************************************
;*** Write a single byte to EEPROM
;***
;***	x0: contains byte to write in upper 8-bits (MSB)
;***	r1: contains address to write to in EEPROM,
;***		where r1 is incremented by 1 following the write
;***	y0: contains I2C device select specifying write
;***
;***	clobbers r0,a
;*********************************************************************
WRITE_byte:
	move	y0,r0				; EEPROM slave address with write bit clr
	bsr		SHI_tx				; write to SHI (I2C device select)

	move	r1,a0
	asl		#8,a,a				; Get MSB of address into TX position
	move	a0,r0				; TX MSByte address
	bsr		SHI_tx				; write to SHI

	asl		#8,a,a				; Now get LSB address into position 
	move	a0,r0				; TX LSByte address
	bsr		SHI_tx				; write to SHI

	move 	x0,r0				; write desired byte to EEPROM
	bsr		SHI_tx				; write to SHI

	bset	#M_HIDLE,x:M_HCSR	; generate I2C stop event to complete write


; write a device select here, wait for EEPROM to ack to indicate write complete
poll_till_done:
	move	y0,r0				; EEPROM slave address with write bit clear
	movep	r0,x:M_HTX			; write data to SHI TX register

	brclr	#19,a0,_no_led		; only turn on LED9 when bit 3 of LSB of address is set
								; (remembering that LSB is in uppermost 8 bits of a0...)	
	GPLED8_on					; turn LED on
_no_led:
	rep #$c00					; wait long enough for lack of ACK to cause M_HBER error
		nop						; 
	GPLED8_off					; turn LED off

	brclr	#M_HBER,x:M_HCSR,poll_jump_out	; exit when EEPROM gives an ACK (writing done)

	movep	#0,x:M_HCSR			; reset SHI to clear I2C bus error
	rep 	#3
	nop							; nops for status bit update latency...
	movep	#$008242,X:M_HCSR	; write register but leave SHI disabled...
	bset 	#0,x:M_HCSR			; enable the SHI after register programmed...
	
	bra	poll_till_done			; loop back to write control word again...
	
poll_jump_out:					; at this point, byte written to I2C EEPROM
	bset	#M_HIDLE,x:M_HCSR	; generate I2C stop event
	move	(r1)+				; increment EEPROM address pointer
	move	(r7)+n7				; increment for progress indication
	rts							; return from whence called


;*********************************************************************
;*** SHI TX routine
;***
;***	r0: contains data to write
;*********************************************************************
SHI_tx:
	movep	r0,x:M_HTX			; write data to SHI TX register
	rep #3
	nop							; nops for latency in status bits updating
	brclr	#M_HTDE,X:M_HCSR,*	; Wait for M_HTX register to empty
	rts							; and then return

	
;*********************************************************************
;*** Read a random byte from EEPROM 
;***
;***	EEPROM requires an incomplete I2C write cycle to update the internal
;***	address pointer followed by a read.  Inefficient but it works...
;***
;***	x0: returns byte read from EEPROM in upper 8-bits
;***	r1: contains address to write to in EEPROM
;***	y0: contains I2C device select specifying write
;***	y1: contains I2C device select specifying read
;***
;***	clobbers r0,a
;*********************************************************************
READ_rand_byte:
	move	y0,r0				; EEPROM slave address with write bit clr
	bsr		SHI_tx				; write to SHI

	move	r1,a0				; move address of interest to a0
	asl		#8,a,a				; Shift MSB of address into TX position
	move	a0,r0				; TX MSByte address
	bsr		SHI_tx				; write to SHI

	asl		#8,a,a				; Now get LSB address into position 
	move	a0,r0				; TX LSByte address
	bsr		SHI_tx				; write to SHI
	
	bset	#M_HIDLE,x:M_HCSR	; generate I2C stop event - incomplete write cycle
	rep  	#20					; wait a bit...
		nop
		
	move	y1,r0				; write eeprom slave address, w/read bit set
	movep	r0,x:M_HTX			; write data to SHI TX register
	bset	#M_HIDLE,x:M_HCSR	; don't ack rcv'd byte so EEPROM only sends one byte
	nop							; nops for latency in status bits getting updated
	nop
	nop
	brclr	#M_HTDE,X:M_HCSR,*	; Wait for M_HTX register to empty

	brclr	#M_HRNE,x:M_HCSR,*	; wait for EEPROM to write byte back
	move	x:M_HRX,x0			; read return value from EEPROM
		
	rts


;*********************************************************************
;***  This is a short read routine used to inspect by hand the contents of 
;***  the EEPROM after writing.  Change PC to READ_TEST and then watch x0,x1
;***  as stepping through the loop at the bottom.  Change addresses by 
;***  changing r1 with debugger.  This should probably be turned into a full 
;***  byte by byte verification automatically run after the data is written 
;***  to the EEPROM...  An exercise for the reader?
;*********************************************************************
READ_TEST:
	movep	#$0,X:M_HCSR			; turn off/reset SHI
	
;*** Set PLL clock Rate ***
	movep   #$04401d,x:$FFFFFD		; turn off pll / revert to 25 MHz

;*** Set SHI clock Rate ***
	movep	#$000040,X:M_HCKR		; /64 for crystal value (i.e. 25MHz/(8*8) = 390625 
	
;*** Set M_HIDLE bit / Master Mode / 8 bit data / I2C ***
	movep	#$008242,X:M_HCSR		; write register with disabled...
	bset #0,x:M_HCSR				; then enable the SHI after register programmed...

	move 	#0,r1					; load default EEPROM starting address (0)

randread:
	bsr	READ_rand_byte				; read EEPROM contents (and put in X0)
	move	r1,x1					; put current EEPROM address in X1
	move  (r1)+						; increment EEPROM address pointer
	jmp randread					; jump for next,  break here to change EEPROM address
	
	
;*********************************************************************
;***  This routine blanks entire EEPROM to the original $FFFFFF contents
;***	(this is usually run by hand in debugger...)
;*********************************************************************
EE_BLANK:
	move	#$FF,x0				; blank EEPROM value
	move	#0,r1				; r1 points to EEPROM start address
	move	#$200000,r3			; r3 = 32k bytes in EEPROM
	do r3,blankloop
		bsr		WRITE_byte		; write it to EEPROM
		nop
blankloop:
	nop

	debug						; stop here 
	
	
	endsec

⌨️ 快捷键说明

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