;*****************************************************************************
;   Projet de stack de communication EIB, ayant les fonctionnalités de base  *
;   d'un BCU1/2 sur base d'un PIC 16F877A et d'un TP-UART.                   *
;                                                                            *  
;                                                                            *
;*****************************************************************************
;                                                                            *
;    NOM:     Stack EIB simplifié sur 877A et TP-UART                        *
;    Date:    2007, aôut, 21                                                 *
;    Version: 0.0.1                                                          *
;    Circuit: aucun pour l'instant                                           *
;    Auteur:  Pierre-Yves Keldermans (+ certaines routines de Bigonoff)      *
;                                                                            *
;*****************************************************************************
;                                                                            *
;    Fichier requis: P16F877A.inc                                            *
;                                                                            *
;                                                                            *
;                                                                            *
;*****************************************************************************
;                                                                            *
;    Notes:                                                                  *
;    Le but de cette version 0.0.1 est d'obtenir les fonctions suivantes :   *
;    - réception d'une valeur d'un objet de comm. depuis un télégramme du    *
;      bus et stockage de cette valeur en RAM.                               *
;    - lecture de la valeur d'un objet depuis le bus.                        *
;    - tout le contenu des tables EIB est stocké dans le PIC avec l'ICD2.    *
;                                                                            *
;	Il est important de comprendre que la totalité du stack EIB est traité   *
;	durant les interruptions. En fonctionnement normal, seule l'application  *
;	"tourne", sauf si elle appelle elle-même une routine EIB.                *
;	Le fonctionnement du stack EIB est assuré par des variables qui          *
;	indiquent dans quel "états" sont les "state machines".                   *
;	Cette architecture implique que le PIC va passer beaucoup de temps       *
;	dans les routines d'interruption, c'est pourquoi une gestion sur trois   *
;	niveaux de priorité m'a semblé nécessaire.                               *
;                                                                            *
;	Une fois le stack EIB démarré, les interruptions ne doivent plus être    *
;	désactivée sauf pour une très courte période durant les sections de      *
;	code "critiques".														 *
;                                                                            *
;*****************************************************************************

;	ERRORLEVEL -302			; suppression du message bank select 
	LIST      p=16F877a            ; Définition de processeur
	#include <P16F877A.INC>        ; fichier include
;	#include <"C:\Program Files\Microchip\MPASM Suite\P16F877A.INC">        ; fichier include


	__CONFIG   _CP_OFF & _DEBUG_ON & _WRT_OFF & _CPD_OFF & _LVP_OFF & _BODEN_OFF & _PWRTE_ON & _WDT_OFF & _HS_OSC 

; '__CONFIG' précise les paramètres encodés dans le processeur au moment de
; la programmation du processeur. Les définitions sont dans le fichier include.
; Choisir une valeur par groupe.
; Voici les valeurs et leurs définitions :

; Protection du programme en lecture
; -----------------------
;_CP_ALL		protection totale
;_CP_OFF		Pas de protection

; Debuggage
; ---------
;_DEBUG_ON		RB6 et RB7 utilisées pour debugger
;_DEBUG_OFF		RB6 et RB7 en utilisation normale

; Accès à la flash programme
; --------------------------

;_WRT_OFF			Le programme peut écrire dans la flash
;_WRT_256			Le programme ne peut pas écrire dans la flash dans les 256 premier octets
;_WRT_1FOURTH		Le programme ne peut pas écrire dans la flash dans le premier quart
;_WRT_HALF			Le programme ne peut pas écrire dans la flash dans la premiere moitiée

; Protection de la EEprom
; -----------------------

;_CPD_ON			Mémoire EEprom protégée
;_CPD_OFF           Mémoire EEprom déprotégée

; Programmation sur circuit
; -------------------------

;_LVP_ON		RB3 permet la programmation série de la PIC
;_LVP_OFF		RB3 en utilisation normale

; Reset de la PIC si tension <4V
; ------------------------------
; _BODEN_ON		Reset tension en service
;			Valide PWRTE_ON automatiquement
; _BODEN_OFF		Reset tension hors service

; Retard à la mise sous tension
; -----------------------------

;_PWRTE_OFF		Démarrage rapide
;_PWRTE_ON		Démarrage temporisé

; Watchdog
; --------

;_WDT_ON		Watchdog en service
;_WDT_OFF		Watchdog hors service

; Oscillateur
; -----------
;_LP_OSC		Oscillateur basse vitesse (32<F<200Khz)
;_XT_OSC		Oscilateur moyenne vitesse (200Khz<F<4Mhz)
;_HS_OSC		Oscillateur haute vitesse (4Mhz<F<20Mhz)
;_RC_OSC		Oscillateur à réseau RC

;*****************************************************************************
;                               ASSIGNATIONS SYSTEME                         *
;*****************************************************************************

; REGISTRE OPTION_REG (configuration)
; -----------------------------------
OPTIONVAL	EQU	B'00001100'
;           Bit n°76543210
			; RBPU     b7 : 1= Résistance rappel +5V hors service
			; INTEDG   b6 : 1= Interrupt sur flanc montant de RB0
			;               0= Interrupt sur flanc descend. de RB0
			; TOCS      b5 : 1= source clock = transition sur RA4
			;                0= horloge interne
			; TOSE      b4 : 1= Sélection flanc montant RA4(si B5=1)
			;                0= Sélection flanc descendant RA4
			; PSA       b3 : 1= Assignation prédiviseur sur Watchdog
			;                0= Assignation prédiviseur sur Tmr0
			; PS2/PS0   b2/b0 valeur du prédiviseur
            ;           000 =  1/1 (watchdog) ou 1/2 (tmr0)
			;           001 =  1/2               1/4
			;           010 =  1/4			     1/8
			;           011 =  1/8			     1/16
			;           100 =  1/16			     1/32
			;           101 =  1/32			     1/64
			;           110 =  1/64			     1/128
			;           111 =  1/128		     1/256


; REGISTRE INTCON (contrôle interruptions standard)
; -------------------------------------------------
INTCONVAL	EQU	B'01000000'
;           Bit n°76543210
			; GIE       b7 : masque autorisation générale interrupt
                        ;                ne pas mettre ce bit à 1 ici
                        ;                sera mis en temps utile
			; PEIE      b6 : masque autorisation générale périphériques
			; T0IE      b5 : masque interruption tmr0
			; INTE      b4 : masque interuption RB0/Int
			; RBIE      b3 : masque interruption RB4/RB7
			; T0IF      b2 : flag tmr0
			; INTF      b1 : flag RB0/Int
			; RBIF      b0 : flag interruption RB4/RB7

; REGISTRE PIE1 (contrôle interruptions périphériques)
; ----------------------------------------------------
PIE1VAL		EQU	B'00000000'
;           Bit n°76543210
			; PSPIE     b7 : masque interrupt rx/tx sur port parallèle esclave
			; ADIE      b6 : masque interrupt convertisseur A/D
			; RCIE      b5 : masque interrupt réception USART
			; TXIE      b4 : masque interrupt transmission USART
			; SSPIE     b3 : masque interrupt port série synchrone
			; CCP1IE    b2 : masque interrupt CCP1
			; TMR2IE    b1 : masque interrupt TMR2 = PR2
			; TMR1IE    b0 : masque interrupt débordement tmr1

; REGISTRE PIE2 (contrôle interruptions particulières)
; ----------------------------------------------------
PIE2VAL		EQU	B'00000000'
;           Bit n°76543210
			; UNUSED    b7 : inutilisé, laisser à 0
			; CMIE      b6 : masque interrupt comparateur
			; UNUSED    b5 : inutilisé, laisser à 0
			; EEIE      b4 : masque interrupt écriture EEPROM
			; BCLIE     b3 : masque interrupt collision bus
			; UNUSED    b2 : inutilisé, laisser à 0
			; UNUSED    b1 : inutilisé, laisser à 0
			; CCP2IE    b0 : masque interrupt CCP2

; REGISTRE CMCON (COMPARATEURS)
; ------------------------------------
CMCONVAL	EQU	B'00000111' 
;           Bit n°76543210
			; C2OUT	    b7 :sortie comparateur2
			; C1OUT     b6 :sortie comparateur1
			; C2INV     b5 :inverseur comparateur2
			; C1INV     b4 :inverseur comparateur1
			; CIS       b3 :selection entree des comparateurs
			; CM2-CM0   b2-0 :mode des comparateurs
			;configurer le mode 111 pour utiliser RA0 RA1 RA2 RA3 en I/O

; REGISTRE VRCON (voltage reference module)
; ------------------------------------
CVRCONVAL	EQU	B'00000000'
;           Bit n°76543210
			; CVREN     b7 :Validation du module
			; CVROE     b6 :Sortie sur RA2
			; CVRR      b5 :Choix de la plage 
			; RESERVED  b4 : réservé, laisser à 0
			; CVR3-CVR0 b3-0 :Choix de la valeur dans la plage 
					; si CVRR=1 CVREF=(VR[3:0]/24)*Vdd
					; si CVRR=0 CVREF=(1/4*Vdd)+(VR[3:0]/32)*Vdd

; REGISTRE ADCON1 (ANALOGIQUE/DIGITAL)
; ------------------------------------
ADCON1VAL	EQU	B'00000110' ; PORTA en mode digital
;           Bit n°76543210

; DIRECTION DES PORTS I/O
; -----------------------

DIRPORTA	EQU	B'11111111'	; Direction PORTA (1=entrée)
DIRPORTB	EQU	B'11111111'	; Direction PORTB
DIRPORTC	EQU	B'11111111'	; Direction PORTC
DIRPORTD	EQU	B'11111111'	; Direction PORTD
DIRPORTE	EQU	B'00000111'	; Direction PORTE
;           Bit n°76543210


;*****************************************************************************
;                           ASSIGNATIONS PROGRAMME                           *
;*****************************************************************************

; Pour le stack EIB
; -----------------
MAXOBJ			EQU D'32'
MAXOBJ_SIZE		EQU D'5'
MAXADR			EQU D'128'
MAXADR_SIZE		EQU D'7'
MAXASO			EQU D'15'
MAXASO_SIZE		EQU D'4'
MAXVAL			EQU D'128'
MAXVAL_SIZE		EQU D'7'


; Définition des codes d'erreur
; -----------------------------
; Ne pas utiliser 1 et 2 comme valeurs, c'est trop facile à confondre
; avec le mode "clignotant" en EIB, quand on cherche à identifier un BCU
; visuellement


WTDG_ERROR_CODE		EQU D'3'	;Le watchdog a fait rebooter le PIC.
RXBUFF_ERROR_CODE	EQU D'4'	;Le buffer de réception de l'UART a débordé,
								; le PIC n'est assez rapide, il faut optimiser
								; le code ou prendre un PIC plus rapide.
RXBUG_ERROR_CODE	EQU D'5'	;Il y a un bug dans la routine de reception,
								; le byte recu n'a pas ete reconnu.

TEMPWAR_ERROR_CODE	EQU D'9'	;Le TP-UART a surchauffé, prévoir un radiateur
								; et/ou une ventilation pour lui
INT_ERROR_CODE		EQU D'10'	;Interruption non prévue. (faible chance d'apparaitre)







; Pour la gestion des interrutions sur 3 niveaux de priorité
; ----------------------------------------------------------
; Mettre le bit à 1 si l'interrution est gèrée au niveau 2 / niveau 3
; Masques INTCON (contrôle interruptions standard)
INTCON_mask_2	EQU	B'00000000'
INTCON_mask_3	EQU	B'00000000'
			;	Bit n°xx543xxx
			; T0IE      b5 : masque interruption tmr0
			; INTE      b4 : masque interuption RB0/Int
			; RBIE      b3 : masque interruption RB4/RB7
			; laisser les autres bits tel quels
; Masques PIE1 (contrôle interruptions périphériques)
PIE1_mask_2		EQU	B'00000000'
PIE1_mask_3		EQU	B'00000000'
			;	Bit n°76543210
			; PSPIE     b7 : masque interrupt rx/tx sur port parallèle esclave
			; ADIE      b6 : masque interrupt convertisseur A/D
			; RCIE      b5 : masque interrupt réception USART
			; TXIE      b4 : masque interrupt transmission USART
			; SSPIE     b3 : masque interrupt port série synchrone
			; CCP1IE    b2 : masque interrupt CCP1
			; TMR2IE    b1 : masque interrupt TMR2 = PR2
			; TMR1IE    b0 : masque interrupt débordement tmr1
; Masque PIE2 (contrôle interruptions particulières)
PIE2_mask_2		EQU	B'00000000'
PIE2_mask_3		EQU	B'00000000'
			;	Bit n°x6x43xx0
			; CMIE      b6 : masque interrupt comparateur
			; EEIE      b4 : masque interrupt écriture EEPROM
			; BCLIE     b3 : masque interrupt collision bus
			; CCP2IE    b0 : masque interrupt CCP2
			; laisser les autres bits tel quels







;*****************************************************************************
;                                  DEFINE                                    *
;*****************************************************************************

#DEFINE  UART_Rx_pin	PORTC,7
#DEFINE  UART_Tx_pin	PORTC,6


;*****************************************************************************
;                             MACRO                                          *
;*****************************************************************************

BANK0	macro				; passer en banque0
		bcf	STATUS,RP0
		bcf	STATUS,RP1
	endm

BANK1	macro				; passer en banque1
		bsf	STATUS,RP0
		bcf	STATUS,RP1
	endm

BANK2	macro				; passer en banque2
		bcf	STATUS,RP0
		bsf	STATUS,RP1
	endm

BANK3	macro				; passer en banque3
		bsf	STATUS,RP0
		bsf	STATUS,RP1
	endm




			; Sauts inter-pages
			; -----------------

GOTOX	macro	ADRESSE			; saut inter-page
	local BIT4 = (ADRESSE & 0x1000)	; voir bit 12
	local BIT3 = (ADRESSE & 0x0800) ; voir bit 11
	local	ICI			; adresse courante
ICI
	local PICI = (ICI+2 & 0x1800)	; page du saut
	IF BIT3				; si page 1 ou 3
	bsf	PCLATH , 3		; b3 de PCLATH = 1
	ELSE				; sinon
	bcf	PCLATH , 3		; b3 de PCLATH = 0
	ENDIF
	IF BIT4				; si page 2 ou 3
	bsf	PCLATH , 4		; b4 de PCLATH = 1
	ELSE				; sinon
	bcf	PCLATH , 4		; b4 de PCLATH = 0
	ENDIF
	goto (ADRESSE & 0x7FF | PICI)	; adresse simulée
	endm


PCLAX	macro	ADRESSE			; positionne PCLATH pour
					; les sauts sans le saut
	local BIT4 = (ADRESSE & 0x1000)	; voir bit 12
	local BIT3 = (ADRESSE & 0x0800) ; voir bit 11

	IF BIT3				; si page 1 ou 3
	bsf	PCLATH , 3		; b3 de PCLATH = 1
	ELSE				; sinon
	bcf	PCLATH , 3		; b3 de PCLATH = 0
	ENDIF
	IF BIT4				; si page 2 ou 3
	bsf	PCLATH , 4		; b4 de PCLATH = 1
	ELSE				; sinon
	bcf	PCLATH , 4		; b4 de PCLATH = 0
	ENDIF
	endm

GOTSX	macro	ADRESSE			; saut inter-page sans
					; sélection de PCLATH
	local	ICI			; adresse courante
	local PICI = (ICI & 0x1800)	; page du saut
ICI
	goto (ADRESSE & 0x7FF | PICI)	; adresse simulée
	endm

			; Sous-routines inter-pages
			; -------------------------

CALLX	macro	ADRESSE			; call inter-page
	local BIT4 = (ADRESSE & 0x1000)	; voir bit 12
	local BIT3 = (ADRESSE & 0x0800) ; voir bit 11
	local	ICI			; adresse courante
ICI
	local PICI = (ICI+2 & 0x1800)	; page du saut
	IF BIT3				; si page 1 ou 3
	bsf	PCLATH , 3		; b3 de PCLATH = 1
	ELSE				; sinon
	bcf	PCLATH , 3		; b3 de PCLATH = 0
	ENDIF
	IF BIT4				; si page 2 ou 3
	bsf	PCLATH , 4		; b4 de PCLATH = 1
	ELSE				; sinon
	bcf	PCLATH , 4		; b4 de PCLATH = 0
	ENDIF
	call (ADRESSE & 0x7FF | PICI)	; adresse simulée
	local BIT4 = ((ICI+5) & 0x1000)	; voir bit 12
	local BIT3 = ((ICI+5) & 0x0800)	; voir bit 11
	IF BIT3				; si page 1 ou 3
	bsf	PCLATH , 3		; b3 de PCLATH = 1
	ELSE				; sinon
	bcf	PCLATH , 3		; b3 de PCLATH = 0
	ENDIF
	IF BIT4				; si page 2 ou 3
	bsf	PCLATH , 4		; b4 de PCLATH = 1
	ELSE				; sinon
	bcf	PCLATH , 4		; b4 de PCLATH = 0
	endm


CALLSX	macro	ADRESSE			; sous-routine inter-page sans
					; sélection de PCLATH
	local	ICI			; adresse courante
	local PICI = (ICI & 0x1800)	; page du saut
ICI
	call (ADRESSE & 0x7FF | PICI)	; adresse simulée
	endm

			; Sous-routines eeprom
			; --------------------
REEPROM macro				; lire eeprom(adresse & résultat en w)
		clrwdt			; reset watchdog
		bcf	STATUS,RP0	; passer en banque2
		bsf	STATUS,RP1
		movwf	EEADR		; pointer sur adresse eeprom
		bsf	STATUS,RP0	; passer en banque3
		bcf	EECON1,EEPGD	; pointer sur eeprom
		bsf	EECON1,RD	; ordre de lecture
		bcf	STATUS,RP0	; passer en banque2
		movf	EEDATA,w	; charger valeur lue
		bcf	STATUS,RP1	; passer en banque0
	endm


WEEPROM	macro	addwrite		; la donnée se trouve dans W
	LOCAL	loop
	bcf	STATUS,RP0		; passer en banque2
	bsf	STATUS,RP1
	movwf	EEDATA			; placer data dans registre
	movlw	addwrite		; charger adresse d'écriture
	movwf	EEADR			; placer dans registre
	bsf	STATUS,RP0		; passer en banque3
	bcf	EECON1 , EEPGD		; pointer sur mémoire data
	bsf	EECON1 , WREN		; autoriser accès écriture
	bcf	INTCON , GIE		; interdire interruptions
	movlw	0x55			; charger 0x55
	movwf	EECON2			; envoyer commande
	movlw	0xAA			; charger 0xAA
	movwf	EECON2			; envoyer commande
	bsf	EECON1 , WR		; lancer cycle d'écriture
	bsf	INTCON , GIE		; réautoriser interruptions
loop
	btfsc	EECON1 , WR		; tester si écriture terminée
	goto	loop			; non, attendre
	bcf	EECON1 , WREN		; verrouiller prochaine écriture
	bcf	STATUS , RP0		; passer en banque0
	bcf	STATUS , RP1
	endm


; ////////////////////////////////////////////////////////////////////////////

;                     V A R I A B L E S   E N   R A M 

; ////////////////////////////////////////////////////////////////////////////

; Le stack EIB utilise les banques 2 et 3 pour ses variables en RAM.
; L'application utilisera la banque 0.
; La banque 1 est réservée pour l'instant.


;*****************************************************************************
;                      VARIABLES ZONE COMMUNE                                *
;*****************************************************************************

; Zone de 16 bytes
; ----------------

	CBLOCK 0x70			; Début de la zone (0x70 à 0x7F)
	; Variables pour sauvegarde des paramètres en cas d'interruption
	w_temp : 1			; Sauvegarde registre W
	STATUS_temp : 1		; sauvegarde registre STATUS
	FSR_temp : 1		; sauvegarde FSR (si indirect en interrupt)
	PCLATH_temp : 1		; sauvegarde PCLATH (si prog>2K)

	ENDC
;*****************************************************************************
;                        VARIABLES BANQUE 0                                  *
;*****************************************************************************

; Zone de 80 bytes
; ----------------

	CBLOCK	0x20		; Début de la zone (0x20 à 0x6F)


;Exemples
;--------
;	test :1			; Zone de 1 byte
;	table : 10		; zone de 10 bytes

        ENDC			; Fin de la zone                        
;Exemples
;--------
;var1 	EQU H'006E'		; adresse imposée



;*****************************************************************************
;                        VARIABLES BANQUE 1                                  *
;*****************************************************************************

; Zone de 80 bytes
; ----------------

	CBLOCK	0xA0		; Début de la zone (0xA0 à 0xEF)

	ENDC			; Fin de la zone                        

;*****************************************************************************
;                        VARIABLES BANQUE 2                                  *
;*****************************************************************************

; Zone de 96 bytes
; ----------------

	CBLOCK	0x110	; Début de la zone (0x110 à 0x11F)
	; Variables pour sauvegarde des paramètres en cas d'interruption de niveau 2 (priorité moyenne)
	w_temp_2 :		1		; Sauvegarde registre W
	STATUS_temp_2 :	1		; sauvegarde registre STATUS
	FSR_temp_2 :	1		; sauvegarde FSR (si indirect en interrupt)
	PCLATH_temp_2 :	1		; sauvegarde PCLATH (si prog>2K)
	INTCON_temp_2 :	1		; sauvegarde des bits de INTCOM qui ont été désactivés
							; temporairement durant le traitement de l'interruption de niveau 2
	PIE1_temp_2 :	1		; idem pour PIE1
	PIE2_temp_2 :	1		; idem pour PIE2
	PIR1_temp_2 :	1		; idem pour PIR1
	PIR2_temp_2 :	1		; idem pour PIR2
	ENDC			; Fin de la zone


	CBLOCK	0x120	; Début de la zone (0x120 à 0x16F)
					; zone réservée pour le stack EIB (valeur des objets)
	ENDC			; Fin de la zone                        


;*****************************************************************************
;                        VARIABLES BANQUE 3                                  *
;*****************************************************************************

; Zone de 96 bytes
; ----------------

	CBLOCK	0x190	; Début de la zone (0x190 à 0x19F)
	; Variables pour sauvegarde des paramètres en cas d'interruption de niveau 3 (priorité basse)
	w_temp_3 :		1		; Sauvegarde registre W
	STATUS_temp_3 :	1		; sauvegarde registre STATUS
	FSR_temp_3 :	1		; sauvegarde FSR (si indirect en interrupt)
	PCLATH_temp_3 :	1		; sauvegarde PCLATH (si prog>2K)
	INTCON_temp_3 :	1		; sauvegarde des bits de INTCOM qui ont été désactivés
							; temporairement durant le traitement de l'interruption de niveau 3
	PIE1_temp_3 :	1		; idem pour PIE1
	PIE2_temp_3 :	1		; idem pour PIE2
	PIR1_temp_3 :	1		; idem pour PIR1
	PIR2_temp_3 :	1		; idem pour PIR2

	GrpAdrSrch_b3 :	2		; Adresse de groupe recherchée pour réponse ACK/NACK/BUSY
	ENDC			; Fin de la zone                        


	CBLOCK	0x1A0	; Début de la zone (0x1A0 à 0x1EF)
					; zone réservée pour le stack EIB (valeur des objets)
	ENDC			; Fin de la zone                        



;*****************************************************************************
;                      DEMARRAGE SUR RESET                                   *
;*****************************************************************************

	org 0x000 			; Adresse de départ après reset
	clrf    PCLATH		; Effacer sélecteur de pages
  	goto    PIC_Start	; Initialiser











; ////////////////////////////////////////////////////////////////////////////

;                         I N T E R R U P T I O N S

; ////////////////////////////////////////////////////////////////////////////

;*****************************************************************************
;                         ROUTINE INTERRUPTION                               *
;                                                                            *
;      Attention, ce software crée 3 niveaux d'interruption imbriqués        *
;                         ce qui signifie que                                *
;   LA LIMITE D'IMBRICATION DES PROCEDURES EST DE 5 MAXIMUM et non 7 ou 8 !  *
;*****************************************************************************
;-----------------------------------------------------------------------------
; Si on n'utilise pas l'adressage indirect dans les interrupts, on se passera
; de sauvegarder FSR
; Si le programme ne fait pas plus de 2K, on se passera de la gestion de 
; PCLATH
;-----------------------------------------------------------------------------

	org 0x004			; vecteur d'interruption

			;sauvegarder registres	
			;---------------------
	movwf   w_temp  	; sauver registre W
	swapf	STATUS,w	; swap status avec résultat dans w
	movwf	STATUS_temp	; sauver status swappé
	movf	PCLATH , w	; charger PCLATH
	movwf	PCLATH_temp	; le sauver


;-----------------------------------------------------------------------------
; Gestion des interrutions sur 3 niveaux de priorité.
;-----------------------------------------------------------------------------
; Niveau 1 = priorité la plus élévée, pour les évènements qui doivent être
; traités très rapidement après leur apparition.
; N.B.: pas de sauvegarde de FSR prévue à ce niveau -> ! ne pas modifier FSR !
;-----------------------------------------------------------------------------
; Pour cette application le TMR0 sera utilisé sans prédiviseur (qui sera 
; réservé pour le watchdog) et servira d'horloge de très haute précision.
; Comme une interruption TMR0 apparaitra tous les 256 cycles, il est capital
; que le code soit le plus court et rapide possible, maximum une 20aine de
; cycles la pluspart du temps, sinon le PIC sera paralysé par cette interrupt.
;-----------------------------------------------------------------------------

Int_level_1
			; Interruption TMR0
			; -----------------

	clrf	PCLATH			; on est en page 0
	BANK0					; passer en banque0
	btfsc	INTCON,T0IE		; tester si interrupt timer autorisée
	btfss	INTCON,T0IF		; oui, tester si interrupt timer en cours
	goto 	Intlevel_2		; non, passer aux interrupt de niveau 2





			; placer ici le code pour l'interruption Timer 0
			; XXX


	bcf		INTCON,T0IF		; effacer flag interrupt tmr0
	




			;restaurer registres et quitter l'interrution de niveau 1
			;--------------------------------------------------------

	movf	PCLATH_temp,w	; recharger ancien PCLATH
	movwf	PCLATH			; le restaurer
	swapf	STATUS_temp,w	; swap ancien status, résultat dans w
	movwf   STATUS			; restaurer status
	swapf   w_temp,f		; Inversion L et H de l'ancien W
                       		; sans modifier Z
	swapf   w_temp,w  		; Réinversion de L et H dans W
							; W restauré sans modifier status
	retfie  				; return from interrupt de niveau 1




;-----------------------------------------------------------------------------
; Niveau 2 = priorité moyenne, pour les évènements qui doivent être traités
; rapidement après leur apparition.
; Si une interrution de niveau 1 apparait, le traitement de niveau 2 sera
; mis en attente pour traiter le niveau 1 en priorité.
;-----------------------------------------------------------------------------
; Ce niveau sera utilisé pour la gestion de l'UART.
;-----------------------------------------------------------------------------


Int_level_2

			; sauvegardons avant tout FSR, ce que nous n'avions pas fait en
			; niveau 1 afin de gagner 2 cycles du CPU.
			;--------------------------------------------------------------
	movf	FSR,w			; charger FSR
	movwf	FSR_temp		; sauvegarder FSR



;	XXX  :  ici, premier screening pour voir si il y a une interruption de niveau 2
;				si non,    goto Int_level_3
;				si oui, continuer le traitement dans le niveau 2



Int_level_2_cont

			; Sauvegardons W, STATUS, FSR et PCLATH une seconde fois afin
			; de les protèger si une int. de niveau 1 survient.
			;---------------------------------------------------------------------
	clrf	PCLATH			; on est en page 0
	BANK2					; passer en banque 2
	movf	w_temp,w		; charger w_temp
	movwf   w_temp_2  		; sauver dans w_temp2
	movf	STATUS_temp,w	; charger STATUS_temp
	movwf   STATUS_temp_2  	; sauver dans STATUS_temp2
	movf	FSR_temp,w		; charger FSR_temp
	movwf   FSR_temp_2  	; sauver dans FSR_temp2
	movf	PCLATH_temp,w	; charger PCLATH_temp
	movwf   PCLATH_temp_2  	; sauver dans PCLATH_temp2




			; Sauvegardons les 5 registres liés aux interruptions (filtrés)
			;---------------------------------------------------------------------



			; Modifions les 5 mêmes registres pour ne laisser que les
			; interruptions de niveau 1 autorisées
			;---------------------------------------------------------------------



			; Finalement, ré-activons les interruptions
			;---------------------------------------------------------------------
	bsf		INTCON,GIE		; ré-activer les interruptions de niveau 1




			; divers tests pour vérifier les cas des int. de niveau 2 hors PEIE

			; XXX



			; Suivent les interruptions de niveau 2 qui dépendent de PEIE

	btfss	INTCON,PEIE	; tester si interruptions périphériques autorisées
	goto	End_Int_level_2	; non, fin d'interruption niveau 2
							; oui, continuer

			; Interruption réception USART
			; ----------------------------
Int_level_2_UART_Rx
	BANK1				; sélectionner banque1
	btfss	PIE1,RCIE	; tester si interrupt autorisée
	goto 	End_Int_level_2_UART_Rx		; non sauter
	BANK0				; oui, sélectionner banque0
	btfss	PIR1,RCIF	; tester si interrupt en cours
	goto 	End_Int_level_2_UART_Rx		; non sauter
	call	IntRx		; oui, traiter interrupt
				; LE FLAG NE DOIT PAS ETRE REMIS A 0
				; C'EST LA LECTURE DE RCREG QUI LE PROVOQUE
End_Int_level_2_UART_Rx

			; Interruption transmission USART
			; -------------------------------
Int_level_2_UART_Tx
	BANK1				; sélectionner banque1
	btfss	PIE1,TXIE	; tester si interrupt autorisée
	goto 	End_Int_level_2_UART_Tx		; non, alors sauter
	BANK0				; oui, alors sélectionner banque0
	btfss	PIR1,TXIF	; tester si interrupt en cours
	goto 	End_Int_level_2_UART_Tx		; non, alors sauter
	call	inttx		; oui, alors traiter interrupt
				; LE FLAG NE DOIT PAS ETRE REMIS A 0
				; C'EST L'ECRITURE DE TXREG QUI LE PROVOQUE
End_Int_level_2_UART_Tx


; XXX : ajouter ici le traitement pour les autres int. liées à PEIE
;		Toujours entourer chaque petit "bloc" de 2 labels de debut et de fin,
;		 dans le but de facilement reorganiser l'ordre (et donc la priorite) des blocs.


			;Quitter l'interrution de niveau 2 : restaurer tous les registres
			;----------------------------------------------------------------
End_Int_level_2

	bcf		INTCON,GIE		; dé-activer les interruptions de niveau 1


			; Restaurons les 5 registres liés aux interruptions dans
			; leur état précédent afin de ré-autoriser les interruptions
			; niveau 2 et éventuellement 3 (grace aux filtres)
			;---------------------------------------------------------------------
	

; XXX

			; Restaurons les 4 registres principaux
			;---------------------------------------------------------------------

	BANK2
	movf	PCLATH_temp_2,w	; recharger ancien PCLATH
	movwf	PCLATH			; le restaurer
	movf	FSR_temp_2,w	; charger FSR sauvé
	movwf	FSR				; restaurer FSR
	swapf	STATUS_temp_2,w	; swap ancien status, résultat dans w
	movwf   STATUS			; restaurer status
	swapf   w_temp_2,f		; Inversion L et H de l'ancien W
                       		; sans modifier Z
	swapf   w_temp_2,w 		; Réinversion de L et H dans W
							; W restauré sans modifier status

	retfie  				; return from interrupt de niveau 2



;-----------------------------------------------------------------------------
; Niveau 3 = priorité la plus basse, pour les évènements qui doivent être
; traités prioritairement par rapport à l'application normale mais dont le
; traitement risque de durer longtemps (relativement à la vitesse d'un PIC)
; et perturberait le traitement des autres interruptions si il fonctionnait
; avec le même niveau de priorité.
; Si une interrution de niveau 1 ou 2 apparait, le traitement de niveau 3 sera
; mis en attente pour traiter le niveau 1 ou 2 en priorité.
;-----------------------------------------------------------------------------
; Ce niveau sera utilisé pour traiter la recherche d'une adresse de groupe
; dans la table des adresses de groupe afin d'envoyer ou non un ACK/NACK/BUSY.
;-----------------------------------------------------------------------------

Int_level_3

			; Sauvegardons W, STATUS, FSR et PCLATH une troisième fois
			; afin de les protèger si une int. de niveau 1 ou 2 survient.
			;------------------------------------------------------------
	clrf	PCLATH			; on est en page 0
	BANK3					; passer en banque 3
	movf	w_temp,w		; charger w_temp
	movwf   w_temp_3  		; sauver dans w_temp_3
	movf	STATUS_temp,w	; charger STATUS_temp
	movwf   STATUS_temp_3  	; sauver dans STATUS_temp_3
	movf	FSR_temp,w		; charger FSR_temp
	movwf   FSR_temp_3  	; sauver dans FSR_temp_3
	movf	PCLATH_temp,w	; charger PCLATH_temp
	movwf   PCLATH_temp_3  	; sauver dans PCLATH_temp_3





;	XXX  :  ici, premier screening pour voir si il y a une interruption de niveau 3
;				si non,    goto Int_error   ; il y a eu une interruption non prévue ...
;				si oui, continuer le traitement dans le niveau 3




Int_level_3_cont

			; Sauvegardons les 5 registres liés aux interruptions
			;---------------------------------------------------------------------



			; Modifions les 5 mêmes registres pour ne laisser que les
			; interruptions de niveau 1 et 2 autorisées (filtrés)
			;---------------------------------------------------------------------



			; Finalement, ré-activons les interruptions
			;---------------------------------------------------------------------
	bsf		INTCON,GIE		; ré-activer les interruptions de niveau 1 et 2



			; divers tests pour vérifier et traiter les cas des int. de niveau 3
			;
			; Cas 1) --> Recherche d'adresse de groupe en memoire
			;		


			;
			; Cas 2) --> Des nouvelles donnees sont arrivees, il faut les traiter
			;		a) Copier les buffers adresses et data vers les variables tampons.
			;		b) Sauvegarde du pointeur vers la table des adresses de groupe (obtenu suite a la recherche)
			;		c) Reconnaissance du type de message (read, write, read_response, ...)
			;		d) Boucle sur tous les objets lies a ce groupe
			;		 da) Verification des flags lies a l'objet
			;		 db) Modification eventuelle de la valeur de l'objet + signaler que l'objet a ete modifie.
			;		 dc) Envoi eventuel de la valeur de l'objet vers le bus


			; XXX



			;restaurer registres et quitter l'interrution de niveau 3
			;--------------------------------------------------------
End_Int_level_3

	bcf		INTCON,GIE		; dé-activer les interruptions de niveau 1 et 2


			; Restaurons les 5 registres liés aux interruptions dans
			; leur état précédent afin de réautoriser les interruptions
			; niveau 3 (filtres)
			;---------------------------------------------------------------------
	
			; XXX


			; Restaurons les 4 registres principaux
			;---------------------------------------------------------------------

	BANK3
	movf	PCLATH_temp_3,w	; recharger ancien PCLATH
	movwf	PCLATH			; le restaurer
	movf	FSR_temp_3,w	; charger FSR sauvé
	movwf	FSR				; restaurer FSR
	swapf	STATUS_temp_3,w	; swap ancien status, résultat dans w
	movwf   STATUS			; restaurer status
	swapf   w_temp_3,f		; Inversion L et H de l'ancien W
                       		; sans modifier Z
	swapf   w_temp_3,w 		; Réinversion de L et H dans W
							; W restauré sans modifier status

	retfie  				; return from interrupt de niveau 3








; ////////////////////////////////////////////////////////////////////////////

;                  P R O C E D U R E S  &  F O N C T I O N S

; ////////////////////////////////////////////////////////////////////////////







;*****************************************************************************
;                     RECEPTION USART INTERRUPTION                           *
;*****************************************************************************
IntRx


; Stop, reset et restart du "recieve timeout"

; Incrementer le compteur de bytes (du telegramme en cours)

; Lire le bit de buffer overflow, traiter ce cas. (oui = appel de error_led)

; Lire le biut de frame error, traiter ce cas (oui = appel du warm boot EIB)

; Lire le bit de parite.

; Lire le byte recu et le sauver dans un byte temporaire

Discard_Rx_Byte
	; Si "Discard" = 0 , alors sauter vers "End_Discard_Rx_Byte"
	; Si "Discard" <> 255, alors decrementer "Discard"
			; (En pratique, dans cette premiere version Discard sera tjs a 0 ou a 255 ; a ammeliorer)
	; sortir de l'interruption Rx
End_Discard_Rx_Byte

; Calculer et comparer la parite (si erreur, envoyer NACK, nettoyer les variables de la routine Rx,
			; mettre "Awaiting_Repeat" a 1 et positioner "Discard", puis sortir de l'interruption Rx)

Rx_Adr_Byte
	; Si "Rem_Adr_Bytes" = 0 , alors sauter vers "End_Rx_Adr_Byte"
	; Placer le byte recu dans le "Rx_Adr_Buffer"
	; Faire un XOR sur "Rx_Calc_CheckSum_Byte" avec le byte recu (calcul du byte de checksum de fin de trame)
	; Incrementer le pointeur sur "Rx_Adr_Buffer". (ou bien se servir de "Rem_Adr_Bytes" comme pointeur)
	; Decrementer "Rem_Adr_Bytes"       (== Remainng Address Bytes counter)
	; Si "Rem_Adr_Bytes" <> 0 , alors sortir de l'interruption Rx
	; sinon, ontinuer ... (vu que l'on a les adresses et la longueur, il faut traiter l'info)
	; 
	; Si l'adresse destination est physique
		; Alors : nettoyer les variables de la routine Rx et positioner "Discard", puis sortir de l'interruption Rx
			; ! Attention, ceci est une disposition temporaire pour une premiere version, il faudra ammeliorer !
		; Sinon continuer ...  (il s'agit d'une adresses de groupe ...)
		; Calculer le nombre de bytes restants a recevoir (sans le checksum) et le sauver dans "Rem_Data_Bytes".
		; Aussi sauver le nombre de bytes de data a recevoir dans "Rx_Total_Data_Bytes" (sera utile pour le traitement des datas)
		; Lancer un timer "recherche d'adresses de groupe"
 		; Positioner certains flags ("recherche d'adresse de groupe en cours", ...)
		; Generer la condition pour une interruption de niveau 3, afin de lancer la recherche
				; de l'adresse de groupe en memoire)
	;    ainsi que signaler (positioner un flag) que cette recherche est en cours
	; 
	; Enfin, sortir de l'interruption Rx
End_Rx_Adr_Byte


Rx_Data_Byte
	; Si "Rem_Data_Bytes" = 0 , alors sauter vers "End_Rx_Data_Byte"
	; Placer le byte recu dans le "Rx_Data_Buffer"
	; Faire un XOR sur "Rx_Calc_CheckSum_Byte" avec le byte recu (calcul du byte de checksum de fin de trame)
	; Incrementer le pointeur sur "Rx_Data_Buffer".  (ou bien se servir de "Rem_Data_Bytes" comme pointeur)
	; Decrementer "Rem_Data_Byte"           (== Remaining Data Bytes counter)
	; Si "Rx_Data_Buffer" <> 0 , alors sortir de l'interruption Rx
	; sinon, ontinuer ... (alors on vient de recevoir le dernier byte de data)
	;
	; Positioner le flag "Last_Byte" a 1 car le prochain byte recu sera le checksum.
	; Positionner le flag "Data_Waiting" a 1 car il faudra sans doute traiter le contenu du buffer
	; Positionner le flag "Valid_Data" a 0 (sans doute pas utile ...)
End_Rx_Data_Byte


Rx_EIBControl_Byte
	; Si "First_Byte" = 0 , alors sauter vers "End_Rx_EIBControl_Byte"
	;
	;
	; Divers tests
	;
	;
	;
	; Mettre "Awaiting_Repeat" a 0
	; 
	; Sortir de l'interruption Rx
End_Rx_EIBControl_Byte


Rx_CheckSum_Byte
	; Si "Last_Byte" = 0 , alors sauter vers "End_Rx_CheckSum_Byte"
	;
	; Mettre "Last_Byte" a 0
	; Mettre "First_Byte" a 1

	; Si byte recu = "Rx_Calc_CheckSum_Byte"
	;   Alors  (le checksum est OK)
		; Mettre "Rx_Acquittement" a "ACK"
		; Positionner le flag "Valid_Data" a 1
		; Mettre "Awaiting_Repeat" a 0  (En principe, ce n'est pas utile ici ...)
		; Generer la condition pour une interruption de niveau 3, afin de lancer le traitement des donnees recues.
	;   Sinon  (le checksum est faux, donc la tramme est invalide)
		; Mettre "Rx_Acquittement" a "NACK"
		; Positionner le flag "Valid_Data" a 0 (Sans doute pas indispensable ici)
		; Mettre "Awaiting_Repeat" a 1
	; Sortir de l'interruption Rx
End_Rx_CheckSum_Byte





; Si on arrive ici, c'est que le byte recu n'a pas ete reconnu par la "state machine",
;  donc il y a un bug dans la routine de reception.
; Appellons la routine "Error_Led" avec le code "RXBUG_ERROR_CODE"

; Il n'y pas besoin de "return" ici
End_IntRx







;*****************************************************************************
;                     INTERRUPTION TRANSMISSION USART                        *
;*****************************************************************************
inttx
	return			; fin d'interruption
				; peut être remplacé par 
				; retlw pour retour code d'erreur












;*****************************************************************************
;                   Recherche de la présence d'une adresse                   *
;                   de groupe dans la table correspondante                   *
;*****************************************************************************
;  Cette procedure utilise une donnée 16 bits comme input, il s'agit de
;  l'adresse de groupe à rechercher.
;  La valeur d'input sera dans la variable "GrpAdrSrch_b3".
;  Cette procedure va rechercher en mémoire flash l'adresse de groupe et
;  renvoyer comme réponse :
;  - Si l'adresse de groupe existe : un nombre de 0 à 127 qui est l'index
;    de la première occurance de cette adresse de groupe dans la table.
;  - Si l'adresse de groupe est absente : 255, il suffit donc de tester si
;    le bit 7 est à 1 pour savoir si la réponse est négative.
;  La réponse sera placée dans W.
;  On concidère que la table des adresses de groupe contient au minimum
;  une adresse de groupe, sinon la procedure ne doit PAS être appelée.

GrpAdr_Search

	BANK3

;	ptr_min := 0
;	ptr_max := "last_GrpAdr_entry"
;
;Label_High
;	CLEAR flag overflow
;	TANT QUE (ptr_min <= ptr_max) ET NOT(overflow)
;		ptr := (ptr_max + ptr_min) DIV 2
;		val := read_high(ptr)
;		SI val = HIGH[GrpAdrSrch_b3]
;			ALORS GOTO Label_Low
;		SI val > HIGH[GrpAdrSrch_b3]
;			ALORS ptr_max := ptr - 1 ; attention aux cas d'overflow
;			SINON prt_min := ptr + 1 ; attention aux cas d'overflow
;	FIN TANT QUE
;	GOTO Label_AdrNotFound
;
;Label_Low
;	CLEAR flag overflow
;	TANT QUE (ptr_min <= ptr_max) ET NOT(overflow)
;		ptr := (ptr_max + ptr_min) DIV 2
;		val := read_low(ptr)
;		SI val = LOW[GrpAdrSrch_b3]
;			ALORS GOTO Label_AdrFound
;		SI val > HIGH[GrpAdrSrch_b3]
;			ALORS ptr_max := ptr - 1 ; attention aux cas d'overflow
;			SINON prt_min := ptr + 1 ; attention aux cas d'overflow
;	FIN TANT QUE
;	GOTO Label_AdrNotFound
;
;Label_AdrNotFound
;	W := 255
;	RETURN
;
;Label_AdrFound
;	TANT QUE (read_low(ptr - 1)=LOW[GrpAdrSrch_b3])
;		  ET (read_high(ptr - 1)=HIGH[GrpAdrSrch_b3])
;		  ET ((ptr - 1) >= 0 )
;		DECREMENTER (ptr)
;	FIN TANT QUE
;	W := ptr
;	RETURN









;*****************************************************************************
;                        CALCULER LA PARITE                                  *
;*****************************************************************************
;-----------------------------------------------------------------------------
; L'octet dont on calcule la parité est dans W
; La parité est paire (si impaire, changer bcf en bsf dans la ligne $$$$$$$)
; le flag PARITE est positionné suivant la valeur calculée
;-----------------------------------------------------------------------------
calcpar
	movwf	local1		; sauver dans variable locale (temporaire)
	bcf	PARITE		; effacer bit de parité ($$$$$$$$)

calcparl
	andlw	0x01		; garder bit 0 de l'octet
	xorwf	flags,f		; si " 1 ", inverser parité
	bcf	STATUS,C	; effacer carry pour décalage
	rrf	local1,f	; amener bit suivant en b0
	movf	local1,w	; charger ce qui reste de l'octet
	btfss	STATUS,Z	; il reste des bits à " 1 " ?
	goto	calcparl	; oui, poursuivre
	return			; non, retour




;*****************************************************************************
;                     ERREUR : INTERRUPTION NON PREVUE                       *
;*****************************************************************************
;-----------------------------------------------------------------------------
; Dans le cas ou la procedure d'interruption est appelée mais que aucune
; raison et traitement de cette interrution n'est prévue, on abouti ici
;-----------------------------------------------------------------------------
Int_Error

	movlw INT_ERROR_CODE
	goto Error_Led



;*****************************************************************************
;                     ERREUR : RESET DU PIC PAR LE WATCHDOG                  *
;*****************************************************************************
;-----------------------------------------------------------------------------
; Dans le cas ou le PIC a été réinitialisé par le watchdog, on ne laisse pas
; démarrer le stack EIB mais on viens directement ici.
;
; Une fois le stack EIB fiabilisé, on devra modifier ce comportement afin de
; 1) Lancer le stack EIB
; 2) NE PAS lancer l'application (qui est probablement en faute)
; 3) Envoyer un télégramme particulier pour signaler l'erreur
;-----------------------------------------------------------------------------
Watchdog_Error

	movlw WTDG_ERROR_CODE
	goto Error_Led







;*****************************************************************************
;                     REPORT DU CODE ERREUR SUR LA LED                       *
;*****************************************************************************
;-----------------------------------------------------------------------------
; En cas d'erreur du Stack ou de l'applic. EIB, on appelle cette procedure
; avec le numéro de l'erreur dans W comme parametre.
; Le PIC va alors tourner en boucle en faisant clignoter la LED de
; de programmation de l'adresse physique un nombre de fois correspondant
; au numéro de l'erreur. Il faut reseter le PIC pour sortir de ce mode.
;-----------------------------------------------------------------------------
Error_Led
;	Désactiver toute interruption


	clrwdt

;	Forcer le TP-UART en hard-reset et le laisser dans ce mode

;	Double boucle imbriquée pour le clignotement de la led durant le bon nombre
;	de fois, suivi d'un délai plus long.

	goto Error_Led		;et ensuite on recommence, à l'infini.









; ////////////////////////////////////////////////////////////////////////////

;                           P R O G R A M M E

; ////////////////////////////////////////////////////////////////////////////



;*****************************************************************************
;                    CODE DU STACK EIB HORS INTERRUPTION                     *
;*****************************************************************************

; PIC reset analyse
;-------------------
PIC_Start

	clrwdt				; effacer watch dog

; Divers test pour connaitre la raison du dernier reset.

; Si c'est du au watchdog, lancer la procedure de
;  "clignotement de la LED rouge" avec le bon code erreur
;   ==>  goto Watchdog_Error

; Passer à l'initialisation des divers paramètres du PIC

	goto PIC_Init


;*****************************************************************************
;                          INITIALISATIONS                                   *
;*****************************************************************************
PIC_Init

			; initialisation PORTS (banque 0 et 1)
			; ------------------------------------
	BANK0			; sélectionner banque0
	clrf	PORTA		; Sorties PORTA à 0
	clrf	PORTB		; sorties PORTB à 0
	clrf	PORTC		; sorties PORTC à 0
	clrf	PORTD		; sorties PORTD à 0
	clrf	PORTE		; sorties PORTE à 0
	bsf	STATUS,RP0	; passer en banque1
	movlw	ADCON1VAL	; PORTA en mode digital/analogique
	movwf	ADCON1		; écriture dans contrôle A/D
	movlw	DIRPORTA	; Direction PORTA
	movwf	TRISA		; écriture dans registre direction
	movlw	DIRPORTB	; Direction PORTB
	movwf	TRISB		; écriture dans registre direction
	movlw	DIRPORTC	; Direction PORTC
	movwf	TRISC		; écriture dans registre direction
	movlw	DIRPORTD	; Direction PORTD
	movwf	TRISD		; écriture dans registre direction
	movlw	DIRPORTE	; Direction PORTE
	movwf	TRISE		; écriture dans registre direction

			; Registre d'options (banque 1)
			; -----------------------------
	movlw	OPTIONVAL	; charger masque
	movwf	OPTION_REG	; initialiser registre option

			; registres interruptions (banque 1)
			; ----------------------------------
	movlw	INTCONVAL	; charger valeur registre interruption
	movwf	INTCON		; initialiser interruptions
	movlw	PIE1VAL		; Initialiser registre 
	movwf	PIE1		; interruptions périphériques 1
	movlw	PIE2VAL		; initialiser registre
	movwf	PIE2		; interruptions périphériques 2
	movlw	CVRCONVAL	; charger la valeur du registre pour VREF
	movwf	CVRCON		; initialiser le registre
	movlw	CMCONVAL	; charger la valeur du registre des comparateurs
	movwf	CMCON		; initialiser le registre


			; Effacer RAM banque 0
			; ---------------------
	bcf	STATUS,RP0	; sélectionner banque 0
	movlw	0x20		; initialisation pointeur
	movwf	FSR		; d'adressage indirect
