;---------------------------------------------------------------------------
; ALtimètre vidéo;
; Olivier HUMEZ Octobre 1999
; Sur une expression de besoin de B.N. CHAGNY
;---------------------------------------------------------------------------
; Interface Hardware
; RB0: DS1820
; RB1: Entrée bouton poussoir
; RB2: DOUT AD7714
; RB3: _CS AD7714
; RB4: DIN AD7714
; RB5: SCLK AD7714
; RB6: _RESET AD7714
; RB7: Synchro 
; RA0: Video
; RA1: 
; RA2: 
; RA3: 
; RA4:
;---------------------------------------------------------------------------
 Constant  TEST = 0	; si = 1: mode test, affichage température et pression
;---------------------------------------------------------------------------
; Configuration étalonnage pression
   constant    ECHELLE_PRESSION = d'19673'   ; échelle de recalage capteur
;    remarque: étalonage identique à EMPRESS1 (centrale météo cerf-volant)
; Compensation en température
   constant    COMPENSATION = d'170'      ;  en millième de hPa par øC
;---------------------------------------------------------------------------
 Constant  NMAX_LIGNE = d'312'	; nombre de lignes de l'image
 Constant  N_BITMAP = d'100'	; ligne de départ de l'envoi du bitmap
 Constant  HAUTEUR_PIXEL = d'8'	; hauteur des pixel du bitmap
 Constant  LIGNE_TEMP = d'280'  ; ligne de base du traitement du DS1820 
				; toujours > à 256
;---------------------------------------------------------------------------
; Processeur cible:
;        List p=16C84, f=inhx8M , n = 255   (inutile sous MPLAB)
; Registre de configuration (p2-757)
;       b'11101'
;---------------------------------------------------------------------------
; Registres Bank 0
INDF      EQU   00
TMR0      EQU   01
PCL       EQU   02
STATUS    EQU   03
FSR       EQU   04
PORTA     EQU   05
PORTB     EQU   06
EEDATA    EQU   08
EEADR     EQU   09
PCLATCH   EQU   0A
INTCON    EQU   0B
; Registres Bank 1
OPTIO     EQU   01
TRISA     EQU   05
TRISB     EQU   06
EECON1    EQU   08
EECON2    EQU   09
;---------------------------------------------------------------------------
; Déclaration
#DEFINE    RP0    STATUS,5    ; bit sélection de la Bank Registre
#DEFINE      Z    STATUS,2    ; Zero bit
#DEFINE     DC    STATUS,1    ; Digit Carry bit
#DEFINE      C    STATUS,0    ; Carry bit
#DEFINE   INTEDG  OPTIO,6     ; Edge INT Selection
#DEFINE   RBIF    INTCON,0    ; Flag IT RB Change
#DEFINE   INTF    INTCON,1    ; Flag IT INT
#DEFINE   T0IF    INTCON,2    ; Flag IT Timer TMR0
#DEFINE   RBIE    INTCON,3    ; Enable RB Change
#DEFINE   INTE    INTCON,4    ; Enable INT
#DEFINE   T0IE    INTCON,5    ; Enable IT Timer TMR0
#DEFINE   GIE     INTCON,7    ; Enable général ITs
;---------------------------------------------------------------------------
; Initialisation du registre OPTION:
; bit7 - bit6   - bit5 - bit4 - bit3 - bit2 - bit1 - bit0
; RBPU - INTEDG - T0CS - T0SE - PSA  - PS2  - PS1  - PS0
;
; RPBU = 0  : pullup sur le port B
; INTEDG = 1: Edge de la pin INT = Rising
; T0CS = 0  : Source de TMR0 = Interne
; T0SE = 1  : Edge de la source Externe de TMR0 = Falling
; PSA = 1   : Assignation Prescaler = WATCHGOG
; PS2,PS1,PS0 = 7: Prescaler = 2^(N+1)  (Attention: = 2^N pour le WDOG)
;
 Constant  VAL_OPTION = b'01011111'
;---------------------------------------------------------------------------
; Déclaration RAM
;        DEBUT_RAM  =  0C
;
STATUS_SAVE_INT EQU  	0C
W_SAVE_INT      EQU  	0D
STATUS_APPLI	EQU	0E
STATUS_LIGNE	EQU	0F
CPTR_LIGNE	EQU	10   	; 2 octets
WORK_IT1	EQU	12	
WORK_IT2	EQU	13
BUFFER_BITMAP	EQU	14	; 30 octets = 6 caractères
CPTR_PIXEL	EQU 	32
BUFFER_CARACTERE EQU	33	; 6 octets
STATUS_TEMP	EQU	39
CPTR_BIT_TEMP	EQU	3A
WORK_TEMP	EQU	3B
TEMPO_TEMP	EQU	3C
WORK_1		EQU	3D
WORK_2		EQU	3E
WORK_3		EQU	3F
WORK_4		EQU	40
WORK_5		EQU	41
WORK_6		EQU	42
WORK_7		EQU	43
WORK_8		EQU	44
WORK_9		EQU	45
WORK_10		EQU	46
FSR_SAVE	EQU	47
AD_BUFFER	EQU	48
PRESSION	EQU	49    ; 2 octets
ALTITUDE	EQU	4B    ; 2 octets
DELTA_ALTITUDE	EQU	4D    ; 2 octets
CPTR_AFFICHAGE	EQU	4F
;---------------------------------------------------------------------------
; Déclarations Application
; Variable STATUS_APPLI
; bit 7: TOTO
   ;-----------
#DEFINE		RAZ_ALTITUDE	STATUS_APPLI,7
   ;-----------
; Variable STATUS_TEMP gestion température
   ;-----------
