forked from Spritetm/hadbadge2019_fpgasoc
-
Notifications
You must be signed in to change notification settings - Fork 0
/
LEDctrl.asm
405 lines (374 loc) · 8.2 KB
/
LEDctrl.asm
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
394
395
396
397
398
399
400
401
402
403
404
405
;****************************************************************************
;* Filename: LEDctrl.asm
;****************************************************************************
;* Revision: Rev0
;* Date: 08-16-2019
;****************************************************************************
;* Note:
;* Clock: 6.14 MHz
len equ 16 ;
w equ 1
f equ 0
;----------------------------------------------------------- proc def
list p=16f84a
list R=dec
include "p16f84a.inc"
include "macros.inc"
;----------------------------------------------------------- config
__CONFIG _FOSC_HS & _WDTE_OFF & _PWRTE_ON & _CP_OFF ; HS osc / no WDT / pwrt on / code not protected
;----------------------------------------------------------- ram def
CBLOCK 0x20 ; GP RAM bank 0x20-0x6F (all words little endian)
dim_period ; one step period (must be >0)
ramp_factor ; ramp speed up (must be >0)
preset_a ; new A leds 012, preset by user routine (bit 0 left)
preset_b ; new B leds 012345, preset by user routine (bit 0 left)
pattern ; patern selected (if 0 then no pattern, write to preset_x manually)
inner_count ; inner loop counter
outer_count ; outer loop counter
broad_count ; slow down counter inside one step
pat_count ; pattern step countdown
count_dim ; tempo counter inside one step
tempw ; temporary gp
flag ; bit 0: A active, bit 1: B active
target_b ; OUTB target values (bit 0 first)
dummy_a2
dummy_a3
dummy_a4
dummy_a5
dummy_a6
target_a ; OUTA target values (bit 0 first)
dummy_b2
dummy_b3
slow_b ; OUTB medial values, dynamically loaded (bit 0 first)
dummy_c2
dummy_c3
dummy_c4
dummy_c5
dummy_c6
slow_a ; OUTA medial values, dynamically loaded (bit 0 first)
dummy_d2
dummy_d3
count_b ; OUTB count values, dynamically decremented (bit 0 first)
dummy_e2
dummy_e3
dummy_e4
dummy_e5
dummy_e6
count_a ; OUTA count values, dynamically decremented (bit 0 first)
dummy_f2
dummy_f3
ENDC
; Initial definitions:
#define outb PORTB ; bits 012345 only
#define outa PORTA ; bits 012 only
#define step dim_period ; one step period (must be >0)
#define speedup ramp_factor ; ramp speed up (must be >0)
;----------------------------------------------------------- code
CODE
goto start
;----------------------------------------------------------- gamma table
; LED intensity physiological adjustment table, gamma=2 (input w=0-127, output w=1-253)
; fractional power of 2, multiplied by 2 (that's why it's /64 and not /128) and inc by 1
; note: table must not cross the page boundary
org 1
gamma2
addwf PCL,f
variable xx
xx=0
while xx<128
retlw xx*xx/64+1
xx+=1
endw
pat2 ; wave from right to left
addwf PCL,f
retlw b'100000'
retlw b'110000'
retlw b'111000'
retlw b'111100'
retlw b'111110'
retlw b'011111'
retlw b'001111'
retlw b'000111'
retlw b'000011'
retlw b'000001'
retlw 0x80 ; terminator
pat3 ; wave from left to right
addwf PCL,f
retlw b'000001'
retlw b'000011'
retlw b'000111'
retlw b'001111'
retlw b'011111'
retlw b'111110'
retlw b'111100'
retlw b'111000'
retlw b'110000'
retlw b'100000'
retlw 0x80
pat4 ; wave from center
addwf PCL,f
retlw b'000000'
retlw b'001100'
retlw b'011110'
retlw b'111111'
retlw b'110011'
retlw b'100001'
retlw 0x80
pat5 ; wave to center
addwf PCL,f
retlw b'000000'
retlw b'100001'
retlw b'110011'
retlw b'111111'
retlw b'011110'
retlw b'001100'
retlw 0x80
pat6 ; alternating pattern 111000
addwf PCL,f
retlw b'111000'
retlw b'000111'
retlw 0x80
pat7 ; alternating pattern 101010
addwf PCL,f
retlw b'010101'
retlw b'101010'
retlw 0x80
pat8 ; all blink
addwf PCL,f
retlw b'000000'
retlw b'111111'
retlw 0x80
pat9 ; alternating wave pattern
addwf PCL,f
retlw b'100000'
retlw b'110000'
retlw b'111000'
retlw b'111100'
retlw b'111110'
retlw b'111111'
retlw b'111110'
retlw b'111100'
retlw b'111000'
retlw b'110000'
retlw b'100000'
retlw b'000001'
retlw b'000011'
retlw b'000111'
retlw b'001111'
retlw b'011111'
retlw b'111111'
retlw b'011111'
retlw b'001111'
retlw b'000111'
retlw b'000011'
retlw b'000001'
retlw 0x80
pat10 ; drop pattern
addwf PCL,f
retlw b'100000'
retlw b'010000'
retlw b'001000'
retlw b'000100'
retlw b'100010'
retlw b'010001'
retlw b'001001'
retlw b'000101'
retlw b'100011'
retlw b'010011'
retlw b'001011'
retlw b'000111'
retlw b'100111'
retlw b'010111'
retlw b'001111'
retlw b'101111'
retlw b'011111'
retlw b'011111'
retlw b'111110'
retlw b'111110'
retlw b'111101'
retlw b'111100'
retlw b'111010'
retlw b'111001'
retlw b'111000'
retlw b'110100'
retlw b'110010'
retlw b'110001'
retlw b'101000'
retlw b'100100'
retlw b'100010'
retlw b'010001'
retlw b'001000'
retlw b'000100'
retlw b'000010'
retlw b'000001'
retlw 0x80
pat11 ; breath
addwf PCL,f
retlw b'000000'
retlw b'001100'
retlw b'011110'
retlw b'111111'
retlw b'011110'
retlw b'001100'
retlw 0x80
;----------------------------------------------------------- SFR ini
start
bsf STATUS,RP0
movlw b'00000000'
movwf TRISA
movlw b'00000000'
movwf TRISB
bcf STATUS,RP0
movlw b'00000000'
movwf PORTA
movlw b'00000000'
movwf PORTB
movlw 0x0c
movwf FSR ; FSR = dst ptr for clr
zeros
clrf INDF ; clr one byte
incf FSR,f ; adv dst ptr
btfss FSR,7 ; test if end of RAM...
goto zeros ; ...if not, loop
bsf flag,0 ; leds A active
bsf flag,1 ; leds B active
movlw 1 ; period (1: fastest) (must be >0)
movwf step
movlw 8 ; ramp (1: slowest) (8: ramp=cycle) (must be >0)
movwf speedup
movlw 2
movwf pattern
;----------------------------------------------------------- farm
incf step,w
movwf count_dim ; initialize tempo count
farm ; outer loop
; inner loop #1:
; after [step] passes, [slow] approaches to [target]
; performing INC or DEC or NOP (no chase)
; so [step] is a timing constant for dim tempo
decf count_dim,f
ifnz
goto no_chase
incf step,w
movwf count_dim ; reinitialize tempo count
movf speedup,w
movwf inner_count
speedup_loop
chase_b 0 ; [slow] approach (inc or dec) to [target]
chase_b 1
chase_b 2
chase_b 3
chase_b 4
chase_b 5
chase_a 0
chase_a 1
chase_a 2
decfsz inner_count,f
goto speedup_loop
no_chase
; inner loop #2:
; after 2048 passes, [preset_a:1] and [preset_b:1] will increment and redefine [target:9]
; making one step through the pattern
incf outer_count,w
andlw 0x1f
movwf outer_count
ifnz
goto rough
; every 32th pass
incf broad_count,f
movf broad_count,w
subwf step,w ; NC if step < broad_count
ifc
goto rough
clrf broad_count
; every step*32th pass (moment for new set)
movf pattern,w
movwf inner_count
ifz
goto no_pattern ; no pattern, write to preset_x manually
movlw 0
decf inner_count,f
ifz
goto pattern_inc ; =1 simple binary counting
;-------------------------------
patmac macro patx
local nopatx,again
decf inner_count,f
ifnz
goto nopatx ; not that pattern
again
movf pat_count,w
call patx ; read from lookup table
movwf tempw
btfsc tempw,7
clrf pat_count
btfsc tempw,7
goto again
incf pat_count,f
btfsc flag,1
movwf preset_b
btfsc flag,0
movwf preset_a
goto no_pattern
nopatx
endm
;--------------------------------
patmac pat2
patmac pat3
patmac pat4
patmac pat5
patmac pat6
patmac pat7
patmac pat8
patmac pat9
patmac pat10
patmac pat11
goto no_pattern
pattern_inc ; simple binary counting
btfsc flag,1
incf preset_b,f ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
btfsc flag,0
incf preset_a,f ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
no_pattern ; no pattern, write to [preset_x] manually
wide_b 0
wide_b 1
wide_b 2
wide_b 3
wide_b 4
wide_b 5
wide_a 0
wide_a 1
wide_a 2
rough
; [slow:9] is linearized and written to [count:9]
copy_b 0 ; [slow] ---linearize---> [count]
copy_b 1
copy_b 2
copy_b 3
copy_b 4
copy_b 5
copy_a 0
copy_a 1
copy_a 2
; inner loop #3: (executed 256 times)
; at evety pass, all LEDs will first go ON
; and, when some of [count:9] registers reaches zero, that LED will be switched off
clrf inner_count
movlw 0x3f
movwf outb ; all LEDs on
movlw 0x07
movwf outa ; all LEDs on
go_inner ; inner loop
dec_b 0 ; decrement [count], LED off if [count]=0
dec_b 1 ;
dec_b 2 ;
dec_b 3 ;
dec_b 4 ;
dec_b 5 ;
dec_a 0 ;
dec_a 1 ;
dec_a 2 ;
decfsz inner_count ;
goto go_inner ; inner loop, 30t=5us (256 x 5us = 1.3 ms)
goto farm ; main loop (infinite)
END