]> cloudbase.mooo.com Git - avrcpm.git/blobdiff - avr/timer.asm
* I2C Support added
[avrcpm.git] / avr / timer.asm
index 80e9fca44fafaa6077b007cc9a4d91a1ed87f9d8..fa2b31f846ebe5cd85f13d7691ce7ebc7d146d21 100644 (file)
@@ -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
+
 ; ----------------------------------------------
 ;