
/******************************************************************************
*@file  : app.c
*@brief : application
******************************************************************************/

#include "app.h" 

#define ADC_NUM    (1)
uint32_t gadcBuffer[ADC_NUM]; 
static volatile uint32_t gadc1ItcConunt = 0;                 

#define ADCX    (ADC1)

DMA_InitTypeDef DMA_InitStruct;//需配置为全局变量，不然DMA只会触发一次


/******************************************************************************
* @brief : DMA adc to memory transfer complete interrupt Callback.
* @param : None
* @return: None
******************************************************************************/ 
void ADC_DMA_ITC_Callback(void)
{ 
    /* Transfer complete interrupt */
    if (SET == DMA_GetFlagStatus(DMA1_Channel3, DMA_FLAG_TC))
    {
        gadc1ItcConunt = 1;
        DMA_ClearFlag(DMA1_Channel3, DMA_FLAG_TC);
    }     
}


/******************************************************************************
* @brief : ADC GPIO config.
* @param : None
* @return: None
******************************************************************************/
void ADC_GPIO_Config(void)
{
    GPIO_InitTypeDef GPIO_InitStruct;
    
    __RCC_GPIOC_CLK_ENABLE();
    
    /* Configure ADC Channel_13 pin as analog input */
    GPIO_InitStruct.Pin       = GPIO_PIN_3;
    GPIO_InitStruct.Mode      = GPIO_MODE_ANALOG;
    GPIO_InitStruct.Pull      = GPIO_NOPULL;
    GPIO_Init(GPIOC, &GPIO_InitStruct); 
}

/******************************************************************************
* @brief : ADC Common register config.
* @param : None
* @return: None
******************************************************************************/
void ADC_Common_Register_Config(void)
{
    ADC_CommonInitTypeDef ADC_CommonInitStructure;

    ADC_CommonInitStructure.ADC_Mode = ADC_MODE_INDEPENDENT;//双ADC模式选择
    ADC_CommonInitStructure.ADC_Prescaler = ADC_CLOCK_DIV4;//ADC_CLK分频选择
    ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAACCESSMODE_DISABLED;//双ADC下DMA功能选择
    ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TWOSAMPLINGDELAY_5CYCLES;//2个采样阶段之间的延迟
    ADC_CommonInit(&ADC_CommonInitStructure);
}

/******************************************************************************
* @brief : ADC config.
* @param : None
* @return: None
******************************************************************************/
void ADC_Config(void)
{
    ADC_InitTypeDef ADC_InitStructure;
    
    ADC_InitStructure.ADC_Resolution = ADC_RESOLUTION_12B;//分辨率
    ADC_InitStructure.ADC_ContinuousConvMode = ADC_CONT_DISABLE;//连续转换模式
    ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;//外部触发边沿选择
    ADC_InitStructure.ADC_ExternalTrigConv = ADC_EXTERNAL_TIG0;//触发模式
    ADC_InitStructure.ADC_DataAlign = ADC_DATAALIGN_RIGHT;//数据对齐
    ADC_InitStructure.ADC_NbrOfConversion = ADC_NUM;//规则通道序列长度
    ADC_Init(ADCX, &ADC_InitStructure);
    
    //规则通道设置
    ADC_RegularChannelConfig(ADCX, ADC_CHANNEL_13, ADC_SEQUENCE_SQ1, ADC_SMP_CLOCK_320);
}

/******************************************************************************
* @brief : ADC DMA config.
* @param : None
* @return: None
******************************************************************************/
void ADC_DMA_Config(void)
{
    __RCC_DMA1_CLK_ENABLE();
    
    DMA_BigEndianConfig(DMA1, DISABLE);
    
    DMA_DeInit(DMA1_Channel3);
    
    DMA_InitStruct.Mode = DMA_MODE_CIRCULAR;    
    DMA_InitStruct.DataFlow = DMA_DATAFLOW_P2M;
    DMA_InitStruct.ReqID = DMA1_REQ0_ADC1;
    DMA_InitStruct.RawInt = DMA_RAWINT_ENABLE;
    DMA_InitStruct.SrcInc = DMA_SRCINC_DISABLE;
    DMA_InitStruct.DestInc = DMA_DESTINC_ENABLE;
    DMA_InitStruct.SrcWidth = DMA_SRCWIDTH_WORD;   
    DMA_InitStruct.DestWidth = DMA_DESTWIDTH_WORD;
    DMA_InitStruct.SrcBurst = DMA_SRCBURST_1;
    DMA_InitStruct.DestBurst = DMA_DESTBURST_1;

    DMA_InitStruct.SrcAddr     = (uint32_t)&ADC1->DR;
    DMA_InitStruct.DestAddr    = (uint32_t)gadcBuffer;
    DMA_InitStruct.Size        = 1;    

    DMA_Init(DMA1_Channel3, &DMA_InitStruct);
    
    // Enable interrupt
    DMA_ClearFlag(DMA1_Channel3, DMA_FLAG_RTC);
    DMA_ITConfig(DMA1_Channel3, DMA_IT_TC, ENABLE);
    
    // Enable NVIC IRQ
    NVIC_ClearPendingIRQ(DMA1_IRQn);
    NVIC_SetPriority(DMA1_IRQn, 0x00);
    NVIC_EnableIRQ(DMA1_IRQn); 
    
    DMA_Cmd(DMA1_Channel3, ENABLE); 
}


/******************************************************************************
* @brief:  Enable ADC, start conversion of regular channle 
* @param:  None 
* @return: None
******************************************************************************/
void ADC_RegularStart(void)
{
    /* Enable ADC DMA mode */
    ADC_DMACmd(ADCX, ENABLE);
    
    /* Enable the ADC peripheral */
    ADC_Cmd(ADCX, ENABLE);

    /* Clear the SR register */
    ADC_ClearFlag(ADCX, ADC_IT_FLAG_ALL);      

    /* Start conversion */
    ADC_SoftwareStartConv(ADCX);

}


/******************************************************************************
* @brief : ADC function test.
* @param : None
* @return: None
******************************************************************************/
void APP_ADC_Test(void)
{
    uint32_t i;
    
    printfS("ADC DMA test \r\n");
    
    ADC_GPIO_Config();
    
    ADC_Common_Register_Config();
    
    ADC_Config();
    
    ADC_DMA_Config();
    
    ADC_RegularStart();
    
    while(1)
    {
        ADC_SoftwareStartConv(ADCX);
        
        while(!gadc1ItcConunt);
        gadc1ItcConunt =0;
        for (i = 0; i < ADC_NUM; i++)
        {
            printfS("Channel_%d = %d\r\n", ((gadcBuffer[i] >> 16) & 0xFF), (gadcBuffer[i] & 0xFFF));
        }
        DelayMs(1000);
    }
    
    
    
}






