corrected careless mistake
[my-code/atmel.git] / beginners / rgb_mali.asm
1 ; rgb_mali.asm
2 ;
3 ; 3 leds (red, green, blue) on different ports.
4 ; cm mode: continuous mixed colors
5 ; rgb mode: keep one special color
6 ;
7 ; modes switchable by uart
8 ;
9 ; author: hackbard@hackdaworld.dyndns.org
10
11
12 .include "../include/2313def.inc"
13
14 ; defines & equals
15 .def zero = r0
16 .def one = r1
17 .def countrgb = r2
18 .def desc = r3
19 .equ RUP = 0
20 .equ RDOWN = 1
21 .equ GUP = 2
22 .equ GDOWN = 3
23 .equ BUP = 4
24 .equ BDOWN = 5
25 .def tmp = r16
26 .def uart_count = r17
27 .def count = r18
28 .def RED = r19
29 .def GREEN = r20
30 .def BLUE = r21
31 .def mode = r22
32 .equ cm = 0
33 .equ rgb = 1
34 .def OUTR = r23
35 .def FULLR = r24
36 .def tmp2 = r25
37 .equ LED_R = PD2
38 .equ LED_G = PD3
39 .equ LED_B = PD4
40 .equ LED_PORT = PORTD
41 .equ CM1 = 85
42 .equ CM2 = 170
43
44 ;
45 ; interrupt voctors
46 ;
47 ; reset
48 rjmp INIT
49 ; int0
50 reti
51 ; int1
52 reti
53 ; timer/counter capt 1
54 reti
55 ; timer/counter compare
56 reti
57 ; timer/counter overflow 1
58 rjmp DO_IT
59 ; timer/counter overflow 0
60 reti
61 ; uart rx complete
62 rjmp UART_RECEIVE
63 ; uart data register empty
64 reti
65 ; uart tx complete
66 reti
67 ; analog comparator
68 reti
69
70 ;
71 ; init routine
72 ;
73 INIT:
74 ; alloc stack pointer
75 ldi r16,low(RAMEND)
76 out SPL,r16
77 ; timer: clock/8
78 ldi tmp,((1<<CS11))
79 out TCCR1B,tmp
80 ; enable timer overflow interrupt
81 ldi tmp,(1<<TOIE1)
82 out TIMSK,tmp
83 ; enable uart + rx complete interrupt
84 ldi tmp,51 ; 9600 baud, 0,2% error @ 8mhz
85 out UBRR,tmp
86 ldi tmp,((1<<RXCIE)|(1<<RXEN)|(1<<TXEN))
87 out UCR,tmp
88 ; init registers
89 ldi tmp,1
90 mov one,tmp
91 ldi tmp,0
92 mov zero,tmp
93 mov countrgb,tmp
94 ldi uart_count,0
95 ldi count,0
96 ldi RED,CM2
97 ldi GREEN,0x0
98 ldi BLUE,0x0
99 ; led pins are outputs
100 ldi tmp,((1<<LED_R)|(1<<LED_G)|(1<<LED_B))
101 out DDRD,tmp
102 ; default mode: cm
103 ldi mode,cm
104 ; enable interrupts (global)
105 sei
106 ; jump to main
107 rjmp MAIN
108
109 ;
110 ; decide what to do
111 ;
112 DO_IT:
113 cpi mode,cm
114 breq CM_ACTION
115 reti
116
117 ;
118 ; specify action
119 ;
120
121
122 ;
123 ; continuous mode action
124 ;
125 CM_ACTION:
126 cp countrgb,zero
127 breq RD_GU
128 ldi tmp,CM1
129 cp countrgb,tmp
130 breq GD_BU
131 ldi tmp,CM2
132 cp countrgb,tmp
133 breq BD_RU
134 ldi tmp,255
135 cp countrgb,tmp
136 breq RESET_RGB
137 rjmp MAKE_RGB
138
139 ;
140 ; reset rgb
141 ;
142 RESET_RGB:
143 ldi RED,CM2
144 mov GREEN,zero
145 mov BLUE,zero
146 mov desc,zero
147 rjmp MAKE_RGB
148
149 ;
150 ; set desc
151 ;
152 RD_GU:
153 ldi tmp,((1<<RDOWN)|(1<<GUP))
154 mov desc,tmp
155 rjmp MAKE_RGB
156 GD_BU:
157 ldi tmp,((1<<GDOWN)|(1<<BUP))
158 mov desc,tmp
159 rjmp MAKE_RGB
160 BD_RU:
161 ldi tmp,((1<<BDOWN)|(1<<RUP))
162 mov desc,tmp
163 rjmp MAKE_RGB
164
165 ;
166 ; do the actual rgb calculation
167 ;
168 MAKE_RGB:
169 ldi tmp,(1<<RUP)
170 and tmp,desc
171 add tmp,tmp
172 add RED,tmp
173 ldi tmp,(1<<GUP)
174 and tmp,desc
175 lsr tmp
176 lsr tmp
177 add tmp,tmp
178 add GREEN,tmp
179 ldi tmp,(1<<BUP)
180 and tmp,desc
181 lsr tmp
182 lsr tmp
183 lsr tmp
184 lsr tmp
185 add tmp,tmp
186 add BLUE,tmp
187 ldi tmp,(1<<RDOWN)
188 and tmp,desc
189 lsr tmp
190 add tmp,tmp
191 sub RED,tmp
192 ldi tmp,(1<<GDOWN)
193 and tmp,desc
194 lsr tmp
195 lsr tmp
196 lsr tmp
197 add tmp,tmp
198 sub GREEN,tmp
199 ldi tmp,(1<<BDOWN)
200 and tmp,desc
201 lsr tmp
202 lsr tmp
203 lsr tmp
204 lsr tmp
205 lsr tmp
206 add tmp,tmp
207 sub BLUE,tmp
208 add countrgb,one
209 reti
210
211 ;
212 ; main routine
213 ;
214 MAIN:
215 ; jump to main loop
216 rjmp LOOP
217
218 :
219 ; main loop
220 ;
221 LOOP:
222 ; reset lights if loop starts 
223 cpi count,0
224 breq RESET_LEDS
225 ; now check leds
226 rjmp CHECK_RED
227
228 ;
229 ; reset leds
230 ;
231 RESET_LEDS:
232 ldi OUTR,((1<<LED_R)|(1<<LED_G)|(1<<LED_B))
233 rjmp CHECK_RED
234
235 ;
236 ; check red + jump to green check
237 ;
238 CHECK_RED:
239 cp count,RED
240 breq SWITCH_OFF_R
241 rjmp CHECK_GREEN
242
243 ;
244 ; switch of red led
245 ;
246 SWITCH_OFF_R:
247 subi OUTR,(1<<LED_R)
248 rjmp CHECK_GREEN
249
250 ;
251 ; check green + jump to blue check
252 ;
253 CHECK_GREEN:
254 cp count,GREEN
255 breq SWITCH_OFF_G
256 rjmp CHECK_BLUE
257
258 ;
259 ; switch of green led
260 ;
261 SWITCH_OFF_G:
262 subi OUTR,(1<<LED_G)
263 rjmp CHECK_BLUE
264
265 ;
266 ; check blue + "do the light"
267 ;
268 CHECK_BLUE:
269 cp count,BLUE
270 breq SWITCH_OFF_B
271 rjmp LIGHT
272
273 ;
274 ; switch of blue led
275 ;
276 SWITCH_OFF_B:
277 subi OUTR,(1<<LED_B)
278 rjmp LIGHT
279
280 ;
281 ; light it up
282 ;
283 LIGHT:
284 ldi FULLR,0xff
285 eor FULLR,OUTR
286 out LED_PORT,FULLR
287 rjmp INC_COUNT
288
289 ;
290 ; increase counter + jump back to main loop
291 ;
292 INC_COUNT:
293 add count,one
294 rjmp LOOP
295
296 ;
297 ; receive from uart
298 ;
299 UART_RECEIVE:
300 cp uart_count,zero
301 breq GET_MODE
302 cpi uart_count,1
303 breq GET_R_VALUE
304 cpi uart_count,2
305 breq GET_G_VALUE
306 cpi uart_count,3
307 breq GET_B_VALUE
308
309 ;
310 ; get mode
311 ;
312 GET_MODE:
313 in tmp,UDR
314 cpi tmp,0x63 ; 0x63 = 'c'
315 breq SET_CONTINUOUS_MODE
316 cpi tmp,0x73 ; 0x73 = 's'
317 breq SET_SPECIFY_MODE
318 ldi uart_count,0
319 reti
320
321 ;
322 ; set cmode
323 ;
324 SET_CONTINUOUS_MODE:
325 ldi mode,cm
326 ldi uart_count,0
327 reti
328
329 ;
330 ; set specify mode
331 ;
332 SET_SPECIFY_MODE:
333 ldi mode,rgb
334 add uart_count,one
335 ; check
336 out UDR,mode
337 reti
338
339 ;
340 ; get red value
341 ;
342 GET_R_VALUE:
343 in RED,UDR
344 add uart_count,one
345 ; check
346 out UDR,RED
347 reti
348
349 ;
350 ; get green value
351 ;
352 GET_G_VALUE:
353 in GREEN,UDR
354 add uart_count,one
355 ; check
356 out UDR,GREEN
357 reti
358
359 ;
360 ; get blue value
361 ;
362 GET_B_VALUE:
363 in BLUE,UDR
364 mov uart_count,zero
365 ; check
366 out UDR,BLUE
367 reti
368