#include "adc.h"

void (* pFncADC) (void); /* d�claration d�un pointeur de fonction */

void MyADC_Init_Periph (void (* ptrFonction)(void))
{
	pFncADC = ptrFonction; /* affectation du pointeur */
}

void MyADC_Init(MyADC_Struct_TypeDef * ADCStructPtr)
{
	RCC->CFGR |= RCC_CFGR_ADCPRE_1;			// ADC Prescaler : divided by 6 -> 72MHz to 12MHz
	RCC->APB2ENR |= RCC_APB2ENR_ADC1EN;	//We activate the clock first
	if(ADCStructPtr->channel < 10)			//Cycle and channel selection	-> permet de regler en fonction de la r�sistance donn�e
	{
		
		ADCStructPtr->ADC->SMPR2 |= (ADCStructPtr->cycle<<(ADCStructPtr->channel*3)); //Channel < 10
	}
	else {
		ADCStructPtr->ADC->SMPR1 |= (ADCStructPtr->cycle<<((ADCStructPtr->channel-10)*3)); //Channel > 10
	}
	ADCStructPtr->ADC->SQR1 &= ADC_SQR1_L;						//Channel sequence length -> 1 conversion (0000)
	ADCStructPtr->ADC->SQR3 |= ADCStructPtr->channel;	//Sequence Reader, seulement le SQ1 est lu dans notre cas, nous associons un channel � ce dernier.
	ADCStructPtr->ADC->CR2 |= ADC_CR2_EXTTRIG;				//Activation du trigger externe
	ADCStructPtr->ADC->CR2 |= ADC_CR2_EXTSEL;					//Event externe choisie : SWSTART
	MyADC_ActiveIT(ADCStructPtr->ADC,0);
	ADCStructPtr->ADC->CR2 |= ADC_CR2_ADON;						//Init l'ADC
	MyADC_Base_Start(ADCStructPtr->ADC);							//Debut du premier ADC
}

void MyADC_ActiveIT(ADC_TypeDef * ADC, uint8_t Prio)
{
	ADC->CR1 |= ADC_CR1_EOCIE; 									//Interruption active
	NVIC->IP[ADC1_2_IRQn] |= (Prio << 0x4);			//Prio de l'interruption (p.197 manuel reference RM0008 pour ADC1_IRQn)
	NVIC->ISER[0] |= (0x1<<ADC1_2_IRQn);				//Active l'interruption au niveau NVIC  (p.119 manuel programming pour ISER[0])
}

void ADC1_2_IRQHandler(void)
{
	if (pFncADC != 0)
	(*pFncADC) (); /* appel indirect de la fonction */
	MyADC_Base_Start(ADC1);
	ADC1->SR &= ~ADC_SR_EOC;	//Prochaine lecture pouvant �tre effectu�e.
}
