forked from quasipedia/Lanterns
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmacClock24.S
284 lines (232 loc) · 7.18 KB
/
macClock24.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
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
;;;
;;; Code for Mac' Great Russian Word Clock with 1 minute resolution, 24 hours
;;; to set proper LED strings on depending on the time.
;;;
;;; There are 24 * 60 = 1440 possible time values
;;; There are 7 TLC chips * 16 bits the bitmask table for each time =
;;; 14 bytes per time, or a total size of 20160 bytes. Problem!
;;; 106 strings, 8
;;;
;;; Mask of which strings are on for a given time are stored as a sequence of
;;; bytes indicating the numbers of on-strings. The last byte for a given
;;; time number has the high bit set.
;;;
#import "reg_mnemonics.h"
.text
.global clockFace_init
.global clockFace_setStrings
clockFace_init:
/*
;; Set any strings constantly on here
;;
;; Get the desired intensity due to ambient light, use as parameter to
;; set TLC intensity
mov REG_TLC_CHANNEL_INTENSITY_LOW, REG_CHANNEL_INTENSITY_LOW
mov REG_TLC_CHANNEL_INTENSITY_HIGH, REG_CHANNEL_INTENSITY_HIGH
clr REG_TLC_CHANNEL_NUMBER
call TLC_setChannelTargetIntensity
inc REG_TLC_CHANNEL_NUMBER
call TLC_setChannelTargetIntensity
inc REG_TLC_CHANNEL_NUMBER
call TLC_setChannelTargetIntensity
*/
ret
clockFace_setStrings:
;;
;; Algo: multiply hours by 60 and add to minutes to get index into
;; bitmask.
;;
;; Compare this index to the value previously used to obtain the pointer
;; into to the bit mask data. If the new index is greater or equal to the
;; previously used index, step forward through the byte data to reach the
;; new value. Otherwise start from the beginning, looping though high
;; bit values.
;;
;; Set strings related to minutes
;; This will be channel numbers 3,4,5,6,7,8,9,10,11,12,13
;; Loop twice, first turn channels off, then turn channels on, just to
;; avoid moving stuff in and out of the TLC parameter registers all the
;; time.
;;
;; Load Z with program memory address of minute word
;;
ldi REG_SCRATCH_4, 8
mov REG_SCRATCH_3, REG_SCRATCH_4 ; Counter will be decremented
ldi ZH, hi8( minuteStringData )
ldi ZL, lo8( minuteStringData )
mov REG_SCRATCH_1, MINS_PAST
;; Multiply minutes past by two to get index into table (because each
;; entry is two bytes
lsl REG_SCRATCH_1
add ZL, REG_SCRATCH_1
clr REG_SCRATCH_1
adc ZH, REG_SCRATCH_1
push ZL
push ZH ; Save
clr REG_TLC_CHANNEL_INTENSITY_LOW
clr REG_TLC_CHANNEL_INTENSITY_HIGH
ldi REG_SCRATCH_4, 3 ; Channel number of first channel
mov REG_SCRATCH_2, REG_SCRATCH_4
lpm REG_SCRATCH_1, Z+ ; REG_SCRATCH_1 now has low byte of string
call clockFace_setOffChannels
;;
;; When we get here, the first 8 variable channels (3-10) which should
;; be off have been turned off
;;
;; Handle the remaining three minute channels
;;
ldi REG_SCRATCH_4, 3
mov REG_SCRATCH_3, REG_SCRATCH_4 ; Counter
lpm REG_SCRATCH_1, Z+ ; REG_SCRATCH_1 now has high byte of string
call clockFace_setOffChannels
;;
;; When we get here, all channels that should be off have been turned
;; off.
pop ZH
pop ZL
;;
;; Set desired on intensity
;;
mov REG_TLC_CHANNEL_INTENSITY_LOW, REG_CHANNEL_INTENSITY_LOW
mov REG_TLC_CHANNEL_INTENSITY_HIGH, REG_CHANNEL_INTENSITY_HIGH
ldi REG_SCRATCH_4, 8 ; Counter
mov REG_SCRATCH_3, REG_SCRATCH_4
ldi REG_SCRATCH_4, 3
mov REG_SCRATCH_2, REG_SCRATCH_4 ; First channel
lpm REG_SCRATCH_1, Z+ ; REG_SCRATCH_1 now has low byte of string
call clockFace_setOnChannels
ldi REG_SCRATCH_4, 3
mov REG_SCRATCH_3, REG_SCRATCH_4 ; Counter
lpm REG_SCRATCH_1, Z+ ; REG_SCRATCH_1 now has high byte of string
call clockFace_setOnChannels
;;
;; When we get here, all minute channels should be set to their proper
;; target value. Do the same thing with the hour values
;;
;;
;; Load Z with program memory address of minute word
;;
ldi ZH, hi8( hourStringData )
ldi ZL, lo8( hourStringData )
mov REG_SCRATCH_1, HOURS
;;
;; If minutes past is 5 or greater, use the next hour, because we will
;; be using "halv" or "i" forms of time.
;;
cpi MINS_PAST, 5
brlo keepHour
mov REG_SCRATCH_4, REG_SCRATCH_1
cpi REG_SCRATCH_4, 11
brne notMidnight
clr REG_SCRATCH_1
rjmp keepHour
notMidnight:
inc REG_SCRATCH_1
keepHour:
;; Multiply hours by two to get index into table (because each
;; entry is two bytes
lsl REG_SCRATCH_1
add ZL, REG_SCRATCH_1
clr REG_SCRATCH_1
adc ZH, REG_SCRATCH_1
push ZL
push ZH ; Save
clr REG_TLC_CHANNEL_INTENSITY_LOW
clr REG_TLC_CHANNEL_INTENSITY_HIGH
ldi REG_SCRATCH_4, 8
mov REG_SCRATCH_3, REG_SCRATCH_4 ; Counter will be decremented
ldi REG_SCRATCH_4, 14 ; Channel number of first channel
mov REG_SCRATCH_2, REG_SCRATCH_4 ; Channel number of first channel
lpm REG_SCRATCH_1, Z+ ; REG_SCRATCH_1 now has low byte of string
call clockFace_setOffChannels
ldi REG_SCRATCH_4, 8
mov REG_SCRATCH_3, REG_SCRATCH_4 ; use all 8 bits
lpm REG_SCRATCH_1, Z+ ; REG_SCRATCH_1 now high byte of bit mask
call clockFace_setOffChannels
;;
;; When we get here, all hour channels which should be off have been
;; turned off.
;;
;; Turn hour channels on
;;
pop ZH
pop ZL
;;
;; Set desired on intensity
;;
mov REG_TLC_CHANNEL_INTENSITY_LOW, REG_CHANNEL_INTENSITY_LOW
mov REG_TLC_CHANNEL_INTENSITY_HIGH, REG_CHANNEL_INTENSITY_HIGH
ldi REG_SCRATCH_4, 8 ; Counter
mov REG_SCRATCH_3, REG_SCRATCH_4 ; Counter
ldi REG_SCRATCH_4, 14 ; First channel
mov REG_SCRATCH_2, REG_SCRATCH_4 ; First channel
lpm REG_SCRATCH_1, Z+ ; REG_SCRATCH_1 now has low byte of string
call clockFace_setOnChannels
ldi REG_SCRATCH_4, 8 ; Counter
mov REG_SCRATCH_3, REG_SCRATCH_4 ; Counter
lpm REG_SCRATCH_1, Z+ ; REG_SCRATCH_1 now has high byte of string
call clockFace_setOnChannels
;;
;; Done!
;;
ret
;; There are 11 strings related to minutes
;; this table has one word (16 bits) to indicate which strings are on
;;
;; LSB in each word is for string 3, bit 10 for string d
minuteStringData:
.word 0x0000
.word 0x0001
.word 0x0003
.word 0x0007
.word 0x000f
.word 0x001f
.word 0x002f
.word 0x003f
.word 0x007f
.word 0x00ff
.word 0x01ff
.word 0x03ff
/*
.word 0x0000 ; on the hour
.word 0b0000000110000100 ; five past the hour (fem över) 0x184
.word 0b0000000110001000 ; ten past the hour (tio över)
.word 0b0000000110110000 ; quarter past the hour (kvart över)
.word 0b0000000110000011 ; twenty past the hour (tjugo över)
.word 0b0000011001000100 ; twenty five past the hour (fem i halv)
.word 0b0000011000000000 ; half past ("halv")
.word 0b0000011110000100 ; 35 minutes past (fem över halv)
.word 0b0000000001000011 ; 40 minutes past (tjugo i)
.word 0b0000000111000000 ; 45 minutes past (kvart i)
.word 0b0000000001001000 ; 50 minutes past (tio i)
.word 0b0000000001000100 ; 55 minutes past (fem i)
*/
;; There are 16 strings related to hours
hourStringData:
.word 0x0001
.word 0x0002
.word 0x0004
.word 0x0008
.word 0x0010
.word 0x0020
.word 0x0040
.word 0x0080
.word 0x0100
.word 0x0200
.word 0x0400
.word 0x0800
/*
.word 0b0110000000000000 ; 12
.word 0b0000000000000010 ; 1
.word 0b0000000000000001 ; 2
.word 0b0000000010000000 ; 3
.word 0b0000000000001100 ; 4
.word 0b0000000000010000 ; 5
.word 0b0000001000000000 ; 6
.word 0b0001000000000000 ; 7
.word 0b0000000001100000 ; 8
.word 0b1000000000000000 ; 9
.word 0b0000000100000000 ; 10
.word 0b0000110000000000 ; 11
*/
.end