#include "timer.h"
#include "gpio.h"

void plantage(void) {
	while(1);
}

void (*IT_Tim1) (void) = plantage;
void (*IT_Tim2) (void) = plantage;
void (*IT_Tim3) (void) = plantage;
void (*IT_Tim4) (void) = plantage;

void MyTimer_Base_Init(MyTimer_Struct_Typedef * Timer) {
	if ((Timer->Timer) == TIM1)
		RCC->APB2ENR |= RCC_APB2ENR_TIM1EN;
	if ((Timer->Timer) == TIM2)
		RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;
	if ((Timer->Timer) == TIM3)
		RCC->APB1ENR |= RCC_APB1ENR_TIM3EN;
	if ((Timer->Timer) == TIM4)
		RCC->APB1ENR |= RCC_APB1ENR_TIM4EN;

	Timer->Timer->PSC = Timer->PSC;
	Timer->Timer->ARR = Timer->ARR;
}

void MyTimer_ActiveIT(TIM_TypeDef * Timer, char Prio, void (*IT_function) (void)) {
	Timer->DIER |= TIM_DIER_UIE;
	if (Timer == TIM2) {
		NVIC_EnableIRQ(TIM1_BRK_IRQn);
		NVIC_SetPriority(TIM1_BRK_IRQn, Prio);
		IT_Tim1 = IT_function;
	}
	if (Timer == TIM2) {
		NVIC_EnableIRQ(TIM2_IRQn);
		NVIC_SetPriority(TIM2_IRQn, Prio);
		IT_Tim2 = IT_function;
	}
	if (Timer == TIM3) {
		NVIC_EnableIRQ(TIM3_IRQn);
		NVIC_SetPriority(TIM3_IRQn, Prio);
		IT_Tim3 = IT_function;
	}
	if (Timer == TIM4) {
		NVIC_EnableIRQ(TIM4_IRQn);
		NVIC_SetPriority(TIM4_IRQn, Prio);
		IT_Tim4 = IT_function;
	}
}

void TIM1_IRQHandler(void) {
	TIM1->SR &= ~TIM_SR_UIF;
	(*IT_Tim1)();
}

void TIM2_IRQHandler(void) {
	TIM2->SR &= ~TIM_SR_UIF;
	(*IT_Tim2)();
}

void TIM3_IRQHandler(void) {
	TIM3->SR &= ~TIM_SR_UIF;
	(*IT_Tim3)();
}

void TIM4_IRQHandler(void) {
	TIM4->SR &= ~TIM_SR_UIF;
	(*IT_Tim4)();
}

void MyTimer_PWM(TIM_TypeDef * Timer ,char Channel)
{
	MyGPIO_Struct_TypeDef PWM_OUT;
	PWM_OUT.GPIO_Conf = AltOut_Ppull;
	switch (Channel) {
		case 1:
		case 2:
			Timer->CCMR1 &= ~TIM_CCMR1_OC1M_0;
			Timer->CCMR1 |= (TIM_CCMR1_OC1M_1| TIM_CCMR1_OC1M_2);
			break;
		
		case 3:
		case 4:
			Timer->CCMR2 &= ~TIM_CCMR1_OC1M_0;
			Timer->CCMR2 |= (TIM_CCMR1_OC1M_1| TIM_CCMR1_OC1M_2);
			break;
	}
	
	Timer->CCER |= (TIM_CCER_CC1E << (4*(Channel-1)));

if(Timer == TIM1)
	{
		TIM1->BDTR |= 0x8000;
		PWM_OUT.GPIO = GPIOA;
		switch (Channel) {
		case 1:
			PWM_OUT.GPIO_Pin = 8;
			break;
		case 2:
			PWM_OUT.GPIO_Pin = 9;
			break;
		case 3:
			PWM_OUT.GPIO_Pin = 10;
			break;
		case 4:
			PWM_OUT.GPIO_Pin = 11;
			break;
		}
	}
	if(Timer == TIM2)
	{
		PWM_OUT.GPIO = GPIOA;
		switch (Channel) {
		case 1:
			PWM_OUT.GPIO_Pin = 0;
			break;
		case 2:
			PWM_OUT.GPIO_Pin = 1;
			break;
		case 3:
			PWM_OUT.GPIO_Pin = 2;
			break;
		case 4:
			PWM_OUT.GPIO_Pin = 3;
			break;
		}
	}
	
		if(Timer == TIM3)
	{
		switch (Channel) {
		case 1:
			PWM_OUT.GPIO = GPIOA;
			PWM_OUT.GPIO_Pin = 6;
			break;
		case 2:
			PWM_OUT.GPIO = GPIOA;
			PWM_OUT.GPIO_Pin = 7;
			break;
		case 3:
			PWM_OUT.GPIO = GPIOB;
			PWM_OUT.GPIO_Pin = 0;
			break;
		case 4:
			PWM_OUT.GPIO = GPIOB;
			PWM_OUT.GPIO_Pin = 1;
			break;
		}
	}
	
		if(Timer == TIM4)
	{
			PWM_OUT.GPIO = GPIOB;
		switch (Channel) {
		case 1:
			PWM_OUT.GPIO_Pin = 6;
			break;
		case 2:
			PWM_OUT.GPIO_Pin = 7;
			break;
		case 3:
			PWM_OUT.GPIO_Pin = 8;
			break;
		case 4:
			PWM_OUT.GPIO_Pin = 9;
			break;
		}
	}
	MyGPIO_Init(&PWM_OUT);
}

void MyTimer_DutyCycle(TIM_TypeDef * Timer, char Channel, unsigned int DutyCycle)
{
	unsigned int RC;
	RC = ((Timer->ARR)*(DutyCycle)/10000);
	switch (Channel) {
		case 1:
			Timer->CCR1 = RC;
			break;
		
		case 2:
			Timer->CCR2 = RC;
			break;
		
		case 3:
			Timer->CCR3 = RC;
			break;
		
		case 4:
			Timer->CCR4 = RC;
			break;
	}
}
