-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathuart.s
137 lines (105 loc) · 3.14 KB
/
uart.s
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
.global uart_init
.global uart_char
.global uart_str
uart_init:
mov x19, x30 // push return address
// set last bit at address 0x3f21 5004 to 1 (AUX_ENABLE, uart1)
mov x0, 0x5004
movk x0, 0x3f21, lsl 16
ldr w1, [x0]
orr w1, w1, 1 // force last bit to 1
str w1, [x0]
// write 0 to address 0x3f21 5060 (AUX_MU_CNTL, disable Tx, Rx)
mov x0, 0x5060
movk x0, 0x3f21, lsl 16
str wzr, [x0] // write zero register to address
// write 3 to address 0x3f21 504c (AUX_MU_LCR, 8 bits)
mov x0, 0x504c
movk x0, 0x3f21, lsl 16
mov w1, 3
str w1, [x0]
// write 0 to address 0x3f21 5050 (AUX_MU_MCR)
mov x0, 0x5050
movk x0, 0x3f21, lsl 16
str wzr, [x0]
// write 0 to address 0x3f21 5044 (AUX_MU_IER)
mov x0, 0x5044
movk x0, 0x3f21, lsl 16
str wzr, [x0]
// write 198 to address 0x3f21 5048 (AUX_MU_IIR, disable interrupts)
mov x0, 0x5048
movk x0, 0x3f21, lsl 16
mov w1, 198
str w1, [x0]
// write 270 to address 0x3f21 5068 (AUX_MU_BAUD, 115200 baud)
mov x0, 0x5068
movk x0, 0x3f21, lsl 16
mov w1, 270
str w1, [x0]
// store bitmask at address 0x3f20 0004 (GPFSEL1)
mov x0, 0x0004
movk x0, 0x3f20, lsl 16
ldr w1, [x0]
// and bitmask with 0xffff ffff fffc 0fff (GPIO14, GPIO15)
and w1, w1, 0xfffffffffffc0fff
// or bitmask with 0x0001 2000 (ALT5)
mov w0, 0x2000
movk w0, 0x0001, lsl 16
orr w1, w1, w0
// write bitmask back to address 0x3f20 0004 (GPFSEL1)
mov x0, 0x0004
movk x0, 0x3f20, lsl 16
str w1, [x0]
// write 0 to address 0x3f20 0094 (GPPUD, enable pins 14 and 15)
mov x0, 0x0094
movk x0, 0x3f20, lsl 16
str wzr, [x0]
mov x0, 150
bl delay // delay for 150 cycles
// write 49152 to address 0x3f20 0098 (GPPUDCLK0)
mov x0, 0x0098
movk x0, 0x3f20, lsl 16
mov w1, 49152
str w1, [x0]
mov x0, 150
bl delay // delay for 150 cycles
// write 0 to address 0x3f20 0098 (GPPUDCLK0)
mov x0, 0x0098
movk x0, 0x3f20, lsl 16
str wzr, [x0]
// write 3 to address 0x3f21 5060 (AUX_MU_CTRL, enable Tx, Rx)
mov x0, 0x5060
movk x0, 0x3f21, lsl 16
mov w1, 3
str w1, [x0]
mov x30, x19 // pop return address
ret
uart_char: // x0: character to print
// check value at address 0x3f21 5054 (AUX_MU_LSR, ready to print)
mov x1, 0x5054
movk x1, 0x3f21, lsl 16
ldr w1, [x1]
and w1, w1, 32
cbnz w1, uart_char.print // continue if we are ready to print
// otherwise wait a cycle and repeat the check
nop
b uart_char
uart_char.print:
// write character to address 0x3f21 5040 (AUX_MU_IO)
mov x1, 0x5040
movk x1, 0x3f21, lsl 16
str x0, [x1]
ret
uart_str: // x0: address of the first character of string to print
mov x19, x30 // push return address
uart_str.loop:
mov x20, x0 // push character address
// check the character value (zero indicates end of string)
ldr x0, [x0]
cbz x0, uart_str.done // we are done printing the string
bl uart_char // print the character
add x0, x20, 1 // increment and pop character address
b uart_str.loop // repeat for next character
uart_str.done:
mov x30, x19 // pop return address
ret