#DEFINE		READ_TEMP	STATUS_TEMP,0
#DEFINE		WRITE_TEMP	STATUS_TEMP,1
#DEFINE		RESET_TEMP	STATUS_TEMP,2
#DEFINE		FLAG_WRITE_TEMP	STATUS_TEMP,6
#DEFINE		FLAG_RESET_TEMP	STATUS_TEMP,7
;---------------------------------------------------------------------------
; Vecteurs
         ORG 00
         goto RESET
         ORG 04
         goto INTERRUPT
;---------------------------------------------------------------------------
; Début code
         ORG 05
;---------------------------------------------------------------------------
INTERRUPT	movwf W_SAVE_INT
                swapf STATUS,0
                bcf RP0
                movwf STATUS_SAVE_INT  ; sauvegardes W et STATUS
		movf FSR,0
		movwf FSR_SAVE
		;
		btfsc STATUS_LIGNE,0
		goto LIGNE0
	        btfsc STATUS_LIGNE,1
		goto LIGNE1
	        btfsc STATUS_LIGNE,2
		goto LIGNE2
	        btfsc STATUS_LIGNE,3
		goto LIGNE3
	        btfsc STATUS_LIGNE,4
		goto LIGNE4
	        btfsc STATUS_LIGNE,5
		goto LIGNE5
	        btfsc STATUS_LIGNE,6
		goto LIGNE6
;
INTER_FIN	incf CPTR_LIGNE + 1,1  ; incrémentation pointeur de ligne
		btfsc Z
		incf CPTR_LIGNE,1
; test dernière ligne
		movf CPTR_LIGNE,0
		sublw HIGH(NMAX_LIGNE)
		btfss Z
		goto INTER_FIN1
		movf CPTR_LIGNE + 1,0
		sublw LOW(NMAX_LIGNE)
		btfss Z
		goto INTER_FIN1
		clrf CPTR_LIGNE			
		clrf CPTR_LIGNE + 1
INTER_FIN1	clrf STATUS_LIGNE 
	        movf CPTR_LIGNE,0	
		btfss Z
		goto INTER_FIN10
		movlw N_BITMAP
		subwf CPTR_LIGNE + 1,0
		btfsc C
		goto INTER_FIN10
;
		movlw d'10'
		subwf CPTR_LIGNE + 1,0
		btfsc C
		goto INTER_FIN20
;
		movf CPTR_LIGNE + 1,0
		sublw 2
		btfss C
		goto INTER_FIN2
		bsf STATUS_LIGNE,2
		goto INTER_FINFIN		
INTER_FIN2	movf CPTR_LIGNE + 1,0
		sublw 3
		btfss C
		goto INTER_FIN3
		bsf STATUS_LIGNE,3
		goto INTER_FINFIN		
INTER_FIN3	movf CPTR_LIGNE + 1,0
		sublw 5
		btfss C
		goto INTER_FIN4
		bsf STATUS_LIGNE,4
		goto INTER_FINFIN		
INTER_FIN4	movf CPTR_LIGNE + 1,0
		sublw 6
		btfss C
		goto INTER_FIN5
		bsf STATUS_LIGNE,5
		goto INTER_FINFIN		
INTER_FIN5	movf CPTR_LIGNE + 1,0
		sublw 8
		btfss C
		goto INTER_FIN6
		bsf STATUS_LIGNE,2
		goto INTER_FINFIN		
; ligne >=9 et < 10 
INTER_FIN6	bsf STATUS_LIGNE,0
		btfss PORTB,1    ; bouton poussoir
		bsf RAZ_ALTITUDE
		goto INTER_FINFIN
; ligne >= 10 et < N_BITMAP
INTER_FIN20	bsf STATUS_LIGNE,0
		movf CPTR_LIGNE + 1,0
		sublw d'10'
		btfsc Z
		goto INTER_FIN21
		addlw 001      ; '11'
		btfsc Z
		goto INTER_FIN22
		addlw 001      ; '12'
		btfsc Z
		goto INTER_FIN23
		addlw 001      ; '13'
		btfsc Z
		goto INTER_FIN24
		addlw 001      ; '14'
		btfsc Z
		goto INTER_FIN25
		addlw 001      ; '15'
		btfsc Z
		goto INTER_FIN26
		goto INTER_FINFIN
INTER_FIN21	movlw BUFFER_BITMAP
		movwf FSR
		movf BUFFER_CARACTERE,0
		call CHARGE_CARACTERE
		goto INTER_FINFIN		
INTER_FIN22	movlw BUFFER_BITMAP + 5
		movwf FSR
		movf BUFFER_CARACTERE + 1,0
		call CHARGE_CARACTERE
		goto INTER_FINFIN		
INTER_FIN23	movlw BUFFER_BITMAP + d'10'
		movwf FSR
		movf BUFFER_CARACTERE + 2,0
		call CHARGE_CARACTERE
		goto INTER_FINFIN		
INTER_FIN24	movlw BUFFER_BITMAP + d'15'
		movwf FSR
		movf BUFFER_CARACTERE + 3,0
		call CHARGE_CARACTERE
		goto INTER_FINFIN		
INTER_FIN25	movlw BUFFER_BITMAP + d'20'
		movwf FSR
		movf BUFFER_CARACTERE + 4,0
		call CHARGE_CARACTERE
		goto INTER_FINFIN		
INTER_FIN26	movlw BUFFER_BITMAP + d'25'
		movwf FSR
		movf BUFFER_CARACTERE + 5,0
		call CHARGE_CARACTERE
		movlw HAUTEUR_PIXEL
		movwf CPTR_PIXEL
		movf FSR_SAVE,0
		movwf FSR
		goto INTER_FINFIN		
