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

📄 exampleasm.asm

📁 Implementing a Software UART on the TMS320C54x with the McBSP and DMA
💻 ASM
字号:
*****************************************************************
* Filename: ExampleASM.asm					*
* Function: Demonstrates usage of the SW UART			*
* Author:   Robert J. DeNardo					*
*	    Texas Instruments, Inc.				*
* Revision History:						*
* 11/12/99  Original Code			Robert DeNardo	*
* 12/21/99  Changed example loop structure.	Robert DeNardo	*
* 09/05/00  Setup to run on 5402DSK.            Robert DeNardo  *
*                                                               *
* This code is set to run on 5402DSK.  Make sure to set CPLD    *
* to use McBSP0 from daughterboard (0x4@io = 0xFF03).           *
*****************************************************************
	.mmregs

	.include "UARTsetup.inc"       

********** routines called by this file ***********
	.ref	_UARTTxChar
	.ref	_UARTRxChar
	.ref	_UARTStart  
	.ref	_UARTStop
	.ref	_UARTInit   
	.ref	_UARTSetBaudRate    
	.ref	_UARTSetBreak
	.ref	_UARTDMATxISR
	.ref	_UARTDMARxISR

********** routines defined in this file ***********
	.def	_main
	.def	_c_int00	; use this label so we can share vectors.asm with C example      
 .if INTERRUPT_BASED
	.def	_UARTLSIint
	.def	_UARTRBFint
	.def	_UARTTBEint  
 .endif
*********** public variables referenced ************
      	.ref	_UARTLSR
      	
*************** variable definitions ***************
	.bss	RxHeadPtr,1
	.bss	RxTailPtr,1 
	.bss	RxCharCnt,1
	.bss	TxHeadPtr,1
	.bss	TxTailPtr,1    

******************* equates ************************
DMPREC	.set	54h	; DMA channel PRiority and Enable Control register

TXNUM		.set	10
STACKSIZE	.set	100
RxCharBuf	.usect	"ExampleRxBuf",TXNUM*2	; address of the circular character receive buffer 
TxCharBuf	.usect	"ExampleTxBuf",TXNUM*2	; address of the circular character transmit buffer
stack  		.usect  ".stack",STACKSIZE                                          
	                                           
    	.text  
 .if INTERRUPT_BASED    	
*****************************************************************
*	Function: _UARTLSIint					*
*       Called By: _UARTDMARxISR				*
*	Purpose: Run when a Line Status Interrupt event occurs.	*
*		 This is when a Parity Error, Overrun Error,	*
*		 Break Interrupt Error, or Framing Error occurs.*
*		 The registers, ar2, a, b, st0, st1, brc, rsa, 	*
*		 rea are saved and restored by _UARTDMARXISR.	*
*		 Any other registers used MUST be saved and 	*
*		 restored by this routine.			*
*	Inputs:	 none						*	 
*	Outputs: none						*
*	Modified: none                          		*
*****************************************************************
_UARTLSIint:      
	pshm	bk
     	stm	#TXNUM*2,BK			; set for circular addressing   
	call	ErrRoutine
	popm	bk
	ret

*****************************************************************
*	Function: _UARTRBFint					*
*       Called By: _UARTDMARxISR				*
*	Purpose: Run when a new char is received into rxchar.	*
*		 The registers, ar2, a, b, st0, st1, brc, rsa, 	*
*		 rea are saved and restored by _UARTDMARXISR.	*
*		 Any other registers used MUST be saved and	*
*		 restored during this routine.			*	 
*	Inputs:	 CPL=0 (data page rel. direct addressing)	*	 
*	Outputs: none						*
*	Modified: none                                        	*
*****************************************************************
_UARTRBFint:  
	pshm	bk
      	stm	#TXNUM*2,BK			; set for circular addressing   
   	call	RxRoutine  
   	popm	bk
	ret
	
*****************************************************************
*	Function: _UARTTBEint					*
*       Called By: _UARTDMATxISR				*
*	Purpose: Run when a char has just been transmitted	*
*		 and the UART is ready to transmit another.	*
*		 The st0 register is saved and restored by	*
*		 _UARTDMATxISR.  Any other registers used MUST 	*
*		 be  saved and restored during this routine.	*
*	Inputs:	 none						*
*	Outputs: none						*
*	Modified: none                                     	*
*****************************************************************
_UARTTBEint:
	pshm	al
	pshm	ah
	pshm	ag 
	pshm	st1   
	pshm	ar2 
	pshm	bk
	pshm	brc
	pshm	rea
	pshm	rsa 
     	stm	#TXNUM*2,BK			; set for circular addressing   
	call	TxRoutine
	popm	rsa
	popm	rea
	popm	brc  
	popm	bk
	popm	ar2  
	popm	st1
	popm	ag
	popm	ah
	popm	al
	ret	    
 .endif



*****************************************************************
*	Function: _InitPLL					*
*	Purpose: Sets the PLL for a 3.75 multiplier.        	*
*	Inputs:	 none						*
*	Outputs: none						*
*	Modified: clkmd,tc					*
***************************************************************** 
_InitPLL:
	stm	#0,CLKMD
waitDiv:                              
	bitf	*(CLKMD),#1   			; check the status bit to see if in DIV mode
	bc	waitDiv,tc  			; if not, keep looping
	stm	#0fffbh,CLKMD			; set multiplier to 15/4=3.75 and set count to 0xff
waitPLL:
	bitf	*(CLKMD),#1	              	; check the status bit to see if in PLL mode
	bc	waitPLL,ntc  			; if not, keep looping
	ret                                                       
	
*****************************************************************
*	Function: _main						*
*	Purpose: Example routine to use the UART.		*
*		 This demonstrates the calls to the 		*
*		 initialization routines and how to read and	*
*		 write characters with the UART.		*
*	Inputs:	 none						*
*	Outputs: none						*
*	Modified: NA						*
***************************************************************** 
_c_int00:
_main:
	stm	#0100000000100000b,PMST
		;010000000~~~~~~~b		IPTR: 	Vector table resides at 04000h
		;~~~~~~~~~0~~~~~~b		MP/MC_:	On-chip ROM is enabled
		;~~~~~~~~~~1~~~~~b		OVLY:	On-chip RAM mapped into program and data space
		;~~~~~~~~~~~0~~~~b		AVIS:	Address visibility mode off
		;~~~~~~~~~~~~0~~~b		DROM:	On-chip ROM not mapped into data space
		;~~~~~~~~~~~~~0~~b		CLKOFF:	CLOCKOUT not disabled
		;~~~~~~~~~~~~~~0~b		SMUL:	Saturate on Multiply is disabled
		;~~~~~~~~~~~~~~~0b		SST:	Saturate on Store is disabled	
	stm	#stack + STACKSIZE,sp         	; init the stack pointer to top of stack
	stm	#0,imr                         	; disable all interrupts
	stm	#0ffffh,ifr    			; clear all pending interrupts
	st	#0,*(DMPREC)			; disable all DMA channels.
	call	_InitPLL                        ; init the PLL
	call	_UARTInit			; init the UART
	st	#0,*(RxCharCnt)			; initialize received character count to 0
	st	#RxCharBuf,*(RxHeadPtr) 	; initialize the head ptr into received character buffer
	st	#RxCharBuf,*(RxTailPtr) 	; initialize the tail ptr into received character buffer
	st	#TxCharBuf,*(TxHeadPtr) 	; initialize the head ptr into transmit character buffer
	st	#TxCharBuf,*(TxTailPtr) 	; initialize the tail ptr into transmit character buffer
     
     	stm	#TXNUM*2,BK			; set for circular addressing   
     	ld	#0,a				; start the Rx and Tx UART channels  
	call	_UARTStart          		; 
	stm	#1,ar0				; use for copy below
 .if INTERRUPT_BASED ; example for interrupt based servicing of UART
