; Double timer
; Quartz de 3.6864 MHz, PIC 16F84
; Interruption timer toutes les 50ms avec prescaler 1:256
; -------------------------------------------------------

; Programmation des temps par touches OK, +, -
; Temps minimum : 1mn
; Programmation par pas de 12sec
; Affichage par codage binaire sortie sur 5 LED (PORTA)



	list p=16f84a
	include <p16f84a.inc>


	__CONFIG _WDT_OFF & _PWRTE_ON & _XT_OSC & _CP_ON


	cblock	0x0C
		etat_t , etat_s
		w_temp , status_temp
		PDel0 , PDel1
		var_t1 , var_t2 , usedvar1 , usedvar2
		varson
		var12t1 , var12t2
		minvar1 , minvar2		
	endc


#DEFINE	bpt1	PORTB,0
#DEFINE	bpt2	PORTB,1
#DEFINE	bpok	PORTB,3
#DEFINE	bpplus	PORTB,2
#DEFINE	bpmoins	PORTB,4
#DEFINE	bpson	PORTB,5
#DEFINE	out1	PORTB,6
#DEFINE	out2	PORTB,7

#DEFINE	led1	PORTA,0
#DEFINE	led2	PORTA,4

#DEFINE	t_ok	etat_t,0
#DEFINE	t1_ok	etat_t,1
#DEFINE	t2_ok	etat_t,2

#DEFINE	son1	etat_s,0
#DEFINE	son2	etat_s,1
#DEFINE	son1_1	etat_s,2
#DEFINE	son2_1	etat_s,3
#DEFINE	son1_p	etat_s,4
#DEFINE	son2_p	etat_s,5
#DEFINE	son1_2	etat_s,6
#DEFINE	son2_2	etat_s,7


; Reset Vector
; ============

	org	0x00
	goto	start

; Interrupt Vector
; ================
	
	org	0x04
	movwf	w_temp
	movf	STATUS,w
	movwf	status_temp
	bcf	INTCON,T0IF
	btfss	t_ok
	goto	test_son
	btfss	t1_ok
	goto	test_t2
	decfsz	var12t1,f
	goto	test_t2
	movlw	D'169'
	movwf	var12t1
	movf	minvar1,f
	btfsc	STATUS,Z
	goto	$+3
	decfsz	minvar1,f
	goto	test_t2
	movf	usedvar1,f
	btfsc	STATUS,Z
	goto	$+3
	decf	usedvar1,f
	goto	test_t2
	bsf	led1
	bsf	son1
	movlw	D'5'
	movwf	minvar1
	movf	var_t1,w
	movwf	usedvar1
	bcf	t1_ok
	btfss	t2_ok
	bcf	t_ok	; remise à zero de t_ok si t2 non utilisé
	bsf	son1_1	
test_t2	btfss	t2_ok
	goto	test_son
	decfsz	var12t2,f
	goto	test_son
	movlw	D'169'
	movwf	var12t2
	movf	minvar2,f
	btfsc	STATUS,Z
	goto	$+3
	decfsz	minvar2,f
	goto	test_son
	movf	usedvar2,f
	btfsc	STATUS,Z
	goto	$+3
	decf	usedvar2,f
	goto	test_son
	bcf	t2_ok
	bsf	son2
	bsf	led2
	movlw	D'5'
	movwf	minvar2
	movf	var_t2,w
	movwf	usedvar2
	btfss	t1_ok
	bcf	t_ok
	bsf	son2_1
test_son	btfss	son1
	goto	test_son2
	btfss	son1_1
	goto	test_s1p
	bcf	out1
	decfsz	varson,f
	goto	restore		; ne pas mélanger son1 et son2
	bsf	out1
	bcf	son1_1
	bsf	son1_p
	movlw	D'3'
	movwf	varson
	goto	restore	
test_s1p	btfss	son1_p
	goto	test_s12
	decfsz	varson,f
	goto	restore
	bcf	out1
	bcf	son1_p
	bsf	son1_2
	movlw	D'3'
	movwf	varson
	goto	restore
test_s12	decfsz	varson,f
	goto	restore
	bsf	out1
	bcf	son1_2
	bcf	son1
	bsf	led1
	movlw	d'3'
	movwf	varson
	goto	restore
test_son2	btfss	son2
	goto	restore
	btfss	son2_1
	goto	test_s2p
	bcf	out2
	decfsz	varson,f
	goto	restore
	bsf	out2
	bcf	son2_1
	bsf	son2_p
	movlw	D'3'
	movwf	varson
	goto	restore	
test_s2p	btfss	son2_p
	goto	test_s22
	decfsz	varson,f
	goto	restore
	bcf	out2
	bcf	son2_p
	bsf	son2_2
	movlw	D'3'
	movwf	varson
	goto	restore
test_s22	decfsz	varson,f
	goto	restore
	bsf	out2
	bcf	son2
	bcf	son2_2
	bsf	led2
	movlw	D'3'
	movwf	varson
restore	movf	status_temp,w
	movwf	STATUS
	movf	w_temp,w
	retfie

; Routine de démarrage
; ====================

start	bsf	STATUS,RP0		; init registres & variables
	clrf	TRISA
	movlw	B'00111111'
	movwf	TRISB
	movlw	B'00000111'
	movwf	OPTION_REG
	bcf	STATUS,RP0
	clrf	PORTA
	bsf	out1
	bsf	out2
	movlw	D'169'
	movwf	var12t1
	movwf	var12t2
	movlw	D'5'
	movwf	minvar1
	movwf	minvar2
	movlw	D'3'
	movwf	varson
	clrf	etat_t
	clrf	etat_s
	clrf	EEADR		; chargement des données temps EEPROM
	bsf	STATUS,RP0
	bsf	EECON1,RD
	bcf	STATUS,RP0
	btfss	EEDATA,0		; data 0x00 à 0 => pas de données valides
	goto	init
	incf	EEADR,f
	bsf	STATUS,RP0
	bsf	EECON1,RD
	bcf	STATUS,RP0
	movf	EEDATA,w
	movwf	var_t1
	movwf	usedvar1
	incf	EEADR,f
	bsf	STATUS,RP0
	bsf	EECON1,RD
	bcf	STATUS,RP0
	movf	EEDATA,w
	movwf	var_t2
	movwf	usedvar2
	movlw	H'FF'
	movwf	PORTA
	goto	wait
init	movlw	B'00001111'
	movwf	var_t1
	movwf	var_t2
	call	save_var
	movlw	H'FF'
	movwf	PORTA
	goto	wait


; Boucle d'attente
; ================

wait	btfsc	t_ok		; test des poussoirs OK et SON
	goto	test_bp1
	btfsc	son1
	goto	test_bp1
	btfsc	son2
	goto	test_bp1
	bcf	INTCON,T0IE
	btfss	bpok
	goto	appui_ok
	btfss	bpson
	call	appui_son
test_bp1	btfsc	t1_ok		; test du poussoir 1
	goto	test_bp2	
	btfsc	bpt1
	goto	test_bp2
	bsf	t1_ok
	bsf	t_ok
	bcf	led1
	movlw	B'10100000'
	movwf	INTCON	
test_bp2	btfsc	t2_ok		; test du poussoir 2
	goto	wait	
	btfsc	bpt2
	goto	wait
	bsf	t2_ok
	bsf	t_ok
	bcf	led2
	movlw	B'10100000'
	movwf	INTCON
	goto	wait	

; Routine de modification des tempos
; ==================================

appui_ok	call	delai
	bcf	led1
	call	delai
	call	delai
	call	delai
	call	delai
	call	delai
	bsf	led1
	call	delai
	call	delai
	call	delai
	call	delai
	call	delai
	comf	var_t1,w
	movwf	PORTA
