-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmas4loop.asm
More file actions
394 lines (307 loc) · 15.6 KB
/
mas4loop.asm
File metadata and controls
394 lines (307 loc) · 15.6 KB
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
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
;**********************************************************************
; *
; Description: *
; *
; Author: Chris White *
; Company: Monitor Computing Services Ltd. *
; *
; *
;**********************************************************************
; *
; Copyright (C) 1998 Monitor Computing Services Ltd. *
; *
; This program is free software; you can redistribute it and/or *
; modify it under the terms of the GNU General Public License *
; as published by the Free Software Foundation; either version 2 *
; of the License, or any later version. *
; *
; This program is distributed in the hope that it will be useful, *
; but WITHOUT ANY WARRANTY; without even the implied warranty of *
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
; GNU General Public License for more details. *
; *
; You should have received a copy of the GNU General Public *
; License (http://www.gnu.org/copyleft/gpl.html) along with this *
; program; if not, write to: *
; The Free Software Foundation Inc., *
; 59 Temple Place - Suite 330, *
; Boston, MA 02111-1307, *
; USA. *
; *
;**********************************************************************
list p=16f84
#include <p16f84.inc>
__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC
; '__CONFIG' directive is used to embed configuration data within .asm file.
; The lables following the directive are located in the respective .inc file.
; See respective data sheet for additional information on configuration word.
portAStatus EQU B'00000000'
portBStatus EQU B'10000001'
detOn EQU 0xFF ; Detector 'On' state
detOff EQU 0x0 ; Detector 'Off' state
detAccHigh EQU 0xAA ; Detection accumulator "On" threshold value
detAccLow EQU 0x55 ; Detection accumulator "Off" threshold value
detInA EQU 0 ; Signal A detector input bit, port B
detOutA EQU 2 ; Signal A detector 'On' indication ouput bit, port A
redA EQU 1 ; Signal A red aspect output bit, port B
yellowA EQU 2 ; Signal A yellow aspect output bit, port B
greenA EQU 3 ; Signal A green aspect output bit, port B
aspectMaskA EQU B'11110001' ; Signal A mask to clear all aspect output bits, port B
detInB EQU 7 ; Signal B detector input bit, port B
detOutB EQU 1 ; Signal B detector 'On' indication ouput bit, port A
redB EQU 6 ; Signal B red aspect output bit, port B
yellowB EQU 5 ; Signal B yellow aspect output bit, port B
greenB EQU 4 ; Signal B green aspect output bit, port B
aspectMaskB EQU B'10001111' ; Signal B mask to clear all aspect output bits, port B
tickOut EQU B'00000001' ; Timer tick ouput bit, port A
rtccInt EQU 216 ; 1Mhz / 40 = 25Khz
intMilli EQU 25 ; Interrupts per millisecond
secMilliLow EQU 0xE8 ; Milliseconds per second low byte
secMilliHigh EQU 0x03 ; Milliseconds per second high byte
minLoopTime EQU 8
initAspTime EQU 4
;***** VARIABLE DEFINITIONS
CBLOCK 0x0C
w_temp ; variable used for context saving
status_temp ; variable used for context saving
milliCount ; Interrupt counter for millisecond timing
secCountLow ; Millisecond counter (low byte) for second timing
secCountHigh ; Millisecond counter (high byte) for second timing
detAccA ; Signal A detector input integration accumulator
detStateA ; Signal A current detector state
loopTimerA ; Second counter for signal A loop timing
aspectTimerA ; Second counter for signal A aspect timing
timeAspectA ; Signal A seconds per aspect
aspectA ; Signal A current aspect
detAccB ; Signal B detector input integration accumulator
detStateB ; Signal B current detector state
loopTimerB ; Second counter for signal B loop timing
aspectTimerB ; Second counter for signal B aspect timing
timeAspectB ; Signal B seconds per aspect
aspectB ; Signal B current aspect
ENDC
;**********************************************************************
ORG 0x000 ; processor reset vector
goto Main ; go to beginning of program
ORG 0x004 ; interrupt vector location
BeginISR btfss INTCON,T0IF ; Test for RTCC interrupt
retfie ; If not, skip service routine
movwf w_temp ; save off current W register contents
movf STATUS,W ; move status register into W register
movwf status_temp ; save off contents of STATUS register
movlw tickOut
xorwf PORTA,F ; Toggle tick output bit
bcf INTCON,T0IF ; Reset the RTCC interrupt bit
movlw rtccInt
movwf TMR0 ; Reload RTCC
DetTestA btfss PORTB,detInA ; Skip if signal A detector input is set
goto DecDetAccA ; Jump if not set
IncDetAccA incf detAccA,F ; Increment signal A detector accumulator
btfsc STATUS,Z ; Skip if not overflowed to zero
decf detAccA,F ; If overflowed, roll back accumulator
goto DetTestB
DecDetAccA movf detAccA,F ; Test signal A detector accumulator
btfss STATUS,Z ; Skip if zero
decf detAccA,F ; Decrement if not zero
DetTestB btfss PORTB,detInB ; Skip if signal B detector input is set
goto DecDetAccB ; Jump if not set
IncDetAccB incf detAccB,F ; Increment signal B detector accumulator
btfsc STATUS,Z ; Skip if not overflowed to zero
decf detAccB,F ; If overflowed, roll back accumulator
goto MilliTest
DecDetAccB movf detAccB,F ; Test signal B detector accumulator
btfss STATUS,Z ; Skip if zero
decf detAccB,F ; Decrement if not zero
MilliTest movf milliCount,F ; Test millisecond interrupt counter
btfss STATUS,Z ; Skip if zero
decf milliCount,F ; Decrement if not zero
EndISR movlw tickOut
xorwf PORTA,F ; Toggle tick output bit
movf status_temp,W ; retrieve copy of STATUS register
movwf STATUS ; restore pre-isr STATUS register contents
swapf w_temp,F
swapf w_temp,W ; restore pre-isr W register contents
retfie ; return from interrupt
Main clrf PORTA ; Clear I/O ports
clrf PORTB
clrf detAccA ; Initialise variables
clrf aspectA
movlw detOff
movwf detStateA
movwf detStateB
movlw minLoopTime ; Ensure a minimum ...
movwf loopTimerA ; ... loop timer
movlw initAspTime ; Load aspect times
movwf timeAspectA
movwf aspectTimerA
bcf STATUS,C
rrf aspectTimerA,F
addwf aspectTimerA,F ; Bump up red aspect period
clrf loopTimerA ; Reset loop timer
clrf aspectA ; Set initial aspect ...
bsf aspectA,redA ; ... to red
movlw minLoopTime ; Ensure a minimum ...
movwf loopTimerB ; ... loop timer
movlw initAspTime ; Load aspect times
movwf timeAspectB
movwf aspectTimerB
bcf STATUS,C
rrf aspectTimerB,F
addwf aspectTimerB,F ; Bump up red aspect period x 1.5
clrf aspectB ; Set initial aspect ...
bsf aspectB,redB ; ... to red
movlw intMilli
movwf milliCount
movlw secMilliLow
movwf secCountLow
movlw secMilliHigh
movwf secCountHigh
BANKSEL OPTION_REG
movlw portAStatus ; Program I/O port bit directions
movwf TRISA
movlw portBStatus
movwf TRISB
clrf OPTION_REG
bsf OPTION_REG,NOT_RBPU
bsf OPTION_REG,PSA
BANKSEL TMR0
movlw rtccInt
movwf TMR0 ; Load RTCC
bsf INTCON,GIE ; Enable interrupts
bsf INTCON,T0IE ; Enable RTCC interrupts
MainLoop ; Top of main processing loop
Timing movf milliCount,F ; Test millisecond interrupts counter
btfss STATUS,Z ; Skip if zero, a millisecond has elapsed
goto NotMillisec ; Jump timing processing if a millisecond hasn't elapsed
Millisec movlw intMilli ; Reload millisecond interrupts counter
movwf milliCount
decfsz secCountLow,F ; Decrement second milliseconds counter low byte ...
goto NotSecond ; ... skipping this jump if reached zero
decfsz secCountHigh,F ; Decrement second milliseconds counter high byte
goto NotSecond ; Jump timing processing if a second has not elapsed
Second movlw secMilliLow ; Reload one second milliseconds counter
movwf secCountLow
movlw secMilliHigh
movwf secCountHigh
incf loopTimerA,F ; Increment loop timer
btfsc STATUS,Z ; Skip if not overflowed to zero
decf loopTimerA,F ; If overflowed roll back loop timer
movf aspectTimerA,F ; Test aspect timer
btfss STATUS,Z ; Skip if aspect timer is zero
decf aspectTimerA,F ; Decrement aspect timer
incf loopTimerB,F ; Increment loop timer
btfsc STATUS,Z ; Test for overflow
decf loopTimerB,F ; If overflow roll back loop timer
movf aspectTimerB,F ; Test aspect timer
btfss STATUS,Z ; Skip if aspect timer is 0
decf aspectTimerB,F ; Decrement aspect timer
NotMillisec
NotSecond
Detect movf detStateA,F ; Test detector state
btfsc STATUS,Z ; Skip if state is "On"
goto DetectOffA ; Jump if state is "Off"
DetectOnA movf detAccA,W ; Test if detector integration accumulator ...
sublw detAccLow ; ... is above "Off" threshold
btfss STATUS,C ; Skip if at or below threshold
goto DetectEndA ; Jump if above threshold
; Detector has turned "Off"
movlw detOff
movwf detStateA ; Set detector state to "Off"
bcf PORTA,detOutA ; Clear "detecting" output bit
goto DetectEndA
DetectOffA movf detAccA,W ; Test if detector integration accumulator ...
sublw detAccHigh ; ... is above "On" threshold
btfsc STATUS,C ; Skip if above threshold
goto DetectEndA ; Jump if at or below threshold
; Detector has turned "On"
btfsc aspectA,redA ; Skip is aspect is not red
goto DetectEndA ; Jump if aspect is already red
movlw detOn
movwf detStateA ; Set detector state to "On"
bsf PORTA,detOutA ; Set "detecting" output bit
movf loopTimerA,W
sublw minLoopTime ; Test loop timer against minimum
btfsc STATUS,C ; Skip if loop timer greater than minimum
goto LoopTimeLowA ; Jump if loop timer less than or equal to mimimum
movf loopTimerA,W
goto LoopTimeSetA
LoopTimeLowA movlw minLoopTime ; Force a minimum loop time
LoopTimeSetA movwf timeAspectA ; Set time per aspect to be last loop time / 4
bcf STATUS,C
rrf timeAspectA,F
bcf STATUS,C
rrf timeAspectA,F
movf timeAspectA,W
movwf aspectTimerA ; Load aspect timer
bcf STATUS,C
rrf aspectTimerA,F
addwf aspectTimerA,F ; Bump up red aspect period x 1.5
clrf loopTimerA ; Reset loop timer
clrf aspectA ; Set current aspect ...
bsf aspectA,redA ; ... to red
DetectEndA movf detStateB,F ; Test detector state
btfsc STATUS,Z ; Skip if state is "On"
goto DetectOffB ; Jump if state is "Off"
DetectOnB movf detAccB,W ; Test if detector integration accumulator ...
sublw detAccLow ; ... is above "Off" threshold
btfss STATUS,C ; Skip if at or below threshold
goto CheckAspectA ; Jump if above threshold
; Detector has turned "Off"
movlw detOff
movwf detStateB ; Set detector state to "Off"
bcf PORTA,detOutB ; Clear "detecting" output bit
goto CheckAspectA
DetectOffB movf detAccB,W ; Test if detector integration accumulator ...
sublw detAccHigh ; ... is above "On" threshold
btfsc STATUS,C ; Skip if above threshold
goto CheckAspectA ; Jump if at or below threshold
; Detector has turned "On"
btfsc aspectB,redB ; Skip is aspect is not red
goto CheckAspectA ; Jump if aspect is already red
movlw detOn
movwf detStateB ; Set detector state to "On"
bsf PORTA,detOutB ; Set "detecting" output bit
movf loopTimerB,W
sublw minLoopTime ; Test loop timer against minimum
btfsc STATUS,C ; Skip if loop timer greater than minimum
goto LoopTimeToLowB ; Jump if loop timer less than or equal to mimimum
movf loopTimerB,W
goto LoopTimeSetB
LoopTimeToLowB movlw minLoopTime ; Force a minimum loop time
LoopTimeSetB movwf timeAspectB ; Set time per aspect to be last loop time / 4
bcf STATUS,C
rrf timeAspectB,F
bcf STATUS,C
rrf timeAspectB,F
movf timeAspectB,W
movwf aspectTimerB ; Load aspect timer
bcf STATUS,C
rrf aspectTimerB,F
addwf aspectTimerB,F ; Bump up red aspect period x 1.5
clrf loopTimerB ; Reset loop timer
clrf aspectB ; Set current aspect ...
bsf aspectB,redB ; ... to red
CheckAspectA movf aspectTimerA,F ; Test if aspect timer has elapsed
btfss STATUS,Z ; Skip if it has elapsed
goto CheckAspectB ; Jump if it has not elapsed
ChangeAspectA movf timeAspectA,W
movwf aspectTimerA ; Reset aspect timer
bcf STATUS,C ; Clear carry flag ready for bit rotation
btfss aspectA,greenA ; Skip if already displaying green aspect
rlf aspectA,F ; Change to next aspect
CheckAspectB movf aspectTimerB,F ; Test if aspect timer has elapsed
btfss STATUS,Z ; Skip if it has elapsed
goto SetOutput ; Jump if it has not elapsed
ChangeAspectB movf timeAspectB,W
movwf aspectTimerB ; Reset aspect timer
bcf STATUS,C ; Clear carry flag ready for bit rotation
btfss aspectB,greenB ; Skip if already displaying green aspect
rrf aspectB,F ; Change to next aspect
SetOutput movf PORTB,W ; Get output byte value
andlw aspectMaskA ; Clear signal A aspect bits
andlw aspectMaskB ; Clear signal B aspect bits
iorwf aspectA,W ; Set current signal A aspect bit
iorwf aspectB,W ; Sets current signal B aspect bit
movwf PORTB ; Output new value
goto MainLoop ; End of main processing loop
end ; directive 'end of program'