; ligne >= N_BITMAP
INTER_FIN10	movf CPTR_LIGNE,0	
		btfss Z
		goto INTER_FIN13
	        movlw (8 * HAUTEUR_PIXEL) + N_BITMAP
		subwf CPTR_LIGNE + 1,0
		btfss C
		goto INTER_FIN11
INTER_FIN13	bsf STATUS_LIGNE,0   ; ligne noire
		movf CPTR_LIGNE,0
		sublw HIGH(LIGNE_TEMP)
		btfss Z
		goto INTER_FINFIN
		movf CPTR_LIGNE + 1,0
		sublw LOW(LIGNE_TEMP)
		btfsc Z
		goto INTER_FIN30   ; lorsque CPTR_LIGNE = LIGNE_TEMP
		addlw 001    ; ligne + 1
		btfsc Z
		goto INTER_FIN35   ; lorsque CPTR_LIGNE = LIGNE_TEMP + 1
		addlw d'10'    ; ligne + 10
		btfsc Z
		goto INTER_FIN40   ; lorsque CPTR_LIGNE = LIGNE_TEMP + 11 (700us)
		goto INTER_FINFIN
;		
INTER_FIN11	decfsz CPTR_PIXEL,1
		goto INTER_FIN12
		bsf STATUS_LIGNE,6  ; envoi pixel avec shift
		movlw HAUTEUR_PIXEL
		movwf CPTR_PIXEL
		goto INTER_FINFIN
;
INTER_FIN12     bsf STATUS_LIGNE,1   ; envoi pixel sans shift
;
INTER_FINFIN	clrwdt
		movf FSR_SAVE,0
		movwf FSR
		swapf STATUS_SAVE_INT,0
	        movwf STATUS             ; restauration contexte
        	swapf W_SAVE_INT,1
	        swapf W_SAVE_INT,0
		bcf T0IF
		retfie	
;---------------------------------------------------------------------------
; Aquisition DS1820
INTER_FIN30	decf TEMPO_TEMP,1
		btfsc READ_TEMP
		goto TRAITE_READ
		btfsc WRITE_TEMP
		goto TRAITE_WRITE
		btfsc RESET_TEMP
		goto TRAITE_RESET
		goto INTER_FINFIN
;
TRAITE_RESET	bsf RP0
		bcf TRISB,0
		bcf RP0
		bcf PORTB,0   ; B0 = 0
		bsf FLAG_RESET_TEMP
		goto INTER_FINFIN
;
TRAITE_WRITE	bsf RP0
		bcf TRISB,0
		bcf RP0
		bcf PORTB,0   ; B0 = 0
		rrf WORK_TEMP,1
		nop
		nop
		btfss C
		goto TRAITE_WRITE1
		bsf PORTB,0   ; forçage à 1 pour alimentation pendant la conversion
TRAITE_WRITE1	bsf FLAG_WRITE_TEMP
		goto INTER_FINFIN				
;----------
INTER_FIN35	btfss FLAG_WRITE_TEMP
		goto INTER_FINFIN
		decf CPTR_BIT_TEMP,1
		btfsc Z
		bcf WRITE_TEMP
		bsf PORTB,0            ; forçage
		bcf FLAG_WRITE_TEMP
		goto INTER_FINFIN
;----------
TRAITE_READ	bsf RP0
		bcf TRISB,0
		bcf RP0
		bcf PORTB,0   ; B0 = 0
		movlw 001
		call TEMPO_1US
		bsf RP0
		bsf TRISB,0
		bcf RP0
		movlw 6
		call TEMPO_1US
		btfss PORTB,0
		goto TRAITE_READ1
		bsf C
		goto TRAITE_READ2
TRAITE_READ1	bcf C
TRAITE_READ2	rrf WORK_TEMP,1
		decf CPTR_BIT_TEMP,1
		btfsc Z
		bcf READ_TEMP
		goto INTER_FINFIN				
;----------
INTER_FIN40	btfss FLAG_RESET_TEMP     ; relachement pulse reset 700us après
		goto INTER_FINFIN
		bsf RP0
		bsf TRISB,0
		bcf RP0      ; B0 en entrée
		bcf FLAG_RESET_TEMP
		bcf RESET_TEMP
		goto INTER_FINFIN
;---------------------------------------------------------------------------
; Ligne vide
LIGNE0		nop   ; tempo 12 cycles
		nop
		nop
		movlw 01
		call TEMPO_1US
; synchro ligne 4us
		bcf PORTB,7
		movlw 3
		call TEMPO_1US
		bsf PORTB,7
;
		goto INTER_FIN
;---------------------------------------------------------------------------
; Ligne avec envoi Bitmap contenu dans le buffer sans shift
LIGNE1		nop   ; tempo 10 cycles
		movlw 01
		call TEMPO_1US
; synchro ligne 4us
		bcf PORTB,7
		movlw 3
		call TEMPO_1US
		bsf PORTB,7
; émission de la ligne contenue dans BUFFER_BITMAP
		movlw d'8'
		call TEMPO_1US
; envoi 6 caractères 
		movlw 06
		movwf WORK_IT1
		movlw BUFFER_BITMAP
		movwf FSR
LIGNE1_1	rrf INDF,0
		rlf PORTA,1
		incf FSR,1
		rrf INDF,0
		rlf PORTA,1
		incf FSR,1
		rrf INDF,0
		rlf PORTA,1
		incf FSR,1
		rrf INDF,0
		rlf PORTA,1
		incf FSR,1
		rrf INDF,0
		rlf PORTA,1
		incf FSR,1
		nop
		bcf PORTA,0
		decfsz WORK_IT1,1
		goto LIGNE1_1
;
		goto INTER_FIN
