📄 bbu_uart.s
字号:
; in the buffer).
;
BBU_FFgetchr FUNCTION
stmfd sp!, {r1-r3, lr} ; Save r1-r3 and link register on the stack
ldr r2, =bbu_FFUART_PHYSICAL_BASE ; FFUART base address
IF :DEF: bbu_FF_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 %F22 ; No - just return
ldr r0, [r1, #bbu_UARBR_offset] ; Yes - Fetch byte out of receive buffer
22 ldmfd sp!, {r1-r3, pc} ; Restore r1-r3 and return to caller
ENDFUNC
;
;*********************************************************************************
;
; ****************
; * *
; * BBU_STgetchr * Subroutine "BBU Get Character" from the Standard UART
; * *
; ****************
;
; This subroutine places the received character in r0 from the Standard UART.
;
; Unlike the regular BBU "getchr" subroutine, this subroutine does not echo received
; characters back to the STUART. It only fetches characters from the STUART
;
; PARAMETER PASSING:
;
; INPUT:
;
; NO PARAMETERS
;
; OUTPUT:
; r0 returns the ASCII value received (0x0 indicates no character was
; in the buffer).
;
BBU_STgetchr FUNCTION
stmfd sp!, {r1-r3, lr} ; Save r1-r3 and link register on the stack
ldr r2, =bbu_STUART_PHYSICAL_BASE ; STUART base address
IF :DEF: bbu_ST_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 %F24 ; No - just return
ldr r0, [r1, #bbu_UARBR_offset] ; Yes - Fetch byte out of receive buffer
24 ldmfd sp!, {r1-r3, pc} ; Restore r1-r3 and return to caller
ENDFUNC
;
;*********************************************************************************
;
; **************
; * *
; * BBU_getstr * Subroutine "BBU Get String"
; * *
; **************
;
; This subroutine will fetch an ASCII string from the BBU UART. When the user presses
; the <return> key it will be replaced in BBU_ibuf with a NULL byte.
;
;
; 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
;
; OUTPUT:
; ASCII string output stored at address "BBU_ibuf"
;
; NOTES:
;
; 1. The selected UART port must be initalized first - otherwise this will hang!
;
; 2. There is "backspace" protection so the user can't backspace over code that is
; below the start of the buufer.
;
; 3. There is buffer overrun protection however if the user enters over 78 bytes
; the terminal emulator will not accurately represent what is actually in the
; buffer.
;
; Control is passed back to the caller only after the user presses the <return> key.
;
BBU_getstr FUNCTION
stmfd sp!, {r0-r6, lr} ; Save used registers on the stack
mov r6, r0 ; Copy r0 to r6
ldr r2, =BBU_ibuf ; Load address of input buffer
mov r1, #0 ; Zero out byte count
90 mov r0, r6 ; Copy user parameter back to r0
bl BBU_getchr ; Fetch a character from the BBU UART
cmp r0, #0 ; Anything come in?
beq %B90 ; No - keep waiting for something
;
; At last! the user typed something! - see what needs to be done.
; <return>, <backspace> and a value of 0xFF are the only special keys
; BBU worries about.
;
cmp r0, #0x8 ; Was it a <backspace>?
beq %F92 ; Yes - take care of this special case
cmp r0, #0xD ; Was it a <return>?
beq %F94 ; Yes - take care of this special case
cmp r0, #0xFF ; Was an <up arrow> detected?
beq %F98 ; Yes - restore previously entered command
;
; If the code fell through to this point - add the byte to the BBU input buffer
;
cmp r1, #78 ; Is the input byte count up to 78?
beq %B90 ; Yes - Ignore and wait for another byte
strb r0, [r2], #1 ; Store byte in buffer and increment pointer
add r1, r1, #1 ; Increment byte count
b %B90 ; Fetch another byte
;
; A <backspace> was entered - update the buffer
;
92 cmp r1, #0 ; Is the byte count zero?
beq %B90 ; Yes - don't let user "backspace" over code!
sub r1, r1, #1 ; Decrement byte count
sub r2, r2, #1 ; Decrement byte pointer
b %B90 ; Fetch another byte
;
; A <return> was entered - Stuff a NULL in the buffer
;
94 mov r0, #0 ; Change data to a NULL
strb r0, [r2] ; Place it in the buffer
;
; Copy BBUs input buffer into BBUs recall buffers to allow the user to recall
; two previously typed input strings.
;
ldr r0, =BBU_ibuf ; Input buffer address
ldr r1, =BBU_rbuf1 ; Recall buffer #1 address
ldr r4, =BBU_rbuf2 ; Recall buffer #2 address
mov r2, #20 ; Copy 20 double words (80 bytes)
96 ldr r3, [r1] ; Fetch data from recall buffer #1
str r3, [r4], #4 ; Copy to recall buffer #2
ldr r3, [r0], #4 ; Fetch data from the BBU input buffer
str r3, [r1], #4 ; Save it in recall buffer #1
subs r2, r2, #1 ; Decrement word counter
bne %B96 ; Keep looping until it's all moved
ldmfd sp!, {r0-r6, pc} ; Return to caller
;
; <up arrow> detected - restore the previous command entered by the user
; Copy recall buffer #1 to BBU's input buffer.
;
98 ldr r2, =BBU_ibuf ; Input buffer address
ldr r0, =BBU_rbuf1 ; Recall buffer #1 address
mov r1, #80 ; Copy up to 80 bytes
99 ldrb r3, [r0], #1 ; Read a byte into r3 and increment r0 by 1
strb r3, [r2], #1 ; Write the byte in r3 and increment r2 by 1
cmp r3, #0 ; Was this a NULL byte?
beq %F70 ; Yes - exit from the loop
subs r1, r1, #1 ; Decrement byte counter
bne %B99 ; Keep looping until it's all moved
;
; Copy recall buffer #2 to recall buffer #1
;
70 ldr r0, =BBU_rbuf1 ; Recall buffer #1 address
ldr r3, =BBU_rbuf2 ; Recall buffer #2 address
mov r4, #20 ; Move 20 4-byte words (80 bytes)
75 ldr r5, [r3], #4 ; Fetch 4 bytes from recall buffer 2
str r5, [r0], #4 ; Place into recall buffer 1
subs r4, r4, #1 ; Decrement word count
bne %B75 ; Loop until done
;
; "Repaint" the current command line by doing a <cr>, chear the line
; output another <cr>, BBU prompt, and display the previously entered
; command line.
;
mov r0, #0xD ; <cr> character
bl BBU_putchr ; Output <cr>
mov r1, #70 ; Send 70 characters
mov r0, #' ' ; Put a <space> in r0
77 bl BBU_putchr ; Output a <space>
subs r1, r1, #1 ; Decrement count
bne %B77 ; Loop until done
mov r0, #0xD ; <cr> character
bl BBU_putchr ; Output <cr>
ldr r0, =BBU_PROMPT_MSG ; BBU's prompt
bl BBU_putstr ; Output this
ldr r0, =BBU_ibuf ; Now contains the previous user input
bl BBU_putstr ; Output this
;
; r1 needs to contain the number of characters in the input string. All
; BBU needs to do here is subtract the BBU_ibuf address from r1. r2 needs
; to point to the current character location in the input buffer.
;
ldr r0, =BBU_ibuf ; Address of buffer
sub r1, r2, r0 ; Caclculate # of bytes
sub r1, r1, #1 ; Subtract 1 more to counteract the post increment
sub r2, r2, #1 ; Need to back up pointer by 1 byte
b %B90 ; Wait for user input
ENDFUNC
;
;*********************************************************************************
;
; ***************
; * *
; * BBU_TXempty * Subroutine
; * *
; ***************
;
; This subroutine does not return to the caller until the BBU UART transmitter buffer is empty
;
; PARAMETER PASSING:
;
; No parameters required
;
; NOTES:
;
; 1. The selected UART port must be initalized first - otherwise this will hang the system!
;
; Control is passed back to the caller only after the transmitter buffer has been emptied of
; all characters on the FIFO buffer.
;
BBU_TXempty FUNCTION
stmfd sp!, {r0, r1, lr} ; Save r0, r1 and link register on the stack
ldr r1, =bbu_BBUART_PHYSICAL_BASE
100 ldr r0, [r1, #bbu_UALSR_offset] ; Get Line Status Register Data
ands r0, r0, #bbu_TEMT ; Is TDRQ (Transmit Data Request) bit set?
beq %B100 ; No - loop until it is
ldmfd sp!, {r0, r1, pc} ; Restore r0, r1 and return to caller
ENDFUNC
;
;*********************************************************************************
;
; ******************
; * *
; * BBU_BT_TXempty * Subroutine
; * *
; ******************
;
; This subroutine does not return to the caller until the Bluetooth UART
; transmitter buffer is empty
;
; PARAMETER PASSING:
;
; No parameters required
;
; NOTES:
;
; 1. The selected UART port must be initalized first - otherwise this will hang the system!
;
; Control is passed back to the caller only after the transmitter buffer has been emptied of
; all characters on the FIFO buffer.
;
BBU_BT_TXempty FUNCTION
stmfd sp!, {r0, r1, lr} ; Save r0, r1 and link register on the stack
ldr r1, =bbu_BTUART_PHYSICAL_BASE
102 ldr r0, [r1, #bbu_UALSR_offset] ; Get Line Status Register Data
ands r0, r0, #bbu_TEMT ; Is TDRQ (Transmit Data Request) bit set?
beq %B102 ; No - loop until it is
ldmfd sp!, {r0, r1, pc} ; Restore r0, r1 and return to caller
ENDFUNC
;
;*********************************************************************************
;
; ******************
; * *
; * BBU_FF_TXempty * Subroutine
; * *
; ******************
;
; This subroutine does not return to the caller until the Full Feature UART
; transmitter buffer is empty
;
; PARAMETER PASSING:
;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -