This repository was archived by the owner on Jul 22, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathKeypad.s
250 lines (204 loc) · 4.76 KB
/
Keypad.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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
INCLUDE stm32l476xx_constants.s
AREA Keypad, CODE, READONLY
EXPORT Keypad ; make __main visible to linker
EXPORT KeypadInit
; Corresponding flag will be updated after completion
; Pin map: GPIOC(0, 1, 2, 3) as output, GPIOB(1, 2, 3, 4) as input
keypad PROC
PUSH{LR}
; Pull all rows low
LDR r10, =GPIOB_BASE
LDR r0, =GPIOC_BASE
LDR r1, [r0, #GPIO_ODR]
BIC r1, #0xF
STR r1, [r0, #GPIO_ODR]
BL delay
; If all cols are 1, loop
LDR r0, =GPIOB_BASE
LDR r1, [r0, #GPIO_IDR]
AND r1, #0x1E
CMP r1, #0x1E
POPEQ {LR} ;temp
BXEQ LR
; Pull row 1 low
LDR r0, =GPIOC_BASE
LDR r1, [r0, #GPIO_ODR]
MOV r1, #0xE
STR r1, [r0, #GPIO_ODR]
BL delay
; If all cols are 1 continue, else branch
LDR r0, =GPIOB_BASE
LDR r1, [r0, #GPIO_IDR]
AND r1, #0x1E
CMP r1, #0x1E
BNE checkrow1
; Pull row 2 low
LDR r0, =GPIOC_BASE
LDR r1, [r0, #GPIO_ODR]
MOV r1, #0xD
STR r1, [r0, #GPIO_ODR]
BL delay
; If all cols are 1 continue, else branch
LDR r0, =GPIOB_BASE
LDR r1, [r0, #GPIO_IDR]
AND r1, #0x1E
CMP r1, #0x1E
BNE checkrow2
; Pull row 3 low
LDR r0, =GPIOC_BASE
LDR r1, [r0, #GPIO_ODR]
MOV r1, #0xB
STR r1, [r0, #GPIO_ODR]
BL delay
; If all cols are 1 continue, else branch
LDR r0, =GPIOB_BASE
LDR r1, [r0, #GPIO_IDR]
AND r1, #0x1E
CMP r1, #0x1E
BNE checkrow3
; Pull row 4 low
LDR r0, =GPIOC_BASE
LDR r1, [r0, #GPIO_ODR]
MOV r1, #0x7
STR r1, [r0, #GPIO_ODR]
BL delay
; If all cols are 1 continue, else branch
LDR r0, =GPIOB_BASE
LDR r1, [r0, #GPIO_IDR]
AND r1, #0x1E
CMP r1, #0x1E
BNE checkrow4
POP {LR}
BX LR ; else exit
wait ; Wait until col becomes high
;LDR r10, =GPIOB_BASE
;LDR r1, [r10, #GPIO_IDR]
;AND r1, r1, r2 ; mask col pin, will be 0 if low
;CMP r1, #0x0 ; if col low, loop
;BEQ wait
BL delay
LDR r0, =GPIOC_BASE ; Reset all rows
LDR r1, [r0, #GPIO_ODR]
BIC r1, #0xF
STR r1, [r0, #GPIO_ODR]
POP{LR}
BX LR
checkrow1
LDR r1, [r10, #GPIO_IDR] ; Load input
MOV r2, #0x2 ; Compare to col 1
AND r3, r1, r2
CMP r3, #0x0 ; If low, update flag, wait for unpress, exit interrupt
ORREQ r5, #0x1000 ; Update floor 1 flag
BEQ wait
MOV r2, #0x4 ; Compare to col 2
AND r3, r1, r2
CMP r3, #0x0
ORREQ r5, #0x2000 ; Update floor 2 flag
BEQ wait
MOV r2, #0x8
AND r3, r1, r2
CMP r3, #0x0 ; Compare to col 3
ORREQ r5, #0x4000 ; Update floor 3 flag
BEQ wait
MOV r2, #0x10
AND r3, r1, r2
CMP r3, #0x0 ; Compare to col 4
ORREQ r5, #0x8000
BEQ wait
BX LR
checkrow2
LDR r1, [r10, #GPIO_IDR]
MOV r2, #0x2
AND r3, r1, r2
CMP r3, #0x0
ORREQ r6, #0x1 ; Up flag floor 1
BEQ wait
MOV r2, #0x4
AND r3, r1, r2
CMP r3, #0x0
ORREQ r6, #0x2 ; Up flag floor 2
BEQ wait
MOV r2, #0x8
AND r3, r1, r2
CMP r3, #0x0
ORREQ r6, #0x4 ; Up flag floor 3
BEQ wait
MOV r2, #0x10
AND r3, r1, r2
CMP r3, #0x0
ORREQ r6, #0x80 ; Down flag floor 4
BEQ wait
BX LR
checkrow3
LDR r1, [r10, #GPIO_IDR] ; Load input
MOV r2, #0x2 ; Compare to col 1
AND r3, r1, r2
CMP r3, #0x0 ; If low, update flag, wait for unpress, exit interrupt
; Unassigned button
BEQ wait
MOV r2, #0x4 ; Compare to col 2
AND r3, r1, r2
CMP r3, #0x0
ORREQ r6, #0x20 ; Down flag floor 2
BEQ wait
MOV r2, #0x8
AND r3, r1, r2
CMP r3, #0x0 ; Compare to col 3
ORREQ r6, #0x40 ; Down flag floor 3
BEQ wait
MOV r2, #0x10
AND r3, r1, r2
CMP r3, #0x0 ; Compare to col 4
; Unassigned button
BEQ wait
BX LR
checkrow4
LDR r1, [r10, #GPIO_IDR] ; Load input
MOV r2, #0x2 ; Compare to col 1
AND r3, r1, r2
CMP r3, #0x0 ; If low, update flag, wait for unpress, exit interrupt
ORREQ r5, #0x10
BEQ wait
MOV r2, #0x4 ; Compare to col 2
AND r3, r1, r2
CMP r3, #0x0
ORREQ r5, #0x20
BEQ wait
MOV r2, #0x8
AND r3, r1, r2
CMP r3, #0x0 ; Compare to col 3
BICEQ r5, #0xF000
BICEQ r6, #0xFF
ORREQ r6, #0x100
BEQ wait
MOV r2, #0x10
AND r3, r1, r2
CMP r3, #0x0 ; Compare to col 4
BICEQ r5, #0xF000 ; Admin
BICEQ r6, #0xFF
ORREQ r5, #0x1000
BEQ wait
BX LR
ENDP
delay PROC
; Delay for software debouncing
LDR r2, =0x9999
delayloop
SUBS r2, #1
BNE delayloop
BX LR
ENDP
KeypadInit PROC
LDR r0, =GPIOC_BASE ; set pins C0, 1, 2, 3 as output (Keypad)
LDR r1, [r0, #GPIO_MODER]
BIC r1, #0xFF
ORR r1, #0x55
STR r1, [r0, #GPIO_MODER]
LDR r0, =GPIOB_BASE ; set pins B1, 2, 3, 4 as input (Keypad)
LDR r1, [r0, #GPIO_MODER]
BIC r1, #0x300
BIC r1, #0xFF
STR r1, [r0, #GPIO_MODER]
BX LR
ENDP
END