test11_bp	btfsc	bpplus		; pour t1
	goto	test12_bp
	incf	var_t1,f
	comf	var_t1,w
	movwf	PORTA
	call	delai
	call	delai
test12_bp	btfsc	bpmoins
	goto	test13_bp
	decf	var_t1,f
	comf	var_t1,w
	movwf	PORTA
	call	delai
	call	delai
test13_bp	btfsc	bpok
	goto	test11_bp
	movlw	H'FF'
	movwf	PORTA
	call	delai
	call	delai
	call	delai
	call	delai
	bcf	led2
	call	delai
	call	delai
	call	delai
	call	delai
	call	delai
	bsf	led2
	call	delai
	call	delai
	call	delai
	call	delai
	call	delai
	comf	var_t2,w
	movwf	PORTA
test21_bp	btfsc	bpplus		; cela concerne t2 maintenant
	goto	test22_bp
	movf	var_t2,w
	sublw	B'00011111'
	btfsc	STATUS,Z
	goto	test22_bp
	incf	var_t2,f
	comf	var_t2,w
	movwf	PORTA
	call	delai
	call	delai
test22_bp	btfsc	bpmoins
	goto	test23_bp
	decf	var_t2,f
	comf	var_t2,w
	movwf	PORTA
	call	delai
	call	delai
test23_bp	btfsc	bpok
	goto	test21_bp
	movlw	H'FF'
	movwf	PORTA
	call	delai
	call	delai
	call	save_var		; sauvegarde des nouvelles données
	clrf	PORTA
	call	delai
	call	delai
	call	delai
	call	delai
	call	delai
	movlw	H'FF'
	movwf	PORTA
	goto	wait

; Routine de test du son
; ======================

appui_son	bcf	out1
	bsf	out2
	call	delai
	call	delai
	call	delai
	bsf	out1
	call	delai
	call	delai
	call	delai
	bcf	out2
	call	delai
	call	delai
	call	delai
	bsf	out2
	return

; Routine de delai 100ms (debouncing principalement)
; =================================================

delai	movlw     	D'95'
	movwf     	PDel0
PLoop1	movlw     	D'161'
 	movwf     	PDel1
PLoop2 	clrwdt
PDelL1 	goto 	PDelL2
PDelL2    	decfsz    	PDel1,f
        	goto      	PLoop2
     	decfsz    	PDel0,f
  	goto      	PLoop1 
PDelL3	goto 	PDelL4 
PDelL4	goto 	PDelL5 
PDelL5	clrwdt 
        	return 	

; Routine de sauvegarde des variables de tempos dans l'EEPROM
; ===========================================================

save_var	movf	var_t1,w
	movwf	usedvar1
	movwf	EEDATA
	clrf	EEADR
	incf	EEADR,f
	bsf	STATUS,RP0
	bsf	EECON1,WREN
	movlw	H'55'
	movwf	EECON2
	movlw	H'AA'
	movwf	EECON2
	bsf	EECON1,WR
	btfss	EECON1,EEIF
	goto	$-1
	bcf	EECON1,WREN
	bcf	STATUS,RP0
	movf	var_t2,w
	movwf	usedvar2
	movwf	EEDATA
	incf	EEADR,f
	bsf	STATUS,RP0
	bsf	EECON1,WREN
	movlw	H'55'
	movwf	EECON2
	movlw	H'AA'
	movwf	EECON2
	bsf	EECON1,WR
	btfss	EECON1,EEIF
	goto	$-1
	bcf	EECON1,WREN
	bcf	STATUS,RP0
	movlw	H'FF'
	movwf	EEDATA
	clrf	EEADR
	bsf	STATUS,RP0
	bsf	EECON1,WREN
	movlw	H'55'
	movwf	EECON2
	movlw	H'AA'
	movwf	EECON2
	bsf	EECON1,WR
	btfss	EECON1,EEIF
	goto	$-1
	bcf	EECON1,WREN
	bcf	STATUS,RP0
	return

	END
