URL
https://opencores.org/ocsvn/rtf65002/rtf65002/trunk
Subversion Repositories rtf65002
[/] [rtf65002/] [trunk/] [software/] [asm/] [serial.asm] - Rev 40
Compare with Previous | Blame | View Log
; ============================================================================; __; \\__/ o\ (C) 2014 Robert Finch, Stratford; \ __ / All rights reserved.; \/_// robfinch<remove>@opencores.org; ||;;; This source file is free software: you can redistribute it and/or modify; it under the terms of the GNU Lesser General Public License as published; by the Free Software Foundation, either version 3 of the License, or; (at your option) any later version.;; This source file is distributed in the hope that it will be useful,; but WITHOUT ANY WARRANTY; without even the implied warranty of; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the; GNU General Public License for more details.;; You should have received a copy of the GNU General Public License; along with this program. If not, see <http://www.gnu.org/licenses/>.;; ============================================================================;UART EQU 0xFFDC0A00UART_LS EQU 0xFFDC0A01UART_MS EQU 0xFFDC0A02UART_IS EQU 0xFFDC0A03UART_IE EQU 0xFFDC0A04UART_MC EQU 0xFFDC0A06UART_CM1 EQU 0xFFDC0A09UART_CM2 EQU 0xFFDC0A0AUART_CM3 EQU 0xFFDC0A0Btxempty EQU 0x40rxfull EQU 0x01bssorg 0x01FBC000Uart_rxfifo fill.b 512,0org 0x7D0Uart_rxhead db 0Uart_rxtail db 0Uart_ms db 0Uart_rxrts db 0Uart_rxdtr db 0Uart_rxxon db 0Uart_rxflow db 0Uart_fon db 0Uart_foff db 0Uart_txrts db 0Uart_txdtr db 0Uart_txxon db 0Uart_txxonoff db 0;==============================================================================; Serial port;==============================================================================code;------------------------------------------------------------------------------; Initialize the serial port; r1 = low 28 bits = baud rate; r2 = other settings; The desired baud rate must fit in 28 bits or less.;------------------------------------------------------------------------------;public SerialInit:; asl r1,r1,#4 ; * 16; shlui r1,r1,#32 ; * 2^32; inhu r2,CR_CLOCK ; get clock frequency from config record; divu r1,r1,r2 ; / clock frequencylsr r1,r1,#8 ; drop the lowest 8 bitssta UART_CM1 ; set LSBlsr r1,r1,#8sta UART_CM2 ; set middle bitslsr r1,r1,#8sta UART_CM3 ; set MSBstz Uart_rxhead ; reset buffer indexesstz Uart_rxtaillda #0x1f0sta Uart_foff ; set threshold for XOFFlda #0x010sta Uart_fon ; set threshold for XONlda #1sta UART_IE ; enable receive interrupt onlystz Uart_rxrts ; no RTS/CTS signals availablestz Uart_txrts ; no RTS/CTS signals availablestz Uart_txdtr ; no DTR signals availablestz Uart_rxdtr ; no DTR signals availablelda #1sta Uart_txxon ; for nowlda #1sta SERIAL_SEMArts;---------------------------------------------------------------------------------; Get character directly from serial port. Blocks until a character is available.;---------------------------------------------------------------------------------;public SerialGetCharDirect:sgc1:lda UART_LS ; uart statusand #rxfull ; is there a char available ?beq sgc1lda UARTrts;------------------------------------------------; Check for a character at the serial port; returns r1 = 1 if char available, 0 otherwise;------------------------------------------------;public SerialCheckForCharDirect:lda UART_LS ; uart statusand #rxfull ; is there a char available ?rts;-----------------------------------------; Put character to serial port; r1 = char to put;-----------------------------------------;public SerialPutChar:phxphypush r4push r5ldx UART_MCor r2,r2,#3 ; assert DTR / RTSstx UART_MCldx Uart_txrtsbeq spcb1ld r4,Millisecondsldy #1000 ; delay count (1 s)spcb3:ldx UART_MSand r2,r2,#$10 ; is CTS asserted ?bne spcb1ld r5,Millisecondscmp r4,r5beq spcb3ld r4,r5deybne spcb3bra spcabortspcb1:ldx Uart_txdtrbeq spcb2ld r4,Millisecondsldy #1000 ; delay countspcb4:ldx UART_MSand r2,r2,#$20 ; is DSR asserted ?bne spcb2ld r5,Millisecondscmp r4,r5beq spcb4ld r4,r5deybne spcb4bra spcabortspcb2:ldx Uart_txxonbeq spcb5spcb6:ldx Uart_txxonoffbeq spcb5ld r4,UART_MSand r4,r4,#0x80 ; DCD ?bne spcb6spcb5:ld r4,Millisecondsldy #1000 ; wait up to 1sspcb8:ldx UART_LSand r2,r2,#0x20 ; tx not full ?bne spcb7ld r5,Millisecondscmp r4,r5beq spcb8ld r4,r5deybne spcb8bra spcabortspcb7:sta UARTspcabort:pop r5pop r4plyplxrts;-------------------------------------------------; Compute number of characters in recieve buffer.; r4 = number of chars;-------------------------------------------------CharsInRxBuf:ld r4,Uart_rxheadldx Uart_rxtailsub r4,r4,r2bpl cirxb1ld r4,#0x200add r4,r4,r2ldx Uart_rxheadsub r4,r4,r2cirxb1:rts;----------------------------------------------; Get character from rx fifo; If the fifo is empty enough then send an XON;----------------------------------------------;public SerialGetChar:phxphypush r4ldy Uart_rxheadldx Uart_rxtailcmp r2,r3beq sgcfifo1 ; is there a char available ?lda Uart_rxfifo,x ; get the char from the fifo into r1inx ; increment the fifo pointerand r2,r2,#$1ffstx Uart_rxtailldx Uart_rxflow ; using flow control ?beq sgcfifo2ldy Uart_fon ; enough space in Rx buffer ?jsr CharsInRxBufcmp r4,r3bpl sgcfifo2stz Uart_rxflow ; flow offld r4,Uart_rxrtsbeq sgcfifo3ld r4,UART_MC ; set rts bit in MCor r4,r4,#2st r4,UART_MCsgcfifo3:ld r4,Uart_rxdtrbeq sgcfifo4ld r4,UART_MC ; set DTRor r4,r4,#1st r4,UART_MCsgcfifo4:ld r4,Uart_rxxonbeq sgcfifo5ld r4,#XONst r4,UARTsgcfifo5:sgcfifo2: ; return with char in r1pop r4plyplxrtssgcfifo1:lda #-1 ; no char availablepop r4plyplxrts;-----------------------------------------; Serial port IRQ;-----------------------------------------;public SerialIRQ:phaphxphypush r4lda UART_IS ; get interrupt statusbpl sirq1 ; no interruptand #0x7f ; switch on interrupt typecmp #4beq srxirqcmp #$0Cbeq stxirqcmp #$10beq smsirq; unknown IRQ typesirq1:pop r4plyplxplarti; Get the modem status and record itsmsirq:lda UART_MSsta Uart_msbra sirq1stxirq:bra sirq1; Get a character from the uart and store it in the rx fifosrxirq:srxirq1:lda UART ; get the char (clears interrupt)ldx Uart_txxonbeq srxirq3cmp #XOFFbne srxirq2lda #1sta Uart_txxonoffbra srxirq5srxirq2:cmp #XONbne srxirq3stz Uart_txxonoffbra srxirq5srxirq3:stz Uart_txxonoffldx Uart_rxheadsta Uart_rxfifo,x ; store in bufferinxand r2,r2,#$1ffstx Uart_rxheadsrxirq5:lda UART_LS ; check for another ready characterand #rxfullbne srxirq1lda Uart_rxflow ; are we using flow controls?bne srxirq8jsr CharsInRxBuflda Uart_foffcmp r4,r1bmi srxirq8lda #1sta Uart_rxflowlda Uart_rxrtsbeq srxirq6lda UART_MCand #$FD ; turn off RTSsta UART_MCsrxirq6:lda Uart_rxdtrbeq srxirq7lda UART_MCand #$FE ; turn off DTRsta UART_MCsrxirq7:lda Uart_rxxonbeq srxirq8lda #XOFFsta UARTsrxirq8:bra sirq1
