📄 exampleasm.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 + -