⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bbu_uart.s

📁 关于PXA310的最小系统的程序,初级学习阶段会有所帮助,汇编语言编写的
💻 S
📖 第 1 页 / 共 5 页
字号:
        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 + -