#include "stm32f10x.h"
#include "../Include/Timer.h"

//REMEMBER TO ENALBLE TIMERS
//EXAMPLES
	//RCC -> APB1ENR |= RCC_APB1ENR_TIM2EN | RCC_APB1ENR_TIM3EN; // Enable TIM2
	//RCC->APB2ENR |= RCC_APB2ENR_TIM1EN; // Enable TIM1

void MyTimer_Base_Init( TIM_TypeDef * Timer , unsigned short ValARR , unsigned short ValPSC ) { // Configuration du timer
Timer -> PSC=(ValPSC);
Timer-> ARR = (ValARR);
Timer->EGR |= TIM_EGR_UG;
};


static void (*p_IT_functions[4])(void); // Pour créer l'array des fonctions

void MyTimer_ActiveIT(TIM_TypeDef *Timer, char Prio,void(*IT_function)(void)) {
		//Enable interruption requisition 
    Timer->DIER |= TIM_DIER_UIE; // Update interrupt enable

    //Id the interruption timer routine
    IRQn_Type IRQn; 

    int timer_index = -1; // Indice pour notre array des pointeurs
    if (Timer == TIM2) {
        IRQn = TIM2_IRQn;
        timer_index = 0;
    } else if (Timer == TIM3) {
        IRQn = TIM3_IRQn;
        timer_index = 1;
    } else if (Timer == TIM4) {
        IRQn = TIM4_IRQn;
        timer_index = 2;
    }
    // Keep the pointer of the valid timer function
    if (timer_index != -1) {
        p_IT_functions[timer_index] = IT_function; // index the function
    } else {
        return; // Timer invalid
    }
		
		// set interruption priority
    NVIC_SetPriority(IRQn, Prio);

    // Enable routine
    NVIC_EnableIRQ(IRQn);
};


void TIM2_IRQHandler(void) {
    // Clean flag
    TIM2->SR &= ~TIM_SR_UIF; // Drapeau d'interuption 
		//Call function
	  if (p_IT_functions[0] != 0) {
        p_IT_functions[0](); // Execute fonction
    }
};
void TIM3_IRQHandler(void) {
  // Clean flag
  TIM3->SR &= ~TIM_SR_UIF;
  //Call function
  if (p_IT_functions[1] != 0) {
    p_IT_functions[1](); // Execute function
  }
};
void TIM4_IRQHandler(void) {
    // Clean flag
    TIM4->SR &= ~TIM_SR_UIF; 
		//Call function
	  if (p_IT_functions[2] != 0) {
        p_IT_functions[2](); // Execute function
    }
};
// IT PWM
void TIM1_CC_IRQHandler(void) {
    // Clean flag
    TIM1 -> DIER &= ~TIM_DIER_CC1IE; 
    //Set bit
	GPIOA -> ODR |= (0x1 << 8);
};

void TIM1_UP_IRQHandler(void) {
    // Clean flag
    TIM1-> DIER &= ~TIM_DIER_TIE;

    //Reset bit
      GPIOA -> ODR &=  ~(0x1 << 8);
    
};
void EnableTimer(TIM_TypeDef *Timer){
	if(Timer == TIM2){
		RCC -> APB1ENR |= RCC_APB1ENR_TIM2EN;
	}
	else if(Timer == TIM3){
		RCC -> APB1ENR |= RCC_APB1ENR_TIM3EN;
	}
	else if(Timer == TIM4){
		RCC -> APB1ENR |= RCC_APB1ENR_TIM4EN;
	}
	else if(Timer == TIM1){
		RCC->APB2ENR |= RCC_APB2ENR_TIM1EN;
	}
	else{
	}
}
