#include <cstring>
#include "computing.h"

uint8_t ExtAdcBuffer[EXT_ADC_BUFFER_SIZE];


bool computeAdcResults(uint32_t &freq, double &amplitude, double &dc) {
    // Краевые значения не обрабатываем
#define edge1 32

    // Частота АЦП
    const double Fd = (168.0f / 9.0f) * 1e6f; // Частота дискретизации в герцах

    //    uint8_t ExtAdcBuffer[EXT_ADC_BUFFER_SIZE];

    // Применем медианный фильтр
    // MedianFilter3();

    // Применим фильтр скользящего среднеего
    // MovAvgFilter5();

    // **************************************************************************
    // Оценка размаха. Построим гистограмму
    // знаем, что разрядность АЦП 8 бит - 256 значений

    // Обнуляем вспомогательный массив
    int gg[256];
    memset(gg, 0, sizeof(gg));

    // Формируем гистограмму
    for (uint16_t i = edge1; i < EXT_ADC_BUFFER_SIZE - edge1; i++)
        gg[ExtAdcBuffer[i]]++;

    // Оцениваем пики гистограммы

    int xm = 0;
    uint8_t km1 = 0;
    uint8_t km2 = 0;
    for (uint16_t i = 0; i < 120; i++) {
        if (xm < gg[i]) {
            xm = gg[i];
            km1 = i;
        }
    }

    xm = 0;
    for (uint16_t i = 134; i <= 0xFF; i++) {
        if (xm < gg[i]) {
            xm = gg[i];
            km2 = i;
        }
    }

    // Определяем оценку напряжения в милливольтах, применительно к размаху АЦП
    amplitude = (double) (km2 - km1) / 256.0;
    amplitude *= 2.6048450117218023; // NOTE: магический кофицент для схемы

    // расчет постоянной составляющей
    dc = ((((double) km1 + (double) km2) / 2.0f) / 256.0f * 1000.0f) + 2000.0f;
    // y = 2 + x


    // **************************************************************************
    // Оцениваем частоту
    // Считаем, что 128й уровень находится ровно посередине

    const uint16_t z = 8; // Защитный интервал
    uint32_t xk1 = 0;
    uint32_t xk2 = 0;
    uint32_t xsum = 0;
    uint32_t xnum = 0;

    uint32_t i = edge1;
    // ищем переходы через 128
    while ((i < EXT_ADC_BUFFER_SIZE - edge1) && (ExtAdcBuffer[i] > 128))
        i++;
    i = i + z;
    while ((i < EXT_ADC_BUFFER_SIZE - edge1) && (ExtAdcBuffer[i] < 128))
        i++;
    xk1 = i;
    while ((i < EXT_ADC_BUFFER_SIZE - edge1) && (ExtAdcBuffer[i] > 128))
        i++;
    i = i + z;
    while ((i < EXT_ADC_BUFFER_SIZE - edge1) && (ExtAdcBuffer[i] < 128))
        i++;
    xk2 = i;
    i = i + i;
    xsum = xk2 - xk1;
    xnum = 1;

    // Находим много периодов
    while (i < EXT_ADC_BUFFER_SIZE - edge1) {
        while ((i < EXT_ADC_BUFFER_SIZE - edge1) && (ExtAdcBuffer[i] > 128))
            i++;
        i = i + z;
        while ((i < EXT_ADC_BUFFER_SIZE - edge1) && (ExtAdcBuffer[i] < 128))
            i++;
        if (i < EXT_ADC_BUFFER_SIZE - edge1) {
            xsum = xsum + (i - xk2);
            xnum++;
            xk2 = i;
        }
        i = i + z;
    }
    // Оценка частоты в герцах
    freq = (uint32_t) (Fd / (double) xsum * (double) xnum);

    // Посмотрим, если есть переполнение АЦП в одну или в друнгую сторону, то
    // выдадим ошибку
    if ((km1 == 0) | (km2 == 255))
        return (false);
    else
        return (true);
}
