Portenta H7 ADC DMA first steps

Hello everyone,

it seems that my collegue Moes_Pub and I have found a solution to operate the ADC in the Msps region.

The solution was:

  1. To update CubeMx. We found an update from November 2021 that was specifically for the STM32H7.

  2. To generate the code in STM32CubeMX and then copy all of the generated files (.c & .h) and folders into the folder of an Arduino project. Finally, we copied the main.c in an Arduino (main.ino) sketch and changed the loops to setup() and loop().

Doing so, however, the IDE finds that some functions are defined multiple times. The solution is to comment every function in the stm32h7xx_it.c file or delete it.

Important ADC settings:

hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV1;
hadc1.Init.ContinuousConvMode = DISABLE;
hadc1.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN;

ADC_CLOCK_SYNC_PCLK_DIV1 Did the trick. You can find this setting in CubeMX.

The example code:

The ADC samples in the loop() until a threshold is reached.

Then the program moves into a noInterrupts() area to block any sort of interruptions that will cause the process to hang and disturb the more or less equidistant ADC samples.
See: Fast GPIO-Toggle with portenta H7 using HAL

In the noInterrupts() area the ADC will collect 100000 measurements and store them in the data array. The GPIO pin PH15 is set and reset to measure the time required for one ADC read.

You can see two things from the oscilliscope screenshot:

  1. The ADC takes about 1 us (1Msps) for one ADC conversion and storage in the data array
  2. The duration is not equal for all conversions

Our solution at the moment: Include a timer TIM16 which is started at the beginning of each ADC read. Then the while loop waits until 2 us have passed. This way, we get equidistant samples with 500ksps. Using noInterrupts() we were able to sample a 250kHz rect() signal twice every period for 500ms and got perfect results without having a synchronization problem.

´

Playing with the timer prescaler etc. should allow equidistant sampling at more than 800ksps.

Here is the working example as .zip file.

Fast_ADC_arduino.zip (13.1 KB)

At the moment, we think that we dont reach the 3.6Msps because we cant change SystemClock_Config().

We get the same error as alexbau in How to set up the Portenta with 480MHz Clock (at least more than 4MHz)

Greetings,
An_Dreh