-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathFIFO.s
178 lines (163 loc) · 6.01 KB
/
FIFO.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
; FIFO.s
; Runs on LM4F120/TM4C123
; main program to test the FIFO
; Jonathan Valvano
; September 11, 2013
; This example accompanies the book
; "Embedded Systems: Introduction to ARM Cortex M Microcontrollers"
; ISBN: 978-1469998749, Jonathan Valvano, copyright (c) 2015
;
;Copyright 2015 by Jonathan W. Valvano, [email protected]
; You may use, edit, run or distribute this file
; as long as the above copyright notice remains
;THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
;OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
;MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
;VALVANO SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL,
;OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
;For more information about my classes, my research, and my books, see
;http://users.ece.utexas.edu/~valvano/
EXPORT TxFifo_Init
EXPORT TxFifo_Put
EXPORT TxFifo_Get
EXPORT TxFifo_Size
EXPORT RxFifo_Init
EXPORT RxFifo_Put
EXPORT RxFifo_Get
EXPORT RxFifo_Size
AREA DATA, ALIGN=2
SIZE EQU 16
RxPutPt SPACE 4
RxGetPt SPACE 4
RxFifo SPACE SIZE ; space for SIZE bytes
TxPutPt SPACE 4
TxGetPt SPACE 4
TxFifo SPACE SIZE ; space for SIZE bytes
AREA |.text|, CODE, READONLY, ALIGN=2
THUMB
;Initialize RxFifo
RxFifo_Init
LDR R0,=RxFifo ;pointer to beginning
LDR R1,=RxPutPt
STR R0,[R1]
LDR R1,=RxGetPt
STR R0,[R1]
BX LR
;Put data into RxFifo
; Input R0 8-bit data
; Output: R0 1 if successful
; 0 if unsuccessful, because it was ful
RxFifo_Put LDR R1,=RxPutPt
LDR R2,[R1] ;RxPutPt
ADD R3,R2,#1
LDR R12,=RxFifo+SIZE
CMP R3,R12 ;check if should wrap
BNE NoWrap
LDR R3,=RxFifo ;wrap
NoWrap LDR R12,=RxGetPt
LDR R12,[R12] ;RxGetPt
CMP R3,R12 ;full when holding SIZE-1
BNE NotFull
MOV R0,#0 ;full
BX LR
NotFull STRB R0,[R2] ;save
STR R3,[R1] ;update RxPutPt
MOV R0,#1 ;success
BX LR
;remove one element from RxFifo
;Input: call by reference to a place to store removed data
; Output: R0 1 if successful
; 0 if unsuccessful, because it was empty
RxFifo_Get PUSH {R4,R5,LR}
LDR R1,=RxPutPt
LDR R1,[R1] ;RxPutPt
LDR R2,=RxGetPt
LDR R3,[R2] ;RxGetPt
CMP R1,R3 ;empty if RxPutPt equals RxGetPt
BNE NotEmpty
MOV R0,#0 ;fail, empty
B done
NotEmpty LDRSB R4,[R3] ;read from RxFifo
STRB R4,[R0] ;return by reference
ADD R3,R3,#1 ;next place to Get
LDR R5,=RxFifo+SIZE
CMP R3,R5 ;check if need to wrap
BNE NoWrap2
LDR R3,=RxFifo ;wrap
NoWrap2 STR R3,[R2] ;update RxGetPt
done POP {R4,R5,PC}
;Returns the number of elements in the RxFifo
; Input: none
; Output: R0 0 to SIZE-1
RxFifo_Size
LDR R1,=RxPutPt
LDR R1,[R1] ;RxPutPt
LDR R2,=RxGetPt
LDR R3,[R2] ;RxGetPt
SUB R0,R1,R3 ;RxPutPt-RxGetPt
AND R0,#(SIZE-1) ; SIZE must be a power of two
BX LR
;Initialize TxFifo
TxFifo_Init
LDR R0,=TxFifo ;pointer to beginning
LDR R1,=TxPutPt
STR R0,[R1]
LDR R1,=TxGetPt
STR R0,[R1]
BX LR
;Put data into TxFifo
; Input R0 8-bit data
; Output: R0 1 if successful
; 0 if unsuccessful, because it was ful
TxFifo_Put LDR R1,=TxPutPt
LDR R2,[R1] ;TxPutPt
ADD R3,R2,#1
LDR R12,=TxFifo+SIZE
CMP R3,R12 ;check if should wrap
BNE TxNoWrap
LDR R3,=TxFifo ;wrap
TxNoWrap LDR R12,=TxGetPt
LDR R12,[R12] ;TxGetPt
CMP R3,R12 ;full when holding SIZE-1
BNE TxNotFull
MOV R0,#0 ;full
BX LR
TxNotFull STRB R0,[R2] ;save
STR R3,[R1] ;update TxPutPt
MOV R0,#1 ;success
BX LR
;remove one element from TxFifo
;Input: call by reference to a place to store removed data
; Output: R0 1 if successful
; 0 if unsuccessful, because it was empty
TxFifo_Get PUSH {R4,R5,LR}
LDR R1,=TxPutPt
LDR R1,[R1] ;TxPutPt
LDR R2,=TxGetPt
LDR R3,[R2] ;TxGetPt
CMP R1,R3 ;empty if TxPutPt equals TxGetPt
BNE TxNotEmpty
MOV R0,#0 ;fail, empty
B Txdone
TxNotEmpty LDRSB R4,[R3] ;read from TxFifo
STRB R4,[R0] ;return by reference
ADD R3,R3,#1 ;next place to Get
LDR R5,=TxFifo+SIZE
CMP R3,R5 ;check if need to wrap
BNE TxNoWrap2
LDR R3,=TxFifo ;wrap
TxNoWrap2 STR R3,[R2] ;update TxGetPt
Txdone POP {R4,R5,PC}
;Returns the number of elements in the TxFifo
; Input: none
; Output: R0 0 to SIZE-1
TxFifo_Size
LDR R1,=TxPutPt
LDR R1,[R1] ;TxPutPt
LDR R2,=TxGetPt
LDR R3,[R2] ;TxGetPt
SUB R0,R1,R3 ;TxPutPt-TxGetPt
AND R0,#(SIZE-1) ; SIZE must be a power of two
BX LR
ALIGN ; make sure the end of this section is aligned
END ; end of file