#include "stm32f0xx_hal.h"
#include "adc.h"
#include "led.h"

#if 0

#define ADC_FACTOR          0.000806

ADC_HandleTypeDef             AdcHandle;
ADC_ChannelConfTypeDef        sConfig;
ADC_FILTER_t                  adc_bat;
float                         bat_voltage = 0.0; 

//
void adc_init(void)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};

    __HAL_RCC_GPIOA_CLK_ENABLE();
    __HAL_RCC_ADC1_CLK_ENABLE();

    GPIO_InitStruct.Pin = GPIO_PIN_4;
    GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
    
    
    AdcHandle.Instance          = ADC1;
    
    HAL_ADC_DeInit(&AdcHandle);
  
    AdcHandle.Init.ClockPrescaler        = ADC_CLOCK_SYNC_PCLK_DIV2;      /* Synchronous clock mode, input ADC clock with prscaler 2 */

    AdcHandle.Init.Resolution            = ADC_RESOLUTION_12B;            /* 12-bit resolution for converted data */
    AdcHandle.Init.DataAlign             = ADC_DATAALIGN_RIGHT;           /* Right-alignment for converted data */
    AdcHandle.Init.ScanConvMode          = ADC_SCAN_DIRECTION_FORWARD;    /* Sequencer disabled (ADC conversion on only 1 channel: channel set on rank 1) */
    AdcHandle.Init.EOCSelection          = ADC_EOC_SINGLE_CONV;           /* EOC flag picked-up to indicate conversion end */
    AdcHandle.Init.LowPowerAutoPowerOff  = DISABLE;
    AdcHandle.Init.LowPowerAutoWait      = DISABLE;                       /* Auto-delayed conversion feature disabled */
    AdcHandle.Init.ContinuousConvMode    = ENABLE;                        /* Continuous mode enabled (automatic conversion restart after each conversion) */
    AdcHandle.Init.DiscontinuousConvMode = DISABLE;                       /* Parameter discarded because sequencer is disabled */
    AdcHandle.Init.ExternalTrigConv      = ADC_SOFTWARE_START;            /* Software start to trig the 1st conversion manually, without external event */
    AdcHandle.Init.ExternalTrigConvEdge  = ADC_EXTERNALTRIGCONVEDGE_NONE; /* Parameter discarded because software trigger chosen */
    AdcHandle.Init.DMAContinuousRequests = DISABLE;                       /* ADC DMA continuous request to match with DMA circular mode */
    AdcHandle.Init.Overrun               = ADC_OVR_DATA_OVERWRITTEN;      /* DR register is overwritten with the last conversion result in case of overrun */
    AdcHandle.Init.SamplingTimeCommon    = ADC_SAMPLETIME_28CYCLES_5;
        
    HAL_ADC_Init(&AdcHandle);
  
    HAL_ADCEx_Calibration_Start(&AdcHandle);
  
    sConfig.Channel                      = ADC_CHANNEL_4;               /* Channel to be converted */
    sConfig.Rank                         = ADC_RANK_CHANNEL_NUMBER;
    
    HAL_ADC_ConfigChannel(&AdcHandle, &sConfig);
  
    HAL_ADC_Start(&AdcHandle);
}


//
float adc_get_bat_voltage(void)
{
    return HAL_ADC_GetValue(&AdcHandle) * ADC_FACTOR;
}


//
float adc_average(ADC_FILTER_t *flt, float new_value)
{
    if (!(flt->head < ADC_FILTER_LEN))
        flt->head = 0;

    if (flt->count < ADC_FILTER_LEN)
        flt->count++;

    flt->sum -= flt->buf[flt->head];
    flt->sum += new_value;
    flt->buf[flt->head++] = new_value;
  
    return flt->sum/(flt->count);
}


//
void adc_task(void)
{
    bat_voltage = 2*adc_average(&adc_bat, HAL_ADC_GetValue(&AdcHandle) * ADC_FACTOR);
    
    if (bat_voltage > 3.4)
        led_but_on();
    else
        led_but_toggle();
}

#endif