;---------------------------------------------------------------------------
; Ligne avec envoi Bitmap contenu dans le buffer avec shift
LIGNE6		bcf PORTB,7   ; synchro ligne 4us
		movlw 3
		call TEMPO_1US
		bsf PORTB,7
;
; émission de la ligne contenue dans BUFFER_BITMAP
		movlw d'8'
		call TEMPO_1US
; envoi 6 caractères 
		movlw 06
		movwf WORK_IT1
		movlw BUFFER_BITMAP
		movwf FSR
LIGNE6_1	rrf INDF,1
		rlf PORTA,1
		incf FSR,1
		rrf INDF,1
		rlf PORTA,1
		incf FSR,1
		rrf INDF,1
		rlf PORTA,1
		incf FSR,1
		rrf INDF,1
		rlf PORTA,1
		incf FSR,1
		rrf INDF,1
		rlf PORTA,1
		incf FSR,1
		nop
		bcf PORTA,0
		decfsz WORK_IT1,1
		goto LIGNE6_1
		bcf PORTA,0
;
		goto INTER_FIN
;---------------------------------------------------------------------------
; Equalizing pulse
LIGNE2		call TEMPO_4NOP
		call TEMPO_4NOP
; Pulse synchro 2us
		bcf PORTB,7
		movlw 1
		call TEMPO_1US
		bsf PORTB,7
; tempo 30us
		movlw d'30'
		call TEMPO_1US
; Pulse synchro 2us
		bcf PORTB,7
		movlw 1
		call TEMPO_1US
		bsf PORTB,7
;
		goto INTER_FIN
;---------------------------------------------------------------------------
; Premier vertical pulse
LIGNE3		call TEMPO_4NOP
		nop
		nop
; pulse inversé		
		bcf PORTB,7
; tempo 32us
		movlw d'32'
		call TEMPO_1US
; Pulse synchro inverse 2us
		bsf PORTB,7
		movlw 1
		call TEMPO_1US
		bcf PORTB,7
;
		goto INTER_FIN
;---------------------------------------------------------------------------
; Vertical pulse
LIGNE4		call TEMPO_4NOP
; Pulse synchro inverse 2us
		bsf PORTB,7
		movlw 1
		call TEMPO_1US
		bcf PORTB,7
; tempo 30us
		movlw d'30'
		call TEMPO_1US
; Pulse synchro inverse 2us
		bsf PORTB,7
		movlw 1
		call TEMPO_1US
		bcf PORTB,7
;
		goto INTER_FIN
;---------------------------------------------------------------------------
; Premier Equilizing Pulse suivant le dernier Vertical Pulse
LIGNE5		nop
		nop
		bsf PORTB,7
; tempo 2us
		movlw d'1'
		call TEMPO_1US
; Pulse synchro 2us
		bcf PORTB,7
		movlw 1
		call TEMPO_1US
		bsf PORTB,7
; tempo 28us
		movlw d'28'
		call TEMPO_1US
; Pulse synchro 2us
		bcf PORTB,7
		movlw 1
		call TEMPO_1US
		bsf PORTB,7
;
		goto INTER_FIN
;---------------------------------------------------------------------------
;------------------------
; Init port A
RESET        bsf RP0
             movlw b'00000' ; en sortie
             movwf TRISA
             bcf RP0
             movlw b'00000'  ; 
             movwf PORTA
;------------------------
; Init port B
             bsf RP0
             movlw b'00000111' ; 
             movwf TRISB
             bcf RP0
	     movlw b'10000000'	
             movwf PORTB
;------------------------
; init registre option
             bsf RP0
             movlw VAL_OPTION
             movwf OPTIO
             bcf RP0
;
             clrf EEADR    ; pour limiter la conso
;------------------------
; Init Application
             call INIT_APPLI
;------------------------
; Init sequenceur
             clrf TMR0
	     bcf T0IF	 ; clear éventuelles IT déjà présentes
             bsf T0IE    ; autorisation IT TMR0
;------------------------
; Programme principal
             bsf GIE
;
BOUCLE         	bsf RESET_TEMP	   ; acquisition DS1820
TEMP1		btfsc RESET_TEMP
		goto TEMP1
;
		movlw 0CC    ; Skip ROM
		movwf WORK_TEMP	
		movlw 08
		movwf CPTR_BIT_TEMP
		bsf WRITE_TEMP
TEMP2		btfsc WRITE_TEMP
		goto TEMP2
;
		movlw 044    ; Convert
		movwf WORK_TEMP	
		movlw 08
		movwf CPTR_BIT_TEMP
		bsf WRITE_TEMP
TEMP3		btfsc WRITE_TEMP
		goto TEMP3
;		
		movlw d'50'		; unité 20ms
		movwf TEMPO_TEMP
TEMP4		movf TEMPO_TEMP,1  ; attente 50 trames image = 1s
		btfss Z
		goto TEMP4
;
		bsf RESET_TEMP	   ; acquisition DS1820
TEMP5		btfsc RESET_TEMP
		goto TEMP5
;
		movlw 0CC    ; Skip ROM
		movwf WORK_TEMP	
		movlw 08
		movwf CPTR_BIT_TEMP
		bsf WRITE_TEMP
TEMP6		btfsc WRITE_TEMP
		goto TEMP6
;
		movlw 0BE    ; Read RAM
		movwf WORK_TEMP	
		movlw 08
		movwf CPTR_BIT_TEMP
		bsf WRITE_TEMP
TEMP7		btfsc WRITE_TEMP
		goto TEMP7
;
		movlw 08
		movwf CPTR_BIT_TEMP
		bsf READ_TEMP
TEMP8		btfsc READ_TEMP   ; lecture valeur température
		goto TEMP8
