#include <stm32f10x.h>
#include <stdio.h>
#include <Horloge.h>

	
//Il faut trouver le signal
//On est à Timer 2

static void (*TIM2_Appel)(void) = 0;

void Timer_Init(TIM_TypeDef *Timer, unsigned short Autoreload, unsigned short Prescaler){
	if (Timer == TIM1) {
			RCC->APB2ENR |= RCC_APB2ENR_TIM1EN; //L'horloge est enabléd
	} else if (Timer == TIM2) {
			TIM2->CR1 |= TIM_CR1_CEN; //On enable l'horloge interne
			RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;
	} else if (Timer == TIM3) {		
			RCC->APB1ENR |= RCC_APB1ENR_TIM3EN;
	} else if (Timer == TIM4) {
			RCC->APB1ENR |= RCC_APB1ENR_TIM4EN;
	}
	Timer->ARR |= Autoreload;
	Timer->PSC |= Prescaler;
}

//La fonction TIM2_IRQHandler s'utilise dans le processeur, on l'a juste redifint, tel qu'à chaque overflow on met un bit 1 dans GPIOA_ODR
void TIM2_IRQHandler(void) { //On redefinit le IRQHandler qui est déjà ecrit dans le code source
    if (TIM2->SR & TIM_SR_UIF) { //On met le bit de overflow à un dès qu'on a overflow
        TIM2->SR &= ~TIM_SR_UIF; //Remise à zero
				
			if (TIM2_Appel){TIM2_Appel();}
    }
}


void MyTimer_ActiveIT(TIM_TypeDef * Timer, char Prio, void(*Interrupt_fonc)(void)){ //On veut créer une fonction qui envoie un signal au cas où il y a debordement, avec une prioritaire, 0 plus importante 15 moins importante
	if (Timer == TIM2){
		
		TIM2_Appel = Interrupt_fonc;
		
		NVIC_EnableIRQ(TIM2_IRQn);
		NVIC_SetPriority(TIM2_IRQn, Prio);
		TIM2->DIER |= TIM_DIER_UIE; //Le registre DIER(Interrupt Enable Register) est mis au bit Update Interrupt, qui se commute lors d'un overflow
		TIM2->CR1 |= TIM_CR1_CEN; //Clock Enable
	}
}


//Fonction qui permet de clignoter le DEL à un pulse volue (Sinusoïdale)
//Si le sinus est haut(haute tension) le Duty Cicle est proche de 100%,
//si le sinus est bas (vers la tension la plus basse) le Duty Cycle est vers 0%
//On s'applique sur un plage de [0V; 3.3V]


void MyTimer_PWM(TIM_TypeDef * Timer , int Channel){
	int pwrmd;
	int CCR_VAL = (ARR_VAL + 1) * DUTYC / 100.0f;
	#if POWERMODE //Powermode 1
			pwrmd = 0b110;
	#else
			pwrmd = 0b111; //Powermode 2
	#endif
				if (Channel 		== 1){
					Timer->CCR1 	= CCR_VAL; //Faut avoir le bon valeur
					Timer->CCMR1 	&= ~(0b111<<4); //On clear les trois bits qui sont de pwm
					Timer->CCMR1 	|= (pwrmd<<4); //On affecte le powermode au bits de lecture pour le µ-controlleur
					Timer->CCMR1 	|= TIM_CCMR1_OC1PE; //Update preload, il n'affecte pas le valeur avant que la prochaine cycle
					Timer->CCER 	= TIM_CCER_CC1E; //Enable le pin voulu basculer
				}
				else if (Channel == 2){
					Timer->CCR2 		= CCR_VAL;
					Timer->CCMR1 		&= ~(0b111<<12); //Le TIMx_CCMR1 configure deux channels, de bit [6:4] CH1, [14:12] CH2 (OC2M = Output Channel 2 )
					Timer->CCMR1 		|= (pwrmd<<12); 
					Timer->CCMR1 		|= TIM_CCMR1_OC2PE; 
					Timer->CCER 		|= TIM_CCER_CC2E; 
				}
				else if (Channel == 3){
					Timer->CCR3 		= CCR_VAL;
					Timer->CCMR1 		&= ~(0b111<<4);
					Timer->CCMR2 		|= (pwrmd<<4); 
					Timer->CCMR2 		|= TIM_CCMR2_OC3PE; 
					Timer->CCER 		|= TIM_CCER_CC3E; 
				}
				else if (Channel == 4){
					Timer->CCR4			= CCR_VAL;
					Timer->CCMR1		&= ~(0b111<<12);
					Timer->CCMR2 		|= (pwrmd<<12);
					Timer->CCMR2 		|= TIM_CCMR2_OC4PE;
					Timer->CCER 		|= TIM_CCER_CC4E; 
				}
				
				//En dessous d'ici, on a l'aide du plus gentil chat que je connais
			  // Enable auto-reload preload -- //Ensures that your initial configuration — PWM mode, duty cycle, period — actually takes effect before the timer starts counting.	
				Timer->CR1 |= TIM_CR1_ARPE;
				// Force update event to load ARR and CCR values immediately
				Timer->EGR |= TIM_EGR_UG;
				// Start the timer
				Timer->CR1 |= TIM_CR1_CEN;
	
}

//Une fonction qui met le bon PWM volue
int Set_DutyCycle_PWM(TIM_TypeDef *Timer, int Channel, float DutyC){
		int CCR_VAL = (ARR_VAL + 1) * DutyC / 100.0f; //ARR_VAL déjà definie
		switch (Channel){
			case 1: Timer->CCR1 = CCR_VAL;
			case 2: Timer->CCR2 = CCR_VAL;
			case 3: Timer->CCR3 = CCR_VAL;
			case 4: Timer->CCR4 = CCR_VAL;
			default: break;
}
return 0;
Timer->EGR |= TIM_EGR_UG;
}
//Putaing con, ça marche pas 


				/*
				Pulse width modulation mode allows you to generate a signal with a frequency determined 
				by the value of the TIMx_ARR register and a duty cycle determined by the value of the 
				TIMx_CCRx register.
			
				The PWM mode can be selected independently on each channel (one PWM per OCx 
				output) by writing 110 (PWM mode 1) or ‘111 (PWM mode 2) in the OCxM bits in the 
				TIMx_CCMRx register. You must enable the corresponding preload register by setting the 
				OCxPE bit in the TIMx_CCMRx register, and eventually the auto-reload preload register by 
				setting the ARPE bit in the TIMx_CR1 register.
				*/
//Il faut créer une autre fonction qui lui met le bon duty cycle
//Timer->CCR1 =  Duty_cycle*0.01*3.3; // On divise par cent et multiplue par 3.3V, plage de ADC

//Pareil pour la frequence, faut une fonction externe qui lui fait ça


 //Pendant les vacances terminer l'ADC et l'USART (Activités sur Moodle)
//Hell naw, that did not happen cuh

