; LCDCID3.ASM - 6/2/2000
; ############### Version LCDCID.ASM pour carte 80C32. ###############

; Reprise du fichier LCDMOD6.ASM, même fonctionnalités sauf 
; modem remplacé par le CI MC145447.

; Projet à réaliser:
; Affiche n° CID téléphone sur LCD.
; Affichage de l'heure sur LCD, sauvegarde n° en RAM I2C
;	 (à partir adr. 20h => FFh, 13 n° ou Nom + date/heure (16 octets)).
; Clavier  2 touches pour lire/effacer les n° reçus:
;	 rappel de n° enregistrés en RAM avec 1 touche et affichage n° 
;	 sur LCD.
; La date/heure et le no sont codées sous forme d'octets 
;	 (5 octets pour le no et 4 pour la date/heure), Ils sont stockés dans 
;	 un tampon en RAM interne pour recherche annuaire puis ensuite 
;	 sauvegardées en RAM I2C.
; Recherche Nom correspondant au n° en EPROM I2c et affichage sur LCD.
;	 (5 octets pour le no et 12 pour le nom ). 

;Affichage d'attente:
;               +----------------+
;               ¦Sam  8 Jan 22:59¦
;               ¦Attente appel...¦
;               +----------------+
 
;Affichage réception no: 
;               +----------------+
;               ¦Le: 04/01 08:30 ¦
;               ¦No: 0123456789  ¦
;               +----------------+

;Affichage réception nom: 
;               +----------------+
;               ¦Le: 04/01 08:30 ¦
;               ¦No: Domos       ¦
;               +----------------+

;En consultation no reçus:
;               +----------------+
;               ¦Date:04/01 08:30¦
;               ¦No: 0123456789  ¦
;               +----------------+

;==============================================================================
	.include	8051_equ.asm
;==============================================================================
RamI2c	  equ 020h		;1ière adr. ram n° tél. sur PCF8583.
FinRamI2c equ 000h		;Dernière adr. ram n° tél. sur PCF8583 (F0h + 10h).
NbNo      equ 010h		;Nbre octets par n° en Ram I2c.	 
NbNom     equ 00Ch		;Nbre octets par nom en EEprom I2c.	 
;==============================================================================
; Adresses RAM interne utilisées. 
; En 80h début pile.
; 25 octets max. utilisés pour la réception CID.
; 5 octets max. utilisés pour I2C.
; Un seul Buffer i2C de lecture/écriture.

cid_buf equ 67h                 ;Buffer d'écriture octets CID.
i2c_buf equ 62h                 ;Buffer de lecture/écriture I2C.
acq     equ 61h                 ;Adresse d'acquittement I2C (00h=OK).

led	equ 60h			;Contient état led lcd (FEh:on ou F6h:off).
list	equ 5Fh			;Pointeur enregistrement n° en RAM PCF8583.
noaff	equ 5Eh			;Pointeur sur n° en RAM  PCF8583 à afficher.
tampon	equ 4Eh			;Stocke 4 octets date/heure + (5 octets n° ou 12 octets nom)
				;Soit 16 octets max.
tmp	equ 4Dh			;Adr. utilisée comme registre temporaire.
;=============================================================================
;Ports I2C
bsda    equ 097H		;P1.7
bscl    equ 096H		;P1.6
;trig   equ 091H		;P1.1 (Plus utilisé, modifié par des NOP)
;=============================================================================
	org 0000h ;**********************80c32*****************************
	ajmp debut

; Interruptions non utilisées 
       	org   03h                   ;external interrupt 0
    	reti
   	org   0Bh                   ;timer 0 interrupt
    	reti
   	org   13h                   ;external interrupt 1
    	reti
   	org   1Bh                   ;timer 1 interrupt
    	reti
   	org   23h                   ;serial port interrupt
    	reti
   	org   2Bh                   ;I2C port interrupt
    	reti

	org 0100h ;**********************80c32*****************************

debut    
	mov sp, #80h		;Initialise la pile.    ******80c652******	
    	mov ie, #00h            ;disable interrupts

	acall 	init_rs2	;Débit uart 1200 Bds.
	; Le module CID n'utilise que RXD du 80C32.
		
