/*
 * adc.c
 *
 *  Created on: Sep 6, 2017
 *      Author: dmitrijs
 */

#include "main.h"

void Adc_Init(void) {

	RCC->APB2ENR |= RCC_APB2ENR_ADCEN;
	ADC1->CFGR2 = (0x00000002 << 30);		// pclk/4 -> 12Mhz
	ADC1->SMPR = 0x00000001;				// Sample 7.5 adc cycles
	ADC1->CFGR1 = 0;
	/* (1) Ensure that ADEN = 0 */
	/* (2) Clear ADEN by setting ADDIS*/
	/* (3) Clear DMAEN */
	/* (4) Launch the calibration by setting ADCAL */
	/* (5) Wait until ADCAL=0 */
	if ((ADC1->CR & ADC_CR_ADEN) != 0) /* (1) */
	{
		ADC1->CR |= ADC_CR_ADDIS; /* (2) */
	}
	while ((ADC1->CR & ADC_CR_ADEN) != 0) {
		/* For robust implementation, add here time-out management */
	}
	ADC1->CFGR1 &= ~ADC_CFGR1_DMAEN; /* (3) */
	ADC1->CR |= ADC_CR_ADCAL; /* (4) */
	while ((ADC1->CR & ADC_CR_ADCAL) != 0) /* (5) */
	{
		/* For robust implementation, add here time-out management */
	}
	/* (1) Ensure that ADRDY = 0 */
	/* (2) Clear ADRDY */
	/* (3) Enable the ADC */
	/* (4) Wait until ADC ready */
	if ((ADC1->ISR & ADC_ISR_ADRDY) != 0) /* (1) */
	{
		ADC1->ISR |= ADC_ISR_ADRDY; /* (2) */
	}
	ADC1->CR |= ADC_CR_ADEN; /* (3) */
	while ((ADC1->ISR & ADC_ISR_ADRDY) == 0) /* (4) */
	{
		/*TODO For robust implementation, add here time-out management */
	}

	ADC1->IER = 0;
//NVIC_EnableIRQ(ADC1_IRQn);
}

unsigned short LPF(unsigned short lpf_c, unsigned short value,
		unsigned short old_value) {
	// Averageing filtering

	float tmp;

	tmp = ((float) (value - old_value) * ((float) (lpf_c) / (float) 1000.0)); // filter
	if (tmp > 0)
		tmp += (float) 0.5;					// roundup
	else
		tmp -= (float) 0.5;

	return (unsigned short) ((signed int) old_value + (signed int) tmp);

}

unsigned short Adc_Read(unsigned char ch) {
	unsigned short tmp;
	if (ADC1->ISR & ADC_ISR_EOC)
		tmp = ADC1->DR;     //ADC1->ISR |= ADC_ISR_EOC; // clear EOC flag
	ADC1->CHSELR = (1 << ch);     // select channel
	ADC1->CR |= ADC_CR_ADSTART;
	while ((~ADC1->ISR) & ADC_ISR_EOC)
		;
	ADC1->ISR |= ADC_ISR_EOC;
	tmp = ADC1->DR;
	return tmp;
}

