//-----------------------------------------------------------------------------------//
// Nom du projet 		:	Coursera_Microcontroleur
// Nom du fichier 		:   main_4_1C.c
// Date de création 	:   27.02.2015
// Date de modification : 	xx.xx.2015
// 
// Auteur 				: 	Philou (Ph. Bovey) 
//
// Description 			:   Si le pieton veut traverser, il faut qu'il appuie sur 
//							un bouton. Ceci va permettrre au feu pieton de commuter du 
//							rouge au vert et vis et versa les feux des voitures
//							passeront du vert au rouge. Dans cette version tous les 
//                          feux sont utilisés (Rouge - Orange - Vert)   
// Remarques			: 
// 	    chemin pour trouver le headerfile 
//		C:\Program Files\Microchip\MPLAB C30\support\dsPIC33F\h
//
//	    lien utile :
//		1) taille de type en C 
// 		http://fr.wikipedia.org/wiki/C_(langage)
//
//----------------------------------------------------------------------------------//
//--- librairie à inclure ---// 
#if defined(__dsPIC33F__)
#include "p33Fxxxx.h"
#endif

//--- autres librairires ---// 
#include "antirebond.h"									// 
//#include <string.h>
//#include <stdlib.h>

//--- Fusibles ---//	
_FOSCSEL(FNOSC_PRI); 									// utilisation du quartz de 8MHz externe 
_FOSC(FCKSM_CSECMD & OSCIOFNC_OFF  & POSCMD_XT); 		// pin OS2 garder pour l'horlohe 
														// oscillateur XT	
_FWDT(FWDTEN_OFF); 										// ne pas activer le watchdog

//--- definition ---//
//--- feux cotés EST ---//
#define LED_FR_EST 			LATAbits.LATA2				 
#define LED_FO_EST 			LATAbits.LATA0			
#define LED_FG_EST 			LATAbits.LATA1		

//--- feux cotés WEST ---//
#define LED_FR_WEST 		LATAbits.LATA10				 
#define LED_FO_WEST 		LATAbits.LATA15		
#define LED_FG_WEST 		LATAbits.LATA14		
		
//--- feux cotés NORD ---//
#define LED_FR_NORD 		LATAbits.LATA3		 
#define LED_FO_NORD 		LATAbits.LATA4		
#define LED_FG_NORD 		LATAbits.LATA5		
		
//--- feux cotés SUD ---//
#define LED_FR_SUD 			LATAbits.LATA6		
#define LED_FO_SUD 			LATAbits.LATA7		
#define LED_FG_SUD 			LATAbits.LATA9		
		
//--- CMD pieton ---//
#define SWITCH_PIETON		PORTBbits.RB0		


//--- déclaration de prototypes ---// 
void Init_Oscillateur(void); 					// configuration oscillateur 
void Init_In_Out(void);							// configuration entree - sortie  
void Init_Feux(void); 							// Phase initialisation Feux -> ETAT 1 
void Init_Timer1(void); 						// configuration Timer1  
void Feux_Axe_NS_Orange(void); 					// Sequence Feux -> ETAT 2  
void Feux_2_Axes_Rouge(void);					// Sequence Feux -> ETAT 3
void Feux_Axe_EW_RO(void);						// Sequence Feux -> ETAT 4 
void Feux_Axe_EW_V(void); 						// Sequence Feux -> ETAT 5 	
void Feux_2_Axe_O(void);						// Sequence Feux -> ETAT 6
 
//--- déclaration de variables gloables ---//
Etat_switch pt_SWITCH_PIETON;

char ACTIVE_CMD_CMPT;  
int CMPT_FEUX_PIETON;
 