;
  IF TEST == 0 
	     	btfss PORTB,1
	     	goto AFF_TEMP      ; si bouton appuyé
;
		decfsz CPTR_AFFICHAGE,1
		goto ACQ_AD7714
AFF_TEMP	movlw 1 + 3   ; 3 cycles d'acquisition = 15s
		movwf CPTR_AFFICHAGE
  ENDIF
; Affichage température
	     	movf WORK_TEMP,0
             	movwf WORK_2
             	movlw 03
             	movwf WORK_8      ; nombre de chiffres à afficher
             	btfss WORK_2,7
             	goto AFF_TEMP_1
		bsf WORK_8,7      ; température négative
             	movf WORK_2,0
             	sublw 0
             	movwf WORK_2
AFF_TEMP_1 	bcf C
             	rrf WORK_2,1    ; suppression de la décimale
             	clrf WORK_1
             	call TRADUIT_BIN2_BCD
		movf WORK_5,0
             	movwf WORK_7
             	clrf WORK_6
             	clrf WORK_5
		movlw 0A
		movwf BUFFER_CARACTERE 
		movlw BUFFER_CARACTERE + 1
		movwf AD_BUFFER
             	call ECRIT_NOMBRE
		movlw 0C
		movwf BUFFER_CARACTERE + 4
		movlw 0D
		movwf BUFFER_CARACTERE + 5
;	goto BOUCLE
;---------------------------------
; Acquisition altitude
ACQ_AD7714   movlw 14      ; Self calibration: $10 + voie nø4
             call OUT_SPI
             movlw 3C      ; 001G GG00, gain = 2^GGG
             call OUT_SPI
; attente fin busy
ACQ_AD7714_1 movlw 08 + 4    ; lecture status: 08 + voie nø4
             call OUT_SPI
             call IN_SPI
             btfsc WORK_1,7
             goto ACQ_AD7714_1
;
             movlw 5C        ; lecture ($58 + voie nø4)
             call OUT_SPI
             call IN_SPI
             movwf WORK_3     ; MSB
             call IN_SPI
             movwf WORK_4     ; LSB
             call IN_SPI      ; octet non utilisé
; recalage en dizième de bar
             movf WORK_3,0
             movwf WORK_2
             movf WORK_4,0
             movwf WORK_1
             movlw HIGH ECHELLE_PRESSION
             movwf WORK_4
             movlw LOW ECHELLE_PRESSION
             movwf WORK_3
             call MUL16X16
             movf WORK_4,0
             movwf PRESSION
             movf WORK_3,0
             movwf PRESSION + 1
; comprensation de la dérive en température
; = (TEMP + $80) * COMPENSATION - (40 + $80) * COMPENSATION   [40 <-> 20øC]
             clrf WORK_2
             movf WORK_TEMP,0
             addlw 80
             movwf WORK_1                            ; 200: échelle 0.5øC
             movlw HIGH ((COMPENSATION * d'256') / d'200')
             movwf WORK_4
             movlw LOW ((COMPENSATION * d'256') / d'200')
             movwf WORK_3
             call MUL16X16
;
             movf WORK_3,0
             movwf WORK_4
             movf WORK_6,0
             movwf WORK_3
             movf PRESSION,0
             movwf WORK_2
             movf PRESSION + 1,0
             movwf WORK_1
             call SUB16       ; changer par ADD16 si COMPENSATION négative
;
             movlw HIGH ((0A8 * COMPENSATION) / d'200')
             movwf WORK_4
             movlw LOW ((0A8 * COMPENSATION) / d'200')
             movwf WORK_3
             call ADD16       ; changer par SUB16 si COMPENSATION négative
             movf WORK_2,0
             movwf PRESSION
             movwf WORK_4
             movf WORK_1,0
             movwf PRESSION + 1
             movwf WORK_3
; calcul d'altitude
; altitude = (2E9*Q/2^8+B605)*Q/2^16-3C6,  avec Q = 2C7E - P, P en 1/10 hPa
; aproximation polynome de degré 2 (voir fichier PRESS1.XLS)
             movlw 2C
             movwf WORK_2
             movlw 7E
             movwf WORK_1
             call SUB16      ; -P
;
             movf WORK_2,0
             movwf ALTITUDE
             movf WORK_1,0
             movwf ALTITUDE + 1   ; sauvegarde Q
;
             movlw 02
             movwf WORK_4
             movlw 0E9
             movwf WORK_3
             call MUL16X16
             movf WORK_3,0
             movwf WORK_2
             movf WORK_6,0
             movwf WORK_1    ; division par 2^16
             movlw 0B6
             movwf WORK_4
             movlw 05
             movwf WORK_3
             call ADD16
;
             movf ALTITUDE,0
             movwf WORK_4
             movf ALTITUDE + 1,0
             movwf WORK_3
             call MUL16X16
;
             movf WORK_4,0
             movwf WORK_2
             movf WORK_3,0
             movwf WORK_1
             movlw 03
             movwf WORK_4
             movlw 0C6
             movwf WORK_3
             call SUB16
;
             movf WORK_2,0
             movwf ALTITUDE
             movf WORK_1,0
             movwf ALTITUDE + 1
;
  IF TEST == 0 
	     btfsc PORTB,1
	     goto WRITE_ALTITUDE    	; si bouton appuyé
  ENDIF
; Affichage Pression
	     movf PRESSION,0
             movwf WORK_1
             movf PRESSION + 1,0
             movwf WORK_2
             call TRADUIT_BIN2_BCD
;
             movf WORK_5,0
             movwf WORK_7
             movwf WORK_10
             movf WORK_4,0
             movwf WORK_6
             movf WORK_3,0
             movwf WORK_5
