; Program: carteGSM.asm revision 1.0 Board 1.0
; date: 21/3/2004

	device pic16c84,xt_osc,wdt_on,pwrt_on,protect_off

; Equates for port A
Rec	=  ra.1         ; O  Sortie RECord codec audio
Pompe	=  ra.2         ; O  Sortie relais pompe a essence
Led	=  ra.4

; Equates for port B
Std	=  rb.0         ; I  Nouveau ton recu
Ton3	=  rb.1         ; I  
Ton2	=  rb.2		; I  
Ton1	=  rb.3		; I  
Ton0	=  rb.4         ; I  
Play	=  rb.5         ; O Sortie play
A4	=  rb.6         ; O Adresse mot speech codec
A0	=  rb.7         ; O Adresse mot speech codec

; Allocate space for some variables.
	org     0Ch
CODE	ds      4       ; variable pour le password local
RELAIS	ds	1	; variable pour le relais local
REG	ds      5       ; variable pour le registre d'entree + 1 pour la reprog
State	ds	1	; machine d'etat
counter	ds	1	; index de tableau
tempo	ds	1	; variable pour la reception de tons dans la FSM
rc	ds	1
Cmd	=	rc.0
	id      'CGSM'

; Startup program
	org     0
	jmp     Start

; *** Routines d'interruptions ***
	org     4
	clrwdt
	jb      INTF, rb0_edge
	clr     Intcon			; plantage du programme
freeze	clrwdt
	jmp	freeze

rb0_edge                                ; Reception d'un ton
	jnb	STD, :fin
	mov	REG+4, REG+3
	mov	REG+3, REG+2
	mov	REG+2, REG+1
	mov	REG+1, REG
	clr	REG
	movb	REG.3, Ton3
	movb	REG.2, Ton2
	movb	REG.1, Ton1
	movb	REG.0, Ton0
	clr	tempo
	setb	Cmd
:fin	clrb	INTF
	reti

; *** Initialisation du micro-controleur ***
start   clr	ra			; Clear Port
	clr	rb
	mov     !ra,    #00010000b      ; Set port A direction (1=input)
	mov     !rb,    #00011111b      ; Set port B direction (0=output)
	setb    rp0
	mov     Option, #11001111b      ; (no pull up, rb0 rise edge, 1:128)
	clrb    rp0
	mov	intcon, #10010000b	; (GIE on, RB0 on)
	setb	Rec
	setb	Play
	setb	Led
	jb	Led, suite

; *** ecrit dans l'EEPROM le code et le relais par defaut ***
	mov	counter, #00h
:loop	mov	w, counter
	call	string
	mov	EEDATA, w
	mov	EEADR, counter
	call	write
	inc	counter
	cjbe	counter, #04h, :loop


; *** init du relais ***
suite	mov	w, #04h
	call	read
	mov	RELAIS, w

; *** debut de la state machine ***
fsm	movb	Pompe, RELAIS.0
	inc	tempo
	cjbe	tempo, #05h, :foo	; 5 secondes sans dtmf recu
	clr	tempo
	call	clear
	clrb	Cmd
	mov	State, #01h		; retour en state1

:foo	cjbe	State, #03h, :cont	; test si state > 3
	clr	State			; oui => retour en state0

:cont	mov	w, State
	jmp	pc+w
	jmp	state0
	jmp	state1
	jmp	state2
	jmp	state3

attente	sleep
	nop
	jmp	fsm

; Actions etape 0: Initialisation des codes
; lire EECODE dans CODE
; lire EEPROT dans PROT
; next_state = 1
state0
	mov	counter, #00h		; lit dans l'EEPROM le code par defaut
	mov	fsr, #CODE
:loop	mov	w, counter
	call	read
	mov	indirect, w
	inc	fsr
	inc	counter
	cjbe	counter, #03h, :loop
	mov	State, #01h
	call	clear
:fin	jmp	attente

; Actions etape 1: Boucle d'attente
state1	jnb	Cmd, :fin
	cjne	REG, CODE, :fin
	cjne	REG+1, CODE+1, :fin
	cjne	REG+2, CODE+2, :fin
	cjne	REG+3, CODE+3, :fin
	mov	State, #02h		; Code accepte
	call	clear
	clrb	Cmd
:fin	jmp	attente

; Actions etape 2: Boucle de choix
state2	jnb	Cmd, :fin
	clrb	Cmd
	mov	State, #01h
	mov	w, REG
	clr	REG
	jmp	pc+w
	jmp	touche0
	jmp	touche1
	jmp	:fin
	jmp	:fin
	jmp	:fin
	jmp	:fin
	jmp	:fin
	jmp	:fin
	jmp	:fin
	jmp	touche9
	jmp	:fin
	jmp	:fin
	jmp	:fin
	jmp	:fin
	jmp	:fin
	jmp	:fin
:fin	jmp	attente

touche0 clrb	RELAIS.0
	mov	EEDATA, #00h
	mov	EEADR,	#04h
	call	write
	jmp	attente

touche1 setb	RELAIS.0
	mov	EEDATA, #01h
	mov	EEADR,	#04h
	call	write
	jmp	attente

touche9 mov	State, #03h
	jmp	attente

; Actions etape 3: Programmation nouveau code
state3	cjne	REG+4, #09h, :fin
	mov	fsr, #REG+3
	mov	counter, #00
:loop	mov	EEDATA, indirect
	mov	EEADR, counter
	call	write
	inc	counter
	dec	fsr
	cjbe	counter, #03h, :loop
	mov	state, #01
:fin	jmp	attente

; *** Routine d'effacement du registre d'entree ***
clear	clr	REG
	clr	REG+1
	clr	REG+2
	clr	REG+3
	clr	REG+4
	ret

; *** Routine de lecture de l'EEPROM ***
; w contient l'adresse, renvoi la data dans w
read	mov	EEADR, w
	setb	STATUS.5
	setb	EECON1.0
	clrb	STATUS.5
	mov	w, EEADR
	ret

; *** Routine d'ecriture dans l'EEPROM ***
; EEDATA contient la data, EEADR l'adresse
write	setb	STATUS.5
	setb	EECON1.2
	mov	EECON2, #55h
	mov	EECON2, #0AAh
	setb	EECON1.1
	jb	EECON1.1, $
	clrb	STATUS.5
	ret

; *** Code par defaut ***
string	jmp	pc+w
	retw	01h,02h,03h,04h
	retw	00h

	eeorg	00h
	eedata	01h,02h,03h,04h
	eedata	00h

