; Alarme à perte de signal

; ==================================================
	list p=16f84a
	include <p16f84a.inc>

	__CONFIG _WDT_OFF & _PWRTE_ON & _XT_OSC & _CP_ON
; ==================================================

	cblock	0x0C
		nbto
		nbal
		nbpal
		etat
		w_temp
		status_temp
		PDel0
		read
		r_lsb
		r_msb
	endc

msb	equ	B'00101101'	; (envoyé : 00101101)
lsb	equ	B'11100101'	; (envoyé : 11100101)

#DEFINE	buzzer	etat,0	; à 1 si le buzzer est en route
#DEFINE	ledtem	etat,1	; à 1 si la led doit etre allumée
#DEFINE	bip	PORTB,4
#DEFINE	led	PORTB,3
#DEFINE	relais	PORTB,2
#DEFINE	rcpt	PORTB,1

; ==================================================
; Start
; =====
	org	0x00		; Reset Vector
	goto	start

; Interruption
; =============

	org	0x04		; Interrupt Vector
	movwf	w_temp		; sauvegarde des registres courants
	movf	STATUS,w
	movwf	status_temp
	btfsc	INTCON,T0IF
	goto	timer		; timer interrupt
bpint	bcf	INTCON,INTF		; RB0 interrupt
	call	rstvar
	bcf	relais		; on eteint relais et buzzer
	bcf	buzzer
	bsf	led		; on allume la LED
	bsf	ledtem
	goto	loadreg
timer	bcf	INTCON,T0IF		; timer interrupt
	decfsz	nbto,f		; 4 sec ecoulées ?
	goto	loadreg		; non
	movlw	D'61'
	movwf	nbto
	decfsz	nbal,f		; alarme atteinte ?
	goto	testp		; non
	bsf	relais
	bcf	buzzer
testp	decfsz	nbpal,f		; pre-alarme (buzzer) atteinte ?
	goto	testl		; non
	bsf	buzzer
testl	btfss	ledtem		; la LED doit elle etre eteinte ?
	bcf	led		; si ledtem à 0 : la led doit etre eteinte
	bcf	ledtem		; si ledtem à 1 : la led sera eteinte 4s plus tard
loadreg	movf	status_temp,w	; restauration des registres courants
	movwf	STATUS
	movf	w_temp,w
	retfie

; Branchement depart
; ==================

start	bsf	STATUS,RP0
	movlw	B'00000011'
	movwf	TRISB
	movlw	B'10000111'	; falling edge, internal osc timer with prescaler 1:256
	movwf	OPTION_REG
	bcf	STATUS,RP0
	clrf	etat
	clrf	PORTB
	call	rstvar
	bsf	led
	bcf	ledtem	; la led reste allumée pendant quelques secondes (<4s)
	movlw	B'10110000'
	movwf	INTCON
test	btfsc	rcpt
	goto	trame
	btfss	buzzer
	goto	test
	goto	bipbip

; Routine de reception et verification de trame série
; ===================================================

trame	bcf	INTCON,GIE	; interdit toute interruption
	bsf	led
wait	btfsc	rcpt		; attente du bit de start (falling edge)
	goto	wait
	movlw	D'118'
	call	tempo		; on attends 0.5T
	call	read1		; on attends en tout 1.5T : on tombe au milieu de D15, lu
	rlf	r_msb,f
	call	read1		; lecture D14
	rlf	r_msb,f
	call	read1
	rlf	r_msb,f
	call	read1
	rlf	r_msb,f
	call	read1
	rlf	r_msb,f
	call	read1
	rlf	r_msb,f
	call	read1
	rlf	r_msb,f
	call	read1		; lecture D8
	call	read2		; lecture D7
	rlf	r_lsb,f
	call	read2		; lecture D6
	rlf	r_lsb,f
	call	read2
	rlf	r_lsb,f
	call	read2
	rlf	r_lsb,f
	call	read2
	rlf	r_lsb,f
	call	read2
	rlf	r_lsb,f
	call	read2
	rlf	r_lsb,f
	call	read2		; lecture D0
	movlw	D'250'
	call	tempo		; on attend encore la fin de la trame
	bcf	INTCON,T0IF
	bcf	INTCON,INTF
	bsf	INTCON,GIE	; autorisation des interruptions
	bcf	led
	movf	r_msb,w
	sublw	msb		
	btfss	STATUS,Z	; verification MSb memoire = MSb reçu
	goto	test		; zero=0 => octets differents
	movf	r_lsb,w
	sublw	lsb
	btfss	STATUS,Z	; verification LSb memoire = LSb reçu
	goto	test
	call	rstvar
	bsf	led
	bsf	ledtem
	bcf	buzzer
	bcf	relais
	goto	test

read1	movlw	D'242'
	call	tempo
	movf	PORTB,w		; durée 10 cycles = 10µs
	movwf	read
	rrf	read,w
	andlw	B'00000001'	; on ne garde que le premier bit
	addwf	r_msb,f
	return

read2	movlw	D'242'
	call	tempo
	movf	PORTB,w		; durée 10 cycles = 10µs + tempo
	movwf	read
	rrf	read,w
	andlw	B'00000001'	; on ne garde que le premier bit
	addwf	r_lsb,f
	return

; Routine générant un signal carré à 5.5kHz (T=180µs env.) pour le buzzer
; =======================================================================

bipbip	btfss	buzzer		; buzzer tjrs activé (à voir selon interruption)
	goto	test
	btfsc	rcpt		; trame à recevoir ?
	goto	trame
	bsf	bip
	movlw	D'43'
	call	tempo
	bcf	bip
	movlw	D'42'
	call	tempo
	goto	bipbip

; Routine de delai
; ================

tempo	movwf	PDel0	; w=242=>t=Tbo....w=118=>t=Tbo/2....w=43=>t=180µs (buzzer)
PLoop0	clrwdt	
	decfsz	PDel0,f
	goto	PLoop0
PDelL1	goto	PDelL2
PDelL2	clrwdt
        return

; Routine d'initialisation des variables de comptage
; ==================================================

rstvar	movlw	D'47'	; pour 3mn et 8sec
	movwf	nbal
	movlw	D'42'	; pour 2mn et 48sec
	movwf	nbpal
	movlw	D'61'	; pour 4sec (1µs x 256 x 256 x 61 = 4sec)
	movwf	nbto
	clrf	r_msb
	clrf	r_lsb
	return

	END