//--- programme principale ---//
int main(void)
{
	//--- déclaration de variables ---// 

	//--- initialisation ---//
	Init_Oscillateur(); 				// oscillateur
	Init_Timer1(); 						// Timer 1 
	Init_In_Out(); 						// IN/OUT     
	Init_Feux();						// initialisation des feux
 
	//--- initialisation de variables ---//
	ACTIVE_CMD_CMPT = 0x00; 
	
	LED_FR_NORD = 0x00;  	

	//--- boucle sans fin ---//
	while(1)
	{ 
		//--- test si la touche est pressée ---//
		if(switch_presser(&pt_SWITCH_PIETON))
		{
			//--- remise à zéro du compteur ---//
			CMPT_FEUX_PIETON = 0x00;
			ACTIVE_CMD_CMPT = 0x01;  
			
			//--- remise à zéro de l'info de la touche 
			reset_info_touche_presser(&pt_SWITCH_PIETON);
		}

		//--- test du compteur - passage orange (axe N/S - voiture) - ETAT 2 ---//  
		//--- compteur doit se trouver entre 5s et 10s ->  pour les feux pieton => 5s => 5s/0.1 = 50 Dec = 0x32---//
		if((CMPT_FEUX_PIETON >= 0x32) && (CMPT_FEUX_PIETON < 0x64))
			Feux_Axe_NS_Orange(); 
		
		//--- test du compteur - tous les feux seront au rouges (axe N/S & E/W) - ETAT 3 ---//  
		//--- compteur doit se trouver entre 10s et 15s ->  pour les feux pieton => 10s => 10s/0.1 = 100 Dec = 0x64---//
		if((CMPT_FEUX_PIETON >= 0x64) && (CMPT_FEUX_PIETON < 0x96))
			Feux_2_Axes_Rouge(); 

		//--- test du compteur - passage orange en restant aussi au rouge (E/W) - ETAT 4 ---//  
		//--- compteur doit se trouver entre 15s et 20s ->  pour les feux pieton => 15s => 15s/0.1 = 150 Dec = 0x96---//
		if((CMPT_FEUX_PIETON >= 0x96) && (CMPT_FEUX_PIETON < 0xC8))
			Feux_Axe_EW_RO(); 

		//--- test du compteur - passage au vert pour les pietons (E/W) - ETAT 5 ---//  
		//--- compteur doit se trouver entre 20s et 50s ->  pour les feux pieton => 20s => 20s/0.1 = 200 Dec = 0xC8---//
		if((CMPT_FEUX_PIETON >= 0xC8) && (CMPT_FEUX_PIETON < 0x1F4))
			Feux_Axe_EW_V(); 

		//--- test du compteur - passage à l'orange pour les pietons (axes E/W) - ETAT 6 ---//
		//---                  - passage à l'orange et en restant aussi au rouge pour les voitures (axes N/S)  
		//--- compteur doit se trouver entre 20s et 50s ->  pour les feux pieton => 20s => 20s/0.1 = 200 Dec = 0xC8---//
		if((CMPT_FEUX_PIETON >= 0x1F4) && (CMPT_FEUX_PIETON < 0x226))
			Feux_2_Axe_O(); 
		
		//--- test du compteur pour revenir a l'état initial > 1min => 55/0.1 = 550 dec = 0x226 ---// 
		if(CMPT_FEUX_PIETON >= 0x226)
		{
			Init_Feux();
			ACTIVE_CMD_CMPT = 0x00;
			CMPT_FEUX_PIETON = 0x00; 
		}
	}
}


//----------------------------------------------------------------------------------//
//--- nom 				: init_oscillateur
//--- entrée - sortie 	: - / - 
//--- description 		: configuration oscillateur | clock à choix  
//-- remarque 			: doc = section 7
//----------------------------------------------------------------------------------//
void Init_Oscillateur(void)
{
	//--- configuration de l'oscillateur interne à 8Mhz ---//
	// utilisation formules du datasheet du DSPic33FJ256GP710A --> page 146
	// quartz utilisé sur le carte = 8MHz = Fin
	// Fcy = Fosc / 2 ; Fosc = Fin(M/(N1 N2))
	// Fin = 8Mhz --> Fosc = 16Mhz --> Fcy = 8Mhz 
	OSCCONbits.COSC 	= 3;			// sélection de l'oscillateur XT 
	OSCCONbits.CLKLOCK	= 0;			// l'horloge et la PLL peuvent être modifié 	
	
	CLKDIVbits.ROI		= 0; 			// pas d'effet si il y a interruption 
	CLKDIVbits.DOZE		= 0; 			// pas de réduction sur l'horloge Fcy /1
	CLKDIVbits.DOZEN	= 0; 		
	CLKDIVbits.PLLPRE 	= 0; 			// N1 = 2	
    CLKDIVbits.PLLPOST 	= 0; 			// N2 = 2 	
	
	PLLFBDbits.PLLDIV 	= 6;			// M = 8  

	__builtin_write_OSCCONH(0x03); 		// fonction appelant du code assembleur 
										// configuration du registre NOSC (OSCCON) --> 
										// 011 = Primary Oscillator with PLL (XTPLL, HSPLL, ECPLL)
	__builtin_write_OSCCONL(0x01);		// Active la commutation de la clock
	while(OSCCONbits.COSC != 0b011); 	//
}

