cancel
Showing results for 
Search instead for 
Did you mean: 

To use the ADC data offset registers with ADC1 & 2 should I use Dual injected simultaneous mode?

Robmar
Senior III

Using ADC1 and ADC2 and timer3 trigger rising and falling edges to get a 96KHz event, I understand that we can't use Dual injected simultaneous mode with DMA, so we are using Independent mode, but is there a better (more efficient and robust) mode?

I searched the web and the 407 Ref manual but can find nothing to clearly explain this clearly.

Aim is to have synchronous 16-bit ADC conversion with DMA on two inputs at 96 - 384KHz (selectable by user) with time accurate sampling as this is for I and Q sampling, which are 90 degrees out of phase.

Appreciate expert guidance on this as I am new to this chip though have worked on complex MCUs for years, but its a lot to go through a 1700 page manual and from community comments many people seem uncertain about injected channels.

Project volume is around 3K units a year.

13 REPLIES 13
FBL
ST Employee

Hello @Robmar​, 

If you wonder to find known issues of ADC peripheral on F407, you may refer to this errata sheet, section 2.14 ADC peripheral limitations, where you can find the workaround as well.

You can take a look at this MOOC and explore an interesting mode which is the interleaved mode to perform faster ADC conversions. How to boost ADC conversion rate on STM32L4 - STMicroelectronics

Good reading!

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

As I have now repeatedly mentioned, I do not agree, and would appreciate if you would refrain from making any further posts. Okay?

My experience with STM32CubeIDE is mixed, for example the IDE lacks the simple code to make simple changes to the files to allow users to select alternative MCUs.

There are so many variants to the MCUs that many customers have complained about this over the last many years.

To change one sample project with 50+ files from the F411 to F407 we had to edit the .ioc and project files, replacing the 411 references with the required 407 ones, it was quicker than recreating the entire project, but still a waste of valuable time. This really should have been fixed years ago.

The idea behind Cube MX is to allow clients to focus on their particular application code, not re-read length and occasionally conflicting datasheets. Several people on this forum are trashing Cube MX whereas it generally works well, and can easily be refined in code later.

*** As far as ADC Dual Regular Mode with Alternate trigger, we used Cube MX to generate the code and the IRQs for ADC 1 and 2 are still both being generated, though we can just use the IRQ from ADC 2 and all data samples have arrived to the buffer.

I had understood that only one set of IRQs would be generated with both ADC linked.

Is there something missing from the MX generated code?

/* ADC1 init function */
void MX_ADC1_Init(void)
{
 
  /* USER CODE BEGIN ADC1_Init 0 */
 
  /* USER CODE END ADC1_Init 0 */
 
  /* USER CODE BEGIN ADC1_Init 1 */
 
  /* USER CODE END ADC1_Init 1 */
 
  ADC_ChannelConfTypeDef sConfig = {0};
  ADC_MultiModeTypeDef multimode = {0};
 
  /** Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)
  */
  hadc1.Instance = ADC1;
  hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV8;	// xyzzy ADC_CLOCK_SYNC_PCLK_DIV4
  hadc1.Init.Resolution = ADC_RESOLUTION_12B;
  hadc1.Init.ScanConvMode = DISABLE;
  hadc1.Init.ContinuousConvMode = DISABLE;
  hadc1.Init.DiscontinuousConvMode = DISABLE;
  hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISINGFALLING;
  hadc1.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T3_TRGO;
  hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  hadc1.Init.NbrOfConversion = 1;
  hadc1.Init.DMAContinuousRequests = ENABLE;
  hadc1.Init.EOCSelection = ADC_EOC_SEQ_CONV;	//ADC_EOC_SINGLE_CONV  ADC_EOC_SEQ_CONV;
  if (HAL_ADC_Init(&hadc1) != HAL_OK)
  {
    Error_Handler();
  }
 
 
  /** Configure the ADC multi-mode
  */
  multimode.Mode = ADC_DUALMODE_REGSIMULT_ALTERTRIG;
  multimode.DMAAccessMode = ADC_DMAACCESSMODE_2;
  multimode.TwoSamplingDelay = ADC_TWOSAMPLINGDELAY_5CYCLES;
  if (HAL_ADCEx_MultiModeConfigChannel(&hadc1, &multimode) != HAL_OK)
  {
    Error_Handler();
  }
 
  /** Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
  */
  sConfig.Channel = ADC_CHANNEL_2;
  sConfig.Rank = 1;
  sConfig.SamplingTime = ADC_SAMPLETIME_84CYCLES;	//ADC_SAMPLETIME_84CYCLES ADC_SAMPLETIME_28CYCLES ADC_SAMPLETIME_144CYCLES
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }

Edited by moderation team to adhere to community guidelines 

Thanks for the errate sheet, useful!

The combined multi ADC mode you referenced doesn't work using the code generated by Cube MX. It also stops ADC3 being used for software controlled sampling!

With mutlimode regular enabled, ADC 2's IRQ are still generated, I have posted the code, but but no reply in days.

Maybe you could try that on you own test system.

Could you also please post a code snippet showing the fastest way to save and restore the FPU context for IRQs? This will save scores of your customers from having to dig through datasheets, posts, RTOS code etc., to produce something that has been available for a decade,... but still not posted in a reuseable form.

Thank you!