]> cloudbase.mooo.com Git - avrcpm.git/blob - avr/timer.asm
* minor corrections/enhancements
[avrcpm.git] / avr / timer.asm
1 ; Timer module
2 ;
3 ; Copyright (C) 2010 Leo C.
4 ;
5 ; This file is part of avrcpm.
6 ;
7 ; avrcpm is free software: you can redistribute it and/or modify it
8 ; under the terms of the GNU General Public License as published by
9 ; the Free Software Foundation, either version 3 of the License, or
10 ; (at your option) any later version.
11 ;
12 ; avrcpm is distributed in the hope that it will be useful,
13 ; but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 ; GNU General Public License for more details.
16 ;
17 ; You should have received a copy of the GNU General Public License
18 ; along with avrcpm. If not, see <http://www.gnu.org/licenses/>.
19 ;
20 ; $Id$
21 ;
22
23 .dseg
24
25 delay_timer1:
26 .byte 1
27 delay_timer2:
28 .byte 1
29 timer_base:
30 timer_ms:
31 .byte 2
32 timer_s:
33 .byte 4
34 ; don't change order here, clock put/get depends on it.
35 cntms_out: ; register for ms
36 .byte 2
37 utime_io: ; register for uptime.
38 .byte 4
39 cnt_1ms:
40 .byte 2
41 uptime:
42 .byte 4
43 timer_top:
44 .equ timer_size = timer_top - timer_base
45
46 .equ utofs = cnt_1ms-cntms_out
47 .equ timerofs = cnt_1ms-timer_ms
48
49 clk_out:
50 .byte 6 ;
51 clock:
52 .byte 6 ;Format (bin): Y M D H M S
53 .equ clkofs = clock-clk_out
54
55 .cseg
56
57 ; ------------- system timer 1ms ---------------
58
59
60 ; Timer/Counter1 Compare Match B interrupt
61
62 INTERRUPT OC1Baddr
63
64 push zl
65 in zl,SREG
66 push zl
67 push zh
68 inm8 zl,OCR1BL
69 inm8 zh,OCR1BH
70 addiw z,F_CPU/1000
71 outm8 OCR1BH,zh
72 outm8 OCR1BL,zl
73
74 #if DRAM_8BIT /* Implies software uart */
75 lds zl,srx_char_to
76 subi zl,1
77 brcs syscl0
78 sts srx_char_to,zl
79 brne syscl0
80 rcall srx_to
81 syscl0:
82 #endif
83 lds zl,delay_timer1
84 subi zl,1
85 brcs syscl_t1n
86 sts delay_timer1,zl
87 syscl_t1n:
88 lds zl,delay_timer2
89 subi zl,1
90 brcs syscl_t2n
91 sts delay_timer2,zl
92 syscl_t2n:
93 lds zl,cnt_1ms
94 lds zh,cnt_1ms+1
95 adiw z,1
96
97 sts cnt_1ms,zl
98 sts cnt_1ms+1,zh
99 cpi zl,low(1000)
100 ldi zl,high(1000) ;doesn't change flags
101 cpc zh,zl
102 brge syscl_utime
103 rjmp syscl_end
104
105 syscl_utime:
106 sts cnt_1ms,_0
107 sts cnt_1ms+1,_0
108
109 lds zl,uptime+0
110 inc zl
111 sts uptime+0,zl
112 brne syscl_clk
113 lds zl,uptime+1
114 inc zl
115 sts uptime+1,zl
116 brne syscl_clk
117 lds zl,uptime+2
118 inc zl
119 sts uptime+2,zl
120 brne syscl_clk
121 lds zl,uptime+3
122 inc zl
123 sts uptime+3,zl
124
125 syscl_clk:
126 lds zl,clock+5 ;sec
127 inc zl
128 sts clock+5,zl
129 cpi zl,60
130 brlo syscl_end
131 sts clock+5,_0
132 lds zl,clock+4 ;min
133 inc zl
134 sts clock+4,zl
135 cpi zl,60
136 brlo syscl_end
137 sts clock+4,_0
138 lds zl,clock+3 ;hour
139 inc zl
140 sts clock+3,zl
141 cpi zl,24
142 brlo syscl_end
143 sts clock+3,_0
144 push temp
145
146 ldiw z,dayspm_tab*2 - 1
147 lds temp,clock+1 ;month
148 add zl,temp
149 adc zh,_0
150 lpm zh,z ;days this month
151 cpi temp,2
152 brne syscl_clknf ;february, may be leap year
153 lds zl,(clock+0) ;year
154 andi zl,0xfc
155 brne syscl_clknl
156 inc zh ;leap year
157 syscl_clknl:
158 syscl_clknf:
159 lds zl,clock+2 ;day
160 inc zl
161 sts clock+2,zl
162 cp zh,zl
163 brsh syscl_clke
164 ldi zl,1
165 sts clock+2,zl
166 inc temp ;month
167 sts clock+1,temp
168 cpi temp,13
169 brlo syscl_clke
170
171 sts clock+1,zl
172 lds zl,clock+0 ;year
173 inc zl
174 sts clock+0,zl
175
176 syscl_clke:
177 pop temp
178 syscl_end:
179 pop zh
180 pop zl
181 out SREG,zl
182 pop zl
183 reti
184
185 ; days per month
186
187 dayspm_tab:
188 .db 31,28,31,30,31,30
189 .db 31,31,30,31,30,31
190
191 ; ----------------------------------------------
192 ; delay
193 ;
194 ; wait for temp ms
195 ;
196
197 delay_ms:
198 sts delay_timer1,temp
199 dly_loop:
200 lds temp,delay_timer1
201 cpi temp,0
202 brne dly_loop
203 ret
204
205 ; ----------------------------------------------
206 ;
207
208 clockget:
209 ldi temp,0xFF
210 subi temp2,CLOCKPORT
211 brcs clkget_end ;Port number in range?
212 ldiw z,clk_out
213 breq clkget_copy ;lowest byte requestet, latch clock
214 cpi temp2,6
215 brsh clkget_end ;Port number to high?
216
217 add zl,temp2
218 adc zh,_0
219 ld temp,z
220 clkget_end:
221 ret
222
223
224 clkget_copy:
225 ldi temp2,6
226 cli
227 clkget_l:
228 ldd temp,z+clkofs
229 st z+,temp
230 dec temp2
231 brne clkget_l
232 sei
233 lds temp,clk_out
234 ;req. byte in temp
235 ret
236
237 clockput:
238 subi temp2,CLOCKPORT
239 brcs clkput_end ;Port number in range?
240
241 ldiw z,clk_out
242 breq clkput_copy ;lowest byte requestet, latch clock
243 cpi temp2,6
244 brsh clkput_end ;Port number to high?
245
246 add zl,temp2
247 adc zh,_0
248 st z,temp
249 clkput_end:
250 ldiw z,clk_out
251 ret
252
253 clkput_copy:
254 st z,temp
255 ldi temp2,6
256 cli
257 clkput_l:
258 ld temp,z+
259 std z+clkofs-1,temp
260 dec temp2
261 brne clkput_l
262 sei
263 ldiw z,clk_out
264 ret
265
266 ; ----------------------------------------------
267 ;
268
269 utimeget:
270 ldi temp,0xFF
271 subi temp2,TIMER_MSECS
272 brcs utimget_end ;Port number in range?
273 ldiw z,cntms_out
274 breq utimget_copy ;lowest byte requestet, latch clock
275 cpi temp2,6
276 brsh utimget_end ;Port number to high?
277
278 add zl,temp2
279 adc zh,_0
280 ld temp,z
281 utimget_end:
282 ret
283
284
285
286 utimget_copy:
287 ldi temp2,6
288 cli
289 utimget_l:
290 ldd temp,z+utofs
291 st z+,temp
292 dec temp2
293 brne utimget_l
294 sei
295 lds temp,cntms_out
296 ;req. byte in temp
297 ret
298
299 utimeput:
300 subi temp2,TIMERPORT
301 brcs utput__end ;Port number in range?
302 brne utput__1
303
304 ; clock control
305
306 cpi temp,starttimercmd
307 breq timer_start
308 cpi temp,quitTimerCmd
309 breq utput_quit
310 cpi temp,printTimerCmd
311 breq timer_print
312 cpi temp,uptimeCmd
313 brne utcp_ex
314 rjmp uptime_print
315 utcp_ex:
316 ret
317
318 utput_quit:
319 rcall timer_print
320 rjmp timer_start
321
322 utput__1:
323 dec temp2
324 ldiw z,cntms_out
325 breq utput__copy ;lowest byte requestet, latch clock
326 cpi temp2,6
327 brsh utput__end ;Port number to high?
328
329 add zl,temp2
330 brcc PC+2
331 inc zh
332 st z,temp
333 utput__end:
334 ret
335
336 utput__copy:
337 st z,temp
338 adiw z,5
339 ldi temp2,6
340 cli
341 utput__l:
342 ldd temp,z+utofs
343 st z+,temp
344 dec temp2
345 brne utput__l
346 sei
347 ret
348
349 ; start/reset timer
350 ;
351 timer_start:
352 ldiw z,timer_ms
353 ldi temp2,6
354 cli
355 ts_loop:
356 ldd temp,z+timerofs
357 st z+,temp
358 dec temp2
359 brne ts_loop
360 sei
361 ret
362
363
364 ; print timer
365 ;
366
367 timer_print:
368 push yh
369 push yl
370 ldiw z,timer_ms
371
372 ; put ms on stack (16 bit)
373
374 cli
375 ldd yl,z+timerofs
376 ld temp2,z+
377 sub yl,temp2
378 ldd yh,z+timerofs
379 ld temp2,z+
380 sbc yh,temp2
381 brsh tp_s
382
383 addiw y,1000
384 sec
385 tp_s:
386 push yh
387 push yl
388
389 ldd temp,z+timerofs
390 ld yl,z+
391 sbc temp,yl
392
393 ldd temp2,z+timerofs
394 ld yh,z+
395 sbc temp2,yh
396
397 ldd temp3,z+timerofs
398 ld yl,z+
399 sbc temp3,yl
400
401 sei
402 ldd temp4,z+timerofs
403 ld yh,z+
404 sbc temp4,yh
405
406 printnewline
407 printstring "Timer running. Elapsed: "
408 rcall print_ultoa
409
410 printstring "."
411 pop temp
412 pop temp2
413 ldi temp3,0
414 ldi temp4,0
415 rcall print_ultoa
416 printstring "s."
417
418 pop yl
419 pop yh
420 ret
421
422 uptime_print:
423
424 ldiw z,cnt_1ms
425
426 cli
427 ld temp,z+
428 push temp
429 ld temp,z+
430 push temp
431
432 ld temp,z+
433 ld temp2,z+
434 ld temp3,z+
435 sei
436 ld temp4,z+
437
438 printnewline
439 printstring "Uptime: "
440
441 rcall print_ultoa
442 printstring ","
443
444 ldi temp3,0
445 ldi temp4,0
446 pop temp2
447 pop temp
448 rcall print_ultoa
449 printstring "s."
450
451 ret
452
453 ; vim:set ts=8 noet nowrap
454