//----------------------------------------------------------------------------------//
//--- nom 				: init_timer1
//--- entrée - sortie 	: - / - 
//--- description 		: initialisation timer 1 pour avoir une horloge de 100ms
//--- remarque 			: doc = section 11 
//----------------------------------------------------------------------------------//
void Init_Timer1(void)
{
	//--- registre de configuration du Timer1 ---//
	T1CONbits.TON = 0; 			// désactiver le timer pour la configuration 
	T1CONbits.TCS = 0; 			// clock interne
	T1CONbits.TSYNC = 0; 		// synchroniser la clock externe 	
	T1CONbits.TCKPS = 3; 		// prédivseur régler à 256 --> 8Mhz/256 = 31250Hz --> 32us 
	
	TMR1 = 0; 					// mise à zéro du registre lié au timer 

	PR1 = 3125; 				// période du timer --> 100ms/32us = 3125

	//--- registres des configurations des interruptions liées au Timer1 ---//
	IPC0bits.T1IP = 7; 			// choix de la priorité --> ici la plus élevée 7 = 111
	IFS0bits.T1IF = 0; 			// remise à zéro de l'interruption 
	IEC0bits.T1IE = 1; 			// activation de l'interruption lié au Timer1 

	T1CONbits.TON = 1; 	    	// activer le timer1 
}

//----------------------------------------------------------------------------------//
//--- nom 				: _T1Interrupt
//--- entrée - sortie 	: - / - 
//--- description 		: interruption liée au  
//----------------------------------------------------------------------------------//
void __attribute__((interrupt,no_auto_psv)) _T1Interrupt( void )
{
	//---  ---//
	IFS0bits.T1IF = 0; 			// remise à zéor du flag d'interruption

	//--- test pour si on rentre dans la boucle d'interruption ---//
	//LED_FO_NORD = ~LED_FO_NORD; 
	
	//--- lecture du switch pieton ---//
	antirebond(&pt_SWITCH_PIETON, SWITCH_PIETON);

	//--- incrémentation du compteur pour pieton ---// 
	if(ACTIVE_CMD_CMPT == 1)
		CMPT_FEUX_PIETON++; 
			
	TMR1 = 0; 				// mise à jour du registre de comptage 
	T1CONbits.TON = 1;		// activer à nouveau le Timer */ 
}

//----------------------------------------------------------------------------------//
//--- nom 				: init_in_out
//--- entrée - sortie 	: - / - 
//--- description 		: initialisation IN/OUT ANAL/NUM --> 
//--- remarque 			: doc = section 10 
//----------------------------------------------------------------------------------//
void Init_In_Out(void)
{	
	//--- configuration entrée analogique ---// 

	//--- configuration entrée numérique ---//
	TRISBbits.TRISB0 = 0x01; 					//--> Switch pieton 

	//--- configuration de l'entrée RB0/AN0 en pure Input analogique ---// 
	AD1PCFGLbits.PCFG0 = 0x01; 					// met en mode I/O uniquement (SANS CONFIG ANALOGIQUE) 
 	
	//--- configuration sortie numérique ---//
	TRISAbits.TRISA0 = 0x00;					// LED Orange 	coté EST  
	TRISAbits.TRISA1 = 0x00; 					// LED Vert 	coté EST
	TRISAbits.TRISA2 = 0x00; 					// LED Rouge 	coté EST
	TRISAbits.TRISA3 = 0x00; 					// LED Rouge 	coté WEST
	TRISAbits.TRISA4 = 0x00;					// LED Orange 	coté WEST
	TRISAbits.TRISA5 = 0x00;					// LED Vert 	coté WEST
	TRISAbits.TRISA6 = 0x00;					// LED Rouge	coté SUD
	TRISAbits.TRISA7 = 0x00; 					// LED Orange	coté SUD
	TRISAbits.TRISA9 = 0x00;					// LED Vert		coté SUD
	TRISAbits.TRISA10 = 0x00;					// LED Rouge	coté NORD
	TRISAbits.TRISA14 = 0x00;					// LED Orange	coté NORD
	TRISAbits.TRISA15 = 0x00;					// LED Vert		coté NORD	  
}


