UART I/O
; ******************************************************************
; Lab 7
; ******************************************************************
; Name: UART putChar, getChar, printString in assembly.
; Purpose: Get, put, and printstring in assembly using the UART.
; Programmer: Victor Prechtel (1330310)
; Date: 10/29/2007
; ******************************************************************
; *********************************************************************************
; HW;4 - Assembly program to interact with a UART
; *********************************************************************************
; Name : HW;4
; Purpose : Show how to interact with UART (getting and printing characters).
; Notes : Has 5 functions:
; (1) Function to reset the UART
; * Uses function (5) to print out a message
; (2) Error-checking input/output routine
; * Uses function (3) and (4) to interact with the UART
; (3) Function to get a character from the UART
; (4) Function to send a character to the UART
; (5) Function to print NULL-terminated strings
; * Uses function (3) to send characters to the UART
; *********************************************************************************
; ************************
; UART Definitions
; ************************
.set ERROR_STATUS, 1
.set SUCCESS_STATUS, 0
.set UART_base, 0x40600000 /* UART base address */
.set TX_FIFO_FULL, 8 /* Bit-mask for checking TX-FIFO fullness */
.set TX_FIFO_EMPTY, 4 /* Bit-mask for checking TX-FIFO emptiness */
.set RX_FIFO_FULL, 2 /* Bit-mask for checking RX-FIFO fullness */
.set RX_FIFO_VALID, 1 /* Bit-mask for checking RX-FIFO emptiness (if it has valid data or not)*/
.set UART_RX_FIFO_OFFSET, 0 /* receive FIFO, read only */
.set UART_TX_FIFO_OFFSET, 4 /* transmit FIFO, write only */
.set UART_STATUS_REG_OFFSET, 8 /* status register, read only */
.set UART_CONTROL_REG_OFFSET, 12 /* control register, write only */
; ************************
; Pre-formatted strings
; ************************
$msgReset:
.ascii "\r\n Resetting UART...\0\000"
.text
.align 2
$msgAsk:
.ascii "\r\n Waiting for character...\0\000"
.text
.align 2
; ************************
; Main Program
; ************************
.globl main
main:
; ***************************************************************
; Reset the UART
; ***************************************************************
; Setup stack frame for a function call (save link register)
addi r1, r1, -4
swi r15, r1, 0
; Call print function (return address stored in r15)
brlid r15, resetUART
nop
; Restore link register
lwi r15, r1, 0
addi r1, r1, 4
REPEAT:
; ***************************************************************
; Print out a prompt telling the user to enter a character
; ***************************************************************
; Store string in r5
addi r5, r0, $msgAsk
; Setup stack frame for a function call (save link register)
addi r1, r1, -4
swi r15, r1, 0
; Call print function (return address stored in r15)
brlid r15, myPrintString
nop
; Restore link register
lwi r15, r1, 0
addi r1, r1, 4
; ***************************************************************
; Call input/output routine
; ***************************************************************
; Setup stack frame for a function call (save link register)
addi r1, r1, -4
swi r15, r1, 0
; Call getChar function (return address stored in r15)
brlid r15, myInputOutput
nop
; Restore link register
lwi r15, r1, 0
addi r1, r1, 4
; ***************************************************************
; Check return value of input/output routine
; ***************************************************************
; Temporarily store flag value in r13
addi r13, r3, 0
; If (r13 == ERROR_STATUS) then exit program, otherwise continue
rsubi r13, r13, ERROR_STATUS
beqi r13, EXIT_PROGRAM
; ************** Print carriage return (\r = 0x0d = 13) ****************
; Put carriage return in r5
addi r5, r0, 13
; Setup stack frame for a function call (save link register)
addi r1, r1, -4
swi r15, r1, 0
; Call myPrintChar function (return address stored in r15)
brlid r15, myPrintChar
nop
; Restore link register
lwi r15, r1, 0
addi r1, r1, 4
; ************** Print newline (\n = 0x0a = 10) ****************
; Put newline in r5
addi r5, r0, 10
; Setup stack frame for a function call (save link register)
addi r1, r1, -4
swi r15, r1, 0
; Call myPrintChar function (return address stored in r15)
brlid r15, myPrintChar
nop
; Restore link register
lwi r15, r1, 0
addi r1, r1, 4
; ***************************************************************
; Infinitely loop
; ***************************************************************
brid REPEAT
nop
EXIT_PROGRAM:
; Infinitely loop on exit
brid EXIT_PROGRAM
nop
; *************************************
; My FUNCTION Definitions
; *************************************
; ***************************************************************
; Name: resetUART
; Purpose: A routine to reset the UART
; Parameters:
; * NONE
; Return Values:
; * NONE
; Volatiles:
; * Blows away r5, r6, and r7
; ***************************************************************
.globl resetUART
resetUART:
; ********************************************************************
; Reset UART
; ********************************************************************
; Put UARTs base address into r6
addi r6, r0, UART_base
; Turn off UART interrupt (set bit 27 to '1') and Reset Rx and Tx FIFOs (set bits 30 and 31 to '1')
addi r7, r0, 0x13
swi r7, r6, UART_CONTROL_REG_OFFSET
; ********************************************************************
; Print out a message telling the user that the UART is being reset
; ********************************************************************
; Store string in r5
addi r5, r0, $msgReset
; Setup stack frame for a function call (save link register)
addi r1, r1, -4
swi r15, r1, 0
; Call print function (return address stored in r15)
brlid r15, myPrintString
nop
; Restore link register
lwi r15, r1, 0
addi r1, r1, 4
; Return from subroutine
rtsd r15, 8
nop
; ***************************************************************
; Name: myInputOutput
; Purpose: A routine to send/get characters from the UART (with error check)
; Parameters:
; * NONE
; Return Values:
; * r3 has return value flag
; Volatiles:
; * Blows away r5, r6, r7, r8
; ***************************************************************
.globl myInputOutput
myInputOutput:
; Put UART's base address into r6
addi r6, r0, UART_base
; ****************************************************
; Check for errors (bits 24, 25, 26 of STATUS reg)
; ****************************************************
lwi r7, r6, UART_STATUS_REG_OFFSET
andi r7, r7, 0xE0
; If r7 == 0 then get a character
beqi r7, PROCEED
; Otherwise reset the RxFIFO (bit 30)
addi r7, r0, 0x02
swi r7, r6, UART_CONTROL_REG_OFFSET
; Return with error status
addi r3, r0, ERROR_STATUS
rtsd r15, 8
nop
PROCEED:
; ****************************************************
; Read in a character
; ****************************************************
; Save old link register
addi r1, r1, -4
swi r15, r1, 0
; Call myGetChar
brlid r15, myGetChar
nop
; Restore link register
lwi r15, r1, 0
addi r1, r1, 4
; ****************************************************
; Store character in r19 (Save old r19)
; ****************************************************
; Save old r19
addi r1, r1, -4
swi r19, r1, 0
; Move inputted character into r19
addi r19, r3, 0
; ****************************************************
; Write character out
; ****************************************************
; Save old link register
addi r1, r1, -4
swi r15, r1, 0
; Put inputted character into r5 in order to pass to function
addi r5, r19, 0
; Call myPrintChar
brlid r15, myPrintChar
nop
; Restore link register
lwi r15, r1, 0
addi r1, r1, 4
; ****************************************************
; Restore old r19 and return to callee
; ****************************************************
; Pop r19 off the stack
lwi r19, r1, 0
addi r1, r1, 4
; Return with success status
addi r3, r0, SUCCESS_STATUS
rtsd r15, 8
nop
; ***************************************************************
; Name: myPrintChar
; Purpose: A routine to send a character/message to the UART
; Parameters:
; * r5 holds the character of interest
; Return Values:
; * NONE
; Volatiles:
; * Blows away r5, r6, r7, r8
; ***************************************************************
.globl myPrintChar
myPrintChar:
; Put UART's base address into r6
addi r6, r0, UART_base
; Move character (byte) into r8 from character parameter (r5)
addi r8, r5, 0
; Wait until UART's TX FIFO is not full
myPrintCharLoop:
; Look up FIFO status
lwi r7, r6, UART_STATUS_REG_OFFSET
; Mask out the TX_FIFO_FLAG
andi r7, r7, TX_FIFO_FULL
; Loop back if it is not-zero
bnei r7 myPrintCharLoop
nop
; Loop is over
; Send character to the FIFO
swi r8, r6, UART_TX_FIFO_OFFSET
; Return from subroutine
rtsd r15, 8
nop
; ***************************************************************
; Name: myGetChar
; Purpose: A routine to get a character/message from the UART
; Parameters:
; * NONE
; Return Values:
; * r3 will hold the character read in on the UART
; Volatiles:
; * Blows away r5, r6, and r7
; ***************************************************************
.globl myGetChar
myGetChar:
; Put UART's base address into r6
addi r6, r0, UART_base
; Wait until UART's RX FIFO is not empty
myGetCharLoop:
; Look up FIFO status
lwi r7, r6, UART_STATUS_REG_OFFSET
; Mask out the RX_FIFO_DATA_VALID_FLAG
andi r7, r7, RX_FIFO_VALID
; Loop back if it is zero
beqi r7 myGetCharLoop
nop
; Loop is over
; Get character from the RX-FIFO
lwi r3, r6, UART_RX_FIFO_OFFSET
; Return from subroutine
rtsd r15, 8
nop
; ***********************************************************************************
; Name: myPrintString
; Purpose: A routine to send a string (NULL-terminated set of characters) to the UART
; Parameters:
; * r5 holds a pointer to the string of interest
; Volatiles:
; * Blows away r9, r10
; Notes: Uses myPrintChar to send individual characters to the UART
; *********************************************************************************
.globl myPrintString
myPrintString:
; Save r15 to stack (return address of original function call)
addi r1, r1, -4
swi r15,r1,0
; Save character pointer in r9
addk r9, r5, r0
; Init r10 to first character of the string being passed in
lbui r10, r9, 0
.globl stringCharLoop
stringCharLoop:
; Check loop condition (if r10 = null then function is finished)
beqi r10, endStringCharLoop
nop
; Increment character pointer (move to next character)
addi r9, r9, 1
; Move character to print into r5
addi r5, r10, 0
; Call print function (return address stored in r15)
brlid r15, myPrintChar
nop
; Load in new character to print (lookup [msgPointer + counter])
lbui r10, r9, 0
; Branch back to loop condition
bri stringCharLoop
nop
; **** END OF LOOP ****
.globl endStringCharLoop
endStringCharLoop:
; Restore r15 from stack (restore original return address)
lwi r15,r1,0
addi r1, r1, 4
; Return from subroutine
rtsd r15, 8
nop
; Lab 7
; ******************************************************************
; Name: UART putChar, getChar, printString in assembly.
; Purpose: Get, put, and printstring in assembly using the UART.
; Programmer: Victor Prechtel (1330310)
; Date: 10/29/2007
; ******************************************************************
; *********************************************************************************
; HW;4 - Assembly program to interact with a UART
; *********************************************************************************
; Name : HW;4
; Purpose : Show how to interact with UART (getting and printing characters).
; Notes : Has 5 functions:
; (1) Function to reset the UART
; * Uses function (5) to print out a message
; (2) Error-checking input/output routine
; * Uses function (3) and (4) to interact with the UART
; (3) Function to get a character from the UART
; (4) Function to send a character to the UART
; (5) Function to print NULL-terminated strings
; * Uses function (3) to send characters to the UART
; *********************************************************************************
; ************************
; UART Definitions
; ************************
.set ERROR_STATUS, 1
.set SUCCESS_STATUS, 0
.set UART_base, 0x40600000 /* UART base address */
.set TX_FIFO_FULL, 8 /* Bit-mask for checking TX-FIFO fullness */
.set TX_FIFO_EMPTY, 4 /* Bit-mask for checking TX-FIFO emptiness */
.set RX_FIFO_FULL, 2 /* Bit-mask for checking RX-FIFO fullness */
.set RX_FIFO_VALID, 1 /* Bit-mask for checking RX-FIFO emptiness (if it has valid data or not)*/
.set UART_RX_FIFO_OFFSET, 0 /* receive FIFO, read only */
.set UART_TX_FIFO_OFFSET, 4 /* transmit FIFO, write only */
.set UART_STATUS_REG_OFFSET, 8 /* status register, read only */
.set UART_CONTROL_REG_OFFSET, 12 /* control register, write only */
; ************************
; Pre-formatted strings
; ************************
$msgReset:
.ascii "\r\n Resetting UART...\0\000"
.text
.align 2
$msgAsk:
.ascii "\r\n Waiting for character...\0\000"
.text
.align 2
; ************************
; Main Program
; ************************
.globl main
main:
; ***************************************************************
; Reset the UART
; ***************************************************************
; Setup stack frame for a function call (save link register)
addi r1, r1, -4
swi r15, r1, 0
; Call print function (return address stored in r15)
brlid r15, resetUART
nop
; Restore link register
lwi r15, r1, 0
addi r1, r1, 4
REPEAT:
; ***************************************************************
; Print out a prompt telling the user to enter a character
; ***************************************************************
; Store string in r5
addi r5, r0, $msgAsk
; Setup stack frame for a function call (save link register)
addi r1, r1, -4
swi r15, r1, 0
; Call print function (return address stored in r15)
brlid r15, myPrintString
nop
; Restore link register
lwi r15, r1, 0
addi r1, r1, 4
; ***************************************************************
; Call input/output routine
; ***************************************************************
; Setup stack frame for a function call (save link register)
addi r1, r1, -4
swi r15, r1, 0
; Call getChar function (return address stored in r15)
brlid r15, myInputOutput
nop
; Restore link register
lwi r15, r1, 0
addi r1, r1, 4
; ***************************************************************
; Check return value of input/output routine
; ***************************************************************
; Temporarily store flag value in r13
addi r13, r3, 0
; If (r13 == ERROR_STATUS) then exit program, otherwise continue
rsubi r13, r13, ERROR_STATUS
beqi r13, EXIT_PROGRAM
; ************** Print carriage return (\r = 0x0d = 13) ****************
; Put carriage return in r5
addi r5, r0, 13
; Setup stack frame for a function call (save link register)
addi r1, r1, -4
swi r15, r1, 0
; Call myPrintChar function (return address stored in r15)
brlid r15, myPrintChar
nop
; Restore link register
lwi r15, r1, 0
addi r1, r1, 4
; ************** Print newline (\n = 0x0a = 10) ****************
; Put newline in r5
addi r5, r0, 10
; Setup stack frame for a function call (save link register)
addi r1, r1, -4
swi r15, r1, 0
; Call myPrintChar function (return address stored in r15)
brlid r15, myPrintChar
nop
; Restore link register
lwi r15, r1, 0
addi r1, r1, 4
; ***************************************************************
; Infinitely loop
; ***************************************************************
brid REPEAT
nop
EXIT_PROGRAM:
; Infinitely loop on exit
brid EXIT_PROGRAM
nop
; *************************************
; My FUNCTION Definitions
; *************************************
; ***************************************************************
; Name: resetUART
; Purpose: A routine to reset the UART
; Parameters:
; * NONE
; Return Values:
; * NONE
; Volatiles:
; * Blows away r5, r6, and r7
; ***************************************************************
.globl resetUART
resetUART:
; ********************************************************************
; Reset UART
; ********************************************************************
; Put UARTs base address into r6
addi r6, r0, UART_base
; Turn off UART interrupt (set bit 27 to '1') and Reset Rx and Tx FIFOs (set bits 30 and 31 to '1')
addi r7, r0, 0x13
swi r7, r6, UART_CONTROL_REG_OFFSET
; ********************************************************************
; Print out a message telling the user that the UART is being reset
; ********************************************************************
; Store string in r5
addi r5, r0, $msgReset
; Setup stack frame for a function call (save link register)
addi r1, r1, -4
swi r15, r1, 0
; Call print function (return address stored in r15)
brlid r15, myPrintString
nop
; Restore link register
lwi r15, r1, 0
addi r1, r1, 4
; Return from subroutine
rtsd r15, 8
nop
; ***************************************************************
; Name: myInputOutput
; Purpose: A routine to send/get characters from the UART (with error check)
; Parameters:
; * NONE
; Return Values:
; * r3 has return value flag
; Volatiles:
; * Blows away r5, r6, r7, r8
; ***************************************************************
.globl myInputOutput
myInputOutput:
; Put UART's base address into r6
addi r6, r0, UART_base
; ****************************************************
; Check for errors (bits 24, 25, 26 of STATUS reg)
; ****************************************************
lwi r7, r6, UART_STATUS_REG_OFFSET
andi r7, r7, 0xE0
; If r7 == 0 then get a character
beqi r7, PROCEED
; Otherwise reset the RxFIFO (bit 30)
addi r7, r0, 0x02
swi r7, r6, UART_CONTROL_REG_OFFSET
; Return with error status
addi r3, r0, ERROR_STATUS
rtsd r15, 8
nop
PROCEED:
; ****************************************************
; Read in a character
; ****************************************************
; Save old link register
addi r1, r1, -4
swi r15, r1, 0
; Call myGetChar
brlid r15, myGetChar
nop
; Restore link register
lwi r15, r1, 0
addi r1, r1, 4
; ****************************************************
; Store character in r19 (Save old r19)
; ****************************************************
; Save old r19
addi r1, r1, -4
swi r19, r1, 0
; Move inputted character into r19
addi r19, r3, 0
; ****************************************************
; Write character out
; ****************************************************
; Save old link register
addi r1, r1, -4
swi r15, r1, 0
; Put inputted character into r5 in order to pass to function
addi r5, r19, 0
; Call myPrintChar
brlid r15, myPrintChar
nop
; Restore link register
lwi r15, r1, 0
addi r1, r1, 4
; ****************************************************
; Restore old r19 and return to callee
; ****************************************************
; Pop r19 off the stack
lwi r19, r1, 0
addi r1, r1, 4
; Return with success status
addi r3, r0, SUCCESS_STATUS
rtsd r15, 8
nop
; ***************************************************************
; Name: myPrintChar
; Purpose: A routine to send a character/message to the UART
; Parameters:
; * r5 holds the character of interest
; Return Values:
; * NONE
; Volatiles:
; * Blows away r5, r6, r7, r8
; ***************************************************************
.globl myPrintChar
myPrintChar:
; Put UART's base address into r6
addi r6, r0, UART_base
; Move character (byte) into r8 from character parameter (r5)
addi r8, r5, 0
; Wait until UART's TX FIFO is not full
myPrintCharLoop:
; Look up FIFO status
lwi r7, r6, UART_STATUS_REG_OFFSET
; Mask out the TX_FIFO_FLAG
andi r7, r7, TX_FIFO_FULL
; Loop back if it is not-zero
bnei r7 myPrintCharLoop
nop
; Loop is over
; Send character to the FIFO
swi r8, r6, UART_TX_FIFO_OFFSET
; Return from subroutine
rtsd r15, 8
nop
; ***************************************************************
; Name: myGetChar
; Purpose: A routine to get a character/message from the UART
; Parameters:
; * NONE
; Return Values:
; * r3 will hold the character read in on the UART
; Volatiles:
; * Blows away r5, r6, and r7
; ***************************************************************
.globl myGetChar
myGetChar:
; Put UART's base address into r6
addi r6, r0, UART_base
; Wait until UART's RX FIFO is not empty
myGetCharLoop:
; Look up FIFO status
lwi r7, r6, UART_STATUS_REG_OFFSET
; Mask out the RX_FIFO_DATA_VALID_FLAG
andi r7, r7, RX_FIFO_VALID
; Loop back if it is zero
beqi r7 myGetCharLoop
nop
; Loop is over
; Get character from the RX-FIFO
lwi r3, r6, UART_RX_FIFO_OFFSET
; Return from subroutine
rtsd r15, 8
nop
; ***********************************************************************************
; Name: myPrintString
; Purpose: A routine to send a string (NULL-terminated set of characters) to the UART
; Parameters:
; * r5 holds a pointer to the string of interest
; Volatiles:
; * Blows away r9, r10
; Notes: Uses myPrintChar to send individual characters to the UART
; *********************************************************************************
.globl myPrintString
myPrintString:
; Save r15 to stack (return address of original function call)
addi r1, r1, -4
swi r15,r1,0
; Save character pointer in r9
addk r9, r5, r0
; Init r10 to first character of the string being passed in
lbui r10, r9, 0
.globl stringCharLoop
stringCharLoop:
; Check loop condition (if r10 = null then function is finished)
beqi r10, endStringCharLoop
nop
; Increment character pointer (move to next character)
addi r9, r9, 1
; Move character to print into r5
addi r5, r10, 0
; Call print function (return address stored in r15)
brlid r15, myPrintChar
nop
; Load in new character to print (lookup [msgPointer + counter])
lbui r10, r9, 0
; Branch back to loop condition
bri stringCharLoop
nop
; **** END OF LOOP ****
.globl endStringCharLoop
endStringCharLoop:
; Restore r15 from stack (restore original return address)
lwi r15,r1,0
addi r1, r1, 4
; Return from subroutine
rtsd r15, 8
nop






There are currently no comments for this snippet.