;====================================================
;   WiperSW消し忘れ警報のリスト  12F629 ver1.02
;====================================================
;
;	入出力ピン設定
;	Data Format
;	    +---------------+
;	GPIO|7|6|5|4|3|2|1|0|
;	    +---------------+
;	    | | |I|I|X|O|O|X| I:Input   O:Output
;	    +---------------+
;	※
;       Input Data
;		GP4 => ACC	ACC電源
;		GP5 => WiperSW	ワイパーレバーがINTポジションでGNDに落ちる
;
;	Output Data
;		GP1 => WiperSW <-> GP5　を接続するリレーをON
;		GP2 => Buzzer	ブザー出力（リレーをON）
;
;       Flow Chart
;           (START):
;		初期化処理	内部クロック校正値設定、I/O設定など
;		GP0,1,2=0	全ての出力用ポートのレベルをLowに
;		Go to SLEEP
;           (SLEEP):
;		If GP4=0	ACCがONならばジャンプしない
;			go to ACC_OFF
;		EndIf
;		GP0,1,2=0
;		Sleep z.z.z....
;		Go to START
;           (ACC_OFF):
;		GP1をONにしリレーを動作（GP5を使用可に）
;		If GP5=0	WiperSWがINTポジションならば
;			Go to alm_on
;		EndIf
;		Go to SLEEP
;           (alm_on):
;		GP2=1		ブザー信号
;		ループ（ピン監視）
;			If GP5=1	WiperSWがOFFポジションになったらループ終了
;		Go to SLEEP
;
;
	list    p=12F629
	#include <p12f629.inc>
;
	errorlevel  -302              ; suppress message 302 from list file

	__CONFIG   _CP_OFF & _CPD_OFF & _BODEN_OFF & _MCLRE_OFF & _WDT_OFF & _PWRTE_ON & _INTRC_OSC_NOCLKOUT  
;	Configuration
;		MCLR is OFF
;		Code Protection(CP) is OFF
;		Watch Dog Timer(WDT) is OFF
;		Clock is Internal RC Oscillator

	cblock  0x20    	;ユーザエリアは20hから
		wcnt1		;Wait Counter1
		wcnt2		;Wait Counter2
		chkcnt		;Chechk Counter
	endc

	org 0x00		;Start of Code Space

;=========================================
;  Start Program (& Wake up from Sleep)
;=========================================
START
	call	0x3FF		;OSCCAL Valueの読み込み
	bsf	STATUS,RP0	;bank1に切り替えて次の設定を行う
	movwf	OSCCAL		;読み込んだ校正値をOSCCALレジスタにセット
	bcf	STATUS,RP0	;bank0に切り替え

	bsf	STATUS,RP0	;bank1に切り替えて次の設定を行う
	movlw	b'00110000'	;GP2,1,0:Output  GP5,4:Input
	movwf	TRISIO		;Set GPIO Input/Output
	movlw   b'10000000'	;
	movwf	OPTION_REG	;Pull-up Disable（内部プルアップ使用しない）
	bcf	STATUS,RP0	;bank0に切り替え
	movlw	b'00000111'	;GP0,GP1,GP2をデジタルI/Oに設定
	movwf	CMCON		;
	movlw	b'00000000'	;Port Clear
	movwf	GPIO

MAIN
	btfss	GPIO,4		;If GP4=1(ACCがOnだったら)Skip
	goto	port_check	;(ACCがOFFだったら)ポート確認チェックへジャンプ
SLP
	movlw	b'00000000'	;Port Clear　全ポートの出力をLowに
	movwf	GPIO
	bsf	STATUS,RP0	;bank1
	movlw   b'10001000'	;ポート変化による割込み許可
	movwf	INTCON		;Port Change Interrupt Enable
	movlw   b'00010000'	;許可するポート指定 GP4
	movwf	IOC		;Interrupt-On-Change GPIO
	bcf	STATUS,RP0	;bank0

	sleep			;Go to Sleep Mode
	goto	START

port_check
	movlw	d'50'
	movwf	chkcnt
lp_50ms
	call	wait1ms		;1msのウェイト処理を50回ループ
	btfsc	GPIO,4		;If GP4=0(ACCがOff)ならSkip
	goto	MAIN		;ACCがOn -> MAINへ戻る
	decfsz	chkcnt,F	;カウンタ減算
	goto	lp_50ms
	goto	wiper_chk	;50ms経過後にWiperポジション確認へ

wiper_chk
	movlw	b'00000010'	;GP1をONにしリレーを動作
	movwf	GPIO
	call	wait10ms	;10msウェイト(リレー動作完了待ち)
	movlw	d'50'
	movwf	chkcnt
lp2_50ms
	call	wait1ms		;1msのウェイト処理を50回ループ
	btfsc	GPIO,5		;If GP5=0(Wiper=INT)ならSkip
	goto	SLP		;Wiper<>INT -> SLPへ（MAINへ戻ると無限ループする）
	decfsz	chkcnt,F	;カウンタ減算
	goto	lp2_50ms
	goto	alm_on		;50ms経過後に警報on


;===========================
;  警報出力
;===========================
alm_on
	movlw	b'00000110'	;GP2＆GP1
	movwf	GPIO
	movlw	d'100'
	movwf	chkcnt
lp_100ms
	call	wait1ms		;1msのウェイト処理を100回ループ
	decfsz	chkcnt,F	;カウンタ減算
	goto	lp_100ms
	goto	MAIN

;================================
;  Wait for 1ms
;================================
wait1ms
	movlw	d'250'
	movwf	wcnt1
waitlp1
	nop			;1
	decfsz	wcnt1,F		;+1 = 2
	goto	waitlp1		;+2 = 4
	return			;4*250=1000
;================================
;  Wait for 10ms
;================================
wait10ms
	movlw	d'10'
	movwf	wcnt2
waitlp10
	call	wait1ms
	decfsz	wcnt2,F
	goto	waitlp10
	return


	end
