AnsweredAssumed Answered

Problem with DMA

Question asked by das.sanjib on Jan 23, 2014
Latest reply on Jan 31, 2014 by das.sanjib
ADC converts 512(Half Buffer complete) samples in 3.2 ms. I have configured the TImer2 as 6.25 us  i.e 3.2ms/512 = 6.25us. Now I am calling a iir filter function inside the handler which consumes a time of 0.3 ms and if I am not wrong the process of another half buffer completion is taking place simultneously. The IIR filter takes 512 as buffer input and gives an 4 output buffer of 64 size ya1(ADC1), ya2(ADC1),yb1(ADC2),yb2(ADC2) . (Different samples are combined together and then divided by 2 to maintain the same phase.) So the DAC should read 8 elements from any of the output buffer which maintain the same phase. well this is the scope. So DAC is triggered as timer 6 which is configured as 0.4 as 3.2ms(time taken for 512 samples)/8 = 0.4ms. But the problem arise when the IIR function is called ADCDualConvertedValues has some different address in the IIR function so the data which is fetched inside the function has wrong value. But I observed that If I disabling DMA_Cmd(DMA2_Stream0, Disable) inside the handler correct address is passed. But I don't want to disable it should be continous. So what is the mistake  anm doing


One more doubt
I configured DMA in the way I have pasted below . Will this DMA configuration will cause some unexpected behaviour when  I am rumming the DMA contiously(circular).

Here is my updated code



// STM32 ADC IQ Sample @ 200 KHz (PC.0, PC.1) STM32F4 Discovery

// Assumptions per system_stm32f4xx.c CPU @ 128 MHz, APB2 @ 64  MHz max is 84 (/2), APB1 @ 32 MHz max is 42 (/4)


/**
  ******************************************************************************
  * @file    USART/main.c
  * @author  Andrew Markham
  * @version V1.0.0
  * @date    27-April-2012
  * @brief   Main program body
  ******************************************************************************
  */

 /* Issue
  * 16-Jan-2014 Sanjib -  Solved the Problem of ADC_trigger timer interrupt by setting the PSC register and
  * ARR    register to 2 - 1 and 200 - 1 for 6.25 us . as register are index starting from 0 . So we have to
  * set the register with the required value by decrementing it with 1.
  *
  * 18-Jan-2014 SAnjib -  Solved the problem after initializing DAC_Peripheral_size and ADC_Peripheral_size
  * in DMA_Configuration for Both ADC and DAC to Word by initializing it to halfword
  */


/* Includes ------------------------------------------------------------------*/
#include "unistd.h"
#include "stm32f4xx.h"
#include "stm32f4_discovery.h"
#include "stm32f4xx_tim.h"
#include "stm32f4xx_rcc.h"
#include "stm32f4xx.h"
#include <misc.h>
#include "stm32f4xx_adc.h"
#include "stm32f4xx_gpio.h"
#include "stm32f4xx_dac.h"
#include "stm32f4xx_tim.h"
#include "stm32f4xx_dma.h"
#include "stm32f4xx_usart.h"

//#include <stdio.h>

/* Private typedef -----------------------------------------------------------*/
GPIO_InitTypeDef  GPIO_InitStructure;
/* Private define ------------------------------------------------------------*/
#define ADC_PERIP_ADD    (uint32_t)0x40012308
#define DAC_OP_PERIP_ADD    (uint32_t)&DAC->DHR12R1
#define BUFFERSIZE         1024
#define OUT_BUF_SIZE     64
//......................For_checking
const uint16_t aSine12bit[32] = {
                      2047, 2447, 2831, 3185, 3498, 3750, 3939, 4056, 4095, 4056,
                      3939, 3750, 3495, 3185, 2831, 2447, 2047, 1647, 1263, 909,
                      599, 344, 155, 38, 0, 38, 155, 344, 599, 909, 1263, 1647};
//........................
/* Private macro -------------------------------------------------------------*/

