some fixes
[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))
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,CM1
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 ; continuous mode action
119 ;
120 CM_ACTION:
121 cp countrgb,zero
122 breq RD_GU
123 ldi tmp,CM1
124 cp countrgb,tmp
125 breq GD_BU
126 ldi tmp,CM2
127 cp countrgb,tmp
128 breq BD_RU
129 ldi tmp,255
130 cp countrgb,tmp
131 breq RESET_RGB
132 rjmp MAKE_RGB
133
134 ;
135 ; reset rgb
136 ;
137 RESET_RGB:
138 ldi RED,CM1
139 mov GREEN,zero
140 mov BLUE,zero
141 mov desc,zero
142 rjmp MAKE_RGB
143
144 ;
145 ; set desc
146 ;
147 RD_GU:
148 ldi tmp,((1<<RDOWN)|(1<<GUP))
149 mov desc,tmp
150 rjmp MAKE_RGB
151 GD_BU:
152 ldi tmp,((1<<GDOWN)|(1<<BUP))
153 mov desc,tmp
154 rjmp MAKE_RGB
155 BD_RU:
156 ldi tmp,((1<<BDOWN)|(1<<RUP))
157 mov desc,tmp
158 rjmp MAKE_RGB
159
160 ;
161 ; do the actual rgb calculation
162 ;
163 MAKE_RGB:
164 ldi tmp,(1<<RUP)
165 and tmp,desc
166 add RED,tmp
167 ldi tmp,(1<<GUP)
168 and tmp,desc
169 lsr tmp
170 lsr tmp
171 add GREEN,tmp
172 ldi tmp,(1<<BUP)
173 and tmp,desc
174 lsr tmp
175 lsr tmp
176 lsr tmp
177 lsr tmp
178 add BLUE,tmp
179 ldi tmp,(1<<RDOWN)
180 and tmp,desc
181 lsr tmp
182 sub RED,tmp
183 ldi tmp,(1<<GDOWN)
184 and tmp,desc
185 lsr tmp
186 lsr tmp
187 lsr tmp
188 sub GREEN,tmp
189 ldi tmp,(1<<BDOWN)
190 and tmp,desc
191 lsr tmp
192 lsr tmp
193 lsr tmp
194 lsr tmp
195 lsr tmp
196 sub BLUE,tmp
197 add countrgb,one
198 reti
199
200 ;
201 ; main routine
202 ;
203 MAIN:
204 ; jump to main loop
205 rjmp LOOP
206
207 :
208 ; main loop
209 ;
210 LOOP:
211 ; reset lights if loop starts 
212 cpi count,0
213 breq RESET_LEDS
214 ; now check leds
215 rjmp CHECK_RED
216
217 ;
218 ; reset leds
219 ;
220 RESET_LEDS:
221 ldi OUTR,((1<<LED_R)|(1<<LED_G)|(1<<LED_B))
222 rjmp CHECK_RED
223
224 ;
225 ; check red + jump to green check
226 ;
227 CHECK_RED:
228 cp count,RED
229 breq SWITCH_OFF_R
230 rjmp CHECK_GREEN
231
232 ;
233 ; switch of red led
234 ;
235 SWITCH_OFF_R:
236 subi OUTR,(1<<LED_R)
237 rjmp CHECK_GREEN
238
239 ;
240 ; check green + jump to blue check
241 ;
242 CHECK_GREEN:
243 cp count,GREEN
244 breq SWITCH_OFF_G
245 rjmp CHECK_BLUE
246
247 ;
248 ; switch of green led
249 ;
250 SWITCH_OFF_G:
251 subi OUTR,(1<<LED_G)
252 rjmp CHECK_BLUE
253
254 ;
255 ; check blue + "do the light"
256 ;
257 CHECK_BLUE:
258 cp count,BLUE
259 breq SWITCH_OFF_B
260 rjmp LIGHT
261
262 ;
263 ; switch of blue led
264 ;
265 SWITCH_OFF_B:
266 subi OUTR,(1<<LED_B)
267 rjmp LIGHT
268
269 ;
270 ; light it up
271 ;
272 LIGHT:
273 ldi FULLR,0xff
274 eor FULLR,OUTR
275 out LED_PORT,FULLR
276 rjmp INC_COUNT
277
278 ;
279 ; increase counter + jump back to main loop
280 ;
281 INC_COUNT:
282 add count,one
283 rjmp LOOP
284
285 ;
286 ; receive from uart
287 ;
288 UART_RECEIVE:
289 reti
290