lab000	acall	initram		;Init. valeur Ram interne
	acall	inithor		;Init. RTC i2c. (la maj de la RTC n'est pas effectué par le prog.)
	acall	initlcd		;Init. LCD
	acall	initaff		;Init aff. d'attente msg LCD + horloge.

 	;Boucle principale *************************************************.
lab001	mov	r0, #cid_buf		;Zone stockage octets réception.
lab002	acall	rx_rs2			;Attend réception caractère.
	jc	lab024			;Saut si réception CID.

     	acall 	litkey			;Sinon lit touches.
     	jnz 	lab020			;Saut si touche appuyée.

 	;Affiche date/heure si seconde à 0 et si pas de n° reçu ***************.
	mov	a, led			;Led allumé si n° reçu.
	cjne	a, #0FEh, lab002	;Saut si led allumé (pas aff. horloge)
 	mov	a, noaff		;Si consultion n°, noaff <> 20h.
	cjne	a, #20h,  lab002	;Saut si noaff <> 20h (pas aff. horloge).
	acall	tst_sec			;Si seconde  à 00, affiche date/heure.
	ajmp	lab002			;Retourne lecture rs.

 	;Test touches clavier *************************************************.
lab020	cjne	a, #01, lab022		;A = 01 si touche 1 appuyée
	acall	led_off			;Eteint led LCD
	mov	noaff, #20h		;Réinit. liste n° à afficher.
	acall	initaff			;Si touche 1, efface n° reçu en réaffiche date/heure + attente ...
lab021  acall 	litkey			;Lit touches.
     	jnz 	lab021			;Boucle si touche encore appuyée.
	ajmp	lab002			;Retourne lecture rs.

lab022	cjne	a, #02, lab023		;A = 02 si touche 2 appuyée.	
	acall	affcid			;Affiche n° enregistrés.
	ajmp	lab002			;Retourne lecture rs.

lab023	cjne	a, #04, lab002		;A = 04 si touche 3 appuyée.	
	ajmp	lab000			;Retourne init pour raz.

 	;Réception octets CID *************************************************.
lab024	cjne	a, #80h, lab002		;Saut si <> de 80h (1ier octet cid)	
	acall	rx_rs2			;Attend réception caractère.
	jnc	lab002			;Retourne lecture rs si time-out.
	mov	r1, a			;Octet longueur trame cid.
	; 80h et longueur trame non sauvegardés en Ram.
lab003	acall	rx_rs2			;Attend réception caractère.
	jnc	lab002			;Retourne lecture rs si time-out.
	mov	@r0, a			;Sauve dans buffer cid.
	inc	r0
	djnz	r1, lab003		;R1 octets à recevoir.
	
	;Interprétation octets CID reçus **************************************.
	acall	clrlcd			;Efface LCD.
	mov	dptr, #msgdh
	acall	afftxlcd		;Affiche message 'Le: ' sur LCD
	mov	r1, #tampon		;Pour stocker infos utils cid.

	;Jour/Mois.
	mov	r0, #cid_buf + 4	;Pointe jour		
	acall	asc2byt			;Convertit octets ascii ab => octet.
	acall 	affalcd			;Affiche A sur LCD (jour du mois).
	mov	@r1, a			;Sauve dans tampon.
	inc	r1

	mov	a, #'/'
	acall 	ecrcarlcd		;Affiche '/' sur LCD.

	mov	r0, #cid_buf + 2	;Pointe mois		
	acall	asc2byt			;Convertit octets ascii ab => octet.
	acall 	affalcd			;Affiche A sur LCD (mois).
	mov	@r1, a			;Sauve dans tampon.
	inc	r1

	mov	a, #' '
	acall 	ecrcarlcd		;Affiche '/' sur LCD.

	;Heures/Minutes		
	mov	r0, #cid_buf + 6	;Pointe heure		
	acall	asc2byt			;Convertit ascii ab => octet.
	acall 	affalcd			;Affiche A sur LCD (Heures).
	mov	@r1, a			;Sauve dans tampon.
	inc	r1

	mov	a, #':'
	acall 	ecrcarlcd		;Affiche '/' sur LCD.

	mov	r0, #cid_buf + 8	;Pointe minute
	acall	asc2byt			;Convertit ascii ab => octet.
	acall 	affalcd			;Affiche A sur LCD (Minutes).
	mov	@r1, a			;Sauve dans tampon.
	inc	r1

	acall	ln2lcd			;Ligne 2 sur LCD.
	mov	dptr, #msgno
	acall	afftxlcd		;Affiche message 'No: ' sur LCD

	mov	r0, #cid_buf + 10	;Pointe type info		
	mov	a, @r0
	cjne	a, #02h, lab006		;Saut si <> de 2 (info n°)	

	;No tél.
	mov	r0, #cid_buf + 12	;Pointe n° tél.
	mov	r2, #05			;5 octets à afficher.
lab005	acall	asc2byt			;Convertit ascii ab => octet.
	acall 	affalcd			;Affiche sur LCD (2 chiffre n°).
	mov	@r1, a			;Sauve dans tampon.
	inc	r1
	inc	r0
	djnz	r2, lab005		
	ajmp	lab007			;Saur recherche nom.
	
	;Info masquée.
lab006	mov	a, #'?'			;Affiche '?' si info masquée ('P' ou 'O')
	acall 	ecrcarlcd		;Affiche sur LCD.
	mov	@r1, a			;Sauve dans tampon.
	inc	r1

	;Recherche nom et sauve en ram i2c.
lab007	acall	no2nom			;Cherche Nom = no.
	acall	sauvram			;Sauve en RAM i2c.
	 	
	;Allume LED pour signalisation.
	acall	led_on			;Allume led LCD
lab008	ajmp	lab001			;Retour boucle principal.

;=============================================================================
;------  Sauvegarde Date/Heure + No ou Nom en RAM PCF8583 sauvegardée par pile.
sauvram	push	b
	push	acc
	mov	a, list			;Pointe n° à écrire.
	cjne	a, #FinRamI2c, sauvra1	;Si fin RAM PCF8583,
	mov	list, #RamI2c		;Init début RAM.
sauvra1	mov	r0, #tampon
	mov	r1, #NbNo		;Nb octets à sauvegarder.
sauvra2	mov	a, @r0			;De tampon vers Ram I2c.
	mov	b, list
	acall	ecrrami2c
	inc	list
	inc	r0
	djnz	r1, sauvra2	
	pop	acc
	pop	b
	ret

;=============================================================================
	;Affiche n° stocké ram i2c (du 1ier au dernier).
 ;Affiche 1 n° et retourne à la boucle principale.	
affcid 	mov	a, noaff		;Pointeur n° à lire
	cjne	a, list, lab200		;Saut vers affichage si noaff <> list.
	acall	led_off			;Sinon fin liste, éteint led LCD
	mov	noaff, #20h		;Réinit. liste n° à afficher.
	acall	initaff			;Efface n° en réaffiche date/heure + attente ...
	ret
 
lab200	acall	clrlcd			;Efface LCD.
	mov	dptr, #msgdh2
	acall	afftxlcd		;Affiche message sur LCD

	mov	b, noaff		;Pointeur n° à lire
	acall	litrami2c
	acall 	affalcd			;Affiche sur LCD.
	inc	b

	mov	a, #'/'
	acall 	ecrcarlcd		;Affiche '/' sur LCD.

	acall	litrami2c
	acall 	affalcd			;Affiche sur LCD.
	inc	b

	mov	a, #' '
	acall 	ecrcarlcd		;Affiche '/' sur LCD.

	acall	litrami2c
	acall 	affalcd			;Affiche sur LCD.
	inc	b

	mov	a, #':'
	acall 	ecrcarlcd		;Affiche '/' sur LCD.

	acall	litrami2c
	acall 	affalcd			;Affiche sur LCD.
	inc	b

	acall	ln2lcd			;Ligne 2 sur LCD.
	mov	dptr, #msgno
 	acall	afftxlcd		;Affiche message sur LCD

	acall	litrami2c
  	cjne 	a, #3Ah, lab201         ;Saut si A <> 3Ah.
lab201  jc	lab202               	;Saut si A < 3Ah (si chiffre).
  	cjne 	a, #'?', lab204         ;Saut si A <> '?' (Nom).
	acall 	ecrcarlcd		;Affiche caractère '?' sur LCD si 'P' ou 'O'.
	mov	a, #NbNom		;Pour pointer enregistrement suivant.
	add	a, b			;Ajouter au pointeur n° à lire.
	ajmp	lab206

lab202	mov	r2, #05			;10 caractères (5 octets) à afficher.
lab203	acall	litrami2c
	acall 	affalcd			;Affiche n° tél. sur LCD.
	inc	b
	djnz	r2, lab203
	mov	a, #NbNom - 5		;Pour pointer enregistrement suivant.
	add	a, b			;Ajouter au pointeur n° à lire.
	ajmp	lab206
	
lab204	mov	r2, #12			;12 caractères du nom à afficher.
lab205	acall	litrami2c
	acall 	ecrcarlcd		;Les affiche sur LCD.
	inc	b
	djnz	r2, lab205
	mov	a, b			
	
lab206 	mov	noaff, a
lab207	acall 	litkey			;Lit touches.
     	jnz 	lab207			;Boucle si touche encore appuyée.

	ret
		
msgdh	db "Le: ", 00
msgdh2	db "Date:", 00
msgno	db "No: ", 00

;=============================================================================
; Recherche Nom en fonction n°. dans Eprom I2c.
no2nom	mov	b, #00h			;Adr. Eprom
	mov	r3, b
lab300	mov	r1, #tampon + 4		;Pointe n° tél.
	mov	r2, #05
lab301	acall	litromi2c		;Lit EPROM i2c à l'adrsse B.
	cjne	a, #0FFh, lab302	;FFh marque fin annuaire.
	ret				;Quitte si fin annuaire.
lab302	mov	tmp, @r1		;N° tél. dans tampon.
	cjne	a, tmp, lab304		;Saut si n° <> annuaire.
	inc	r1
	inc	b
	djnz	r2, lab301		;5 octets à comparer.

	mov	r2, #NbNom		;Nb octets / nom.
	mov	a, #0C4h		
	acall 	poslcd			;Ligne2, colonne 2.
	mov	r1, #tampon + 4		;Pointe n° tél. pour le remplacer par le nom.
lab303	acall	litromi2c
	acall	ecrcarlcd
	mov	@r1, a
	inc	b
	inc	r1
	djnz	r2, lab303		;Remplace n° par nom dans tampon.

	mov	a, #' '
	acall	ecrcarlcd
	acall	ecrcarlcd		;2 espaces de fin sur LCD
	ret

lab304  mov	a, #NbNom + 5
	add	a, r3			;Pointe No suivant Eprom.
	mov	r3, a
	mov	b, a
	ajmp	lab300			;Boucle sur N°/Nom suivant.

;=============================================================================
initram	mov	list,   #RamI2c		;Adr 1ier enregistrement n° tél.
	mov	noaff,  #RamI2c		;Adr 1ier n° tél à afficher.
	ret

;=============================================================================
initaff	acall	clrlcd			;Efface LCD.
	acall	affhor			;Affiche date/heure sur LCD.
	mov	dptr, #msgm1
	acall	ln2lcd			;Ligne 2 sur LCD.
	acall	afftxlcd		;Affiche message d'attente sur LCD.
	ret

msgm1	db "Attente appel...", 00

;=============================================================================
; Convertit nombre texte ascii en octet
;	ex: texte '15' (octet 31 et 35) convertit en octet 15.
;	R0 pointe les octets en entrée, A le résultat en sortie.
asc2byt	push	b
	mov	a, @r0
	anl	a, #0Fh		;Poids fort à 0 (31h => 01h)
	swap	a		;Inverse quartet (01h => 10h)
	inc	r0		;Ex: (35h)
	mov	b, @r0
	anl	b, #0Fh		;Poids fort à 0 (35h => 05h)
	add	a, b		;(10h + 05h = 15h)
	pop	b
	ret

;=============================================================================
;Gestion LCD / touches I2C.
	include lcdi2c.lib
;Gestion Eprom I2c.	
	include pcf8582.lib
;Gestion RTC/Ram i2c
	include pcf8583.lib
;Routine i2c bas niveau.	
	include	i2c.lib
;Routine gestion port série / terminal		
	include term.lib
;Routine de delai
	include	delai.lib
;=============================================================================
        end
