aboutsummaryrefslogtreecommitdiff
path: root/hexedit/uart.s
diff options
context:
space:
mode:
Diffstat (limited to 'hexedit/uart.s')
-rw-r--r--hexedit/uart.s116
1 files changed, 116 insertions, 0 deletions
diff --git a/hexedit/uart.s b/hexedit/uart.s
new file mode 100644
index 0000000..9804e53
--- /dev/null
+++ b/hexedit/uart.s
@@ -0,0 +1,116 @@
+.syntax unified
+.cpu cortex-m0plus
+.thumb
+
+.equ RESETS_BASE, 0x4000c000
+.equ RESET_OFST, 0x0
+.equ RESET_DONE_OFST, 0x8
+
+.equ IO_BANK0_BASE, 0x40014000
+.equ GPIO0_CTRL_OFST, 0x04
+.equ GPIO1_CTRL_OFST, 0x0c
+
+.equ UART0_BASE, 0x40034000
+.equ UARTDR_OFST, 0x00
+.equ UARTFR_OFST, 0x18
+.equ UARTIBRD_OFST, 0x24
+.equ UARTFBRD_OFST, 0x28
+.equ UARTLCR_H_OFST, 0x2c
+.equ UARTCR_OFST, 0x30
+
+.equ ATOMIC_SET, 0x2000
+.equ ATOMIC_CLEAR, 0x3000
+
+.type setup_uart, %function
+.global setup_uart
+
+setup_uart:
+
+ // Deassert reset
+ ldr r1, =(RESETS_BASE + ATOMIC_CLEAR)
+ movs r0, 0b1 // UART0
+ lsls r0, 22
+ str r0, [r1, RESET_OFST]
+ ldr r1, =RESETS_BASE
+1:
+ ldr r2, [r1, RESET_DONE_OFST]
+ tst r2, r0
+ beq 1b
+
+ // Configure and enable
+ ldr r1, =UART0_BASE
+ movs r0, 6
+ str r0, [r1, UARTIBRD_OFST]
+ movs r0, 33
+ str r0, [r1, UARTFBRD_OFST]
+ movs r0, 0b111 << 4 // 0b11 = word len 8 bits, 0b1 = FIFO enabled
+ str r0, [r1, UARTLCR_H_OFST]
+ ldr r1, =(UART0_BASE + ATOMIC_SET)
+ movs r0, 0b1 // UART enable
+ str r0, [r1, UARTCR_OFST]
+
+ // Configure GPIO 0 and 1 as TX and RX
+ ldr r1, =IO_BANK0_BASE
+ movs r0, 2 // UART function
+ str r0, [r1, GPIO0_CTRL_OFST]
+ str r0, [r1, GPIO1_CTRL_OFST]
+
+ bx lr
+
+.type uart_send, %function
+.global uart_send
+
+uart_send:
+ ldr r1, =UART0_BASE
+ movs r3, 0b1 << 5 // TX FIFO full
+1:
+ ldr r2, [r1, UARTFR_OFST]
+ tst r2, r3
+ bne 1b
+ strb r0, [r1, UARTDR_OFST]
+ bx lr
+
+.type uart_recv, %function
+.global uart_recv
+
+uart_recv:
+ ldr r1, =UART0_BASE
+ movs r3, 0b1 << 4 // RX FIFO empty
+1:
+ ldr r2, [r1, UARTFR_OFST]
+ tst r2, r3
+ bne 1b
+ ldrb r0, [r1, UARTDR_OFST]
+ bx lr
+
+.type send_hex, %function
+.global send_hex
+
+send_hex:
+ push {lr}
+ movs r4, r0
+ movs r0, '0
+ bl uart_send
+ movs r0, 'x
+ bl uart_send
+ movs r5, 8 // eight nibbles in a word
+0:
+ movs r0, 28 // rotate left 4
+ rors r4, r0
+ movs r0, 0xF // lowest nibble mask
+ ands r0, r4
+ cmp r0, 0x9 // number or letter?
+ bhi 1f
+ adds r0, '0
+ b 2f
+1:
+ adds r0, 'A - 0xA
+2:
+ bl uart_send
+ subs r5, 1
+ bne 0b
+ movs r0, '\r
+ bl uart_send
+ movs r0, '\n
+ bl uart_send
+ pop {pc}