cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H7 ADC + DMA working partially

Floki.1
Associate II

Hello,

I am using the ADC1 + DMA to sample 10 analog channels on the CM4 without any MPU config. When I remove any external trigger e.g. 3.3V power source on the analog channel, and I start sampling all 10 channels via the DMA , all values inside the buffer contain few digits like 23. I assume this is noise which is neglectable.

When I start to put the 3V3 power supply trigger selectivly from one ADC channel to another channel I see that the values of the buffer gets individually updated till channel 5 out of 10.

Here comes the strange observation I want to share with you:

When I put the 3V3 power supply on the 6th channel, I see that the buffer value for this channel gets updated accordingly, but also the value in the buffer for channel 7 gets the same value. Its like a mirroring image.

How does this happen ? Same channel registered several time, in the sequencer ?

When I put the 3V3 power supply on channel 7, the value is updated accordingly in the buffer, but also channel 8 in the buffer gets like the half of the value. If I sample 4095 on channel 7, channel 8 contains approx 2200. How can this happen?

When I place the 3V3 power supply on channel 10, nothing happens at all. What does that mean. I didn't register the channel properly ?

Is there more I need to take into account? I mean the ADC has some fast, slow and direct connections internally. Acutally, everything should be fine, when I select the ADC channel as single-ended and I use only ADC_INP pins.

7 REPLIES 7
TDK
Guru

There is some bleed between channels due to the nature of the ADC. Increasing sample time or decreasing impedance can mitigate. This is what's happening between channels 6/7 or 7/8.

Sounds like channel 10 is not wired properly.

Don't measure voltage on pins that are floating, as the result is meaningless.

https://www.st.com/resource/en/application_note/cd00211314-how-to-get-the-best-adc-accuracy-in-stm32-microcontrollers-stmicroelectronics.pdf

If you feel a post has answered your question, please click "Accept as Solution".
Floki.1
Associate II

Hello TDK,

thanks for you answer. I will come back to you once I try this out on my board. I have another question regarding the initialization step for the ADC periphery. According to the reference manual you can select between synchronous and asynchronous Clokcking (kernel_clk). I see that the ADC provides 3 multiplex possibilites which is PLL2P, PLL3R and PER_CK , although PER_CK could be HSE or HSI or CSI. Which configration mode is seen as synchronous clocking when I need to call HAL_RCCEx_PeriphCLKConfig for the ADC periphery initialization or do I need to skip this and call another function ?

I see in the RCC header files following #defines for the ADC:

/** @defgroup ADC_HAL_EC_COMMON_CLOCK_SOURCE ADC common - Clock source

 * @{

 */

#define ADC_CLOCK_SYNC_PCLK_DIV1      (LL_ADC_CLOCK_SYNC_PCLK_DIV1) /*!< ADC synchronous clock derived from AHB clock without prescaler */

#define ADC_CLOCK_SYNC_PCLK_DIV2      (LL_ADC_CLOCK_SYNC_PCLK_DIV2) /*!< ADC synchronous clock derived from AHB clock with prescaler division by 2 */

#define ADC_CLOCK_SYNC_PCLK_DIV4      (LL_ADC_CLOCK_SYNC_PCLK_DIV4) /*!< ADC synchronous clock derived from AHB clock with prescaler division by 4 */

#define ADC_CLOCK_ASYNC_DIV1        (LL_ADC_CLOCK_ASYNC_DIV1)   /*!< ADC asynchronous clock without prescaler */

#define ADC_CLOCK_ASYNC_DIV2        (LL_ADC_CLOCK_ASYNC_DIV2)   /*!< ADC asynchronous clock with prescaler division by 2  */

#define ADC_CLOCK_ASYNC_DIV4        (LL_ADC_CLOCK_ASYNC_DIV4)   /*!< ADC asynchronous clock with prescaler division by 4  */