/* Private variables ---------------------------------------------------------*/
__IO uint16_t ADCDualConvertedValues[BUFFERSIZE];
short ya1[OUT_BUF_SIZE], ya2[OUT_BUF_SIZE], yb1[OUT_BUF_SIZE], yb2[OUT_BUF_SIZE];
short ya1_dup[8] = {2047, 2447, 2831, 3185, 3498, 3750, 3939, 4056};
//uint32_ADCDualConvertedValues[BUFFERSIZE];
/* Private function prototypes -----------------------------------------------*/


/**
  * @brief  lp_iir_filter
  * @param  None
  * @retval None
  * Author  Sumit
  * Desc    This function applies the 2nd order iir biquad digital filter on the input data.
  */

void lp_iir_filter(  short* dataIn,  short* ya1, short* ya2, short* yb1,  short* yb2)

{

        int i;

        short *ya_1 = ya1;
        short *ya_2 = ya2;
        short *yb_1 = yb1;
        short *yb_2 = yb2;

        short *a1, *b1, *a2, *b2;

        short wa1, wa1Pre1, wa1Pre2;
        short wa2, wa2Pre1, wa2Pre2;
        short wb1, wb1Pre1, wb1Pre2;
        short wb2, wb2Pre1, wb2Pre2;

        /* Initialization section */
        a1 = dataIn;
        b1 = &dataIn[1];
        a2 = &dataIn[2];
        b2 = &dataIn[3];

        wa1Pre1 = wa1Pre2 = 0;
        wa2Pre1 = wa2Pre2 = 0;
        wb1Pre1 = wb1Pre2 = 0;
        wb2Pre1 = wb2Pre2 = 0;

        /* Numerator coefficients */
        double cb0 = 0.25019560726953249;
        double cb1 = 0.50039121453906499;
        double cb2 = 0.25019560726953249;
        /* Denominator coefficients */
        double ca0 = 1;
        double ca1 = 1.454243586251585; //(-)ve value ; will be taken care of in equation.
        double ca2 = 0.57406191508395477;


        /**
         *
         * code for Q15 conversion of coefficients.
         *
         **/
        short coeff_b0 = cb0 * 32768;
        short coeff_b1 = cb1 * 32768;
        short coeff_b2 = cb2 * 32768;
        short coeff_a0 = ca0 * 32768;
        short coeff_a1 = ca1 * 32768;
        short coeff_a2 = ca2 * 32768;

        for(i=0; i<OUT_BUF_SIZE; i++)
        {
                /**
                 *  Different samples are combined together and then divided by 2 to maintain the same phase.
                 *  Note: Discovery board doesn't support detection of (-)ve voltage.
                 **/
                wa1 = ((((*a1 + *(a1+4)) >> 1)  * coeff_a0) >> 15) - ((coeff_a1 * wa1Pre1 * -1) >> 15) - ((coeff_a2 * wa1Pre2) >> 15);
                wb1 = ((((*b1 + *(b1+4)) >> 1)  * coeff_a0) >> 15) - ((coeff_a1 * wb1Pre1 * -1) >> 15) - ((coeff_a2 * wb1Pre2) >> 15);
                wa2 = ((((*a2 + *(a2+4)) >> 1)  * coeff_a0) >> 15) - ((coeff_a1 * wa2Pre1 * -1) >> 15) - ((coeff_a2 * wa2Pre2) >> 15);
                wb2 = ((((*b2 + *(b2+4)) >> 1)  * coeff_a0) >> 15) - ((coeff_a1 * wb2Pre1 * -1) >> 15) - ((coeff_a2 * wb2Pre2) >> 15);

                *ya_1 = ((coeff_b0 * wa1) >> 15) + ((coeff_b1 * wa1Pre1) >> 15) + ((coeff_b2 * wa1Pre2) >> 15);
                *yb_1 = ((coeff_b0 * wb1) >> 15) + ((coeff_b1 * wb1Pre1) >> 15) + ((coeff_b2 * wb1Pre2) >> 15);
                *ya_2 = ((coeff_b0 * wa2) >> 15) + ((coeff_b1 * wa1Pre2) >> 15) + ((coeff_b2 * wa2Pre2) >> 15);
                *yb_2 = ((coeff_b0 * wb2) >> 15) + ((coeff_b1 * wb1Pre2) >> 15) + ((coeff_b2 * wb2Pre2) >> 15);

                ya_1++;        yb_1++;        ya_2++;        yb_2++;

                a1 += 8;    b1 += 8;    a2 += 8;    b2 += 8;

                wa1Pre2 = wa1Pre1;
                wa1Pre1 = wa1;
                wb1Pre2 = wb1Pre1;
                wb1Pre1 = wb1;
                wa2Pre2 = wa2Pre1;
                wa2Pre1 = wa2;
                wb2Pre2 = wb2Pre1;
                wb2Pre1 = wb2;

        }



        wa1Pre1 = wa1Pre2 = 0;
        wa2Pre1 = wa2Pre2 = 0;
        wb1Pre1 = wb1Pre2 = 0;
        wb2Pre1 = wb2Pre2 = 0;

        a1 = ya1;
        b1 = yb1;
        a2 = ya2;
        b2 = yb2;


        i = OUT_BUF_SIZE >> 1;

        while (1)
        {
            if(i < ((ya_1 - ya1)>>1)) // check if one level of filter operation is over on the buffer elements. If so, reduce the i value (number of
            {                          // elements for next level of filter operation) to half. Re-initialise the 'w' variables and assign the initial buffer
                i = i >> 1;              // addresses to ya_1, yb_1, ya_2, yb_2 and aa1,bb1, aa2, bb2 pointers. We are doing in-place pointer arithmetic.
                wa1Pre1 = wa1Pre2 = 0;
                wa2Pre1 = wa2Pre2 = 0;
                wb1Pre1 = wb1Pre2 = 0;
                wb2Pre1 = wb2Pre2 = 0;

                ya_1 = a1 = ya1;
                yb_1 = b1 = yb1;
                ya_2 = a2 = ya2;
                yb_2 = b2 = yb2;
            }

            if(i < (OUT_BUF_SIZE >> 3))
            {
                break;
            }


            wa1 = ((*a1 * coeff_a0) >> 15) - ((coeff_a1 * wa1Pre1 * -1) >> 15) - ((coeff_a2 * wa1Pre2) >> 15);
            wb1 = ((*b1 * coeff_a0) >> 15) - ((coeff_a1 * wb1Pre1 * -1) >> 15) - ((coeff_a2 * wb1Pre2) >> 15);
            wa2 = ((*a2 * coeff_a0) >> 15) - ((coeff_a1 * wa2Pre1 * -1) >> 15) - ((coeff_a2 * wa2Pre2) >> 15);
            wb2 = ((*b2 * coeff_a0) >> 15) - ((coeff_a1 * wb2Pre1 * -1) >> 15) - ((coeff_a2 * wb2Pre2) >> 15);

            *ya_1 = ((coeff_b0 * wa1) >> 15) + ((coeff_b1 * wa1Pre1) >> 15) + ((coeff_b2 * wa1Pre2) >> 15);
            *yb_1 = ((coeff_b0 * wb1) >> 15) + ((coeff_b1 * wb1Pre1) >> 15) + ((coeff_b2 * wb1Pre2) >> 15);
            *ya_2 = ((coeff_b0 * wa2) >> 15) + ((coeff_b1 * wa1Pre2) >> 15) + ((coeff_b2 * wa2Pre2) >> 15);
            *yb_2 = ((coeff_b0 * wb2) >> 15) + ((coeff_b1 * wb1Pre2) >> 15) + ((coeff_b2 * wb2Pre2) >> 15);

            ya_1++;        yb_1++;        ya_2++;        yb_2++;

            a1 += 2;    b1 += 2;    a2 += 2;    b2 += 2;

            wa1Pre2 = wa1Pre1;
            wa1Pre1 = wa1;
            wb1Pre2 = wb1Pre1;
            wb1Pre1 = wb1;
            wa2Pre2 = wa2Pre1;
            wa2Pre1 = wa2;
            wb2Pre2 = wb2Pre1;
            wb2Pre1 = wb2;

        }
}
/* Private functions ---------------------------------------------------------*/
/**
  * @brief  RCC_Configuration
  * @param  None
  * @retval None
  * Author  Sanjib
  * Desc    RCC Configuration for peripherals
  */
