]> cloudbase.mooo.com Git - avrcpm.git/blob - avr/timer.asm
* Set macro I2C=0 as default.
[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 timer_var:
26 delay_timer1:
27 .equ ot_timer1 = delay_timer1-timer_var
28 .byte 1
29 delay_timer2:
30 .equ ot_timer2 = delay_timer2-timer_var
31 .byte 1
32 timer_base:
33 timer_ms:
34 .equ ot_ms = timer_ms-timer_var
35 .byte 2
36 timer_sec:
37 .equ ot_sec = timer_sec-timer_var
38 .byte 4
39
40 ; don't change order here, clock put/get depends on it.
41 cntms_out: ; register for ms
42 .byte 2
43 utime_io: ; register for uptime.
44 .byte 4
45 cnt_1ms:
46 .equ ot_1ms = cnt_1ms-timer_var
47 .byte 2
48 uptime:
49 .equ ot_uptime = uptime-timer_var
50 .byte 4
51 timer_top:
52 .equ timer_size = timer_top - timer_base
53
54 .equ utofs = cnt_1ms-cntms_out
55 .equ timerofs = cnt_1ms-timer_ms
56
57 clk_out:
58 .equ oclk_out = clk_out-timer_var
59 .byte 7 ;
60 clock:
61 .equ o_clock = clock-timer_var
62 .byte 7 ;Format (bin): s m h D M YY
63 .equ clkofs = clock-clk_out
64
65 .cseg
66
67 ; ------------- system timer 1ms ---------------
68
69
70 ; Timer/Counter1 Compare Match B interrupt
71
72 INTERRUPT OC1Baddr
73
74 .if TIMER_DEBUG
75 cbi PORTC,5
76 .endif
77 push zl
78 in zl,SREG
79 push zl
80 push zh
81 inm8 zl,OCR1BL
82 inm8 zh,OCR1BH
83 addiw z,F_CPU/1000
84 outm8 OCR1BH,zh
85 outm8 OCR1BL,zl
86
87 push yl
88 push yh
89 ldiw y,timer_var
90
91 #if DRAM_8BIT /* Implies software uart */
92 lds zl,srx_char_to ;try to decrement character timout
93 subi zl,1
94 brcs syscl0 ;timer was 0 before (not running)
95 sts srx_char_to,zl ;timer is running, store new value
96 brne syscl0
97 rcall srx_to
98 syscl0:
99 #endif
100 ldd zl,y+ot_timer1
101 subi zl,1
102 brcs syscl_t1n
103 std y+ot_timer1,zl
104 syscl_t1n:
105 ldd zl,y+ot_timer2
106 subi zl,1
107 brcs syscl_t2n
108 std y+ot_timer2,zl
109 syscl_t2n:
110
111 ldd zl,y+ot_1ms ;count milli seconds
112 ldd zh,y+ot_1ms+1
113 adiw z,1
114 std y+ot_1ms,zl
115 std y+ot_1ms+1,zh
116 cpi zl,low(1000) ;one second ?
117 ldi zl,high(1000) ;doesn't change flags
118 cpc zh,zl
119 brlt syscl_end
120 ; brge syscl_utime
121 ; rjmp syscl_end
122
123 syscl_utime:
124 std y+ot_1ms,_0
125 std y+ot_1ms+1,_0
126
127 ldd zl,y+ot_uptime+0
128 ldd zh,y+ot_uptime+1
129 adiw z,1
130 std y+ot_uptime+0,zl
131 std y+ot_uptime+1,zh
132 brne syscl_clk
133 ldd zl,y+ot_uptime+2
134 ldd zh,y+ot_uptime+3
135 adiw z,1
136 std y+ot_uptime+2,zl
137 std y+ot_uptime+3,zh
138
139 syscl_clk:
140 ldd zl,y+o_clock+0 ;sec
141 inc zl
142 std y+o_clock+0,zl
143 cpi zl,60
144 brlo syscl_end
145 std y+o_clock+0,_0
146 ldd zl,y+o_clock+1 ;min
147 inc zl
148 std y+o_clock+1,zl
149 cpi zl,60
150 brlo syscl_end
151 std y+o_clock+1,_0
152 ldd zl,y+o_clock+2 ;hour
153 inc zl
154 std y+o_clock+2,zl
155 cpi zl,24
156 brlo syscl_end
157
158 syscl_clk_date:
159 std y+o_clock+2,_0
160 push temp
161
162 ldiw z,dayspm_tab*2 - 1
163 ldd temp,y+o_clock+4 ;month
164 add zl,temp
165 adc zh,_0
166 lpm zh,z ;days this month
167 cpi temp,2
168 brne syscl_clknl ;february, may be leap year
169 ldd zl,y+o_clock+5 ;year
170 andi zl,0x03
171 brne syscl_clknl
172 inc zh ;leap year
173 syscl_clknl:
174 ldd zl,y+o_clock+3 ;day
175 inc zl
176 std y+o_clock+3,zl
177 cp zh,zl
178 brsh syscl_clke
179 ldi zl,1
180 std y+o_clock+3,zl
181 inc temp ;month
182 std y+o_clock+4,temp
183 cpi temp,13
184 brlo syscl_clke
185
186 std y+o_clock+4,zl
187 ldd zl,y+o_clock+5 ;low year
188 ldd zh,y+o_clock+6 ;high year
189 adiw z,1
190 std y+o_clock+5,zl
191 std y+o_clock+6,zh
192
193 syscl_clke:
194 pop temp
195 syscl_end:
196 pop yh
197 pop yl
198 pop zh
199 pop zl
200 out SREG,zl
201 pop zl
202 .if TIMER_DEBUG
203 sbi PORTC,5
204 .endif
205 reti
206
207 ; days per month
208
209 dayspm_tab:
210 .db 31,28,31,30,31,30
211 .db 31,31,30,31,30,31
212
213 ; ----------------------------------------------
214 ; delay
215 ;
216 ; wait for temp ms
217 ;
218
219 delay_ms:
220 sts delay_timer1,temp
221 dly_loop:
222 lds temp,delay_timer1
223 cpi temp,0
224 brne dly_loop
225 ret
226
227 ; ----------------------------------------------
228 ;
229 clockget:
230 ldiw z,clk_out
231 tst temp3
232 breq clkget_copy ;lowest byte requestet, latch clock
233
234 add zl,temp3
235 adc zh,_0
236 ld temp,z
237 clkget_end:
238 ret
239
240
241 clkget_copy:
242 ldi temp3,7
243 cli
244 clkget_l:
245 ldd temp,z+clkofs
246 st z+,temp
247 dec temp3
248 brne clkget_l
249 sei
250
251 ld temp2,-z
252 ld temp, -z
253 rcall binbcd4
254 std z+0,temp
255 std z+1,temp2
256 ldi temp3,5
257 clkget_l2:
258 ld temp,-z
259 rcall binbcd2
260 st z,temp
261 dec temp3
262 brne clkget_l2
263
264 lds temp,clk_out
265 ret ;req. byte in temp
266
267 ; ----------------------------------------------
268 ;
269 clockput:
270 ldiw z,clk_out
271 add zl,temp3
272 adc zh,_0
273 st z,temp
274 tst temp3
275 breq clkput_copy ;lowest byte stored, latch clock
276 clkput_end:
277 ret
278
279
280 clkput_copy:
281 ldi temp3,5
282 clkput_l2:
283 ld temp,z
284 rcall bcdbin2
285 st z+,temp
286 dec temp3
287 brne clkput_l2
288
289 ldd temp,z+0
290 ldd temp2,z+1
291 rcall bcdbin4
292 st z+,temp
293 st z+,temp2
294
295 ldi temp3,7
296 cli
297 clkput_l:
298 ld temp,-z
299 std z+clkofs,temp
300 dec temp3
301 brne clkput_l
302 sei
303 #if I2C
304 rcall rtc_set ; set hardware clock
305 #endif
306 ret
307
308
309 ; ----------------------------------------------
310
311 ; convert binary to bcd
312 ; (only range 0 - 99)
313
314 binbcd2:
315 push temp2
316 ldi temp2,10
317 mov _tmp0,_255
318 tobcd_l:
319 inc _tmp0
320 sub temp,temp2
321 brcc tobcd_l
322 add temp,temp2
323 swap _tmp0
324 add temp,_tmp0
325 pop temp2
326 ret
327
328
329 binbcd4:
330 ldi temp3,16
331 mov _tmp0,temp
332 mov _tmp1,temp2
333 clr temp
334 clr temp2
335 binbcd4l:
336 lsl _tmp0
337 rol _tmp1
338 rol temp
339 rol temp2
340 dec temp3
341 breq binbcd4e
342
343 subi temp2,-0x03
344 sbrs temp2,3
345 subi temp2,0x03
346 subi temp2,-0x30
347 sbrs temp2,7
348 subi temp2,0x30
349 subi temp,-0x03
350 sbrs temp,3
351 subi temp,0x03
352 subi temp,-0x30
353 sbrs temp,7
354 subi temp,0x30
355 rjmp binbcd4l
356
357 binbcd4e:
358 ret
359
360 ; convert bcd to binary
361
362 bcdbin2:
363 push temp2
364 mov temp2,temp ;temp2 = high digit
365 swap temp2
366 andi temp2,0x0f
367 andi temp,0x0f ;temp = low digit
368 mov _tmp0,temp2
369 ldi temp2,10
370 mul temp2,_tmp0 ;high digit * 10
371 add temp,_tmp0 ;high digit * 10 + low digit
372 pop temp2
373 ret
374
375 bcdbin4:
376 rcall bcdbin2
377 push temp
378 mov temp,temp2
379 rcall bcdbin2
380 ldi temp2,100
381 mul temp,temp2
382 pop temp
383 mov temp2,_tmp1
384 add temp,_tmp0
385 adc temp2,_0
386 ret
387
388
389 #if I2C
390
391 ; ----------------------------------------------
392 ; Set software clock from hardware clock
393
394 rtc_get:
395 push _0 ;Placeholder for month/weekday
396 push _0 ;day/year
397 push _0 ;hours
398 push _0 ;minutes
399 ldi temp,0x10 ;register address
400 push temp ;save reg adr/placeholder for sec
401 in zh,sph
402 in zl,spl
403 ldi temp,0xA0 ;PCF8583 slave address
404 push temp
405
406 ldi temp2,2
407 rcall i2c_write
408 ldi temp2,3
409 rcall i2c_read ;get year (stored in RTC-RAM addr. 10h)
410 tst temp
411 breq rtc_get_e
412
413 ldd temp3,z+1 ;save year
414 ldd temp4,z+2
415
416 ldi temp2,2 ;register pointer. 2 = secs
417 std z+1,temp2
418 rcall i2c_write
419 ldi temp2,6
420 rcall i2c_read
421 tst temp
422 breq rtc_get_e
423
424 ldd temp,z+4 ;get year
425 rol temp
426 rol temp
427 rol temp
428 eor temp,temp3
429 andi temp,0x03
430 breq rtc_get_1
431 inc temp3
432 adc temp4,_0
433 rtc_get_1:
434 ldiw x,clock
435 cli
436
437 ldd temp,z+1 ;get seconds
438 rcall bcdbin2
439 st x+,temp
440 ldd temp,z+2 ;get minutes
441 rcall bcdbin2
442 st x+,temp
443 ldd temp,z+3 ;get hours
444 rcall bcdbin2
445 st x+,temp
446 ldd temp,z+4 ;get day
447 andi temp,0x3f
448 rcall bcdbin2
449 st x+,temp
450 ldd temp,z+5 ;get months
451 andi temp,0x1f
452 rcall bcdbin2
453 st x+,temp ;store month
454 st x+,temp3 ;store year
455 st x+,temp4 ;store year century
456 sei
457
458 rtc_get_e:
459 pop temp
460 pop temp
461 pop temp
462 pop temp
463 pop temp
464 pop temp
465 ret
466
467 ;----------------------------------------------
468 ; Set hardware clock from software clock
469 ;
470 ; Register: temp2: s
471 ; temp3: m
472 ; temp4: h
473 ; xl: D
474 ; temp: M
475 ; yl: Yl
476 ; yh: Yh
477
478 rtc_set:
479 ldiw z,clock
480 cli
481 ldd temp2,z+0 ;sec
482 ldd temp3,z+1 ;min
483 ldd temp4,z+2 ;hours
484 ldd xl,z+3 ;day
485 ldd temp,z+4 ;month
486 ldd yl,z+5 ;yearl
487 ldd yh,z+6 ;yearh
488 sei
489 rcall binbcd2
490 push temp ;-1 save month
491 mov temp,xl
492 rcall binbcd2
493 mov xl,yl ; least significant 2 bits of year
494 swap xl
495 lsl xl
496 lsl xl
497 andi xl,0xc0
498 or temp,xl ; combine with day
499 push temp ;-2 save year/day
500 mov temp,temp4
501 rcall binbcd2
502 push temp ;-3 save hours
503 mov temp,temp3
504 rcall binbcd2
505 push temp ;-4 save min
506 mov temp,temp2
507 rcall binbcd2
508 push temp ;-5 save sec
509
510 push _0 ;-6 1/10s, 1/100s
511 ldi temp,0x84 ; stop count, alarm enable
512 push temp ;-7
513 push _0 ;-8 register address
514 in zh,sph
515 in zl,spl
516 ldi temp,0xA0 ; PCF8583 slave address
517 push temp ;(-9)
518
519 ldi temp2,9
520 rcall i2c_write
521 ldi temp,0x04 ;enable counting
522 std z+2,temp
523 ldi temp2,3
524 rcall i2c_write
525 std z+3,yh ;store year in RTC RAM
526 std z+2,yl
527 ldi temp,0x10
528 std z+1,temp
529 ldi temp2,4
530 rcall i2c_write
531
532 addiw z,8 ;remove buffer from stack
533 cli
534 out spl,zl
535 sei
536 out sph,zh
537
538 ret
539 #endif
540
541 ; ----------------------------------------------
542 ;
543
544 utimeget:
545 ldi temp,0xFF
546 ldiw z,cntms_out
547 subi temp3,1
548 brcs utimget_end ;Rel. port number = 0 ? (controlport)
549 breq utimget_copy ;lowest byte requestet, latch clock
550
551 add zl,temp3
552 adc zh,_0
553 ld temp,z
554 utimget_end:
555 ret
556
557 utimget_copy:
558 ldi temp2,6
559 cli
560 utimget_l:
561 ldd temp,z+utofs
562 st z+,temp
563 dec temp2
564 brne utimget_l
565 sei
566 lds temp,cntms_out
567 ;req. byte in temp
568 ret
569
570 utimeput:
571 subi temp3,1
572 brcc utput__1
573
574 ; clock control
575
576 cpi temp,starttimercmd
577 breq timer_start ;timer_ms
578 cpi temp,quitTimerCmd
579 breq utput_quit ;
580 cpi temp,printTimerCmd
581 breq timer_print ;timer_ms
582 cpi temp,uptimeCmd
583 brne utcp_ex
584 rjmp uptime_print ;cnt_1ms
585 utcp_ex:
586 ret
587
588 utput_quit:
589 rcall timer_print
590 rjmp timer_start
591
592 utput__1:
593 ldiw z,cntms_out
594 breq utput__copy ;lowest byte requestet, latch clock
595
596 add zl,temp3
597 adc zh,_0
598 st z,temp
599 ret
600
601 utput__copy:
602 st z,temp
603 adiw z,5
604 ldi temp2,6
605 cli
606 utput__l:
607 ldd temp,z+utofs
608 st z+,temp
609 dec temp2
610 brne utput__l
611 sei
612 ret
613
614 ; start/reset timer
615 ;
616 timer_start:
617 ldiw z,timer_ms
618 ldi temp2,6
619 cli
620 ts_loop:
621 ldd temp,z+timerofs
622 st z+,temp
623 dec temp2
624 brne ts_loop
625 sei
626 ret
627
628
629 ; print timer
630 ;
631
632 timer_print:
633 push yh
634 push yl
635 ldiw z,timer_ms
636
637 ; put ms on stack (16 bit)
638
639 cli
640 ldd yl,z+timerofs
641 ld temp2,z+
642 sub yl,temp2
643 ldd yh,z+timerofs
644 ld temp2,z+
645 sbc yh,temp2
646 brsh tp_s
647
648 addiw y,1000
649 sec
650 tp_s:
651 push yh
652 push yl
653
654 ldd temp,z+timerofs
655 ld yl,z+
656 sbc temp,yl
657
658 ldd temp2,z+timerofs
659 ld yh,z+
660 sbc temp2,yh
661
662 ldd temp3,z+timerofs
663 ld yl,z+
664 sbc temp3,yl
665
666 sei
667 ldd temp4,z+timerofs
668 ld yh,z+
669 sbc temp4,yh
670
671 printnewline
672 printstring "Timer running. Elapsed: "
673 rcall print_ultoa
674
675 printstring "."
676 pop temp
677 pop temp2
678 ldi temp3,0
679 ldi temp4,0
680 rcall print_ultoa
681 printstring "s."
682
683 pop yl
684 pop yh
685 ret
686
687 uptime_print:
688 ldiw z,cnt_1ms
689 cli
690 ld temp,z+
691 push temp
692 ld temp,z+
693 push temp
694
695 ld temp,z+
696 ld temp2,z+
697 ld temp3,z+
698 sei
699 ld temp4,z+
700
701 printnewline
702 printstring "Uptime: "
703
704 rcall print_ultoa
705 printstring ","
706
707 ldi temp3,0
708 ldi temp4,0
709 pop temp2
710 pop temp
711 rcall print_ultoa
712 printstring "s."
713
714 ret
715
716 ; vim:set ts=8 noet nowrap
717