AnsweredAssumed Answered

STM32F7 - Bug in ADC?

Question asked by schramm.daniel on Oct 8, 2015
Latest reply on Oct 13, 2015 by schramm.daniel
Hello,

i'm currently working with the STM32F7-Disco and ran into problems with the ADC.
I sample all 6 ADC inputs of the Arduino header on ADC3 in a sequence to DMA and triggered by Timer 1 (TRGO).
The sequence is started and I get the correct DMA interrupts.
But now the interesting things begin. The picture shows a 3.6Hz sinus like I get it from the ADC. every point in time direction repesents the average of 8 samplings. Sample Rate is 45kHz.
The two lines represent input Channel 4 and 6 to which the signal is connected.
(Not visible Channels 5 and 7 are connected to 3.3V and the other 2 inputs are open.)

adc.png

As you can see, the value I get from the ADC stays the same for some time and then jumps according to the analog input. Signal Source is a low impedance (8 Ohm 65W) Signal generator and I added some ceramic capacitors extra to the inputs.
Of course I tried different sample times and trigger frequencies and it always reacts in the same way.
I read about the sequencer problem in the errata which does not effect my use case.

Thanks for your feedback

This is my initialisation code:

    void gpioInit() {
        GPIO_InitTypeDef          GPIO_InitStruct;
        GPIO_InitStruct.Pin = GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10;
        GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
        GPIO_InitStruct.Pull = GPIO_NOPULL;
        HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);

        GPIO_InitStruct.Pin = GPIO_PIN_0;
        HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);


        // LED pin for timing
        GPIO_InitStruct.Pin = GPIO_PIN_1;
        GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
        GPIO_InitStruct.Pull = GPIO_NOPULL;
        HAL_GPIO_Init(GPIOI, &GPIO_InitStruct);

    }

    void dmaInit() {
        hdma_adc.Instance = DMA2_Stream0;

        hdma_adc.Init.Channel  = DMA_CHANNEL_2;
        hdma_adc.Init.Direction = DMA_PERIPH_TO_MEMORY;
        hdma_adc.Init.PeriphInc = DMA_PINC_DISABLE;
        hdma_adc.Init.MemInc = DMA_MINC_ENABLE;
        hdma_adc.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
        hdma_adc.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
        hdma_adc.Init.Mode = DMA_CIRCULAR;
        hdma_adc.Init.Priority = DMA_PRIORITY_HIGH;
        hdma_adc.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
        hdma_adc.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
        hdma_adc.Init.MemBurst = DMA_MBURST_SINGLE;
        hdma_adc.Init.PeriphBurst = DMA_PBURST_SINGLE;

        HAL_DMA_Init(&hdma_adc);

        __HAL_LINKDMA(&adcHandle, DMA_Handle, hdma_adc);

        HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 0, 0);
        HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn);
    }
    void timerInit() {
        TimHandle.Instance = TIM1;
        TimHandle.Init.Period            = 10;
        TimHandle.Init.Prescaler         = TIM_CLOCKDIVISION_DIV2;
        TimHandle.Init.ClockDivision     = 0;
        TimHandle.Init.CounterMode       = TIM_COUNTERMODE_UP;
        TimHandle.Init.RepetitionCounter = 0;
        TIM_MasterConfigTypeDef mConfig;
        mConfig.MasterOutputTrigger=TIM_TRGO_UPDATE;
        mConfig.MasterSlaveMode=TIM_MASTERSLAVEMODE_ENABLE;

        HAL_TIM_Base_Init(&TimHandle);
        HAL_TIMEx_MasterConfigSynchronization(&TimHandle, &mConfig);
        HAL_TIM_Base_Start(&TimHandle);
    }

    void init() {
        __HAL_RCC_TIM1_CLK_ENABLE();
        __HAL_RCC_ADC3_CLK_ENABLE();
        __HAL_RCC_GPIOA_CLK_ENABLE();
        __HAL_RCC_GPIOF_CLK_ENABLE();
        __HAL_RCC_DMA2_CLK_ENABLE();

        gpioInit();
        dmaInit();

        adcHandle.Instance          = ADC3;

        adcHandle.Init.ClockPrescaler        = ADC_CLOCKPRESCALER_PCLK_DIV2;
        adcHandle.Init.Resolution            = ADC_RESOLUTION_12B;
        adcHandle.Init.ScanConvMode          = ENABLE;
        adcHandle.Init.ContinuousConvMode    = DISABLE;
        adcHandle.Init.DiscontinuousConvMode = DISABLE;
        adcHandle.Init.NbrOfDiscConversion   = 0;
        adcHandle.Init.ExternalTrigConvEdge  = ADC_EXTERNALTRIGCONVEDGE_RISING; 
        adcHandle.Init.ExternalTrigConv      = ADC_EXTERNALTRIGCONV_T1_TRGO;
        adcHandle.Init.DataAlign             = ADC_DATAALIGN_RIGHT;
        adcHandle.Init.NbrOfConversion       = activeChannels;
        adcHandle.Init.DMAContinuousRequests = ENABLE;
        adcHandle.Init.EOCSelection          = EOC_SEQ_CONV;
        HAL_ADC_Init(&adcHandle);


        ADC_ChannelConfTypeDef adcChannelConfig;
        //adcChannelConfig.SamplingTime = ADC_SAMPLETIME_480CYCLES;
        adcChannelConfig.SamplingTime = ADC_SAMPLETIME_15CYCLES;
        adcChannelConfig.Offset = 0;
        adcChannelConfig.Channel = ADC_CHANNEL_0;
        adcChannelConfig.Rank = 1;
        HAL_ADC_ConfigChannel(&adcHandle, &adcChannelConfig);
        adcChannelConfig.Channel = ADC_CHANNEL_4;
        adcChannelConfig.Rank = 2;
        HAL_ADC_ConfigChannel(&adcHandle, &adcChannelConfig);
        adcChannelConfig.Channel = ADC_CHANNEL_5;
        adcChannelConfig.Rank = 3;
        HAL_ADC_ConfigChannel(&adcHandle, &adcChannelConfig);
        adcChannelConfig.Channel = ADC_CHANNEL_6;
        adcChannelConfig.Rank = 4;
        HAL_ADC_ConfigChannel(&adcHandle, &adcChannelConfig);
        adcChannelConfig.Channel = ADC_CHANNEL_7;
        adcChannelConfig.Rank = 5;
        HAL_ADC_ConfigChannel(&adcHandle, &adcChannelConfig);
        adcChannelConfig.Channel = ADC_CHANNEL_8;
        adcChannelConfig.Rank = 6;
        HAL_ADC_ConfigChannel(&adcHandle, &adcChannelConfig);
        filter_count=0;
        for(uint8_t i=0; i<activeChannels; i++) {
            filter[i]=0;
        }

        start();
        timerInit();

    }

Outcomes