#define ADC_CLOCK_ASYNC_DIV6        (LL_ADC_CLOCK_ASYNC_DIV6)   /*!< ADC asynchronous clock with prescaler division by 6  */

The code which is initialized by Cumbemx uses ADC_CLOCK_ASYNC_DVx defines which means the ADC is fed by a asynchrnous clock?

How can I change this to a synchronous PLL?

Moreover, which maximum frequency can be handled by the ADC periphery when used during operating as the multiplexed PLL can provide different frequency values? 

TDK
Guru

> How can I change this to a synchronous PLL?

Change it in CubeMX and let it generate the initialization code for you.

0693W00000BclhlQAB.png 

> Moreover, which maximum frequency can be handled by the ADC periphery...?

The max ADC clock is given in the datasheet. You don't specify what chip you're using. For the H743, it's 36 MHz. Probably better to focus on the needs of your project rather than maximum capabilities.

0693W00000BclhqQAB.png

If you feel a post has answered your question, please click "Accept as Solution".
Floki.1
Associate II

Hello TDK,

thanks to your reply. It seems to be working rigtht now as expected with the ADC and DMA.

I have one question regarding backwards compatibility what I have seen on the F4 series. Is it possible to use the ADC in circular as double buffered mode?

I didn't find any example so far for the double buffered mode for the ADC which is taking advantage of the following HW registers:

1: DMA_SxM0AR,

2: DMA_SxM1AR,

and

CT: current target

CT = 0: DMA is accessing storage area 0, CPU can access storage area 1

CT = 1: DMA is accessing storage area 1, CPU can access storage area 0

I can remember there was something like DMA_DoubleBufferModeCmd in the past, but for the H7 I cannot find anything in the H7 HAL libs apart from HAL_DMAEx_MultiBufferXXX. I am not sure if this is the rigtht spot to look at as it doesn't explain the initialization steps.

I mean I have seen some double buffered implementation in SW with a simple DMA circular mode (standard approach ) via HalfCompt and FullComplt interrupts but I would like to avoid interrupts at all here.

Is it possible on the H7 series to use a complete HW-based approach for double buffering without any use of the interrupts? So in the end, the application would look like this:

Initilaization of the 2 buffers and the DMA, start the ADC conversion. Buffers are continously filled with new data. Buffer is swapped automatically once one buffer is full. Application can decide with the CT flag which buffer to access and process.

TDK
Guru

Double buffered mode is possible on the H7 hardware. Using have a single buffer and monitoring for the half-complete and transfer complete flags is very similar and is what most people do.

Double buffer mode uses interrupts just like single buffer continuous mode.

If you don't want the interrupts to fire, you can disable them. But then you need to poll the bits to figure out where the process is, which will cost more overhead than the interrupts themselves.

If you feel a post has answered your question, please click "Accept as Solution".
Floki.1
Associate II

Hello TDK,

thanks for the clarification and fast reply. Do you know where I could take a look at for some reference material in order to accelerate the implementation (repo of old ST mcus?). I went through all examples of different STM32H7 platforms to get some inspiration but I only see single buffer circular mode examples. I assume that the effort for the double buffer extension as previously described (in HW without interrutps) is not that high.

Nevertheless, do you know which HAL functions I need to use in order to setup the DMA properly on the H7 when I execute the DMA Init?

PAkRad
Associate III

Hello all.

We have developed in the past some devices using the STM32F4 and F7 families, with no issues using ADC+DMA+Timer Triggering with no effort (mostly tweaking the examples provided by ST and using the ioc Cube files).

However, we are trying to do the same, but we are finding big issues with the H7 family, in specific when we use more than one ADC (to my knowledge this example is not provided by ST yet). There are also problems with the DMA (we have reader and moved the data buffers to RAM D2 area) and we do not see the triggering of the DMA interrupt with the Timer trigger.

Maybe somebody in the forum knows one repository or is able to share a simple example of this structure (if it is based on STM32Cubemx ioc file the better, since for it will be easier to add things).

Thank you in advance.