📄 bbu_uart.s
字号:
bl BBU_putchr ; Output byte to UART
ldmfd sp!, {r0, pc}; Return to caller
ENDFUNC
;
;*********************************************************************************
;
; **************
; * *
; * BBU_getchr * Subroutine "BBU Get Character"
; * *
; **************
;
; This subroutine places the received character in r0 from the selected UART.
;
; This routine will also echo the typed character to the transmit buffer - The assumption is
; BBU code will not have things like passwords that need to be hidden from view. It will also
; echo the <return> key with a <CR><LF> pair. The <Backspace> key echos <Backspace><Space><Backspace>
; but only the <Backspace> code is returned to the calling routine and the programmer will
; have to deal with it. Remember, this subroutine only fetches bytes & does not edit input strings!
;
; Control is returned to the caller with 0x00 in r0 is there is no character in the receive buffer
; rather than waiting for a character to be typed. This makes the subroutine useful in a test loop
; to run a test unti a character is typed on the keyboard. At that point the character can be
; checked and used to cause the program to branch to some other code (for example).
;
; PARAMETER PASSING:
;
; INPUT:
; r0 = Bit 0 set will cause code to skip lower to upper case conversion.
; r0 = Bit 1 set will cause code not to echo the input character
; All other values (other than 1,2 or 3) are ignored
;
; r1 = 0 causes subroutine to return a NULL when any character is entered
;
; OUTPUT:
; r0 returns the ASCII value entered by the user
; r1 - Input value is preserved
;
; NOTES:
;
; 1. The selected UART port must be initalized first - otherwise this will hang the system!
;
; 2. If no data is available in the receive FIFO, r0 is set to 0x00
;
; 3. The character is also placed in the transmit FIFO buffer (echoed)
;
; 4. <backspace> is echoed as <Backspace><Space><Backspace>
; Note: A single backspace character is returned to the caller. This routine
; does not "remove" the character from an input string! If r2 is
; zero, the backspace is not echoed.
;
; 5. <Return>(also known as <CR>) will echo <CR><LF> to the transmit FIFO buffer
; A single <CR> is returned to the caller in r0.
;
; 6. A <ctrl>C entry will cause a branch to BBU_MCR which gets the user
; to the BBU prompt.
;
; 7. If the user enters an <up arrow> (escape sequence) this routine will return
; the value 0xFF in r0.
;
BBU_getchr FUNCTION
stmfd sp!, {r1-r5, lr} ; Save r1-r5 and link register on the stack
;
; Check to see if the IrDA interface is enable and re-configure the
; transceiver to receive IrDA data if this is the case.
;
ldr r5, =bbu_stat_data ; Get address where system status data is stored
ldr r4, [r5] ; Fetch the current BBU Status
ldr r2, =bbu_BBUART_PHYSICAL_BASE ; BBUART base address
ands r4, r4, #BBU_STAT_IRDA ; Is the IrDA bit set?
beq %F79 ; Skip the following if IrDA is disabled
;
; IrDA interface in use = call BBU_TXempty to insure xmit buffer is empty
; before switching to IrDA trasmit mode since IrDA runs in half duplex.
;
bl BBU_TXempty ; Insure the transmit buffer is empty
;
; Switch IrDA tranceiver to receive mode (if IrDA bit was set)
;
mov r3, #0X16 ; Set UART for IRDA receive use
str r3, [r2, #bbu_UAISR_offset] ; Set Infrared Select Register
;
; Only set up r4 if r0 = 1, 2, or 3
;
79 mov r5, #0 ; Clear r5
cmp r0, #1 ; Is r0 = 1?
moveq r5, r0 ; Yes - copy to r5
cmp r0, #2 ; Is r0 = 2?
moveq r5, r0 ; Yes - copy to r5
cmp r0, #3 ; Is r0 = 3?
moveq r5, r0 ; Yes - copy to r5
mov r0, #0 ; Pre-load r0 with zero (meaning no character received)
ldr r3, [r2, #bbu_UALSR_offset] ; Get Line Status Register Data
ands r3, r3, #bbu_DR ; Is the data ready bit set?
beq %F89 ; No - just return
;
; There is a character in the receive buffer - fetch the character and echo it in the transmit buffer
;
80 ldr r1, =bbu_stat_data ; Get address where system status data stored
ldr r3, [r1] ; Fetch BBU status word
ldr r1, =bbu_BBUART_PHYSICAL_BASE
ands r3, r3, #BBU_STAT_IRDA ; Test for IrDA port enable
beq %F801 ; Skip the following if RS232 port is used
;
; The following 2 lines of code set up the UART for IrDA transmit use
;
mov r3, #0X15 ; Set UART for IrDA transmit use
str r3, [r1, #bbu_UAISR_offset] ; Set Infrared Select Register
;
; Code needs to fetch and save the interrupt controller status BEFORE the
; byte is fetched from the UART as clearing the FIFO resets the interrupt
; controller status!
;
801 mrc p6, 0, r4, c5, c0, 0 ; Get interrupt controller status
ldr r0, [r2, #bbu_UARBR_offset] ; Fetch byte out of receive buffer
cmp r0, #0 ; Was byte a NULL?
beq %F89 ; Yes - just return
ands r3, r5, #0x2 ; Skip byte echo?
bne %F70 ; Yes - check for case conversion
cmp r0, #0x3 ; Was byte a <ctrl>C?
beq %F88 ; Yes - branch to special code below
cmp r0, #0x1B ; Was byte an <escape>?
beq %F90 ; Yes - Take a special path.
cmp r0, #0x8 ; is it a backspace?
bne %F81 ; No - echo the character
cmp r1, #0 ; is r1 = 0? (assuming BBU_getstr called this!)
moveq r0, #0 ; Yes - place a NULL into r0...
beq %F89 ; ...and return
81 ldr r3, [r2, #bbu_UALSR_offset] ; Get Line Status Register Data
ands r3, r3, #bbu_TDRQ ; Is TDRQ (Transmit Data Request) bit set?
beq %B81 ; No - loop until it is
str r0, [r2, #bbu_UATHR_offset] ; It's ready! - output byte to buffer
;
; If the byte was <CR>, then also echo a <LF> byte to the transmit buffer
;
cmp r0, #0x0D ; Was byte a <CR>?
bne %F83 ; no - Check for <Backspace>
;
; <CR> was entered and already echoed - also echo a <LF> character
;
82 ldr r3, [r2, #bbu_UALSR_offset] ; Get Line Status Register Data
ands r3, r3, #bbu_TDRQ ; Is TDRQ (Transmit Data Request) bit set?
beq %B82 ; No - loop until it is
mov r3, #0x0A ; Move <LF> into r3
str r3, [r2, #bbu_UATHR_offset] ; send <LF> byte to transmit buffer
b %F89 ; Exit path
;
; Check for backspace
;
83 cmp r0, #0x8 ; Was byte a <Backspace>?
beq %F84 ; Yes - process the backspace
;
; Check for a lower case ASCII character and, if found, make it UPPER CASE
;
70 ands r5, r5, #1 ; Skip lower to upper case conversion?
bne %F89 ; Yes - take the return path
cmp r0, #'a' ; Is the byte lower than "a"?
blt %F89 ; Yes - take return path
cmp r0, #'z' ; Is the byte higher then "z"?
bgt %F89 ; Yes - take return path
and r0, r0, #0xDF ; Clear bit 4 to make UPPER CASE...
b %F89 ; ...and return
;
; <Backspace> was entered (and already echoed) - Follow this up with <Space><Backspace>
;
84 ldr r3, [r2, #bbu_UALSR_offset] ; Get Line Status Register Data
ands r3, r3, #bbu_TDRQ ; Is TDRQ (Transmit Data Request) bit set?
beq %B84 ; No - loop until it is
mov r3, #0x20 ; Move <Space> into r3
str r3, [r2, #bbu_UATHR_offset] ; send <Space> byte to transmit buffer
85 ldr r3, [r2, #bbu_UALSR_offset] ; Get Line Status Register Data
ands r3, r3, #bbu_TDRQ ; Is TDRQ (Transmit Data Request) bit set?
beq %B85 ; No - loop until it is
mov r3, #0x08 ; Move <Backspace> into r3
str r3, [r2, #bbu_UATHR_offset] ; send <Backspace> byte to transmit buffer
86 mov r0, #1 ; Delay time
bl BBU_msWait ; Needed in case IrDA interface is being used.
mov r0, #8 ; Restore backspace char for return to caller
b %F89 ; Exit path
;
; <ctrl>C was entered - The return path is variable!
;
88 ldr r0, =BBU_CTRL_C ; Send out ^C string with <cr><lf>
bl BBU_putstr ; Send it out
;
; The return path taken depends on if STUART interrupts are enabled or
; not!! The valid ID bit must be set for ISR return!
;
ldr r1, =BBU_MCR ; Return address - BBU MAIN LOOP!
ands r3, r4, #0x80000000 ; Is there a valid interrupt ID?
moveq pc, r1 ; No - Branch to main BBU loop
;
; If the code gets here BBU assumes we are in an ISR.
;
mov r0, #3 ; Move ^C character into r0
;
89 ldmfd sp!, {r1-r5, pc} ; Restore r1-r5 and return to caller
;
; The path below is taken if the user entered an escape character which
; could be the start of an escape sequence. BBU dealys breifly to see if
; other characters will be comming in after the <esc>. If not, BBU returns
; the <esc> character. If not, BBU scans the input looking for an <up arrow>
; entry that will be used to restore the user's previously entered line.
;
90 mov r5, r0 ; Save off the escape character
mov r0, #15 ; Set up for delay
bl BBU_msWait ; Delay r0 mS
mov r0, r5 ; Restore the <esc> bute
ldrb r1, [r2, #bbu_UARBR_offset] ; Fetch a byte out of receive buffer
cmp r1, #'[' ; Is the next byte a '['?
bne %F96 ; Nope - take the exit path
ldrb r1, [r2, #bbu_UARBR_offset] ; Fetch a byte out of receive buffer
cmp r1, #'A' ; Is the next byte a 'A'?
bne %F96 ; Nope - take the exit path
mov r0, #0xFF ; Yes - return 0xFF <up arrow> indicator
96 ldmfd sp!, {r1-r5, pc} ; Restore r1-r5 and return to caller
BBU_CTRL_C DCB "^C",0xD,0xA,0xA,0 ; ^C<cr><lf><lf> is sent out
ALIGN 4
ENDFUNC
;
;*********************************************************************************
;
; ****************
; * *
; * BBU_BTgetchr * Subroutine "BBU Get Character" from BlueTooth UART
; * *
; ****************
;
; This subroutine places the received character in r0 from the BlueTooth UART.
;
; Unlike the regular BBU "getchr" subroutine, this subroutine does not echo received
; characters back to the BTUART. It only fetches characters from the BTUART
;
; PARAMETER PASSING:
;
; INPUT:
;
; NO PARAMETERS
;
; OUTPUT:
; r0 returns the ASCII value received (0x0 indicates no character was
; in the buffer).
;
BBU_BTgetchr FUNCTION
stmfd sp!, {r1-r3, lr} ; Save r1-r3 and link register on the stack
ldr r2, =bbu_BTUART_PHYSICAL_BASE ; BTUART base address
IF :DEF: bbu_BT_IRDA ; This code is for IRDA use only!
mov r3, #0X16 ; Set UART for IRDA receive use
str r3, [r2, #bbu_UAISR_offset] ; Set Infrared Select Register
ENDIF
mov r0, #0 ; Pre-load r0 with zero (meaning no character received)
ldr r3, [r1, #bbu_UALSR_offset] ; Get Line Status Register Data
ands r3, r3, #bbu_DR ; Is the data ready bit set?
beq %F20 ; No - just return
ldr r0, [r1, #bbu_UARBR_offset] ; Yes - Fetch byte out of receive buffer
20 ldmfd sp!, {r1-r3, pc} ; Restore r1-r3 and return to caller
ENDFUNC
;
;*********************************************************************************
;
; ****************
; * *
; * BBU_FFgetchr * Subroutine "BBU Get Character" from the Full eature UART
; * *
; ****************
;
; This subroutine places the received character in r0 from the Full Feature UART.
;
; Unlike the regular BBU "getchr" subroutine, this subroutine does not echo received
; characters back to the FFUART. It only fetches characters from the FFUART
;
; PARAMETER PASSING:
;
; INPUT:
;
; NO PARAMETERS
;
; OUTPUT:
; r0 returns the ASCII value received (0x0 indicates no character was
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -