AnsweredAssumed Answered

STM32F4 Triple Mode ADC - DMA - Wrong order Data output

Question asked by da_cunha.julian on Jun 2, 2016
Latest reply on Jun 2, 2016 by Clive One
Hello Everyone,
I have implemented a ADC conversion of 6 Analog Voltages, 2 on each ADC1,2,3. They are running in Triple Mode and The DMA2 is writing them to a buffer.
With the DMA Complete Interrupt i copy the Buffer to wherever i want him.
The Problem I have is that the order i expect the results to be in the buffer is different.

According to the manual they are supposed to be in the order:
ADC1.1 ADC 2.1 ADC3.1 ADC 1.2 ADC 2.2 ADC 3.2.

I write them to a 6 element uint16 buffer while the DMA is ordered to transfer 3 uint32 bit values to a 3 element 32 bit buffer. I think that should not be a problem.

My results though show, that the first two values to be converted somehow show up in the 2nd ord 3rd word, meaning at position 3,4 or 5,6 in my buffer.
If I have 56cycles adc conversion its 3,4
If I have 84cycles adc conversion its 5,6

Can someone tell my how I can fix this, or if this will be at least fix so i can just implement another order of reading them and be done with it.

thanks.

int main(void)
{
    /*------------------------------------------------------------------------*
     *--- Systemclock = 168MHz -----------------------------------------------*
     *--- Systemclock / 80kHz == Number of steps for up and down counting ----*
     *--- Timer1_Steps = Systemclock / (2*80kHz) - 1 Maximum Counter value ---*
     *----Timer1_Steps = 1049 ------------------------------------------------*
     *------------------------------------------------------------------------*/
 
    /*--- Initializing Pins --------------------*/
    init_pins();
    init_pwm_pins();
    init_adc_pins();
 
    /*--- Initializing ADCs --------------------*/
    init_dma2_C0();
    init_ADC123();
 
    /*--- Initializing Timers ------------------*/
    StartTimer1(Timer1_Steps, 0);
    Init_TIM1PWM(50);               // 50 == 300ns deadtime
        //set_CCR(1000, 50, 500);
    StartTimer3(20000,4667,5000,10000,15000,0);
    StartTimer4(359,Timer4_Prescaler);
    //CCR1 = 1000;
    //CCR2 = 50;
    //CCR3 = 500;
 
    while (1)
    {
 
    }//while(1)
}//main
/*--- ADC Pin Init --------------------------------*/
void init_adc_pins(){
      /*u3 -> PC0   ADC123_IN10
        u2 -> PB1   ADC12_IN9
        u1 -> PB0   ADC12_IN8
        i3 -> PA3   ADC123_IN3
        i2 -> PA2   ADC123_IN2
        i1 -> PA1   ADC123_IN1*/
    GPIO_InitTypeDef GPIO_InitStructure;
 
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
 
    /*--- Configure PB -------------------------*/
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
 
    /*--- Configure PA -------------------------*/
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
 
    /*--- Configure PC -------------------------*/
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
    GPIO_Init(GPIOC, &GPIO_InitStructure);
 
}
void init_dma2_C0(){
    extern uint16_t ADC_BUFF[bufferlength];
    DMA_InitTypeDef DMA_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;
 
    /*--- Enable the DMA2 gloabal Interrupt -----------*/
    NVIC_InitStructure.NVIC_IRQChannel =  DMA2_Stream0_IRQn ;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
 
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);
 
    DMA_DeInit(DMA2_Stream0);
 
    DMA_InitStructure.DMA_Channel = DMA_Channel_0;
    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&(ADC->CDR);
    DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t) &ADC_BUFF;
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
    DMA_InitStructure.DMA_BufferSize = bufferlength/2;
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;     //Half-Word
    DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;//Circular;
    DMA_InitStructure.DMA_Priority = DMA_Priority_High;
    DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable;
    DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_3QuartersFull;
    DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
    DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
 
    DMA_Init(DMA2_Stream0, &DMA_InitStructure);
    DMA_ITConfig(DMA2_Stream0, DMA_IT_TC, ENABLE);
    DMA_ClearITPendingBit(DMA2_Stream0, DMA_IT_TCIF0);
    DMA_Cmd(DMA2_Stream0, ENABLE);
}
void init_ADC123(){
      ADC_InitTypeDef ADC_InitStructure;
      ADC_CommonInitTypeDef ADC_CommonInitStructure;
      /*u3 -> PC0    ADC123_IN10
        u2 -> PB1    ADC12_IN9
        u1 -> PB0    ADC12_IN8
        i3 -> PA3    ADC123_IN3
        i2 -> PA2    ADC123_IN2
        i1 -> PA1    ADC123_IN1*/
      /*--- Periperal clock enable ---------------*/
      RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
      RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC2, ENABLE);
      RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC3, ENABLE);
 
      /*--- struct to default settings -----------*/
      ADC_StructInit(&ADC_InitStructure);
      ADC_DeInit();
 
      /*--- ADC1 Configuration -------------------*/
      ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
      ADC_InitStructure.ADC_ScanConvMode = ENABLE;
      ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
      ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConvEdge_None;
      ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
      ADC_InitStructure.ADC_NbrOfConversion = 2;//adc_samples;
      ADC_Init(ADC1, &ADC_InitStructure);
 
      /*--- ADC2 Configuration -------------------*/
      ADC_Init(ADC2, &ADC_InitStructure);
 
      /*--- ADC3 Configuration -------------------*/
      ADC_Init(ADC3, &ADC_InitStructure);
 
      /*--- ADC Common configuration -------------*/
      ADC_CommonInitStructure.ADC_Mode = ADC_TripleMode_Interl;
      ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_20Cycles;
      ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_2;
      ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;
      ADC_CommonInit(&ADC_CommonInitStructure);
 
      /*--- configuration of ADC1 channel ranks --*/
                  /*--- u1 / u2 ---*/
      ADC_RegularChannelConfig(ADC1,ADC_Channel_8,1,ADC_SampleTime_56Cycles);
      ADC_RegularChannelConfig(ADC1,ADC_Channel_9,2,ADC_SampleTime_56Cycles);
 
      /*--- configuration of ADC2 channel ranks --*/
                  /*--- i1 / i2 ---*/
      ADC_RegularChannelConfig(ADC2,ADC_Channel_1,1,ADC_SampleTime_56Cycles);
      ADC_RegularChannelConfig(ADC2,ADC_Channel_2,2,ADC_SampleTime_56Cycles);
 
      /*--- configuration of ADC3 channel ranks --*/
                  /*--- u3 / i3 ---*/
      ADC_RegularChannelConfig(ADC3,ADC_Channel_10,1,ADC_SampleTime_56Cycles);
      ADC_RegularChannelConfig(ADC3,ADC_Channel_3,2,ADC_SampleTime_56Cycles);
 
      /*--- Enable ADC1 - ADC 3 ------------------*/
      ADC_Cmd(ADC1, ENABLE);
      ADC_Cmd(ADC2, ENABLE);
      ADC_Cmd(ADC3, ENABLE);
 
      /*--- Enable multi ADC DMA requests --------*/
      ADC_MultiModeDMARequestAfterLastTransferCmd(ENABLE);
 
      ADC_DMACmd(ADC1, ENABLE);
      /*--- Starting of ADC conversion -----------*/
      ADC_SoftwareStartConv(ADC1);
      ADC_SoftwareStartConv(ADC2);
      ADC_SoftwareStartConv(ADC3);
 
}
void DMA2_Stream0_IRQHandler(void){
    //volatile uint16_t test=1367;
 
    //DMA_Cmd(DMA2_Stream0, DISABLE);
    if(DMA_GetITStatus(DMA2_Stream0,DMA_IT_TCIF0))
      {
        DMA_ClearITPendingBit(DMA2_Stream0, DMA_IT_TCIF0);
 
        if(ADC_wp == ADC_meanlength) ADC_wp=0;
 
        ADC_result[0][ADC_wp]=ADC_BUFF[2];//B0    //u1 1349 1345
        ADC_result[1][ADC_wp]=ADC_BUFF[5];//B1    //u2  958 954
        ADC_result[2][ADC_wp]=ADC_BUFF[4];//C0    //u3 4095 4095
        ADC_result[3][ADC_wp]=ADC_BUFF[3];//A1    //i1 286  278
        ADC_result[4][ADC_wp]=ADC_BUFF[0];//A2    //i2 3576 3552
        ADC_result[5][ADC_wp]=ADC_BUFF[1];//A3    //i3 1    0
 
 
        GPIO_ToggleBits(GPIOD,GPIO_Pin_13);
 
        if(testflag == 0){
            test[0][testflag1] =    ADC_result[4][ADC_wp];//ADC_values[0];
            test[1][testflag1] =    ADC_result[5][ADC_wp];//ADC_values[1];
            test[2][testflag1] =    ADC_result[0][ADC_wp];//ADC_values[2];
            test[3][testflag1] =    ADC_result[3][ADC_wp];//ADC_values[3];
            test[4][testflag1] =    ADC_result[2][ADC_wp];//ADC_values[4];
            test[5][testflag1] =    ADC_result[1][ADC_wp];//ADC_values[5];
            testflag=0;
            testflag1++;
            if(testflag1 == 100)testflag1 = 0;
        }
        else testflag++;
/*
 
*/
        ADC_wp++;
      }
 
}

Outcomes