; PRESSION
             movlw 04
             movwf WORK_1
WRITE_PRESSION_1 rrf WORK_5,1
             rrf WORK_6,1
             rrf WORK_7,1
             decfsz WORK_1,1
             goto WRITE_PRESSION_1
             clrf WORK_5
             movlw 04        ; 4 digits
             movwf WORK_8
	     movlw BUFFER_CARACTERE
	     movwf AD_BUFFER
             call ECRIT_NOMBRE
             movlw 0F      ; '.'
             movwf BUFFER_CARACTERE + 4
             movf WORK_10,0
             andlw 0F
             movwf BUFFER_CARACTERE + 5
; Altitude
		movlw d'80'		; unité 20ms
		movwf TEMPO_TEMP
TEMPOALT	movf TEMPO_TEMP,1  ; attente 50 trames image = 1s
		btfss Z
		goto TEMPOALT
;
WRITE_ALTITUDE btfss RAZ_ALTITUDE
	     goto WRITE_ALTITUDE2
             movf ALTITUDE,0              ; RAZ ALTITUDE relative
             movwf DELTA_ALTITUDE
             movf ALTITUDE + 1,0
             movwf DELTA_ALTITUDE + 1
	     call WRITE_DELTA_ALTITUDE
	     bcf RAZ_ALTITUDE
;
WRITE_ALTITUDE2 movf ALTITUDE,0
             movwf WORK_2
             movf ALTITUDE + 1,0
             movwf WORK_1
             movf DELTA_ALTITUDE,0
             movwf WORK_4
             movf DELTA_ALTITUDE + 1,0
             movwf WORK_3
             call SUB16
             movlw 05
             movwf WORK_8      ; init routine affichage: 5 digits
             btfss WORK_2,7    ; test signe de l'altitude
             goto TRAITE_EMISSION_32
             movf WORK_1,0
             movwf WORK_3
             movf WORK_2,0
             movwf WORK_4
             call NEG16
             movf WORK_4,0
             movwf WORK_2
             movf WORK_3,0
             movwf WORK_1
             bsf WORK_8,7    ; signe -
TRAITE_EMISSION_32 movf WORK_1,0
             movwf WORK_3
             movf WORK_2,0
             movwf WORK_1
             movf WORK_3,0
             movwf WORK_2
             call TRADUIT_BIN2_BCD
             movf WORK_5,0
             movwf WORK_7
             movf WORK_4,0
             movwf WORK_6
             clrf WORK_5
	     movlw BUFFER_CARACTERE
	     movwf AD_BUFFER
             call ECRIT_NOMBRE
WRITE_ALTITUDE_2 movlw 0E   ; 'm'
	     movwf BUFFER_CARACTERE + 5
;
	     goto BOUCLE
;---------------------------------------------------------------------------
; Reset du AD7714 par envoi de 32 bits successifs … 1
; Utilise WORK_1
RESET_AD     bcf PORTB,3      ; (_CS = 0)
             movlw d'32'
             movwf WORK_1
             bsf PORTB,4      ; MOSI = 1
RESET_AD_1   bsf PORTB,5
             nop
	     bcf PORTB,5      ; pulse de CLK
             decfsz WORK_1,1
             goto RESET_AD_1
             bsf PORTB,3      ; (_CS = 1)
             return
;---------------------------------------------------------------------------
; Sort les 8 bits contenus dans W sur le bus SPI
; Utilise WORK_1 et WORK_2
OUT_SPI      movwf WORK_1
             bcf PORTB,3      ; (_CS = 0)
             movlw d'8'
             movwf WORK_2
OUT_SPI_1    bsf PORTB,5
             btfss WORK_1,7   ; MSB en tête
             goto OUT_SPI_2
             bsf PORTB,4      ; MOSI = 1
             goto OUT_SPI_3
OUT_SPI_2    bcf PORTB,4      ; MOSI = 0
OUT_SPI_3    rlf WORK_1,1
             bcf PORTB,5      ; pulse de CLK
             decfsz WORK_2,1
             goto OUT_SPI_1
             bsf PORTB,3
             return
;---------------------------------------------------------------------------
; Lit 8 bits du bus SPI dans W et WORK_1
; Utilise WORK_1 et WORK_2
IN_SPI       bcf PORTB,3    ; _CS = 0
             movlw d'8'
             movwf WORK_2
IN_SPI_1     bsf PORTB,5    ; un coup de CLK
	     nop
	     nop	
             btfss PORTB,2
             goto IN_SPI_2
             bsf C
             goto IN_SPI_3
IN_SPI_2     bcf C
IN_SPI_3     rlf WORK_1,1
             bcf PORTB,5
             decfsz WORK_2,1
             goto IN_SPI_1
             bsf PORTB,3
             movf WORK_1,0
             return
;---------------------------------------------------------------------------
;ADDITION ET SOUSTRACTION DOUBLE PRECISION
; ADD16  WORK_2:WORK_1  + WORK_4:WORK_3   ---> WORK_2:WORK_1
;         msb    lsb       msb    lsb           msb    lsb
; SUB16  WORK_2:WORK_1  - WORK_4:WORK_3   ---> WORK_2:WORK_1
;         msb    lsb       msb    lsb           msb    lsb
SUB16        call NEG16
ADD16        movf WORK_3,0
             addwf WORK_1,1
             btfsc C
             incf WORK_2,1
             movf WORK_4,0
             addwf WORK_2,1
             retlw 0
;
NEG16        comf WORK_3,1
             incf WORK_3,1
             btfsc Z
             decf WORK_4,1
             comf WORK_4,1
             retlw 0
