Applerm-II/uart.S

229 lines
3.8 KiB
ArmAsm

.syntax unified
.cpu cortex-m0
.align 2
.thumb
.thumb_func
.include "registers.inc"
.text
// void uart_init()
.global uart_init
.type uart_init, %function
uart_init:
// 0) Set to provide I/O clock
ldr r0, =#SYSAHBCLKCTRL
ldr r1, [r0]
ldr r2, =#CLK_IOCON
orrs r1, r1, r2
str r1, [r0]
// 1) IO port configuration to use UART
ldr r0, =#IOCON_PIO1_6
movs r1, #(PIO_BASE | FUNC_RXD | MODE_UP)
str r1, [r0]
ldr r0, =#IOCON_PIO1_7
movs r1, #(PIO_BASE | FUNC_TXD)
str r1, [r0]
// 2) Set to provide UART clock
ldr r0, =#SYSAHBCLKCTRL
ldr r1, [r0]
ldr r2, =#CLK_UART
orrs r1, r1, r2
str r1, [r0]
// 3) Set clock divider to enable UART clock
ldr r0, =#UARTCLKDIV
movs r1, #1
str r1, [r0]
// UART_PCLK = 12MHz, BR = 115200
// DLM=0, DLL=4, DIVADDVAL = 5, MULVAL = 8
ldr r0, =#U0LCR
movs r1, #DLAB_ENABLE
str r1, [r0]
ldr r0, =#U0DLM
movs r1, #0
str r1, [r0]
ldr r0, =#U0DLL
movs r1, #4
str r1, [r0]
ldr r0, =#U0FDR
movs r1, #((8 << MULVAL_SHIFT) | 5)
str r1, [r0]
// Configure as 8-bit, 1 stop bit, no parity mode
ldr r0, =#U0LCR
movs r1, #(WORD_LEN_8 | STOP_BIT_1)
str r1, [r0]
// Reset FIFO
ldr r0, =#U0FCR
movs r1, #(FIFO_ENABLE | RX_RESET | TX_RESET)
str r1, [r0]
mov pc, lr
.size uart_init, .-uart_init
// int uart_ready();
.global uart_ready
.type uart_ready, %function
uart_ready:
ldr r0, =#U0LSR
ldr r0, [r0]
movs r1, #LSR_RDR
ands r0, r0, r1
bne 1f
movs r0, #0
mov pc, lr
1:
movs r0, #1
mov pc, lr
.size uart_ready, .-uart_ready
// int uart_getc();
.global uart_getc
.type uart_getc, %function
uart_getc:
ldr r0, =#U0RBR
ldr r0, [r0]
mov pc, lr
.size uart_getc, .-uart_getc
// void uart_putc(char c);
.global uart_putc
.type uart_putc, %function
uart_putc:
ldr r1, =#U0LSR
movs r2, #LSR_THRE
1:
ldr r3, [r1]
ands r3, r2, r3
beq 1b
ldr r1, =#U0THR
str r0, [r1]
mov pc, lr
.size uart_putc, .-uart_putc
// void uart_putstr(const char* str);
.global uart_putstr
.type uart_putstr, %function
uart_putstr:
push {r4, lr}
mov r4, r0
1:
ldrb r0, [r4]
movs r0, r0
beq 1f
bl uart_putc
movs r0, #1
adds r4, r4, r0
b 1b
1:
pop {r4, pc}
.size uart_putstr, .-uart_putstr
// void uart_putx(char x);
.global uart_putx
.type uart_putx, %function
uart_putx:
push {lr}
movs r1, #10
cmp r0, r1
bhs 1f
movs r1, #'0'
adds r0, r0, r1
bl uart_putc
pop {pc}
1:
movs r1, #('a' - 10)
adds r0, r0, r1
bl uart_putc
pop {pc}
.size uart_putx, .-uart_putx
// void uart_puthex(char n);
.global uart_puthex
.type uart_puthex, %function
uart_puthex:
push {lr}
push {r0}
lsrs r0, r0, #4
bl uart_putx
pop {r0}
movs r1, #0xf
ands r0, r0, r1
bl uart_putx
pop {pc}
.size uart_puthex, .-uart_puthex
// void uart_puthex16(short n);
.global uart_puthex16
.type uart_puthex16, %function
uart_puthex16:
push {lr}
push {r0}
lsrs r0, r0, #8
bl uart_puthex
pop {r0}
movs r1, #0xff
ands r0, r0, r1
bl uart_puthex
pop {pc}
.size uart_puthex16, .-uart_puthex16
// void uart_putd(char n);
.global uart_putd
.type uart_putd, %function
uart_putd:
push {lr}
movs r1, #0
movs r2, #100
movs r3, #0
1:
subs r0, r0, r2
bcc 1f
adds r1, r1, #1
b 1b
1:
adds r0, r0, r2
cmp r1, #0
beq 2f
push {r0}
mov r0, r1
bl uart_putx
pop {r0}
movs r3, #1
2:
movs r1, #0
movs r2, #10
1:
subs r0, r0, r2
bcc 1f
adds r1, r1, #1
b 1b
1:
adds r0, r0, r2
cmp r1, #0
bne 1f
cmp r3, #0
beq 2f
1:
push {r0}
mov r0, r1
bl uart_putx
pop {r0}
movs r3, #1
2:
movs r1, #0
movs r2, #1
1:
subs r0, r0, r2
bcc 1f
adds r1, r1, #1
b 1b
1:
mov r0, r1
bl uart_putx
pop {pc}