?? uart.asm
字號:
REVT .set REVT1
XEVT .set XEVT1
.elseif MCBSP_CHOICE==2
SPSA .set SPSA2
DRR1reg .set DRR12
DXR1reg .set DXR12
REVT .set REVT2
XEVT .set XEVT2
.endif
McBSPDataReg .set SPSA+1 ; McBSP register to write/read data values
.if DMA_RX_CHOICE==0
RxDMAptr .set DMSRC0 ; point to first DMA regsiter for this channel
RxDMACh .set DMAch0 ; define bit to enable this DMA channel in DPREC:DE
RxDMAInt .set DMAC0int; define bit mask for this DMA channel interrupt in IMR/IFR
.elseif DMA_RX_CHOICE==1
RxDMAptr .set DMSRC1
RxDMACh .set DMAch1
RxDMAInt .set DMAC1int
.elseif DMA_RX_CHOICE==2
RxDMAptr .set DMSRC2
RxDMACh .set DMAch2
RxDMAInt .set DMAC2int
.elseif DMA_RX_CHOICE==3
RxDMAptr .set DMSRC3
RxDMACh .set DMAch3
RxDMAInt .set DMAC3int
.elseif DMA_RX_CHOICE==4
RxDMAptr .set DMSRC4
RxDMACh .set DMAch4
RxDMAInt .set DMAC4int
.elseif DMA_RX_CHOICE==5
RxDMAptr .set DMSRC5
RxDMACh .set DMAch5
RxDMAInt .set DMAC5int
.endif
.if DMA_TX_CHOICE==0
TxDMAptr .set DMSRC0
TxDMACh .set DMAch0
TxDMAInt .set DMAC0int
.elseif DMA_TX_CHOICE==1
TxDMAptr .set DMSRC1
TxDMACh .set DMAch1
TxDMAInt .set DMAC1int
.elseif DMA_TX_CHOICE==2
TxDMAptr .set DMSRC2
TxDMACh .set DMAch2
TxDMAInt .set DMAC2int
.elseif DMA_TX_CHOICE==3
TxDMAptr .set DMSRC3
TxDMACh .set DMAch3
TxDMAInt .set DMAC3int
.elseif DMA_TX_CHOICE==4
TxDMAptr .set DMSRC4
TxDMACh .set DMAch4
TxDMAInt .set DMAC4int
.elseif DMA_TX_CHOICE==5
TxDMAptr .set DMSRC5
TxDMACh .set DMAch5
TxDMAInt .set DMAC5int
.endif
********************** variable definitions *********************
UARTvars .usect "UART_vars",9,1 ; create a section for the UART vars. Keep in same data page
_UARTLSR .set UARTvars+0 ; Line Status Register (LSR) holds information on errors and ready status
rxchar .set UARTvars+1 ; holds last character received
rxbufhalf .set UARTvars+2 ; defines which half of raw receive buffer will have next character
txbufhalf .set UARTvars+3 ; defines which half of raw transmit buffer is open for write
numTxPkts .set UARTvars+4 ; holds # of pkts in tx buffer
mask1011b .set UARTvars+5 ; used in decoder
mask0100b .set UARTvars+6 ; used in decoder
decodeMask .set UARTvars+7 ; used in decoder
one .set UARTvars+8 ; used in decoder
; This section must be aligned on 2^n boundary greater than TxPKTBITS*2:
TxBuffer .usect "UARTTxBuffer",2*TxPKTBITS; Holds coded bits for transmission.
; This section must be aligned on 2^n boundary greater than RxPKTBITS*2:
RxBuffer .usect "UARTRxBuffer",2*RxPKTBITS; Holds coded bits upon reception.
******** Config Determinations Dependent on Variables ***********
; DMA ptr modification (5410 needs to decrement pointers, while 5402 and others can increment)
.if DMA_PTR_MOD==0 ; (decrement) on 5410 DMA buffers must fill from high to low (start bit at higher addr than stop bits)
.asg ar2-,ar2fwd ; fills from high to low addr, so fwd is a decrement (fwd)
.asg ar2+,ar2bwd ; backward direction is an increment (bwd)
Tx1stStart .set TxBuffer+2*TxPKTBITS-1 ; start of buffer halves are where start bits are
Tx2ndStart .set TxBuffer+TxPKTBITS-1
Rx1stEnd .set RxBuffer+RxPKTBITS ; end of buffer halves are where stop bits are
Rx2ndEnd .set RxBuffer
Rx1stStart .set RxBuffer+2*RxPKTBITS-1
DMAptrMod .set 010b ; post decrement the DMA pointers
.else ; (DMA_PTR_MOD==1, increment) other 54xx DSPs can fill from low to high if desired
.asg ar2+,ar2fwd ; fills from low to high addr, so fwd is an increment (fwd)
.asg ar2-,ar2bwd ; backward direction is a decrement (bwd)
Tx1stStart .set TxBuffer ; start of buffer halves are where start bits are
Tx2ndStart .set TxBuffer+TxPKTBITS
Rx1stEnd .set RxBuffer+RxPKTBITS-1 ; end of buffer halves are where stop bits are
Rx2ndEnd .set RxBuffer+2*RxPKTBITS-1
Rx1stStart .set RxBuffer
DMAptrMod .set 001b ; post increment the DMA pointers
.endif
.sect "uart"
*****************************************************************
* USER DEFINED INTERRUPT FUNCTIONS *
* *
* These are run whenever an interrupt event occurs on *
* the UART. *
* If it is desired to perform processing during an *
* interrupt, these can be used, otherwise a polling *
* scheme will work as well. *
* To include these in the code, INTERRUPT_BASED must be 1.*
* These routines should be defined in your code and must *
* follow the information given in their headers. *
*****************************************************************
.if INTERRUPT_BASED
.ref _UARTLSIint
.ref _UARTRBFint
.ref _UARTTBEint
.if 0 ; Copy these into your own code or create your own C functions
*****************************************************************
* 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:
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:
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:
ret
.endif
.endif ; End INTERRUPT_BASED
*****************************************************************
* Function: _UARTDMARxISR *
* Purpose: ISR which runs whenever a new coded character *
* is received. This occurs when each half of *
* buffer is filled by the DMA Rx channel. *
* Reads raw character from Rx buffer and *
* decodes it from MSb to LSb. A majority rule *
* scheme decodes each bit. Start bits *
* are ignored. Parity and stop bits are *
* checked and stripped. Any error is reported *
* in _UARTLSR register. *
* Inputs: rxbufhalf - contains half of raw rx buffer *
* where data is located *
* Outputs: rxchar - holds value of last rx char *
* _UARTLSR - holds status of line and errors *
* Modified: none *
*****************************************************************
_UARTDMARxISR:
pshm al ; save the registers used in ISR
pshm ah ;
pshm ag ;
pshm bl ;
pshm bh ;
pshm bg ;
pshm st0 ;
pshm st1 ;
pshm ar2 ;
rsbx cpl ; set to data-page relative direct addressing
pshm brc ;
pshm rsa ;
pshm rea ;
ld #UARTvars,DP ; load the UART variable data page
bitf @rxbufhalf,#1 ; check if in 2nd half
xorm #1,@rxbufhalf ; update current half to receive into
stm #Rx2ndEnd,ar2 ; assume in 2nd half of buffer and point to end of it
xc 2,ntc ; if not,
stm #Rx1stEnd,ar2 ; point ar2 to the end of first half of buffer
stm #RxPKTBITS-STARTBITS-1,brc ; loop over the data+parity+stop bit (not start bit)
rptbd DecodeLoop-1 ;
ld *ar2bwd,#STOPBITSHFT,b ; shift 1/2 stop bit so upper 4 bits are in middle of BL
ld #0,a ; init the decoded word to 0000h
and @decodeMask,b ; only look at bits 6-9
sub @mask1011b,b ; check if equal to 11-15, (i.e. will decode to a 1)
bcd DecodeOne,bgeq ; if it is a 1 instead, branch to decode of 1
add @mask0100b,b ; check if equal to -4 (i.e. if was originally a 7)
sftl a,1 ; assume it is a 0 by shifting in 0 into the LSb of decoded word
nop ; need 2 cycles latency for xc
xc 1,beq ; if it is equal to 7, decode to 1
DecodeOne: ;
or @one,a ; or the 1 into the LSb of decoded word
ld *ar2bwd,b ; load the next coded bit
DecodeLoop: ; at end, A holds decoded character
and #STOPBIT,a,b ; check the decoded stop bit
xc 2,aeq ; if stop bit and all data/parity bits are 0,
orm #BI,@_UARTLSR ; note a break detected
xc 2,beq ; if stop bit is invalid (i.e. 0),
orm #FE,@_UARTLSR ; note the framing error
and #(~STOPBIT)&0xffff,a ; strip the stop bit
.if PARITY!=NO
call ParityCheck ; check if the parity is valid and strip parity bit
.endif ; char output in AL
stl a,@rxchar ; store the char
bitf @_UARTLSR,#DR ; check if previous character read yet
orm #DR,@_UARTLSR ; indicate character is ready in rxchar
xc 2,tc ; if it was not read (i.e. DR=1 before we just set it),
orm #OE,@_UARTLSR ; note the overrun error
.if INTERRUPT_BASED ; only do this if user wants to run ISRs for status changes
call _UARTRBFint ; call ISR to process received data
bitf @_UARTLSR,#(BI|FE|PE|OE) ; check for any line status interrupt events
cc _UARTLSIint,tc ; if any events set, call the ISR
.endif
popm rea ; restore context
popm rsa ;
popm brc ;
popm ar2 ;
popm st1 ;
popm st0 ;
popm bg ;
popm bh ;
popm bl ;
popm ag ;
popm ah ;
popm al ;
rete ; return and enable global interrupts
*****************************************************************
* Function: _UARTDMATxISR *
* Purpose: ISR which runs whenever DMA has moved last *
* "bit" of coded character to DXR. *
* This occurs when each half of the raw Tx *
* buffer is emptied by the DMA Tx channel. *
* Resets a flag to indicate transmit process *
* is over and disables DMA Tx ch if no more *
* pkts in Tx buffer. *
* Inputs: none *
* Outputs: none *
* Modified: none *
*****************************************************************
_UARTDMATxISR:
pshm st0
addm #-1,*(numTxPkts) ; decrement # of Tx pkts in Tx buffer
cmpm *(numTxPkts),#1 ; check if another pkt is ready for transmit still
orm #THRE,*(_UARTLSR) ; signal that another pkt can be put in Tx buffer
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -