X-Git-Url: http://cloudbase.mooo.com/gitweb/avrcpm.git/blobdiff_plain/162601cae715d054f74f6882aacb07c1e7a26631..d8fa6a36ffba80be398c90641b3e7e7a79d56d43:/avr/timer.asm diff --git a/avr/timer.asm b/avr/timer.asm index 80e9fca..fa2b31f 100644 --- a/avr/timer.asm +++ b/avr/timer.asm @@ -47,9 +47,9 @@ timer_top: .equ timerofs = cnt_1ms-timer_ms clk_out: - .byte 6 ; + .byte 7 ; clock: - .byte 6 ;Format (bin): Y M D H M S + .byte 7 ;Format (bin): s m h D M YY .equ clkofs = clock-clk_out .cseg @@ -72,11 +72,11 @@ clock: outm8 OCR1BL,zl #if DRAM_8BIT /* Implies software uart */ - lds zl,srx_char_to + lds zl,srx_char_to ;try to decrement character timout subi zl,1 - brcs syscl0 - sts srx_char_to,zl - brne syscl0 + brcs syscl0 ;timer was 0 before (not running) + sts srx_char_to,zl ;timer is running, store new value + brne syscl0 rcall srx_to syscl0: #endif @@ -89,15 +89,15 @@ syscl_t1n: subi zl,1 brcs syscl_t2n sts delay_timer2,zl -syscl_t2n: - lds zl,cnt_1ms +syscl_t2n: + + lds zl,cnt_1ms ;count milli seconds lds zh,cnt_1ms+1 adiw z,1 - sts cnt_1ms,zl sts cnt_1ms+1,zh - cpi zl,low(1000) - ldi zl,high(1000) ;doesn't change flags + cpi zl,low(1000) ;one second ? + ldi zl,high(1000) ;doesn't change flags cpc zh,zl brge syscl_utime rjmp syscl_end @@ -123,55 +123,61 @@ syscl_utime: sts uptime+3,zl syscl_clk: - lds zl,clock+5 ;sec + lds zl,clock+0 ;sec inc zl - sts clock+5,zl + sts clock+0,zl cpi zl,60 brlo syscl_end - sts clock+5,_0 - lds zl,clock+4 ;min + sts clock+0,_0 + lds zl,clock+1 ;min inc zl - sts clock+4,zl + sts clock+1,zl cpi zl,60 brlo syscl_end - sts clock+4,_0 - lds zl,clock+3 ;hour + sts clock+1,_0 + lds zl,clock+2 ;hour inc zl - sts clock+3,zl + sts clock+2,zl cpi zl,24 - brlo syscl_end - sts clock+3,_0 + brsh syscl_clk_date + rjmp syscl_end + +syscl_clk_date: + sts clock+2,_0 push temp ldiw z,dayspm_tab*2 - 1 - lds temp,clock+1 ;month + lds temp,clock+4 ;month add zl,temp adc zh,_0 lpm zh,z ;days this month cpi temp,2 - brne syscl_clknf ;february, may be leap year - lds zl,(clock+0) ;year - andi zl,0xfc + brne syscl_clknl ;february, may be leap year + lds zl,(clock+5) ;year + andi zl,0x03 brne syscl_clknl inc zh ;leap year syscl_clknl: -syscl_clknf: - lds zl,clock+2 ;day + lds zl,clock+3 ;day inc zl - sts clock+2,zl + sts clock+3,zl cp zh,zl brsh syscl_clke ldi zl,1 - sts clock+2,zl + sts clock+3,zl inc temp ;month - sts clock+1,temp + sts clock+4,temp cpi temp,13 brlo syscl_clke - sts clock+1,zl - lds zl,clock+0 ;year + sts clock+4,zl + lds zl,clock+5 ;low year inc zl - sts clock+0,zl + sts clock+5,zl + brne syscl_clke + lds zl,clock+6 ;high year + inc zl + sts clock+6,zl syscl_clke: pop temp @@ -204,65 +210,318 @@ dly_loop: ; ---------------------------------------------- ; - clockget: - ldi temp,0xFF - subi temp2,CLOCKPORT - brcs clkget_end ;Port number in range? ldiw z,clk_out + tst temp3 breq clkget_copy ;lowest byte requestet, latch clock - cpi temp2,6 - brsh clkget_end ;Port number to high? - add zl,temp2 + add zl,temp3 adc zh,_0 ld temp,z clkget_end: ret - + clkget_copy: - ldi temp2,6 + ldi temp3,7 cli clkget_l: ldd temp,z+clkofs st z+,temp - dec temp2 + dec temp3 brne clkget_l sei + + ld temp2,-z + ld temp, -z + rcall binbcd4 + std z+0,temp + std z+1,temp2 + ldi temp3,5 +clkget_l2: + ld temp,-z + rcall binbcd2 + st z,temp + dec temp3 + brne clkget_l2 + lds temp,clk_out - ;req. byte in temp - ret + ret ;req. byte in temp +; ---------------------------------------------- +; clockput: - subi temp2,CLOCKPORT - brcs clkput_end ;Port number in range? - ldiw z,clk_out - breq clkput_copy ;lowest byte requestet, latch clock - cpi temp2,6 - brsh clkput_end ;Port number to high? - - add zl,temp2 + add zl,temp3 adc zh,_0 st z,temp + tst temp3 + breq clkput_copy ;lowest byte stored, latch clock clkput_end: - ldiw z,clk_out ret + clkput_copy: - st z,temp - ldi temp2,6 + ldi temp3,5 +clkput_l2: + ld temp,z + rcall bcdbin2 + st z+,temp + dec temp3 + brne clkput_l2 + + ldd temp,z+0 + ldd temp2,z+1 + rcall bcdbin4 + st z+,temp + st z+,temp2 + + ldi temp3,7 cli clkput_l: - ld temp,z+ - std z+clkofs-1,temp - dec temp2 + ld temp,-z + std z+clkofs,temp + dec temp3 brne clkput_l sei - ldiw z,clk_out +#if I2C + rcall rtc_set ; set hardware clock +#endif + ret + + +; ---------------------------------------------- + +; convert binary to bcd +; (only range 0 - 99) + +binbcd2: + push temp2 + ldi temp2,10 + mov _tmp0,_255 +tobcd_l: + inc _tmp0 + sub temp,temp2 + brcc tobcd_l + add temp,temp2 + swap _tmp0 + add temp,_tmp0 + pop temp2 + ret + + +binbcd4: + ldi temp3,16 + mov _tmp0,temp + mov _tmp1,temp2 + clr temp + clr temp2 +binbcd4l: + lsl _tmp0 + rol _tmp1 + rol temp + rol temp2 + dec temp3 + breq binbcd4e + + subi temp2,-0x03 + sbrs temp2,3 + subi temp2,0x03 + subi temp2,-0x30 + sbrs temp2,7 + subi temp2,0x30 + subi temp,-0x03 + sbrs temp,3 + subi temp,0x03 + subi temp,-0x30 + sbrs temp,7 + subi temp,0x30 + rjmp binbcd4l + +binbcd4e: + ret + +; convert bcd to binary + +bcdbin2: + push temp2 + mov temp2,temp ;temp2 = high digit + swap temp2 + andi temp2,0x0f + andi temp,0x0f ;temp = low digit + mov _tmp0,temp2 + ldi temp2,10 + mul temp2,_tmp0 ;high digit * 10 + add temp,_tmp0 ;high digit * 10 + low digit + pop temp2 + ret + +bcdbin4: + rcall bcdbin2 + push temp + mov temp,temp2 + rcall bcdbin2 + ldi temp2,100 + mul temp,temp2 + pop temp + mov temp2,_tmp1 + add temp,_tmp0 + adc temp2,_0 ret + +#if I2C + +; ---------------------------------------------- +; Set software clock from hardware clock + +rtc_get: + push _0 ;Placeholder for month/weekday + push _0 ;day/year + push _0 ;hours + push _0 ;minutes + ldi temp,0x10 ;register address + push temp ;save reg adr/placeholder for sec + in zh,sph + in zl,spl + ldi temp,0xA0 ;PCF8583 slave address + push temp + + ldi temp2,2 + rcall i2c_write + ldi temp2,3 + rcall i2c_read ;get year (stored in RTC-RAM addr. 10h) + tst temp + breq rtc_get_e + + ldd temp3,z+1 ;save year + ldd temp4,z+2 + + ldi temp2,2 ;register pointer. 2 = secs + std z+1,temp2 + rcall i2c_write + ldi temp2,6 + rcall i2c_read + tst temp + breq rtc_get_e + + ldd temp,z+4 ;get year + rol temp + rol temp + rol temp + eor temp,temp3 + andi temp,0x03 + breq rtc_get_1 + inc temp3 + adc temp4,_0 +rtc_get_1: + ldiw x,clock + cli + + ldd temp,z+1 ;get seconds + rcall bcdbin2 + st x+,temp + ldd temp,z+2 ;get minutes + rcall bcdbin2 + st x+,temp + ldd temp,z+3 ;get hours + rcall bcdbin2 + st x+,temp + ldd temp,z+4 ;get day + andi temp,0x3f + rcall bcdbin2 + st x+,temp + ldd temp,z+5 ;get months + andi temp,0x1f + rcall bcdbin2 + st x+,temp ;store month + st x+,temp3 ;store year + st x+,temp4 ;store year century + sei + +rtc_get_e: + pop temp + pop temp + pop temp + pop temp + pop temp + pop temp + ret + +;---------------------------------------------- +; Set hardware clock from software clock +; +; Register: temp2: s +; temp3: m +; temp4: h +; xl: D +; temp: M +; yl: Yl +; yh: Yh + +rtc_set: + ldiw z,clock + cli + ldd temp2,z+0 ;sec + ldd temp3,z+1 ;min + ldd temp4,z+2 ;hours + ldd xl,z+3 ;day + ldd temp,z+4 ;month + ldd yl,z+5 ;yearl + ldd yh,z+6 ;yearh + sei + rcall binbcd2 + push temp ;-1 save month + mov temp,xl + rcall binbcd2 + mov xl,yl ; least significant 2 bits of year + swap xl + lsl xl + lsl xl + andi xl,0xc0 + or temp,xl ; combine with day + push temp ;-2 save year/day + mov temp,temp4 + rcall binbcd2 + push temp ;-3 save hours + mov temp,temp3 + rcall binbcd2 + push temp ;-4 save min + mov temp,temp2 + rcall binbcd2 + push temp ;-5 save sec + + push _0 ;-6 1/10s, 1/100s + ldi temp,0x84 ; stop count, alarm enable + push temp ;-7 + push _0 ;-8 register address + in zh,sph + in zl,spl + ldi temp,0xA0 ; PCF8583 slave address + push temp ;(-9) + + ldi temp2,9 + rcall i2c_write + ldi temp,0x04 ;enable counting + std z+2,temp + ldi temp2,3 + rcall i2c_write + std z+3,yh ;store year in RTC RAM + std z+2,yl + ldi temp,0x10 + std z+1,temp + ldi temp2,4 + rcall i2c_write + + addiw z,8 ;remove buffer from stack + cli + out spl,zl + sei + out sph,zh + + ret +#endif + ; ---------------------------------------------- ;