void RCC_Configuration(void)
{

    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);        //Enable clock for GPIO A (ADC Pins and DAC Pins)
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE);        //Enable clock for DMA1 (DAC DMA)
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);        //Enable clock for DMA2 (ADC DMA)
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);        //Enable clock for TIM2 (used for ADC Trigger)
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE);        //Enable clock for TIM6 (used for DAC Trigger)
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);        //Enable clock for ADC1
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC2, ENABLE);        //Enable clock for ADC2
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);            //Enable clock for DAC

}

/**
  * @brief  GPIO_Configuration
  * @param  None
  * @retval None
  * Author  Sanjib
  * Desc    GPIO Configuration
  */
void GPIO_Configuration(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4;       //Enable the PA02, PA03 (for ADC) and PA04(DAC)
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;                            //Set as Analog mode
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

}


/**
  * @brief  TIMER2_Configuration
  * @param  None
  * @retval None
  * Author  Sanjib
  * Desc    TIMER2 Configuration For ADC
  */
void TIMER2_Configuration(void)
{
    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
    TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
    TIM_TimeBaseStructure.TIM_Period = 50 - 1;                            //Timer clock for 6.25us
    TIM_TimeBaseStructure.TIM_Prescaler = 2 - 1;
    TIM_TimeBaseStructure.TIM_ClockDivision = 0;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
    TIM_SelectOutputTrigger(TIM2, TIM_TRGOSource_Update);                  // ADC_ExternalTrigConv_T2_TRGO
    TIM_Cmd(TIM2, ENABLE);                                                // TIM2 enable counter
}