;---------------------------------------------------------------------------
; Multiplication 16 bits x 16 bits ---> 32 bits
;   WORK_2:WORK_1 x WORK_4:WORK_3 ---> WORK_4:WORK3;WORK_6:WORK_5
;    msb    lsb      msb    lsb         msb                 lsb
;   utilise WORK_7,WORK_8
MUL16X16     call MUL_SETUP
MUL_LOOP     rrf WORK_8,1
             rrf WORK_7,1
             btfsc C
             call MUL_ADD
             rrf WORK_4,1
             rrf WORK_3,1
             rrf WORK_6,1
             rrf WORK_5,1
             decfsz WORK_9,1
             goto MUL_LOOP
             retlw 0
;
MUL_SETUP    movlw d'16'
             movwf WORK_9
             movf WORK_4,0
             movwf WORK_8
             movf WORK_3,0
             movwf WORK_7
             clrf WORK_4
             clrf WORK_3
             retlw 0
;
MUL_ADD      movf WORK_1,0
             addwf WORK_3,1
             btfsc C
             incf WORK_4,1
             movf WORK_2,0
             addwf WORK_4,1
             retlw 0
;---------------------------------------------------------------------------
INIT_AD7714  call RESET_AD
             movlw 24      ; REGISTER HIGH: $20 + voie nø4
             call OUT_SPI
             movlw 0EF     ; 1110 1111  unipolaire, 24 bits, filtrage max
             call OUT_SPI
             movlw 34      ; REGISTER LOW: $30 + voie nø4
             call OUT_SPI
             movlw 0AF     ; 1010 0000  filtrage max
             call OUT_SPI
             return
;---------------------------------------------------------------------------
; traduit un mot binaire de 16 bits en 5 chiffres BCD
;    WORK_1:WORK_2   ---->  WORK_3,WORK_4,WORK_5
;     msb    lsb                D5  D4 D3  D2 D1
TRADUIT_BIN2_BCD bcf C
             movlw d'16'
             movwf WORK_6
             clrf WORK_3
             clrf WORK_4
             clrf WORK_5
TRADUIT_BIN2_BCD_LOOP rlf WORK_2,1
             rlf WORK_1,1
             rlf WORK_5,1
             rlf WORK_4,1
             rlf WORK_3,1
             decfsz WORK_6,1
             goto TRADUIT_BIN2_BCD_ADJDEC
             retlw 0
TRADUIT_BIN2_BCD_ADJDEC movlw WORK_5
             movwf FSR
             call TRADUIT_BIN2_BCD_ADJBCD
             movlw WORK_4
             movwf FSR
             call TRADUIT_BIN2_BCD_ADJBCD
             movlw WORK_3
             movwf FSR
             call TRADUIT_BIN2_BCD_ADJBCD
             goto TRADUIT_BIN2_BCD_LOOP
;
TRADUIT_BIN2_BCD_ADJBCD movlw 3
             addwf INDF,0
             movwf WORK_7
             btfsc WORK_7,3
             movwf INDF
             movlw 30
             addwf INDF,0
             movwf WORK_7
             btfsc WORK_7,7
             movwf INDF
             retlw 0
;---------------------------------------------------------------------------
; Ecrit dans l'adresse AD_BUFFER le nombre BCD ou HEXA
;  contenu dans WORK_5 (msb), WORK_6, WORK_7 (lsb).
;    le nombre de digit est dans WORK_8 (de 1 à 5),
;    le bit 7 de WORK_8 est à 1 si négatif.
; Utilise WORK_1 à WORK_9
ECRIT_NOMBRE movf AD_BUFFER,0	
	     movwf FSR
	     movlw 0F
             andwf WORK_8,0
             sublw 6
             movwf WORK_9
ECRIT_NOMBRE_1 call ECRIT_NOMBRE_SHIFT
             decfsz WORK_9,1
             goto ECRIT_NOMBRE_1
;
             movlw 0F
             andwf WORK_8,0
             movwf WORK_9
ECRIT_NOMBRE_4 btfss WORK_8,7
             goto ECRIT_NOMBRE_2
; traitement signe '-'
             movf WORK_9,0
             sublw 02
             btfsc Z
             goto ECRIT_NOMBRE_6  ; pour afficher -0
             movlw 0F
             andwf WORK_5,0
             btfsc Z
             goto ECRIT_NOMBRE_2   ; le nombre n+1 à afficher est 0
ECRIT_NOMBRE_6 bcf WORK_8,7
             movlw 0B
             goto ECRIT_NOMBRE_3
ECRIT_NOMBRE_2 swapf WORK_5,0
             andlw 0F
             btfss Z
             goto ECRIT_NOMBRE_5    ; digit non nul
             btfsc WORK_8,6
             goto ECRIT_NOMBRE_5
             decf WORK_9,0
             movlw 00A
             btfss Z
             goto ECRIT_NOMBRE_3
             movlw 000         ; on écrit le dernier 0
             goto ECRIT_NOMBRE_3
ECRIT_NOMBRE_5 bsf WORK_8,6    ; bit mettant fin au non affichage des zéros
ECRIT_NOMBRE_3 movwf INDF
	     incf FSR,1			
             call ECRIT_NOMBRE_SHIFT
             decfsz WORK_9,1
             goto ECRIT_NOMBRE_4
             return
;
ECRIT_NOMBRE_SHIFT movlw 4
             movwf WORK_4
ECRIT_NOMBRE_SHIFT_1 rlf WORK_7,1
             rlf WORK_6,1
             rlf WORK_5,1
             decfsz WORK_4,1
             goto ECRIT_NOMBRE_SHIFT_1
             return