init1
	clrf	INDF		; effacer ram
	incf	FSR,f		; pointer sur suivant
	btfss	FSR,7		; tester si fin zone atteinte (>7F)
	goto	init1		; non, boucler

	goto	EIB_Cold	; puis passer au Cold Start


; EIB Stack Cold Start
;----------------------
EIB_Cold
; Initialiser la valeur de tous les objets à 0

	goto	EIB_Warm	; puis passer au Warm Start


; EIB Stack Warm Start
;----------------------
EIB_Warm
	; Intitialiser tous les buffers
	; -----------------------------

	; Initialiser tous les State-Machine flags
	; ----------------------------------------

	; Paramètrer l'UART
	; -----------------
		; 19200 baud
		; usage du 9ième bit

	; Hard-reset du TP-UART et attendre que sa ligne TX passe à 1
	; -----------------------------------------------------------

	; "Lacher" le control manuel sur la pin RX
	; ----------------------------------------


	; Activer les interrputions (Banque 0)
	; ------------------------------------
	BANK0
	clrf	PIR1		; effacer flags 1
	clrf	PIR2		; effacer flags 2
	bsf		INTCON,GIE	; valider interruptions
	; ==> Le stack EIB est maintenant actif !



	; Tester si une application EIB valide est chargé et la lancer,
	;  sinon boucler.
	; -------------------------------------------------------------

; TANT QUE    EIB_app_chargée = "non"
	clrwdt				; effacer watch dog
; FIN TANT QUE

	goto	start_EIB_App		; programme principal



;*****************************************************************************
;                    APPLICATION EIB SPECIFIQUE                              *
;*****************************************************************************

start_EIB_App

	clrwdt			; effacer watch dog
	
	goto start_EIB_App		; boucler

	END 			; directive fin de programme
