.dseg
+timer_var:
delay_timer1:
+.equ ot_timer1 = delay_timer1-timer_var
.byte 1
delay_timer2:
+.equ ot_timer2 = delay_timer2-timer_var
.byte 1
timer_base:
timer_ms:
+.equ ot_ms = timer_ms-timer_var
.byte 2
-timer_s:
+timer_sec:
+.equ ot_sec = timer_sec-timer_var
.byte 4
+
; don't change order here, clock put/get depends on it.
cntms_out: ; register for ms
.byte 2
utime_io: ; register for uptime.
.byte 4
cnt_1ms:
+.equ ot_1ms = cnt_1ms-timer_var
.byte 2
uptime:
+.equ ot_uptime = uptime-timer_var
.byte 4
timer_top:
.equ timer_size = timer_top - timer_base
.equ timerofs = cnt_1ms-timer_ms
clk_out:
+.equ oclk_out = clk_out-timer_var
.byte 7 ;
clock:
+.equ o_clock = clock-timer_var
.byte 7 ;Format (bin): s m h D M YY
.equ clkofs = clock-clk_out
; Timer/Counter1 Compare Match B interrupt
INTERRUPT OC1Baddr
-
+
+.if TIMER_DEBUG
+ cbi PORTC,5
+.endif
push zl
in zl,SREG
push zl
outm8 OCR1BH,zh
outm8 OCR1BL,zl
+ push yl
+ push yh
+ ldiw y,timer_var
+
#if DRAM_8BIT /* Implies software uart */
lds zl,srx_char_to ;try to decrement character timout
subi zl,1
rcall srx_to
syscl0:
#endif
- lds zl,delay_timer1
+ ldd zl,y+ot_timer1
subi zl,1
brcs syscl_t1n
- sts delay_timer1,zl
+ std y+ot_timer1,zl
syscl_t1n:
- lds zl,delay_timer2
+ ldd zl,y+ot_timer2
subi zl,1
brcs syscl_t2n
- sts delay_timer2,zl
+ std y+ot_timer2,zl
syscl_t2n:
- lds zl,cnt_1ms ;count milli seconds
- lds zh,cnt_1ms+1
+ ldd zl,y+ot_1ms ;count milli seconds
+ ldd zh,y+ot_1ms+1
adiw z,1
- sts cnt_1ms,zl
- sts cnt_1ms+1,zh
+ std y+ot_1ms,zl
+ std y+ot_1ms+1,zh
cpi zl,low(1000) ;one second ?
ldi zl,high(1000) ;doesn't change flags
cpc zh,zl
- brge syscl_utime
- rjmp syscl_end
+ brlt syscl_end
+; brge syscl_utime
+; rjmp syscl_end
syscl_utime:
- sts cnt_1ms,_0
- sts cnt_1ms+1,_0
+ std y+ot_1ms,_0
+ std y+ot_1ms+1,_0
- lds zl,uptime+0
- inc zl
- sts uptime+0,zl
- brne syscl_clk
- lds zl,uptime+1
- inc zl
- sts uptime+1,zl
- brne syscl_clk
- lds zl,uptime+2
- inc zl
- sts uptime+2,zl
+ ldd zl,y+ot_uptime+0
+ ldd zh,y+ot_uptime+1
+ adiw z,1
+ std y+ot_uptime+0,zl
+ std y+ot_uptime+1,zh
brne syscl_clk
- lds zl,uptime+3
- inc zl
- sts uptime+3,zl
+ ldd zl,y+ot_uptime+2
+ ldd zh,y+ot_uptime+3
+ adiw z,1
+ std y+ot_uptime+2,zl
+ std y+ot_uptime+3,zh
syscl_clk:
- lds zl,clock+0 ;sec
+ ldd zl,y+o_clock+0 ;sec
inc zl
- sts clock+0,zl
+ std y+o_clock+0,zl
cpi zl,60
- brlo syscl_clk_te
- sts clock+0,_0
- lds zl,clock+1 ;min
+ brlo syscl_end
+ std y+o_clock+0,_0
+ ldd zl,y+o_clock+1 ;min
inc zl
- sts clock+1,zl
+ std y+o_clock+1,zl
cpi zl,60
brlo syscl_end
- sts clock+1,_0
- lds zl,clock+2 ;hour
+ std y+o_clock+1,_0
+ ldd zl,y+o_clock+2 ;hour
inc zl
- sts clock+2,zl
+ std y+o_clock+2,zl
cpi zl,24
- brsh syscl_clk_date
-syscl_clk_te:
- rjmp syscl_end
+ brlo syscl_end
syscl_clk_date:
- sts clock+2,_0
+ std y+o_clock+2,_0
push temp
ldiw z,dayspm_tab*2 - 1
- lds temp,clock+4 ;month
+ ldd temp,y+o_clock+4 ;month
add zl,temp
adc zh,_0
lpm zh,z ;days this month
cpi temp,2
brne syscl_clknl ;february, may be leap year
- lds zl,(clock+5) ;year
+ ldd zl,y+o_clock+5 ;year
andi zl,0x03
brne syscl_clknl
inc zh ;leap year
syscl_clknl:
- lds zl,clock+3 ;day
+ ldd zl,y+o_clock+3 ;day
inc zl
- sts clock+3,zl
+ std y+o_clock+3,zl
cp zh,zl
brsh syscl_clke
ldi zl,1
- sts clock+3,zl
+ std y+o_clock+3,zl
inc temp ;month
- sts clock+4,temp
+ std y+o_clock+4,temp
cpi temp,13
brlo syscl_clke
- sts clock+4,zl
- lds zl,clock+5 ;low year
- inc zl
- sts clock+5,zl
- brne syscl_clke
- lds zl,clock+6 ;high year
- inc zl
- sts clock+6,zl
+ std y+o_clock+4,zl
+ ldd zl,y+o_clock+5 ;low year
+ ldd zh,y+o_clock+6 ;high year
+ adiw z,1
+ std y+o_clock+5,zl
+ std y+o_clock+6,zh
syscl_clke:
pop temp
syscl_end:
+ pop yh
+ pop yl
pop zh
pop zl
out SREG,zl
pop zl
+.if TIMER_DEBUG
+ sbi PORTC,5
+.endif
reti
; days per month
dec temp3
brne clkput_l
sei
-#if I2C
+#if I2C_SUPPORT
rcall rtc_set ; set hardware clock
#endif
ret
binbcd4:
ldi temp3,16
- mov _tmp0,temp
- mov _tmp1,temp2
+ movw _tmp0,temp
clr temp
clr temp2
binbcd4l:
swap temp2
andi temp2,0x0f
andi temp,0x0f ;temp = low digit
- mov _tmp0,temp2
+ mov r0,temp2
ldi temp2,10
- mul temp2,_tmp0 ;high digit * 10
- add temp,_tmp0 ;high digit * 10 + low digit
+ mul temp2,r0 ;high digit * 10
+ add temp,r0 ;high digit * 10 + low digit
pop temp2
ret
ldi temp2,100
mul temp,temp2
pop temp
- mov temp2,_tmp1
- add temp,_tmp0
+ mov temp2,r1
+ add temp,r0
adc temp2,_0
ret
-#if I2C
+#if I2C_SUPPORT
; ----------------------------------------------
; Set software clock from hardware clock
ldi temp2,3
rcall i2c_read ;get year (stored in RTC-RAM addr. 10h)
tst temp
- breq rtc_get_e
+ brmi rtc_get_e ;i2c error
ldd temp3,z+1 ;save year
- ldd temp4,z+2
+ ldd xl, z+2
ldi temp2,2 ;register pointer. 2 = secs
std z+1,temp2
ldi temp2,6
rcall i2c_read
tst temp
- breq rtc_get_e
+ brmi rtc_get_e
+ mov temp2,xl ;year century
ldd temp,z+4 ;get year
rol temp
rol temp
eor temp,temp3
andi temp,0x03
breq rtc_get_1
- inc temp3
- adc temp4,_0
+ subi temp3, low(-1)
+ sbci temp2, high(-1)
rtc_get_1:
ldiw x,clock
cli
rcall bcdbin2
st x+,temp ;store month
st x+,temp3 ;store year
- st x+,temp4 ;store year century
+ st x+,temp2 ;store year century
sei
rtc_get_e:
;
; Register: temp2: s
; temp3: m
-; temp4: h
+; xh: h
; xl: D
; temp: M
; yl: Yl
cli
ldd temp2,z+0 ;sec
ldd temp3,z+1 ;min
- ldd temp4,z+2 ;hours
+ ldd xh,z+2 ;hours
ldd xl,z+3 ;day
ldd temp,z+4 ;month
ldd yl,z+5 ;yearl
andi xl,0xc0
or temp,xl ; combine with day
push temp ;-2 save year/day
- mov temp,temp4
+ mov temp,xh
rcall binbcd2
push temp ;-3 save hours
mov temp,temp3
out sph,zh
ret
-#endif
+#endif /* I2C_SUPPORT */
; ----------------------------------------------
;
utimeget:
ldi temp,0xFF
- subi temp2,TIMER_MSECS
- brcs utimget_end ;Port number in range?
ldiw z,cntms_out
+ subi temp3,1
+ brcs utimget_end ;Rel. port number = 0 ? (controlport)
breq utimget_copy ;lowest byte requestet, latch clock
- cpi temp2,6
- brsh utimget_end ;Port number to high?
- add zl,temp2
+ add zl,temp3
adc zh,_0
ld temp,z
utimget_end:
ret
-
-
utimget_copy:
ldi temp2,6
cli
ret
utimeput:
- subi temp2,TIMERPORT
- brcs utput__end ;Port number in range?
- brne utput__1
+ subi temp3,1
+ brcc utput__1
; clock control
cpi temp,starttimercmd
- breq timer_start
+ breq timer_start ;timer_ms
cpi temp,quitTimerCmd
- breq utput_quit
+ breq utput_quit ;
cpi temp,printTimerCmd
- breq timer_print
+ breq timer_print ;timer_ms
cpi temp,uptimeCmd
brne utcp_ex
- rjmp uptime_print
+ rjmp uptime_print ;cnt_1ms
utcp_ex:
ret
rjmp timer_start
utput__1:
- dec temp2
ldiw z,cntms_out
breq utput__copy ;lowest byte requestet, latch clock
- cpi temp2,6
- brsh utput__end ;Port number to high?
- add zl,temp2
- brcc PC+2
- inc zh
+ add zl,temp3
+ adc zh,_0
st z,temp
-utput__end:
ret
utput__copy:
;
timer_print:
+ push r15 ;
+ push r14 ;
push yh
push yl
ldiw z,timer_ms
ld yh,z+
sbc temp2,yh
- ldd temp3,z+timerofs
+ ldd r14,z+timerofs
ld yl,z+
- sbc temp3,yl
+ sbc r14,yl
sei
- ldd temp4,z+timerofs
+ ldd r15,z+timerofs
ld yh,z+
- sbc temp4,yh
+ sbc r15,yh
printnewline
printstring "Timer running. Elapsed: "
printstring "."
pop temp
pop temp2
- ldi temp3,0
- ldi temp4,0
+ clr r14
+ clr r15
rcall print_ultoa
printstring "s."
pop yl
pop yh
+ pop r14
+ pop r15
ret
uptime_print:
-
+ push r15
+ push r14
ldiw z,cnt_1ms
-
cli
ld temp,z+
push temp
ld temp,z+
ld temp2,z+
- ld temp3,z+
+ ld r14,z+
sei
- ld temp4,z+
+ ld r15,z+
printnewline
printstring "Uptime: "
rcall print_ultoa
printstring ","
- ldi temp3,0
- ldi temp4,0
+ clr r14
+ clr r15
pop temp2
pop temp
rcall print_ultoa
printstring "s."
+ pop r14
+ pop r15
ret
; vim:set ts=8 noet nowrap