/**
  * @brief  TIMER6_Configuration
  * @param  None
  * @retval None
  * Author  Sanjib
  * Desc    TIMER6 Configuration For DAC
  */
void TIMER6_Configuration(void)
{
    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
    TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
    TIM_TimeBaseStructure.TIM_Period = 3200 - 1;                         //Timer clock for 6.25us
    TIM_TimeBaseStructure.TIM_Prescaler = 2 - 1;
    TIM_TimeBaseStructure.TIM_ClockDivision = 0;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInit(TIM6, &TIM_TimeBaseStructure);
    TIM_SelectOutputTrigger(TIM6, TIM_TRGOSource_Update);               // DAC_ExternalTrigConv_T2_TRGO
    TIM_Cmd(TIM6, ENABLE);
}


/**
  * @brief  NVIC_Configuration
  * @param  None
  * @retval None
  * Author  Sanjib
  * Desc    NVIC Configuration for ADC DMA Stream0 So that we can initiate DMA transfer
  */
void NVIC_Configuration(void)
{
    NVIC_InitTypeDef NVIC_InitStructure;                                 //Enable the DMA Stream IRQ Channel
    NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream0_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
}


/**
  * @brief  DMA_ADC_Configuration
  * @param  None
  * @retval None
  * Author  Sanjib
  * Desc    DMA Configuration for ADC
  */
