/**
  ******************************************************************************
  * @file    main.c
  *
  * @brief   Запускается циклическое преобразование 0 и 1 каналов.
  *          Каждые 32 измерения вызывается прерывание, где устанавливается
  *          флаг, запускающий процедуру вывода результатов измерений через
  *          UART2.
  *
  *          Компилятор: GCC ARM 4.9.3
  *          Среда: Qt Creator 3.4.2
  *
  * @author  НИИЭТ
  *             - Богдан Колбов (bkolbov), kolbov@niiet.ru
  * @date    07.12.2015
  *
  ******************************************************************************
  * @attention
  *
  * ДАННОЕ ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ ПРЕДОСТАВЛЯЕТСЯ «КАК ЕСТЬ», БЕЗ КАКИХ-ЛИБО
  * ГАРАНТИЙ, ЯВНО ВЫРАЖЕННЫХ ИЛИ ПОДРАЗУМЕВАЕМЫХ, ВКЛЮЧАЯ ГАРАНТИИ ТОВАРНОЙ
  * ПРИГОДНОСТИ, СООТВЕТСТВИЯ ПО ЕГО КОНКРЕТНОМУ НАЗНАЧЕНИЮ И ОТСУТСТВИЯ
  * НАРУШЕНИЙ, НО НЕ ОГРАНИЧИВАЯСЬ ИМИ. ДАННОЕ ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ
  * ПРЕДНАЗНАЧЕНО ДЛЯ ОЗНАКОМИТЕЛЬНЫХ ЦЕЛЕЙ И НАПРАВЛЕНО ТОЛЬКО НА
  * ПРЕДОСТАВЛЕНИЕ ДОПОЛНИТЕЛЬНОЙ ИНФОРМАЦИИ О ПРОДУКТЕ, С ЦЕЛЬЮ СОХРАНИТЬ ВРЕМЯ
  * ПОТРЕБИТЕЛЮ. НИ В КАКОМ СЛУЧАЕ АВТОРЫ ИЛИ ПРАВООБЛАДАТЕЛИ НЕ НЕСУТ
  * ОТВЕТСТВЕННОСТИ ПО КАКИМ-ЛИБО ИСКАМ, ЗА ПРЯМОЙ ИЛИ КОСВЕННЫЙ УЩЕРБ, ИЛИ
  * ПО ИНЫМ ТРЕБО ВАНИЯМ, ВОЗНИКШИМ ИЗ-ЗА ИСПОЛЬЗОВАНИЯ ПРОГРАММНОГО ОБЕСПЕЧЕНИЯ
  * ИЛИ ИНЫХ ДЕЙСТВИЙ С ПРОГРАММНЫМ ОБЕСПЕЧЕНИЕМ.
  *
  * <h2><center>&copy; 2015 ОАО "НИИЭТ"</center></h2>
  ******************************************************************************
  */

#include "niietcm4.h"
#include "retarget.h"

void SystemInit()
{
    // переходим на системную частоту 72МГц
    RCC_PLLAutoConfig(RCC_PLLRef_XI_OSC, 72000000);

    // инициализация printf
    retarget_init();

    // хак, чтобы избежать зависших секвенсоров от выставленных запросов по 0 каналу
    // цифровыми компараторами. Хотя в данном случае это необязательно, т.к. 0-ой канал используется.
    for (uint32_t i = 0; i < 24; i++)
    {
        ADC_DC_DeInit((ADC_DC_Module_TypeDef)i);
    }

    // включаем тактирование 0-модуля ацп (0 и 1 каналы)
    // делим системную частоту на 6, и получаем тактирование АЦП 12МГц.
    RCC_ADCClkDivConfig(RCC_ADCClk_0, 2, ENABLE);
    RCC_PeriphClkCmd(RCC_PeriphClk_ADC, ENABLE);
    RCC_ADCClkCmd(RCC_ADCClk_0, ENABLE);

    // настройка модуля АЦП
    ADC_Init_TypeDef ADC_InitStruct;
    ADC_StructInit(&ADC_InitStruct);
    ADC_InitStruct.ADC_Resolution = ADC_Resolution_12bit;
    ADC_InitStruct.ADC_Average = ADC_Average_64;
    ADC_InitStruct.ADC_Mode = ADC_Mode_Active;
    ADC_Init(ADC_Module_0, &ADC_InitStruct);
    // включение модуля АЦП
    ADC_Cmd(ADC_Module_0, ENABLE);

    // секвенсор 0 работает циклически
    ADC_SEQ_Init_TypeDef ADC_SEQ_InitStruct;
    ADC_SEQ_StructInit(&ADC_SEQ_InitStruct);
    ADC_SEQ_InitStruct.ADC_SEQ_StartEvent = ADC_SEQ_StartEvent_Cycle;
    ADC_SEQ_InitStruct.ADC_Channels = ADC_Channel_0 | ADC_Channel_1;
    ADC_SEQ_Init(ADC_SEQ_Module_0, &ADC_SEQ_InitStruct);

    // включаем прерывание секвенсора после 32 измерений
    ADC_SEQ_ITConfig(ADC_SEQ_Module_0, 32, DISABLE);
    ADC_SEQ_ITCmd(ADC_SEQ_Module_0, ENABLE);
    NVIC_EnableIRQ(ADC_SEQ0_IRQn);
}

volatile uint32_t adc_irq_flag = 0;

int main()
{
    uint32_t ch0_res;
    uint32_t ch1_res;

    printf("\nStart!\n");
    printf("Measure results:\n");
    printf(" CH0     CH1\n");
    // включаем секвенсор, циклические измерения сразу же начнутся
    ADC_SEQ_Cmd(ADC_SEQ_Module_0, ENABLE);
    
    while(1)
    {
        if (adc_irq_flag)
        {
            adc_irq_flag = 0;
            while (ADC_SEQ_GetFIFOLoad(ADC_SEQ_Module_0))
            {
                ch0_res = ADC_SEQ_GetFIFOData(ADC_SEQ_Module_0);
                ch1_res = ADC_SEQ_GetFIFOData(ADC_SEQ_Module_0);

                printf("%04d,   %04d\r", ch0_res, ch1_res);
            }
        }
    }
}

void ADC_SEQ0_IRQHandler()
{
    ADC_SEQ_ITStatusClear(ADC_SEQ_Module_0);

    adc_irq_flag = 1;
}