//----------------------------------------------------------------------------------//
//--- nom 				: Init_Feux => ETAT 1
//--- entrée - sortie 	: - / - 
//--- description 		: initialisation les leds correspondants à des feux
//						  les leds verts nord et sud sont allumées
//						  les leds rouges est et ouest sont allumée     
//--- remarque 			: 
//----------------------------------------------------------------------------------//
void Init_Feux(void)
{
	//--- FEUX ALLUMEES ---//
	//--- Feux VERT// 
	LED_FG_NORD 	= 0x01;
	LED_FG_SUD 		= 0x01;

	//--- Feux ROUGE ---//
	LED_FR_EST 		= 0x01; 
	LED_FR_WEST 	= 0x01;

	//--- Feux ETEINTS ---//
	//--- Feux VERT ---//
	LED_FG_EST		= 0x00;
	LED_FG_WEST		= 0x00;

	//--- Feux ROUGE ---//
	LED_FR_NORD 	= 0x00;
	LED_FR_SUD 		= 0x00;

	//--- Feux ORANGE ---//
	LED_FO_EST		= 0x00;
	LED_FO_WEST		= 0x00; 
	LED_FO_NORD		= 0x00;
	LED_FO_SUD		= 0x00;  
}

//----------------------------------------------------------------------------------//
//--- nom 				: Feux_Axe_NS_Orange => ETAT 2
//--- entrée - sortie 	: - / - 
//--- description 		: On garde les feux (pieton) au rouge mais l'axe nord-sud 
//						  passe du vert à l'orange      
//--- remarque 			: changement par à l'état 1 
//                        axe nord/sud -> vert(0) -> orange (1) 
//----------------------------------------------------------------------------------//
void Feux_Axe_NS_Orange(void)
{
	//--- FEUX ALLUMEES ---//
	//--- Feux ORANGE ---//
	LED_FO_NORD		= 0x01;
	LED_FO_SUD		= 0x01;

	//--- Feux ROUGE ---//
	LED_FR_EST 		= 0x01; 
	LED_FR_WEST 	= 0x01;

	//--- Feux ETEINTS ---//
	//--- Feux VERT ---//
	LED_FG_EST		= 0x00;
	LED_FG_WEST		= 0x00;
	LED_FG_NORD 	= 0x00;
	LED_FG_SUD 		= 0x00;

	//--- Feux ORANGE ---//
	LED_FO_EST		= 0x00;
	LED_FO_WEST		= 0x00;

	//--- Feux ROUGE ---//
	LED_FR_NORD 	= 0x00;
	LED_FR_SUD 		= 0x00;
}

//----------------------------------------------------------------------------------//
//--- nom 				: Feux_2_Axes_Rouge => ETAT 3
//--- entrée - sortie 	: - / - 
//--- description 		: Sur les deux Axe Nord/Sud (voiture) et Axe Est/West 
//                        (Pietons) tous les feux sont au rouges     
//--- remarque 			: changement par rapport à l'état 2 
//                        axe nord/sud -> orange(0) -> rouge (1) 
//----------------------------------------------------------------------------------//
void Feux_2_Axes_Rouge(void)
{
	//--- FEUX ALLUMEES ---//
	//--- Feux ROUGE ---//
	LED_FR_NORD 	= 0x01; 
	LED_FR_SUD 		= 0x01;
	LED_FR_EST 		= 0x01;
	LED_FR_WEST 	= 0x01;

	//--- Feux ETEINTS ---//
	//--- Feux VERT ---//
	LED_FG_SUD		= 0x00;
	LED_FG_NORD		= 0x00;
	LED_FG_EST		= 0x00; 
	LED_FG_WEST		= 0x00; 	

	//--- Feux ORANGE ---//
	LED_FO_EST		= 0x00;
	LED_FO_WEST		= 0x00; 
	LED_FO_NORD		= 0x00;
	LED_FO_SUD		= 0x00;
}