void DMA_ADC_Configuration(void)
{
    DMA_InitTypeDef DMA_InitStructure;
    DMA_InitStructure.DMA_Channel = DMA_Channel_0;                                // Enable channel 0 for DMA
    DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&ADCDualConvertedValues;    //Assigning the memory Base address
    DMA_InitStructure.DMA_PeripheralBaseAddr = ADC_PERIP_ADD;                     //Assigning the peripheral Address// CDR_ADDRESS; Packed ADC1, ADC2
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;                        //DMA_transfer_dir-Peripheral to memory
    DMA_InitStructure.DMA_BufferSize = BUFFERSIZE;
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;            //Peripheral address pointer is fixed
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;                        //Memory increment as per as memory size
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;        //DMA_PeripheralDataSize_Word;
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;            //DMA_MemoryDataSize_word
    DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;                                //Circular mode
    DMA_InitStructure.DMA_Priority = DMA_Priority_High;                            //Priority_high
    DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable;                        //To enable the use of the FIFO threshold level, the direct mode must be disabled
    DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
    DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
    DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
    DMA_Init(DMA2_Stream0, &DMA_InitStructure);                                    //Update the registers
    DMA_ITConfig(DMA2_Stream0, DMA_IT_TC | DMA_IT_HT, ENABLE);                    //Enable DMA Stream Half / Transfer Complete interrupt
    DMA_Cmd(DMA2_Stream0, ENABLE);                                                //DMA2_Stream0 enable

}


/**
  * @brief  ADC_Configuration
  * @param  None
  * @retval None
  * Author  Sanjib
  * Desc    ADC Configuration
  */
void ADC_Configuration(void)
{
    ADC_CommonInitTypeDef ADC_CommonInitStructure;
    ADC_InitTypeDef ADC_InitStructure;


    ADC_CommonInitStructure.ADC_Mode =  ADC_DualMode_RegSimult;
    ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;
    ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_2;                 //2 half-words one by one, 1 then 2
    ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;     //really required this?
    ADC_CommonInit(&ADC_CommonInitStructure);

    ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;                            //12 bit resolution
    ADC_InitStructure.ADC_ScanConvMode = DISABLE;                                     //ScanConvMode = DISABLE means Multi channel disabled
    ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;                             //ContinuousConvMode = DISABLE means Triggered conversion mode
    ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_Rising;
    ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T2_TRGO;
    ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
    ADC_InitStructure.ADC_NbrOfConversion = 1;                                        //expecting 1 conversion for both ADC 1 and 2
    ADC_Init(ADC1, &ADC_InitStructure);                                                //updating the register for ADC1
    ADC_Init(ADC2, &ADC_InitStructure);                                             //updating the register for ADC2


    ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 1, ADC_SampleTime_15Cycles);      //ADC1 regular channel2 configuration

    ADC_RegularChannelConfig(ADC2, ADC_Channel_3, 1, ADC_SampleTime_15Cycles);         //ADC2 regular channel3 configuration


    ADC_MultiModeDMARequestAfterLastTransferCmd(ENABLE);                            //Enable DMA request after last transfer (Multi-ADC mode)

    ADC_Cmd(ADC1, ENABLE);                                                            //Enable ADC1

    ADC_Cmd(ADC2, ENABLE);                                                            //Enable ADC2

}


/**
  * @brief  DMA_DAC_Configuration
  * @param  None
  * @retval None
  * Author  Sanjib
  * Desc    DMA Configuration for DAC to fed the data in ADC DMA buffer as soon as it triggers the half buffer completion
  * ISSUE
  */

void DMA_DAC_Configuration(void)
{
    DMA_InitTypeDef DMA_InitStructure;
    DMA_InitStructure.DMA_Channel = DMA_Channel_7;                                //Enable channel 7 for DMA
    DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&ya1_dup;//&ADCDualConvertedValues;    //Assigning the memory Base address
    DMA_InitStructure.DMA_PeripheralBaseAddr = DAC_OP_PERIP_ADD;            //Assigning the peripheral Address// CDR_ADDRESS; DAC CH1
    DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;                        //DMA_transfer_dir-Memory to Peripheral
    DMA_InitStructure.DMA_BufferSize = 32;//BUFFERSIZE;
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;            //Peripheral address pointer is fixed
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;                        //Memory increment as per as memory size
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;    //DMA_PeripheralDataSize_HalfWord;
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;                //DMA_MemoryDataSize_Word
    DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;                                //Circular mode
    DMA_InitStructure.DMA_Priority = DMA_Priority_High;                            //Priority_high
    DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable;                        //To enable the use of the FIFO threshold level, the direct mode must be disabled
    DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
    DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
    DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
    DMA_Init(DMA1_Stream5, &DMA_InitStructure);                                    //Update the registers

    DMA_Cmd(DMA1_Stream5, ENABLE);                                                //DMA2_Stream5 enable

}


