-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathasm_procs.s
142 lines (110 loc) · 1.95 KB
/
asm_procs.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
INCLUDE core_cm4_constants.s
INCLUDE stm32l476xx_constants.s
AREA FLASH_IMAGE, CODE, READONLY
EXPORT flash_image
flash_image
; r0 = pointer to bitmap
; r1 = length of bitmap
PUSH {r4, r5, r6, r7}
;; SETUP
; r2 = offset counter
LDR r2, =0
; r4 = mask
LDR r4, =0x80
; r3 = data byte
LDRB r3, [r0, +r2]
; r5 = GPIOB_BASE
LDR r5, =GPIOB_BASE
; r6 = GPIOB_ODR with logic high
LDR r6, [r5, #GPIO_ODR]
ORR r6, #0x01 ; offset subject to change
; r7 = GPIOB_ODR with logic low
LDR r7, [r5, #GPIO_ODR]
BIC r7, #0x01 ; offset subject to change
start_send
; start by storing logic high
STR r6, [r5, #GPIO_ODR]
;; LOGIC
; test masked data
TST r3, r4
; wait until the timing period is over
; for 32MHz, minimum time to wait is 8 cycles
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
; if byte & mask, send one
BNE send_one
send_zero
; should reach here 11 clock cycles after setting logic high
STR r7, [r5, #GPIO_ODR]
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
B finish_send
send_one
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
; should reach here 24 clock cycles after setting logic high
STR r7, [r5, #GPIO_ODR]
finish_send
; iterating and getting the next byte take about 10 clock cycles
; this adds just a little buffer so we don't miss a timing window
; for the .45us window, we'll have 12cc
; for the .85us window, we'll have 27cc
NOP
NOP
iterate
;; LOOPING
; check if we're at the end of the byte
TEQ r4, #0x01
; if not, just go to the next offset
; if so, go to the next byte
BNE next_offset
next_byte
; add one to offset
ADD r2, #1
; check if we're done
TEQ r2, r1
; if so go to epilogue
BEQ epilogue
; set byte mask to 0x80
LDR r4, =0x80
; load new data byte
LDR r3, [r0, +r2]
B start_send
next_offset
; go to next least significant byte
LSR r4, #1
; pad until other branch is done
NOP
NOP
B start_send
epilogue
STR r7, [r5, #GPIO_ODR]
POP {r4, r5, r6, r7}
MOV pc, lr
END