//----------------------------------------------------------------------------------//
//--- nom 				: Feux_Axe_EW_RO => ETAT 4
//--- entrée - sortie 	: - / - 
//--- description 		: Sur l Axe Est/West (pieton), le feu rouges reste toujours
//						  allumé mais y a aussi le feu orange qui s'allume     
//--- remarque 			: changement par rapport à l'état 3 
//                        axe est/west -> orange(1) 
//----------------------------------------------------------------------------------//
void Feux_Axe_EW_RO(void)
{
	//--- FEUX ALLUMEES ---//
	//--- Feux ROUGE ---//
	LED_FR_NORD 	= 0x01; 
	LED_FR_SUD 		= 0x01;
	LED_FR_EST 		= 0x01;
	LED_FR_WEST 	= 0x01;
	
	//--- Feux ORANGE ---//
	LED_FO_EST		= 0x01;
	LED_FO_WEST		= 0x01;

	//--- Feux ETEINTS ---//
	//--- Feux VERT ---//
	LED_FG_SUD		= 0x00;
	LED_FG_NORD		= 0x00;
	LED_FG_EST		= 0x00; 
	LED_FG_WEST		= 0x00; 	

	//--- Feux ORANGE ---// 
	LED_FO_NORD		= 0x00;
	LED_FO_SUD		= 0x00;
}

//----------------------------------------------------------------------------------//
//--- nom 				: Feux_Axe_EW_V => ETAT 5
//--- entrée - sortie 	: - / - 
//--- description 		: Sur l Axe Est/West (pieton), le feu passe au vert 
//						      
//--- remarque 			: changement par rapport à l'état 3 
//                        axe est/west -> orange(1) 
//----------------------------------------------------------------------------------//
void Feux_Axe_EW_V(void)
{
	//--- FEUX ALLUMEES ---//
	//--- Feux ROUGE ---//
	LED_FR_NORD 	= 0x01; 
	LED_FR_SUD 		= 0x01;

	//--- Feux VERT ---//
	LED_FG_EST		= 0x01; 
	LED_FG_WEST		= 0x01;

	//--- Feux ETEINTS ---//
	//--- Feux VERT ---//
	LED_FG_SUD		= 0x00;
	LED_FG_NORD		= 0x00; 	

	//--- Feux ORANGE ---// 
	LED_FO_NORD		= 0x00;
	LED_FO_SUD		= 0x00;
	LED_FO_EST		= 0x00;
	LED_FO_WEST		= 0x00;

	//---Feux ROUGE ---//
	LED_FR_EST 		= 0x00;
	LED_FR_WEST 	= 0x00;
}

//----------------------------------------------------------------------------------//
//--- nom 				: Feux_2_Axe_O => ETAT 6
//--- entrée - sortie 	: - / - 
//--- description 		: Sur l Axe Est/West (pieton), le feu passe à l'orange et sur
//                        l'axe Nord/Sud (voiture), le feu passe à l'orange tout en 
//						  restant orange      
//--- remarque 			: changement par rapport à l'état 3 
//                        axe est/west -> orange(1) 
//----------------------------------------------------------------------------------//
void Feux_2_Axe_O(void)
{
	//--- FEUX ALLUMEES ---//
	//--- Feux ROUGE ---//
	LED_FR_NORD 	= 0x01; 
	LED_FR_SUD 		= 0x01;

	//--- Feux ORANGE ---//
	LED_FO_NORD		= 0x01;
	LED_FO_SUD		= 0x01;
	LED_FO_EST		= 0x01;
	LED_FO_WEST		= 0x01;	

	//--- Feux ETEINTS ---//
	//--- Feux VERT ---//
	LED_FG_SUD		= 0x00;
	LED_FG_NORD		= 0x00;
	LED_FG_EST		= 0x00; 
	LED_FG_WEST		= 0x00; 	

	//---Feux ROUGE ---//
	LED_FR_EST 		= 0x00;
	LED_FR_WEST 	= 0x00;
}






				