/**
  * @brief  DAC_Configuration
  * @param  None
  * @retval None
  * Author  Sanjib
  * Desc    DAC Configuration for channel 1
  */
void DAC_Configuration(void)
{

    DAC_InitTypeDef DAC_InitStructure;
    DAC_InitStructure.DAC_Trigger = DAC_Trigger_T2_TRGO;                    //DAC channel1 trigger enable
    DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None;
    DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Enable;            //DAC_Output_Buffer_enable

    DAC_Init(DAC_Channel_1, &DAC_InitStructure);
    DAC_Cmd(DAC_Channel_1, ENABLE);                                            // DAC control reg,  channels  1 ON


}


/**
  * @brief  DMA2_Stream0_Handler
  * @param  None
  * @retval None
  * Author  Sanjib
  * Desc    Interrupt handler for half transfer as well as full transfer
  */
void DMA2_Stream0_IRQHandler(void) // Called at 1 KHz for 200 KHz sample rate, LED Toggles at 500 Hz
{
    static int first_time_flag=1;

    if(DMA_GetITStatus(DMA2_Stream0, DMA_IT_HTIF0))
    {
          /* Clear DMA Stream Half Transfer interrupt pending bit */
          DMA_ClearITPendingBit(DMA2_Stream0, DMA_IT_HTIF0);

          STM_EVAL_LEDOn(LED3);

        //  STM_EVAL_LEDOn(LED4);
          lp_iir_filter((uint16_t)ADCDualConvertedValues, ya1,  ya2,  yb1,  yb2);
          memcpy(ya1_dup,ya1,8);
       //   STM_EVAL_LEDOff(LED4);

          if(first_time_flag == 1)
             {
                 DAC_DMACmd(DAC_Channel_1, ENABLE);                                             //DMA mode enabled for DAC channel 1
                 first_time_flag = 0;
             }
    }
    if(DMA_GetITStatus(DMA2_Stream0, DMA_IT_TCIF0))
    {
         /* Clear DMA Stream Transfer Complete interrupt pending bit */
          DMA_ClearITPendingBit(DMA2_Stream0, DMA_IT_TCIF0);

         // STM_EVAL_LEDOff(LED3);

        //  STM_EVAL_LEDOn(LED4);
          lp_iir_filter((uint16_t)(ADCDualConvertedValues+512), ya1,  ya2,  yb1,  yb2);
        //  STM_EVAL_LEDOff(LED4);
    }
}


/**
  * @brief  Main program
  * @param  None
  * @retval None
  * Author  Sanjib
  * Desc    program to read two ADCs using DMA and driving one DACs using DMA
  */
int main(void)
{

    RCC_Configuration();

    GPIO_Configuration();

    NVIC_Configuration();

    TIMER2_Configuration();

    TIMER6_Configuration();

    DMA_ADC_Configuration();

    ADC_Configuration();

    DAC_Configuration();

    DMA_DAC_Configuration();
    STM_EVAL_LEDInit(LED3);
    STM_EVAL_LEDInit(LED4);


#if 0


     // GPIO_Configuration();

       DAC_configure();
        NVIC_Configuration();

        TIM2_Configuration();


        DMA_Configuration();

        ADC_Configuration();
#endif



        while(1); // Don't want to exit
}

      /**************************************************************************************/

      #ifdef  USE_FULL_ASSERT

      /**
        * @brief  Reports the name of the source file and the source line number
        *   where the assert_param error has occurred.
        * @param  file: pointer to the source file name
        * @param  line: assert_param error line source number
        * @retval None
        */
      void assert_failed(uint8_t* file, uint32_t line)
      {
        /* User can add his own implementation to report the file name and line number,
           ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */

        /* Infinite loop */
        while (1)
        {
        }
      }
      #endif

Outcomes