;---------------------------------------------------------------------------
; tempo durant W + 0.5 en microseconde
TEMPO_1US    movwf WORK_IT1
TEMPO_1US1   nop
	     decfsz WORK_IT1,1
             goto TEMPO_1US1
             return
;---------------------------------------------------------------------------
; Tempo entre caractères
TEMPO_CAR    return
;---------------------------------------------------------------------------
TEMPO_4NOP	return
;---------------------------------------------------------------------------
; INITIALISATION DES VARIABLES APPLICATION
INIT_APPLI   	clrf STATUS_APPLI
		movlw 01
		movwf STATUS_LIGNE
		clrf CPTR_LIGNE
		clrf CPTR_LIGNE + 1
		movlw HAUTEUR_PIXEL
		movwf CPTR_PIXEL
;
; INIT AD7714
          	bsf PORTB,6       ; relachement du reset
             	call INIT_AD7714
;
                call INIT_DELTA_ALTITUDE
;
             	movlw HIGH TABLE_BITMAP
             	movwf PCLATCH          ; init pour la table read
;
		clrf STATUS_TEMP
;
		movlw 01
		movwf CPTR_AFFICHAGE
;
		movlw 010
		movwf BUFFER_CARACTERE
		movlw 011
		movwf BUFFER_CARACTERE + 1
		movlw 001
		movwf BUFFER_CARACTERE + 2
		movlw 009
		movwf BUFFER_CARACTERE + 3
		movlw 009
		movwf BUFFER_CARACTERE + 4
		movlw 009
		movwf BUFFER_CARACTERE + 5
             	return
;---------------------------------------------------------------------------
INIT_DELTA_ALTITUDE clrf EEADR
             call READ_EEPROM
             movwf DELTA_ALTITUDE
             incf EEADR,1
             call READ_EEPROM
             movwf DELTA_ALTITUDE + 1
             return
READ_EEPROM  bsf RP0
             bsf EECON1,0;  read
             bcf RP0
             movf EEDATA,0
             return
;---------------------------------------------------------------------------
WRITE_DELTA_ALTITUDE movf DELTA_ALTITUDE,0
             clrf EEADR
             call WRITE_EEPROM
             incf EEADR,1
             movf DELTA_ALTITUDE + 1,0
             call WRITE_EEPROM
             bcf RP0
             return
WRITE_EEPROM movwf EEDATA
             bsf RP0
             bcf GIE    ; incompatible PIC16C
             clrf EECON1
             bsf EECON1,2  ; write enable
             movlw 55
             movwf EECON2
             movlw 0AA
             movwf EECON2
             bsf EECON1,1  ; bit write
             bsf GIE
WRITE_EEPROM_1 btfsc EECON1,1
             goto WRITE_EEPROM_1   ; attente fin d'écriture en cours
             bcf EECON1,2  ; write disable
             bcf RP0
             return
;---------------------------------------------------------------------------
; W contient le numéro du caractère à charger
; FSR contient l'adresse de base du buffer source
CHARGE_CARACTERE movwf WORK_IT1
		addwf WORK_IT1,1
		addwf WORK_IT1,1
		addwf WORK_IT1,1
		addwf WORK_IT1,1 ; multiplication par 5
		movlw 05
		movwf WORK_IT2
CHARGE_CAR1	movf WORK_IT1,0		
		call TABLE_BITMAP
		movwf INDF
		incf FSR,1
		incf WORK_IT1,1
		decfsz WORK_IT2,1
		goto CHARGE_CAR1
		return
;---------------------------------------------------------------------------
; Table des caractères (caractères 5x7, patterns type afficheur LCD)
; PCL est préinitialisé dans les init communes application
; ATTENTION: appel indispensable sous IT interdites
; ne jamais dépasser 128 codes
             	org d'933'  ; 1024 - 20 * 5 - 1 (20 caractères max)
TABLE_BITMAP	addwf PCL,1
; 0
         	retlw 03E   
         	retlw 051
		retlw 049
		retlw 045
		retlw 03E
; 1
		retlw 000
		retlw 042
		retlw 07F
		retlw 040
		retlw 000
; 2
		retlw 042
		retlw 061
		retlw 051
		retlw 049
		retlw 046
; 3
		retlw 021
		retlw 041
		retlw 045
		retlw 04B
		retlw 031
; 4
		retlw 018
		retlw 014
		retlw 012
		retlw 07F
		retlw 010
; 5
		retlw 027
		retlw 045
		retlw 045
		retlw 045
		retlw 039
; 6
		retlw 03C
		retlw 04A
		retlw 049
		retlw 049
		retlw 030
; 7
		retlw 001
		retlw 071
		retlw 009
		retlw 005
		retlw 003
; 8
		retlw 036
		retlw 049
		retlw 049
		retlw 049
		retlw 036
; 9
		retlw 006
		retlw 049
		retlw 049
		retlw 029
		retlw 01E
; ' ' 0A
		retlw 000
		retlw 000
		retlw 000
		retlw 000
		retlw 000
; -  0B
		retlw 008
		retlw 008
		retlw 008
		retlw 008
		retlw 008
; °  0C
		retlw 000
		retlw 007
		retlw 005
		retlw 007
		retlw 000
; C  0D
		retlw 03E
		retlw 041
		retlw 041
		retlw 041
		retlw 022
; m   0E
		retlw 07C
		retlw 004
		retlw 018
		retlw 004
		retlw 078
; .   0F
		retlw 000
		retlw 060
		retlw 060
		retlw 000
		retlw 000
; O   10
		retlw 03E
		retlw 041
		retlw 041
		retlw 041
		retlw 03E
; H   11
		retlw 07F
		retlw 008
		retlw 008
		retlw 008
		retlw 07F
;---------------------------------------------------------------------------
	     	end
