;--------------------------------------------------------------------------------
;	デジタルアンプ・ミュート制御
;	オルタナティブスイッチ版
;	Since 2007/08/07 - 2007/08/10
;--------------------------------------------------------------------------------

	LIST		P=12F629
	INCLUDE		P12F629.INC
	ERRORLEVEL	-302

CB = _CPD_OFF
CB &= _CP_OFF
CB &= _BODEN_OFF
CB &= _MCLRE_OFF
CB &= _PWRTE_ON
CB &= _WDT_OFF
CB &= _EXTRC_OSC_CLKOUT

	__CONFIG	CB
	__IDLOCS	H'0100'

POWER_STATUS	EQU		0x20	; 電源状態管理変数
COUNTER			EQU		0x21	; ループ用カウンタ
FLAG			EQU		0x22	; 状態チェック用フラグ

;--------------------------------------------------------------------------------
;	プログラム先頭
;--------------------------------------------------------------------------------
	ORG	H'0'
	GOTO	INITIALIZE

;--------------------------------------------------------------------------------
;	割り込み処理（割り込み未使用）
;--------------------------------------------------------------------------------
	ORG		H'4'	;	念のため割り込み時の処理を記述
	RETFIE			;	何もしないで戻る

;--------------------------------------------------------------------------------
;	初期化
;--------------------------------------------------------------------------------

INITIALIZE:

	BANKSEL	GPIO
	MOVLW	B'00000000'		; ひとまず全入出力ポートを L レベルに
	MOVWF	GPIO

	BANKSEL	CMCON
	MOVLW	B'00001111'		; デジタル I/O モードに設定
	MOVWF	CMCON

	BANKSEL	TRISIO
	MOVLW	B'00001000'		; PORT 0,1,2 = OUT, PORT 3 = IN
	MOVWF	TRISIO

	BANKSEL	GPIO

	CLRF	POWER_STATUS	; Clear Power Status (POWER OFF)

;--------------------------------------------------------------------------------
;	メインルーチン（キーチェック）
;--------------------------------------------------------------------------------

MAIN_LOOP:

	BTFSC	GPIO,3		; ボタンが押されたか?
	GOTO	CLEAR_FLAG	; 条件 false, 押されていない

SET_FLAG:				; 条件 true, 押されている

	MOVLW	D'1'
	MOVWF	FLAG	; SET FLAG (POWER ON)		;	FLAG を 1 に
	GOTO	KEY_CHECK

CLEAR_FLAG:

	CLRF	FLAG	; CLEAR FLAG (POWER OFF)	;	FLAG を 0 に

KEY_CHECK:

	CALL	Wait_200ms	; 200ミリ秒待ってから

	BTFSC	GPIO,3		; 再度ボタンの状態を確認
	GOTO	CHECK_OFF	; 条件 false, 押されていなければ飛び先で OFF 継続中かチェック

CHECK_ON:				; 押されていれば ON 継続中かチェック

	DECFSZ	FLAG,W		;	押され続けていたのか ?
	GOTO	MAIN_LOOP	;	条件 false, 25ms 前は FLAG = 0 だった。今回とキーの状態が一致しないので戻る
	CALL	POWER_ON	;	条件 true,  キー状態が一致したので電源を ON 処理へ
	GOTO	WAIT_CHECK	;	少し間を空けてから戻る

CHECK_OFF:

	DECFSZ	FLAG,W		;	離され続けていたのか ?
	GOTO	CHECK_OFF2	;	条件 false, 25ms 前 FLAG=0 だった。今回とキー状態が一致するので OFF 処理へ
	GOTO	WAIT_CHECK	;	条件 true,  キー状態が一致しないので少し間を空けてから戻る

CHECK_OFF2:

	CALL	POWER_OFF	;	キー状態が一致したので電源を OFF 処理へ

WAIT_CHECK:

	CALL	Wait_200ms	;	一応少しだけ待って
	GOTO	MAIN_LOOP	;	メインに戻る

;--------------------------------------------------------------------------------
;	電源 ON 処理
;--------------------------------------------------------------------------------

POWER_ON:

	DECFSZ	POWER_STATUS,W	; 現在の電源状態をチェック
	GOTO	POWER_ON2		; 条件 false, OFF 状態なので ON 処理
	RETURN					; 条件 true, 既に POWER ON 状態なので何もしない

POWER_ON2:

	MOVLW	B'00000000'		; MUTE ON, AMP OFF, VR OFF
	MOVWF	GPIO
	CALL	Wait_1sec
	MOVLW	B'00000001'		; VR ON
	MOVWF	GPIO
	CALL	Wait_1sec
	MOVLW	B'00000011'		; AMP ON
	MOVWF	GPIO
	CALL	Wait_1sec
	MOVLW	B'00000111'		; MUTE OFF
	MOVWF	GPIO
	MOVLW	D'1'
	MOVWF	POWER_STATUS	; Set Power Status (POWER ON)
	RETURN

;--------------------------------------------------------------------------------
;	電源 OFF 処理
;--------------------------------------------------------------------------------

POWER_OFF:

	DECFSZ	POWER_STATUS,W	; 現在の電源状態をチェック
	RETURN					; 条件 false, 既に POWER OFF 状態なので何もしない
							; 条件 true, ON 状態なので OFF 処理
	MOVLW	B'00000011'		; MUTE ON
	MOVWF	GPIO
	CALL	Wait_1sec
	MOVLW	B'00000001'		; AMP OFF
	MOVWF	GPIO
	CALL	Wait_1sec
	MOVLW	B'00000000'		; VR OFF
	MOVWF	GPIO
	CLRF	POWER_STATUS	; Clear Power Status (POWER OFF)
	RETURN

;--------------------------------------------------------------------------------
;	クロック 1KHz 時 1 step = 1/250 Sec = 4ms
;--------------------------------------------------------------------------------

Wait_20ms:

    MOVLW	D'1'
    MOVWF	COUNTER
    GOTO	WAIT_LOOP

Wait_200ms:

    MOVLW	D'10'
    MOVWF	COUNTER
    GOTO	WAIT_LOOP

Wait_1sec:

    MOVLW	D'50'
    MOVWF	COUNTER
    GOTO	WAIT_LOOP

WAIT_LOOP:						;5 steps = 20 clocks = 20ms if 1KHz clock

	GOTO	$+1

	DECFSZ	COUNTER,F
	GOTO	WAIT_LOOP		; in case DECFSZ falase

	RETURN					; in case DECFSZ ture

;--------------------------------------------------------------------------------
;	プログラム終了
;--------------------------------------------------------------------------------
	END
