Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ; @file Console.asm
- ; @author Andrew D. Zonenberg
- ; @brief Implementation of serial console
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ; SFR defines
- ; Serial port SFRs
- .define IO_UART 0x00
- .define IO_UART_TXBUF 0x00
- .define IO_UART_TXBUSY 0x01
- .define IO_UART_RXBUF 0x02
- .define IO_UART_RXBUSY 0x03
- .define IO_UART_RXRDY 0x04
- ; String table SFRs
- .define IO_STRING 0x10
- .define IO_STRING_BOOTSTART 0x00
- .define IO_STRING_BOOTEND 0x7b
- .define IO_STRING_CLISTART 0x80
- .define IO_STRING_CLIEND 0x87
- .define IO_STRING_ERRSTART 0xa0
- .define IO_STRING_ERREND 0xb2
- ; PWM channel SFRs
- .define IO_PWM 0x80
- .define IO_PWM_HISTART 0x00
- .define IO_PWM_LOSTART 0x20
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ; Variable defines
- .define strend 0x00
- .define hextemp 0x01
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ; Program entry point
- reset:
- ; Print bootup message
- j main_printversion
- ; Enter main command loop and run forever
- main_loop:
- ; print prompt
- li r1, IO_STRING_CLISTART
- li r2, IO_STRING_CLIEND
- call puts
- ; get a character
- call waitforchar ; wait for a key to be pressed
- li r2, IO_UART
- li r3, IO_UART_RXBUF
- in r0, r2:r3 ; r0 = URXBUF
- ; switch on the character
- li r2, 'v' ; 'v': print version number
- sne r0, r2
- j main_printversion
- li r2, 'd' ; 'd': set duty cycle
- sne r0, r2
- j main_setdcycle
- ; if we get to this point, input is invalid
- ; print error and continue
- li r1, IO_STRING_ERRSTART
- li r2, IO_STRING_ERREND
- call puts
- j main_loop
- ; print version and continue
- main_printversion:
- li r1, IO_STRING_BOOTSTART
- li r2, IO_STRING_BOOTEND
- call puts
- j main_loop
- ; read duty cycle string and apply it
- main_setdcycle:
- ;TODO: write to SFRs
- call readhexbyte ; Channel number
- ; Debug - print the raw value
- li r0, IO_UART
- li r1, IO_UART_TXBUF
- out r3, r0:r1
- ;call readhexbyte ; Duty cycle high
- ;call readhexbyte ; Duty cycle low
- j main_loop
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ; Waits for a character to arrive on the uart.
- ; Busy wait as we havent implemented interrupts yet!
- waitforchar:
- li r2, IO_UART
- li r3, IO_UART_RXRDY
- in r2, r2:r3 ; r2 = URXRDY
- li r0, 1 ; if ready, quit
- seq r0, r2
- j waitforchar
- ret
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ; Print a string to the UART
- ; Arguments:
- ; r1 = starting low-order address of string
- ; r2 = ending low-order address of string
- puts:
- sw r2, strend ; save end of string
- ;r1 = current string pointer
- putsloop:
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;Wait until transmitter is idle
- putsbusyloop:
- li r2, IO_UART
- li r3, IO_UART_TXBUSY
- in r2, r2:r3 ; r2 = UTXBUSY
- li r3, 0 ; if UTXBUSY = 0, we're done
- seq r2, r3
- j putsbusyloop
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- putsprint: ; At this point transmitter is idle and we're ready to send
- ; Read the character from the string table
- li r0, IO_STRING
- in r0, r0:r1 ; r0 = stringtable[i]
- li r2, IO_UART ; send it
- li r3, IO_UART_TXBUF
- out r0, r2:r3
- addi r1, 1 ; bump current position
- lw r2, strend ; if(start == end) break
- seq r1, r2
- j putsloop
- ret
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ; Reads two hex characters from the UART and returns the byte's value in r3
- readhexbyte:
- hexwait1: ; Wait for the first byte to be typed
- li r2, IO_UART
- li r3, IO_UART_RXRDY
- in r2, r2:r3 ; r2 = URXRDY
- li r0, 1 ; if ready, quit
- seq r0, r2
- j hexwait1
- li r2, IO_UART ; Echo it
- li r3, IO_TXBUF
- out r0, r2:r3
- ; Convert '1' to 0x10, etc
- ; If it's a digit, convert to the raw value
- mov r1, r0
- andi r1, 0x40 ;zero if a digit, nonzero if a letter
- li r2, 0
- seq r1, r2
- j hexlet1; ;if a letter, jump
- hexdig1:
- subi r0, 0x30 ;subtract '0'
- j hexdone1
- hexlet1:
- andi r0, 0xdf ;convert from upper/lower case letter to binary
- subi r0, 0x36
- hexdone1:
- ; Done with the first digit, but it's in the wrong nibble
- ; Multiply it by 16 (2^4)
- add r0, r0 ;*2
- add r0, r0 ;*4
- add r0, r0 ;*8
- add r0, r0 ;*16
- sw r0, hextemp
- ; Read the next digit
- hexwait2: ; Wait for the byte to be typed
- li r2, IO_UART
- li r3, IO_UART_RXRDY
- in r2, r2:r3 ; r2 = URXRDY
- li r0, 1 ; if ready, quit
- seq r0, r2
- j hexwait2
- li r2, IO_UART ; Echo it
- li r3, IO_TXBUF
- out r0, r2:r3
- ; Convert '1' to 0x1, etc
- ; If it's a digit, convert to the raw value
- mov r1, r0
- andi r1, 0x40 ;zero if a digit, nonzero if a letter
- li r2, 0
- seq r1, r2
- j hexlet2; ;if a letter, jump
- hexdig2:
- subi r0, 0x30 ;subtract '0'
- j hexdone2
- hexlet2:
- andi r0, 0xdf ;convert from upper/lower case letter to binary
- subi r0, 0x36
- hexdone2:
- ; Low order digit is in r0, high is in hextemp
- lw r3, hextemp
- add r3, r0
- ret
Add Comment
Please, Sign In to add comment