📄 uart.asm
字号:
*****************************************************************
* Filename: uart.asm *
* Function: Software UART *
* Author: Robert J. DeNardo *
* Texas Instruments, Inc *
* Revision History: *
* 11/12/99 Original Code Robert DeNardo *
* 12/21/99 Increased data bits to 1-15. Robert DeNardo *
* Disabled ints during RxChar & *
* TxChar. Break routine rewritten. *
* Removed numTxPkts check from TxChar *
* routine. Removed 'ssbx CPL' in *
* RxISR. Added latency after McBSP *
* reset. Disabled DMA chs and McBSP *
* in Init. Moved INTOSEL init to Init. *
* Disable and enable GRST during McBSP *
* reg writes. Removed UART stop and *
* start from SetBaud routine. Fixed *
* break detect to check stop bit=0 too. *
* Check lower 4 bits of stop bit, not *
* upper. *
* 1/07/00 Added workaround for 5402 DMA ABU Robert DeNardo *
* Added (inc/dec)rement option for *
* DMA pointers. *
* 09/05/00 Fixed _UARTDMATxISR to conditionally Robert DeNardo *
* turn off DMA BEFORE calling *
* _UARTTBEint. Keeps DMA from turning *
* off too late or from turning off even *
* if new packet in buffer. *
* *
* *
* Notes: *
* This code implements a software UART using a McBSP and 2 DMA *
* channels, with the following features: *
* *
* Generation of start and stop bits *
* Compile-time selectable data length (1-15 bits) *
* Compile-time selectable stop bit length (1, 1.5, 2 bits) *
* Compile-time selectable parity (none,even,odd,mark,space) *
* Compile- and Run-time selectable baud rate *
* Break detection and generation *
* Parity detection and generation *
* Overrun detection *
* Framing error detection *
* Double buffered receive and transmit signals *
* Routines to transmit and receive characters *
* Error condition ISR *
* *
* Parameters: *
* All parameters which the user can set are defined in the *
* UARTsetup.inc file. *
* *
* Public Routines: *
* All public routines are C callable. Routines which the *
* user may access include: *
* _UARTDMARxISR - must be branched to from DMA Rx channel *
* interrupt vector. *
* _UARTDMATxISR - must be branched to from DMA Tx channel *
* interrupt vector. *
* _UARTTxChar - transmits a character *
* _UARTRxChar - reads last received character *
* _UARTStart - starts the UART *
* _UARTStop - stops the UART *
* _UARTInit - initializes the McBSP and DMA for the UART *
* _UARTSetBaudRate - changes the baud rate *
* _UARTSetBreak - sends a break *
* *
* If using INTERRUPT_BASED mode, user must define these funcs: *
* _UARTLSIint - handles error conditions *
* _UARTRBFint - handles received chars *
* _UARTTBEint - handles new transmission *
* *
* Public Registers: *
* _UARTLSR - contains status bits. See register definition *
* in UARTsetup.inc for bit information. *
* *
* *
* This code uses the DMA ABU mode. It was tested with an *
* interface to a PC COM port through an RS232 level shifter. *
* on a 5410 EVM and 5402 DSK, and with an interface to a *
* HW UART. *
* * *
* McBSP is selectable for the interface (default=0) *
* DMA Channel for Receive is selectable (default=4) *
* DMA Channel for Transmit is selectable (default=5) *
* *
* Hardware setup: *
* Data receive line must be tied to FSR and DR of the McBSP. *
* The data transmit line must be tied to the DX pin of the *
* McBSP. *
* *
* See the 'Implementing a Software UART on the *
* TMS320C54xx Using a McBSP and DMA' Application Note *
* for detailed information on how this code works and *
* how it can be used (SPRA661). *
*****************************************************************
.version 548
.mmregs
*********** public routines defined in this file ****************
.def _UARTDMARxISR
.def _UARTDMATxISR
.def _UARTTxChar
.def _UARTRxChar
.def _UARTStart
.def _UARTStop
.def _UARTInit
.def _UARTSetBaudRate
.def _UARTSetBreak
*********** public variables defined in this file ***************
.def _UARTLSR
***************** Equates used in this file *********************
; parity choices
NO .set 0
EVEN .set 1
ODD .set 2
MARK .set 3
SPACE .set 4
; decoder equates
DECODER_MASK .set 0xF<<6 ; only test middle 4 bits of 16 bit word
MASK1011b .set 1011b<<6; used to test for a 1
MASK0100b .set 0100b<<6; used to test for a 1
ONE .set 1 ;
STOPBITSHFT .set 6 ; amount to left shift half stop bit before decoding
; puts lower 4 bits into center of 16 bit word
; McBSP register addresses
SPSA0 .set 38h ; address of McBSP0 subaddress register
DRR10 .set 21h ; address of McBSP0 DRR1 register
DXR10 .set 23h ; address of McBSP0 DXR1 register
SPSA1 .set 48h ; address of McBSP1 subaddress register
DRR11 .set 41h ; address of McBSP1 DRR1 register
DXR11 .set 43h ; address of McBSP1 DXR1 register
SPSA2 .set 34h ; address of McBSP2 subaddress register
DRR12 .set 31h ; address of McBSP2 DRR1 register
DXR12 .set 33h ; address of McBSP2 DXR1 register
; offsets for McBSP sub-addressed registers
SPCR1 .set 0 ; Serial Port Control Register 1
SPCR2 .set 1 ; Serial Port Control Register 2
RCR1 .set 2 ; Receive Control Register 1
RCR2 .set 3 ; Receive Control Register 2
XCR1 .set 4 ; Transmit Control Register 1
XCR2 .set 5 ; Transmit Control Register 2
SRGR1 .set 6 ; Sample Rate Generator Register 1
SRGR2 .set 7 ; Sample Rate Generator Register 2
PCR .set 14 ; Pin Control Register
; SPCR1 -- bit definitions
RRST .set 1<<0 ; RRST_ bit
; SPCR2 -- bit definitions
XRST .set 1<<0 ; XRST_ bit mask
XRDY .set 1<<1 ; XRDY bit mask
GRST .set 1<<6 ; GRST_ bit mask
FRST .set 1<<7 ; FRST_ bit mask
; Reset Latency -- amount of time needed after McBSP is put in or out of reset
RESET_LATENCY .set 2*256 ; max time is 2 bit clocks for max divisor (256)
; DMA register addresses
DMPREC .set 54h ; channel PRiority and Enable Control register
DMSA .set 55h ; Sub-Bank Access Register
DMSDI .set 56h ; Sub-Bank Access Register with Auto-Increment
DMSDN .set 57h ; Sub-Bank Access Register without Auto-Increment
; offsets for DMA sub-addressed registers
DMSRC0 .set 0 ; Channel 0 Source Address Register (first reg for ch 0)
DMSRC1 .set 5 ; Channel 1 Source Address Register (first reg for ch 1)
DMSRC2 .set 10 ; Channel 2 Source Address Register (first reg for ch 2)
DMSRC3 .set 15 ; Channel 3 Source Address Register (first reg for ch 3)
DMSRC4 .set 20 ; Channel 4 Source Address Register (first reg for ch 4)
DMSRC5 .set 25 ; Channel 5 Source Address Register (first reg for ch 5)
; DMPREC:DE -- DMA channel enable definitions
DMAch0 .set 1<<0
DMAch1 .set 1<<1
DMAch2 .set 1<<2
DMAch3 .set 1<<3
DMAch4 .set 1<<4
DMAch5 .set 1<<5
; DMSFC:DSYN -- DMA sync event definitions
REVT0 .set 0001b ; McBSP0 receive event
XEVT0 .set 0010b ; McBSP0 transmit event
REVT2 .set 0011b ; McBSP2 receive event
XEVT2 .set 0100b ; McBSP2 transmit event
REVT1 .set 0101b ; McBSP1 receive event
XEVT1 .set 0110b ; McBSP1 transmit event
;IMR/IFR bit definitions
DMAC0int .set 1<<6
DMAC1int .set 1<<7
DMAC2int .set 1<<10
DMAC3int .set 1<<11
DMAC4int .set 1<<12
DMAC5int .set 1<<13
.copy "UARTsetup.inc" ; contains USER specifications for UART
***************** Config Error Checking *****************
.if ((MCBSP_CHOICE>2)|(MCBSP_CHOICE<0))
.emsg "CONFIG ERROR: MCBSP_CHOICE limited to 0, 1, or 2"
.endif
.if ((DMA_RX_CHOICE>5)|(DMA_RX_CHOICE<0))
.emsg "CONFIG ERROR: DMA_RX_CHOICE limited to 0-5"
.endif
.if ((DMA_TX_CHOICE>5)|(DMA_TX_CHOICE<0))
.emsg "CONFIG ERROR: DMA_TX_CHOICE limited to 0-5"
.endif
.if (DMA_RX_CHOICE==DMA_TX_CHOICE)
.emsg "CONFIG ERROR: DMA_RX_CHOICE and DMA_TX_CHOICE must be different"
.endif
.if (INTOSEL<0)|(INTOSEL>3)
.emsg "CONFIG ERROR: INTOSEL limited to 0-3"
.endif
.if (PARITY<NO)|(PARITY>SPACE)
.emsg "CONFIG ERROR: PARITY limited to NO, EVEN, ODD, MARK or SPACE"
.endif
.if (PARITY!=NO)&((DATABITS>14)|(DATABITS<1))
.emsg "CONFIG ERROR: With PARITY, DATABITS limited to 1-14"
.endif
.if (PARITY==NO)&((DATABITS>15)|(DATABITS<1))
.emsg "CONFIG ERROR: Without PARITY, DATABITS limited to 1-15"
.endif
.if ((HSTOPBITS>4)|(HSTOPBITS<2))
.emsg "CONFIG ERROR: HSTOPBITS limited to 2, 3, or 4"
.endif
.if ((DMA_PTR_MOD<0)|(DMA_PTR_MOD>1))
.emsg "CONFIG ERROR: DMA_PTR_MOD limited to 0 or 1"
.endif
.if ((DMA_ABU_FIX<0)|(DMA_ABU_FIX>1))
.emsg "CONFIG ERROR: DMA_ABU_FIX limited to 0 or 1"
.endif
**************** Config Determinations ******************
.if PARITY==NO
PARITYBITS .set 0
.else
PARITYBITS .set 1
.endif
.if PARITY!=NO ; set position of calculated parity bit for ParityCalc routine
.if DATABITS+PARITYBITS>16
PARITYCHECK .set 1<<31
.elseif DATABITS+PARITYBITS>8
PARITYCHECK .set 1<<15
.elseif DATABITS+PARITYBITS>4
PARITYCHECK .set 1<<7
.elseif DATABITS+PARITYBITS>2
PARITYCHECK .set 1<<3
.elseif DATABITS+PARITYBITS>1
PARITYCHECK .set 1<<1
.endif
.endif
STARTBITS .set 1 ; always 1 start bit
RxHSTOPBITS .set 1 ; Receiver only checks first 1/2 stop bit
TxHSTOPBITS .set HSTOPBITS ; Transmitter sends # half stop bits defined by user
STOPBIT .set 1<<DATABITS+PARITYBITS ; define the stop bit position
TxPKTBITS .set STARTBITS+DATABITS+PARITYBITS+TxHSTOPBITS ; total number of bits in each word
RxPKTBITS .set STARTBITS+DATABITS+PARITYBITS+RxHSTOPBITS ; total number of bits in each word
.if MCBSP_CHOICE==0
SPSA .set SPSA0
DRR1reg .set DRR10 ; need to use 'reg' because DRR1 already defined in .mmregs
DXR1reg .set DXR10 ; need to use 'reg' because DXR1 already defined in .mmregs
REVT .set REVT0
XEVT .set XEVT0
.elseif MCBSP_CHOICE==1
SPSA .set SPSA1
DRR1reg .set DRR11
DXR1reg .set DXR11
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -