;====================================================
;   WiperSW消し忘れ警報のリスト  12F629 ver2.01
;====================================================
;
;	入出力ピン設定
;	Data Format
;	    +---------------+
;	GPIO|7|6|5|4|3|2|1|0|
;	    +---------------+
;	    | | |I|I|X|O|O|X| I:Input  O:Output  X:未使用
;	    +---------------+
;	※
;       Input Data
;		GP4 => ACC	ACC電源
;		GP5 => WiperSW	ワイパーレバーがINTポジションでGND
;
;	Output Data
;		GP1 => WiperSWの状態を出力（GP5の状態をコピーし天下雨滴側に出力）
;		GP2 => ChimeModule（鳴動時にTrをONにしChimeModuleの特定ラインをGNDに）
;
;	Flow Chart
;	(START):
;		初期化処理	内部クロック校正値設定、I/O設定など
;		GP0,1,2=0	全ての出力用ポートのレベルをLowに
;	(MAIN):
;		If GP4=1	ACCがONならば
;			go to Wp_chk_acc_on	レバーポジションチェック１
;		EndIf
;		If GP4=0	ACCがOFFならば
;			go to Wp_chk_acc_off	レバーポジションチェック２
;		EndIf
;	(SLEEP):
;		GP0,1,2=0
;		Sleep z.z.z....
;		Go to START
;	(Wp_chk_acc_on):
;		If GP5=0	WiperSWがINTポジションならば
;			Go to Wiper_INT
;		EndIf
;		Go to MAIN
;	(Wp_chk_acc_off):
;		If GP5=0	WiperSWがINTポジションならば
;			Go to alm_on
;		EndIf
;		Go to SLEEP
;	(Wiper_INT):
;		GP1=1		GP1をHiに（Trを動作＝天下雨滴の信号線をGNDに）
;		Go to MAIN
;	(alm_on):
;		GP2=1		GP2をHiに（Trを動作＝ChimeModuleの特定ラインをGNDに）
;		Go to MAIN
;
;
	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
	goto	START
	org 0x04
	goto	MAIN

START
	call	0x3FF		;OSCCAL Valueの読み込み
	bsf	STATUS,RP0	;bank1に切り替えて次の設定を行う
	movwf	OSCCAL		;読み込んだ校正値をOSCCALレジスタにセット
;	bcf	STATUS,RP0	;bank0に切り替え
;	bsf	STATUS,RP0	;bank1に切り替えて次の設定を行う
	movlw	b'00111000'	;GP2,1,0:Output  GP5,4,3:Input
	movwf	TRISIO		;Set GPIO Input/Output
	movlw   b'00000000'	;
	movwf	OPTION_REG	;Pull-up Enable（内部プルアップ使用する）
	movlw   b'00100000'	;
	movwf	WPU		;GP5 Pull-up Enable
	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	Wp_chk_acc_off	;(ACCがOFFだったら)
	goto	Wp_chk_acc_on	;(ACCがOnだったら)
SLP
	movlw	b'00000000'	;Port Clear　全ポートの出力をLowに
	movwf	GPIO
	bsf	STATUS,RP0	;bank1
	movlw   b'10001000'	;ポート変化による割込み許可
	movwf	INTCON		;Port Change Interrupt Enable
	movlw   b'00110000'	;許可するポート指定 GP4,GP5
	movwf	IOC		;Interrupt-On-Change GPIO
	bcf	STATUS,RP0	;bank0

	sleep			;Go to Sleep Mode
	goto	MAIN

;===========================
;  ACCがONの場合
;===========================
Wp_chk_acc_on
	movlw	d'20'
	movwf	chkcnt
lp11_20ms
	call	wait1ms		;1msのウェイト処理を20回ループ
	btfss	GPIO,4		;If GP4=1(ACCがOn)ならSkip
	goto	MAIN		;ACCがOff -> MAINへ戻る
	decfsz	chkcnt,F	;カウンタ減算
	goto	lp11_20ms
	goto	wiper_chk	;20ms経過後にWiperポジション確認へ
wiper_chk
	bcf	GPIO,2		;警報中にACC ONとなった場合の対処
	movlw	d'20'
	movwf	chkcnt
lp12_20ms
	call	wait1ms		;1msのウェイト処理を20回ループ
	btfsc	GPIO,5		;If GP5=0(Wiper=INT)ならSkip
	goto	wiper_chk_ex	;INT以外なら確認へ
	decfsz	chkcnt,F	;カウンタ減算
	goto	lp12_20ms
	goto	Wiper_INT	;ACC=ON and Wiper=INT なら情報出力
wiper_chk_ex
	movlw	d'20'
	movwf	chkcnt
lp13_20ms
	call	wait1ms		;1msのウェイト処理を20回ループ
	btfss	GPIO,5		;If GP5=0(INT以外)ならSkip
	goto	wiper_chk	;INTならINT確認処理へ戻る
	decfsz	chkcnt,F	;カウンタ減算
	goto	lp13_20ms
	goto	SLP		;ACC=ON and Wiper<>INT ならSLEEPへ
;===========================
;  レバーポジション情報出力
;===========================
Wiper_INT
	bsf	GPIO,1		;GP1をHiに（Trを動作＝天下雨滴の信号線をGNDに）
	nop
	goto	MAIN

;===========================
;  ACCがOFFの場合
;===========================
Wp_chk_acc_off
	movlw	d'20'
	movwf	chkcnt
lp21_20ms
	call	wait1ms		;1msのウェイト処理を20回ループ
	btfsc	GPIO,4		;If GP4=0(ACCがOFF)ならSkip
	goto	MAIN		;ACCがON -> MAINへ戻る
	decfsz	chkcnt,F	;カウンタ減算
	goto	lp21_20ms
	goto	wiper_chk2	;20ms経過後にWiperポジション確認２へ
wiper_chk2
	movlw	d'20'
	movwf	chkcnt
lp22_20ms
	call	wait1ms		;1msのウェイト処理を20回ループ
	btfsc	GPIO,5		;If GP5=0(Wiper=INT)ならSkip
	goto	wiper_chk2_ex	;INT以外なら確認処理へ
	decfsz	chkcnt,F	;カウンタ減算
	goto	lp22_20ms
	goto	alm_on		;ACC=OFF and Wiper=INT なら警報
wiper_chk2_ex
	movlw	d'20'
	movwf	chkcnt
lp23_20ms
	call	wait1ms		;1msのウェイト処理を20回ループ
	btfss	GPIO,5		;If GP5=1(INT以外)ならSkip
	goto	wiper_chk2	;INTならINT確認処理へ戻る
	decfsz	chkcnt,F	;カウンタ減算
	goto	lp23_20ms
	goto	SLP		;ACC=OFF and Wiper<>INT ならSLEEPへ

;===========================
;  警報出力
;===========================
alm_on				;
	bsf	GPIO,2		;GP2 Hi
	nop
	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

	end
