//-----------------------------------------------------------------------------------//
// Nom du projet 		:	Coursera_Microcontroleur
// Nom du fichier 		:   main_2_10_Map.c
// Date de création 	:   08.03.2014
// Date de modification : 	15.03.2014
// 
// Auteur 				: 	Philou (Ph. Bovey) 
//
// Description 			: 	implémentation de la fonction map() (adaptation d'échelle)   
//
// Remarques			: 
// 	    chemin pour trouver le headerfile 
//		C:\Program Files\Microchip\MPLAB C30\support\dsPIC33F\h
//
//	    doc pour le DSP : 
//		http://www.microchip.com/wwwproducts/Devices.aspx?dDocName=en546064
//
// 		lien pour la doc de la fonction MAP() --> ARDUINO 
//		http://arduino.cc/en/reference/map#.Uxowyz95NBk
//----------------------------------------------------------------------------------//
//--- librairie à inclure ---// 
#if defined(__dsPIC33F__)
#include "p33Fxxxx.h"
#endif

//--- 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 ECHELLE1_MIN	0							// constante pour les limites de la fonction MAP 
#define ECHELLE1_MAX	10							// ces valeurs ne sont qu'arbitraire 
#define ECHELLE2_MIN	0
#define ECHELLE2_MAX	20

#define LED_3 LATAbits.LATA0                        // led 3

//--- déclaration de prototypes ---// 
void init_oscillateur(void); 				// configuration oscillateur 
void init_in_out(void);                     // configuration entrée - sortie  
int conv_echelle(int x, int min_ech1, int max_ech1, int min_ech2, int max_ech2);  

//--- programme principale ---//
int main(void)
{
	//--- déclaration de variables ---// 
	long i = 0;          // variable pour la 2ème boucle while 
	int var = 5;         // var a adapter sur l'autre échelle    
	int res;             // réponse    

	//--- initialisation ---//
	init_oscillateur(); 				// oscillateur
	init_in_out(); 					    // IN / OUT  
	
	
	LED_3 = 0; 							// led 3 allumée  
	
	//--- boucle sans fin ---//
	while(1)
	{
        //--- boucle de traitement ---//
		while(i < 1000000)
		{
			res = conv_echelle(var, ECHELLE1_MIN, ECHELLE1_MAX, ECHELLE2_MIN, ECHELLE2_MAX); 
			i++; 
		}

		LED_3 = ~LED_3;               // inversion de la valeurs             
		i = 0;                        // remise à zéro    
	}
}

//----------------------------------------------------------------------------------//
//--- 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 ---// 
 	
	//--- configuration sortie numérique ---//
	TRISAbits.TRISA0 = 0; 						// --> LED3  
 
}

//----------------------------------------------------------------------------------//
//--- 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 				: conv_echelle
//--- entrée - sortie 	: x, min_ech1, max_ech1, min_ech2, max_ech2 / int 
//--- description 		: configuration oscillateur | clock à choix  
//-- remarque 			: doc = section 7
//----------------------------------------------------------------------------------//
int conv_echelle(int x, int min_ech1, int max_ech1, int min_ech2, int max_ech2)
{
	return((x-min_ech1)*((max_ech1 - min_ech1)/(max_ech2 - min_ech2))+ min_ech2); 
}
