;==================================================
;=   Programme du detecteur d'impulsions 175 Hz   =
;==================================================

;Directives d'assemblage
;=======================

	.title "det175Hz.asm"
	.vers "st6215"
	.input "6225_reg.asm"


;Constantes
===========

; les deux impulsions doivent etre rangees par ordre croissant de numero
N1              .set 5                          ; numero de la 1e impulsion attendue
N2              .set 15                         ; numero de la 2e impulsion attendue

watchtim        .equ 0FEh               
precharg        .equ 238
quartdep        .equ 140                        ; nb de 1/4 de periode du signal a integrer
seuil           .equ 100
topdep          .equ 3
Fenetopn        .equ 10
Testtopn        .equ 2


Fenetr1         .set (15 + (50 * N1)) / 4       ; delai en nb d'interruptions
Fenetr2         .set (15 + (50 * N2)) / 4
Fintram         .set (15 + (50 * 40)) / 4       ; 40eme impulsion

;Adresses registres
;==================
Table           .def 84H, 0FFh, 0FFh
Fintabl         .equ 8Ch

mesures         .def 8Ch, 0FFh, 0FFh            ; 2 octets
mespos          .def 8Eh, 0FFh, 0FFh            ; 1 octet

Nbint           .def 90h, 0FFh, 0FFh            ; nb d'interruptions totalisees
Sortie          .def 91h, 0FFh, 0FFh            ; etat des sorties
Imp1            .def 92h, 0FFh, 0FFh            ; etat de la premiere impulsion
Imp2            .def 93h, 0FFh, 0FFh            ; etat de la deuxieme impulsion
SauvAcc         .def 94h, 0FFh, 0FFh            ; registre de sauvegarde de l'accu lors de l'interruption
Signal          .def 95h, 0FFh, 0FFh            ; ordre pour gestion des voyants
	
;PROGRAMME PRINCIPAL            
;===================            
			
; Initialisation
; ==============
			
		.org 880h                       ; pour les modeles 2 KO de ROM
Reset           ldi wdr, watchtim               ;chargt chien de garde  

; Initialisation memoire

		ldi Y, Table                    ; Y est l'index reserve a l'interruption

		ldi V, Signal-Table             ; X est l'index reserve au programme principal
		ldi X, Table
		clr a
Raz             ld (X), a                       ; remise a zero de la memoire
		inc X
		dec V
		jrnz Raz

; Initialisation des entrees/sorties            

		ldi ddra, 0FFh  
		ldi ora, 11b                    ; Pa2-3 : Sortie drain ouvert
		ldi dra, 0FFh                   ; Pa0-1 : push-pull

		clr ddrb                        ; Pb 7 entree analogique
		ldi drb, 10000000b
		ldi orb, 10000000b

		clr ddrc
		clr orc
		clr drc
			
; Initialisation du convertisseur

		ldi adcr, 30h

; Initialisation du timer

		ldi ior, 00010000b              ; interruptions timer seulement
		ldi tcr, precharg               ; compte pour le relancement du timer 

; Depart timer et demasquage interruptions
	
		ldi tscr, 01111010b             ; horloge vient du quartz, rapport 1/4 de 8 MHz
		ldi Signal, 1                   ; hors pointe par defaut
		reti                            ; retour au mode normal

;Programme principal
;===================

; 1) Recherche de l'impulsion de depart

Princip         ld a, mesures
AttInt          cp a, mesures                   ; on attend l'incrementation
		jrz AttInt

ReDep           clr mespos
		clr mesures
		clr mesures+1

		res 1, Sortie

		ld a, mesures
Depart          cp a, mesures                   ; on attend l'incrementation
		jrz Depart

		ld a, mesures
		cp a, mespos                    ; toutes les mesures sont positives ?
		jrz Dep2

		jp ReDep                        ; non : on attend

Dep2            cpi a, topdep                   ; nombre prevu d'impulsions positives successives ?
		jrz Dep3

		jp Depart                       ; non

Dep3            set 1, Sortie                   ; affiche qu'une trame est en cours

; 2) Test de presence de la premiere impulsion attendue

		ldi V, Fenetr1 / 256
		ldi W, Fenetr1 % 256
		call TestImp    ; test si impulsion presente au temps indique
		ld Imp1, a      ; resultat du test

; 3) Test de presence de la deuxieme impulsion attendue

		ldi V, Fenetr2 / 256
		ldi W, Fenetr2 % 256
		call TestImp    ; test si impulsion presente au temps indique
		ld Imp2, a                      ; resultat du test

		ldi V, Fintram / 256
		ldi W, Fintram % 256
		call TestImp                    ; juste pour attendre derniere impulsion

; 4) Utilisation des signaux recus

		call Exploite

		jp Princip                      ; attente trame suivante.


; Sous-programme attente et detection d'une impulsion

TestImp         ld a, V                         ; V est la borne inferieure de la fenetre
		cp a, mesures+1                 ; on attend l'incrementation jusqu'a la borne inferieure
		jrnz TestImp                    ; octet fort d'abord

		ld a, W
		cp a, mesures
		jrnz TestImp

		clr mespos                      ; raz compteur de mesures

		ld a, W                         ; on decale VW a la borne superieure de la fenetre
		addi a, Fenetopn
		ld W, a
		jrnc TstI2

		inc V

TstI2           ld a, V
		cp a, mesures+1                 ; on attend l'incrementation jusqu'a la borne superieure
		jrnz TstI2

		ld a, W
		cp a, mesures
		jrnz TstI2

		ld a, mespos
		cpi a, Testtopn                 ; assez de lectures positives ?
		jrc TstI3                       ; non : impulsion absente

		ldi a, 1                        ; oui : impulsion presente
		ret
		ldi wdr, 01                     ;declenchement de la reinitialisation en cas d'erreur

TstI3           clr a
		ret
		ldi wdr, 01                     ; declenchement de la reinitialisation en cas d'erreur

; Sous-programme d'utilisation des signaux recus.
; La LED branchee en PA2 indique l'etat normal.
; La LED branchee en PA3 indique l'etat "jour de pointe".
; Le clignotement des deux indique l'alerte.
; Signal vaut 1 si hors pointe (par defaut), 2 si alerte, 3 si pointe.

Exploite        ld a, Imp1
		sla a                           ; impulsion 5 en bit 1
		add a, Imp2                     ; impulsion 15 en bit 0
		jrz FinExpl                     ; aucune impulsion : on conserve l'affichage

		ld Signal, a                    ; impulsion presente : on modifie l'affichage

FinExpl         ret
		ldi wdr, 01                     ; declenchement de la reinitialisation en cas d'erreur

;Sous-programme interruption timer
;=================================
; Y est le registre pointeur de table

IntTimer        res 7, tscr                     ; RAZ du bit TMZ        
		ldi wdr,watchtim                ; on jette un os au chien de garde
		ld SauvAcc, a                   ; sauvegarde accu

		ld a, Sortie                    ; synchronisation des transitions de sorties
		ld dra, a                       ; pour qu'elles ne se produisent pas pendant la conversion

		ldi a,  precharg-2              ; etat actuel du timer ; on en tient compte
		add a, tcr                      ; pour le relancement du timer de sorte que la 
		ld tcr, a                       ; frequence soit constante. Le -2 inclut le temps de calcul

		ld a, adr                       ; acquisition de la tension d'entree
		ldi adcr, 030h                  ; lancement conversion suivante

		add a, (Y)                      ; accumulation en table
		ld (y), a
		inc Y

		jrnc Tim1                       ; report de la retenue eventuelle.
		inc (Y)

Tim1            inc Y                           ; on pointe sur le prochain mot en table
		ld a, Y
		cpi a, Fintabl                  ; arrive a fin ?
		jrc Tim2

		ldi Y, Table                    ; oui : on retourne au debut

Tim2            inc Nbint                       ; nb de mesures faites
		ld a, Nbint
		cpi a, quartdep
		jrnc Tim2a                      ; fin du cycle ?

		ld a, SauvAcc                   ; oui : restauration accu
		reti                            ; plus rien a faire
		ldi wdr, 01                     ; declenchement de la reinitialisation en cas d'erreur

Tim2a           clr Nbint
		inc mesures                     ; oui : un de plus
		jrnz Tim3

		inc mesures+1

Tim3            ld a, Table                     ; valeur de rang 0
		sub a, Table+4                  ; - valeur de rang 2
		ld Table, a                     ; dans valeur de rang 0
		jrnc Tim4

		inc Table+5                     ; si retenue, on incremente la valeur de rang 2

Tim4            ld a, Table+1
		sub a, Table+5
		ld Table+1, a
		jrr 7, a, Tim6                  ; si difference negative, on inverse le signe

		ld a, Table
		com a
		inc a
		ld Table, a

		jrnz Tim5 

		dec Table+5                     ; si retenue

Tim5            ld a, Table+1
		com a
		ld Table+1, a
	
Tim6            ld a, Table+2                   ; valeur de rang 1
		sub a, Table+6                  ; - valeur de rang 3
		ld Table+2, a                   ; dans valeur de rang 1
		jrnc Tim7

		inc Table+7                     ; si retenue, on incremente la valeur de rang 2

Tim7            ld a, Table+3
		sub a, Table+7
		ld Table+3, a
		jrr 7, a, Tim9                  ; si difference negative, on inverse le signe

		ld a, Table+2
		com a
		inc a
		ld Table+2, a

		jrnz Tim8 

		dec Table+7                     ; si retenue

Tim8            ld a, Table+3
		com a
		ld Table+3, a
	
Tim9            ld a, Table                     ; addition des deux valeurs absolues
		add a, Table+2
		ld Table, a
		jrnc Tim10

		inc Table+1

Tim10           ld a, Table+1
		add a, Table+3
		ld Table+1, a

		ld a, Table+1
		jrnz mesurbon                   ; si <>0, le cumul est > 255 : ok

		ld a, Table
		cpi a, seuil
		jrnc mesurbon

		res 0, Sortie                   ; indication visuelle d'absence
		jp IntTim2

mesurbon        set 0, Sortie                   ; indication visuelle de presence

		inc mespos                      ; oui : une mesure positive de plus

IntTim2         clr Table
		clr Table+1
		clr Table+2
		clr Table+3
		clr Table+4
		clr Table+5
		clr Table+6
		clr Table+7

; Traitement de l'affichage
; note : res allume et set eteint car c'est une sortie drain ouvert

		ld a, Signal
		cpi a, 1
		jrnz Affiche

AffHP           res 2, Sortie                   ; hors pointe
		set 3, Sortie
		jp FinTim

Affiche         cpi a, 3
		jrnz Affich2

AffP            res 3, Sortie                   ; pointe
		set 2, Sortie
		jp FinTim
	
Affich2         jrr 2, Sortie, AffP             ; alerte. On permute les deux voyants
		jp AffHP

FinTim          ld a, SauvAcc   ; restauration accu
		reti    ; fin de l'interruption.
		ldi wdr, 01                     ; declenchement de la reinitialisation en cas d'erreur


; ces routines d'interruption ne servent qu'a attrapper les eventuelles 
; interruptions imprevues
;=============================================
IntADC          ldi adcr, 90h
IntGen          reti
		ldi wdr, 01                     ; declenchement de la reinitialisation en cas d'erreur

; Le reste de la memoire est rempli par le programmeur avec des 00 qui equivalent
; a des NOP. En cas d'egarement du processeur, on atteint cet endroit qui force 
; le declenchement du chien de garde, provoquant la reinitialisation.
; =======================================================================

		.org 0FEDh
		ldi wdr, 01                     ; declenchement de la reinitialisation en cas d'erreur

;Vecteurs d'interruption timer et de demarrage
;=============================================
		.org 0FF0h
		jp IntADC 

		.org 0FF2h
		jp IntTimer

		.org 0FF4h
		jp IntGen

		.org 0FF6h
		jp IntGen

		nop
		ldi wdr, 01                     ; declenchement de la reinitialisation en cas d'erreur

		.org 0FFCh
		jp IntGen

		.org 0FFEh
		jp Reset