echoLoop:
	ld	*(RxCharCnt),a
	sub	#TXNUM,a			; see if TXNUM or greater characters received
	bc	echoLoop,alt			; if not, loop

	mvdk	*(RxTailPtr),ar2		; load the receive tail pointer (oldest rx char) to ar2
	mvdk	*(TxHeadPtr),ar3   		; load the transmit head pointer to ar3
	rpt	#TXNUM-1
	  mvdd	*ar2+0%,*ar3+0%			; copy TXNUM received chars to transmit buffer
	mvkd	ar2,*(RxTailPtr)		; update the receive tail pointer
	mvkd	ar3,*(TxHeadPtr)		; update the transmit head pointer
	addm	#-TXNUM,*(RxCharCnt)	  	; decrement the received character count by TXNUM 
	call	TxRoutine			; need to "kickstart" UART for transmit.
	call	TxRoutine			; need to "kickstart" UART for transmit 
						; (put 2 chars in buf to get consecutive transmits).
						; It will transmit these TXNUM chars and then stop.
	b	echoLoop
 .else ; example for polling based servicing of UART
echoLoop:
	bitf	*(_UARTLSR),#DR			; Check if new character received
	cc	RxRoutine,tc			; if so, call routine to process it
	bitf	*(_UARTLSR),#THRE             	; Check if new character can be sent
	cc	TxRoutine,tc			; if so, call routine to process it  
	bitf	*(_UARTLSR),#(BI|FE|PE|OE)	; Check if any errors
	cc	ErrRoutine,tc			; if so, process the errors

	ld	*(RxTailPtr),a          	; check if any received data is available
	sub	*(RxHeadPtr),a          	
	bc	echoLoop,aeq			; if head=tail ptr for rx, skip copy
	mvdk	*(RxTailPtr),ar2
	mvdk	*(TxHeadPtr),ar3
	mvdd	*ar2+0%,*ar3+0%			; move rx char to tx buffer 
	mvkd	ar2,*(RxTailPtr)		; update pointers
	mvkd	ar3,*(TxHeadPtr)
	b	echoLoop
 .endif

RxRoutine:	
     	call	_UARTRxChar                    	; returns char in al
	mvdk	*(RxHeadPtr),ar2     		; load the receive head pointer into ar2
	stl	a,*ar2+%   			; store the newly decoded character into the received character buffer
	mvkd	ar2,*(RxHeadPtr)                ; update the head ptr
	addm	#1,*(RxCharCnt)			; increment received character count
	ret

TxRoutine:       	
	ld	*(TxTailPtr),a          	; check if any transmit data is available to be sent
	sub	*(TxHeadPtr),a          	
	rc	aeq                    		; if transmit head=tail pointer, no data, so exit
	mvdk	*(TxTailPtr),ar2                ; otherwise load the transmit tail pointer
	ld	*ar2+%,a                        ; get the next character to transmit
	mvkd	ar2,*(TxTailPtr)     		; update the tail pointer
	sub	#2,a
	bcd	sendBreak,alt			; if buffer has 0 or 1, send break
	  add	#2,a
	call	_UARTTxChar   			; format the character for transmit.
	ret
sendBreak:
	call	_UARTSetBreak			; sending a 1 sends break, 0 sends end of break
	ret
	
ErrRoutine:          				; this error routine puts break in tx buffer and clears flags
	andm	#~(BI|FE|PE|OE),*(_UARTLSR)    	; clear error flags
	mvdk	*(TxHeadPtr),ar2              	; get current tx head ptr to write new data
	st	#1,*ar2+%			; add a break to transmit buffer
	st	#0,*ar2+%			; add end of break to transmit buffer 
	mvkd	ar2,*(TxHeadPtr)               	; update transmit head ptr
	ret
	
					

⌨️ 快捷键说明

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