//-----------------------------------------------------------------------------------//
// Nom du projet 		:	Coursera_Microcontroleur
// Nom du fichier 		:   main_3_9.c
// Date de création 	:   20.08.2014
// Date de modification : 	29.08.2014
// 
// Auteur 				: 	Philou (Ph. Bovey) 
//
// Description 			:   Sans fonction d'antirebond, le but est déterminé le temps 
//							de pression du bouton, on utilisera des 8 leds 
//                          32ms, 64ms, 96ms, 128ms, 160ms, 192ms, 224ms   
//
// 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)
//
//		!!! CODE A REVOIR CONCEPT !!!
//----------------------------------------------------------------------------------//
//--- 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 ---//
#define LED_ALLUMEES	0xFF						// toutes les leds sont allumées 
#define LED_ETEINTES	0x00						// toutes les leds sont éteintes 
//#define MULTI_DOUBLE	2							// multiplicateur pour 2 états 
#define UNITE_DIV  		8000						// un cycle normalement 125ns = 1/8MHz 

#define SWITCH 		PORTDbits.RD6					// entrée   
#define LEDS 		LATA 							// sortie 

//--- déclaration de prototypes ---// 
void init_oscillateur(void); 					// configuration oscillateur 
void init_in_out(void);							// configuration entree - sortie  
void init_timer1(void); 						// configuration Timer1  
void cligno_LEDS(char nb_cligno); 				// augmenter la vitesse de clignotement des leds  
 
//--- déclaration de variables gloables ---//
 
//--- programme principale ---//
int main(void)
{
	//--- déclaration de variables ---// 
	char i = 0; 
	char choix = 1; 
	char tb_8_etat[] = {32, 64, 96, 128, 160, 192, 224};  

	unsigned long compteur;
	unsigned long time_ms;
	int tb_LED[] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};  

	//--- initialisation ---//
	init_oscillateur(); 				// oscillateur
	//init_timer1(); 						// Timer 1 
	init_in_out(); 						// IN/OUT     
			 	
	//--- séquence d'initialisation ---//
	LEDS = LED_ALLUMEES; 

	//--- boucle sans fin ---//
	while(1)
	{
		//--- remise à zéro du compteur ---//
		compteur = 0;

		//--- incrémente un compteur ---//  
		while(SWITCH == 0)
		{
			compteur++;
			i = 7; 
			choix = 1;

			//--- déterminer le nb de clignotement de manière manuelle ---//
			// Remarque : un cylce faut 1/8MHz = 125ns => 1ms = 8000 * 125ns => UNITE_DIV = 8000;    
			time_ms = compteur/UNITE_DIV;   
		} 
 
		//--- ---//
		while((choix != 0) && (i > 0))
		{
			if(time_ms >= tb_8_etat[i])
			{
				LEDS = tb_LED[i]; 
				choix = 0; 
			}

			else if(time_ms < 32)
			{
				LEDS = tb_LED[0]; 
				choix = 0; 
			} 
			else 
				i--; 
		}
	}   
}

//----------------------------------------------------------------------------------//
//--- 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 ---//
	TRISDbits.TRISD6 = 1; 						//--> SWI3 
 	
	//--- configuration sortie numérique ---//
	TRISA = 0x00; 								// 8 bits sur le port A
	  
}

//----------------------------------------------------------------------------------//
//--- 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); 	//
}
			
