;
; PIC12C509
; One-Touch Open/Close Window Rev. 0.1
; Programmed by DD
; Greatly Supported by S.IWANO
;
;
; Data Format
; +---------------+
; | | |O|O|X|X|I|I| GPIO I:Input O:Output X:Don't Use
; +---------------+ 
; Input Data
; GPO => Open Switch 
; GP1 => Close Switch
;
; Output Data
; GP4 => Open Signal
; GP5 => Close Signal
;
; Function
; (1)Press open button and release it within 0.1-0.4 sec
;    to open passenger's window automatically.
; (2)Press close button and release it within 0.1-0.4 sec
;    to close passenger's window automatically.
; (3)Press open button again when automatically opening the window
;    to stop opening it.
; (4)Press close button again when automatically closing the window
;    to stop closing it.


list p=pic12C509A
include "p12c509a.inc"
;
__FUSES _MCLRE_OFF & _CP_OFF & _WDT_OFF & _IntRC_OSC
; Configuration Code = 0xFFEA
; When burning PIC, the following configuration is necessary
; MCLR is OFF
; Code Protection(CP) is OFF
; Watch Dog Timer(WDT) is OFF
; Clock is Internal RC Oscillator

cblock 0x08 ;Store variables above control registers
        timecnt ;Time Counter
        wcnt1 ;Wait Counter1 (For 25ms Wait)
        wcnt2 ;Wait Counter2 (For 25ms Wait)
endc


org 0x00 ;Start of Code Space
;=========================================
; Start Program (& Wake up from Sleep)
;=========================================
START   movlw b'00001011'    ;GP5,4,2:Output GP3,1,0:Input
        tris 6               ;Set GPIO Input/Output
        movlw b'11000000'    ;Wakeup Disable
        option
        movlw b'00000000'    ;GP5,4=0
        movwf GPIO

;===========================
; State 1
;===========================
State1  btfss GPIO,0         ;If GP0=0 (Press Open Button),
        goto State2          ; go to State2
        btfss GPIO,1         ;If GP1=0 (Press Close Button),
        goto State5          ; go to State5
        goto State1

;===========================
; State 2
;===========================
State2  clrf timecnt         ;Set timecnt=0
St2lp   call wait25ms        ;Wait 25ms
        incf timecnt,1       ;Increment timecnt
        btfsc GPIO,0         ;if GP0=1 (Release Open Button),
        goto St2TimeCheck    ; go to St2TimeCheck
        goto St2lp           ;go to St2lp
St2TimeCheck
        movlw d'4'           ;W=4
        subwf timecnt,0      ;timecnt-4 => W
        btfss STATUS,C       ;if timecnt<4,
        goto State1          ; go to State1
        movlw d'15'          ;W=15
        subwf timecnt,0      ;timecnt-15 => W
        btfsc STATUS,C       ;if timecnt>=15,
        goto State1          ; go to State1

;===========================
; State 3
;===========================
State3  bsf GPIO,4           ;Set GP4=1 (Turn on Open Signal)
        movlw d'240'
        movwf timecnt        ;timecnt=240 (6sec)
St3lp   btfss GPIO,0         ;If GP0=0 (Press Open Button),
        goto St3St4          ; go to St3St4
        btfss GPIO,1         ;If GP1=0 (Press Close Button),
        goto St3St5          ; go to St3St5
        call wait25ms        ;Wait 25ms
        decfsz timecnt,F     ;Decrement timecnt
        goto St3lp           ;if less than 5sec, continue
        bcf GPIO,4           ;Set GP4=0 (Turn off Open Signal)
        goto State1          ;Go to State1
St3St4  bcf GPIO,4           ;Set GP4=0 (Turn off Open Signal)
        goto State4          ;Go to State4
St3St5  bcf GPIO,4           ;Set GP4=0 (Turn off Open Signal)
        goto State5          ;Go to State5

;===========================
; State 4
;===========================
State4  btfsc GPIO,0         ;If GP0=1 (Release Open Button),
        goto State1          ; go to State1
        goto State4          ;Continue

;===========================
; State 5
;===========================
State5  clrf timecnt         ;Set timecnt=0
St5lp   call wait25ms        ;Wait 25ms
        incf timecnt,1       ;Increment timecnt
        btfsc GPIO,1         ;if GP1=1 (Release Close Button),
        goto St5TimeCheck    ; go to St5TimeCheck
        goto St5lp           ;go to St5lp
St5TimeCheck
        movlw d'4'           ;W=4
        subwf timecnt,0      ;timecnt-4 => W
        btfss STATUS,C       ;if timecnt<4,
        goto State1          ; go to State1
        movlw d'15'          ;W=9
        subwf timecnt,0      ;timecnt-15 => W
        btfsc STATUS,C       ;if timecnt>=15,
        goto State1          ; go to State1

;===========================
; State 6
;===========================
State6  bsf GPIO,5           ;Set GP5=1 (Turn on Close Signal)
        movlw d'240'
        movwf timecnt        ;timecnt=240 (6sec)
St6lp   btfss GPIO,1         ;If GP1=0 (Press Close Button),
        goto St6St7          ; go to St6St7
        btfss GPIO,0         ;If GP0=0 (Press Open Button),
        goto St6St2          ; go to St2St2
        call wait25ms        ;Wait 25ms
        decfsz timecnt,F     ;Decrement timecnt
        goto St6lp           ;if less than 5sec, continue
        bcf GPIO,5           ;Set GP5=0 (Turn off Close Signal)
        goto State1          ;Go to State1
St6St7  bcf GPIO,5           ;Set GP5=0 (Turn off Close Signal)
        goto State7          ;Go to State4
St6St2  bcf GPIO,5           ;Set GP5=0 (Turn off Close Signal)
        goto State2          ;Go to State2

;===========================
; State 7
;===========================
State7  btfsc GPIO,1         ;If GP1=1 (Release Close Button),
        goto State1          ; go to State1
        goto State7          ;Continue


;Subroutine

;================================
; Wait for 25ms
;================================
wait25ms
        movlw d'32'          ;*32
        movwf wcnt2
waitlp2 clrf wcnt1
waitlp1 decfsz wcnt1,F
        goto waitlp1
        decfsz wcnt2,F
        goto waitlp2
        retlw 0

end