cancel
Showing results for 
Search instead for 
Did you mean: 

STM32MP157F-DK2 Dual ADC with DMA

jutoroa
Associate III

Dear all,

I'm currently using the STM32MP157F-DK2 series, and I'm trying to use the ADC1 and ADC2 in dual regular simultaneous mode triggered by TIM2 out event. Also, I used one DMA stream (DMA2_stream0) to read the ADC values of the Common Data Register (ADC_CDR) as it is indicated in the MP157F reference manual:
image_2023-09-21_165417637.png

This is how I'm starting the ADCs:

if(HAL_ADC_Start(&hadc2) != HAL_OK){
/* Start Error */
Error_Handler();
}
if (HAL_ADCEx_MultiModeStart_DMA(&hadc1, (uint32_t *)adc_buff, 8) != HAL_OK)
{
/* Start Error */
Error_Handler();
}
if (HAL_TIM_Base_Start(&htim2) != HAL_OK)
{
Error_Handler();
}

Also, I have checked the ADC's registers, to make sure the configuration is correct. This is the configuration for the ADC1 and ADC2:

static void MX_ADC1_Init(void)
{

/* USER CODE BEGIN ADC1_Init 0 */

/* USER CODE END ADC1_Init 0 */

ADC_MultiModeTypeDef multimode = {0};
ADC_ChannelConfTypeDef sConfig = {0}



hadc1.Instance = ADC1;
hadc1.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1;
hadc1.Init.Resolution = ADC_RESOLUTION_12B;
hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE;
hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
hadc1.Init.LowPowerAutoWait = DISABLE;
hadc1.Init.ContinuousConvMode = DISABLE;
hadc1.Init.NbrOfConversion = 2;
hadc1.Init.DiscontinuousConvMode = DISABLE;
hadc1.Init.ExternalTrigConv = ADC_EXTERNALTRIG_T2_TRGO;
hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISING;
hadc1.Init.ConversionDataManagement = ADC_CONVERSIONDATA_DMA_CIRCULAR;
hadc1.Init.Overrun = ADC_OVR_DATA_PRESERVED;
hadc1.Init.LeftBitShift = ADC_LEFTBITSHIFT_NONE;
hadc1.Init.OversamplingMode = DISABLE;
if (HAL_ADC_Init(&hadc1) != HAL_OK)
{
Error_Handler();
}

/** Configure the ADC multi-mode
*/
multimode.Mode = ADC_DUALMODE_REGSIMULT;
multimode.DualModeData = ADC_DUALMODEDATAFORMAT_32_10_BITS;
multimode.TwoSamplingDelay = ADC_TWOSAMPLINGDELAY_5CYCLES;
if (HAL_ADCEx_MultiModeConfigChannel(&hadc1, &multimode) != HAL_OK)
{
Error_Handler();
}

/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_6;
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SamplingTime = ADC_SAMPLETIME_1CYCLE_5;
sConfig.SingleDiff = ADC_SINGLE_ENDED;
sConfig.OffsetNumber = ADC_OFFSET_NONE;
sConfig.Offset = 0;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}

/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_13;
sConfig.Rank = ADC_REGULAR_RANK_2;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN ADC1_Init 2 */

/* USER CODE END ADC1_Init 2 */

}

 

static void MX_ADC2_Init(void)
{

/* USER CODE BEGIN ADC2_Init 0 */

/* USER CODE END ADC2_Init 0 */

ADC_ChannelConfTypeDef sConfig = {0};

/* USER CODE BEGIN ADC2_Init 1 */

/* USER CODE END ADC2_Init 1 */

/** Common config
*/
hadc2.Instance = ADC2;
hadc2.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1;
hadc2.Init.Resolution = ADC_RESOLUTION_12B;
hadc2.Init.ScanConvMode = ADC_SCAN_ENABLE;
hadc2.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
hadc2.Init.LowPowerAutoWait = DISABLE;
hadc2.Init.ContinuousConvMode = DISABLE;
hadc2.Init.NbrOfConversion = 2;
hadc2.Init.DiscontinuousConvMode = DISABLE;
hadc2.Init.ConversionDataManagement = ADC_CONVERSIONDATA_DR;
hadc2.Init.Overrun = ADC_OVR_DATA_PRESERVED;
hadc2.Init.LeftBitShift = ADC_LEFTBITSHIFT_NONE;
hadc2.Init.OversamplingMode = DISABLE;
if (HAL_ADC_Init(&hadc2) != HAL_OK)
{
Error_Handler();
}

/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_2;
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SamplingTime = ADC_SAMPLETIME_1CYCLE_5;
sConfig.SingleDiff = ADC_SINGLE_ENDED;
sConfig.OffsetNumber = ADC_OFFSET_NONE;
sConfig.Offset = 0;
if (HAL_ADC_ConfigChannel(&hadc2, &sConfig) != HAL_OK)
{
Error_Handler();
}

/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_6;
sConfig.Rank = ADC_REGULAR_RANK_2;
if (HAL_ADC_ConfigChannel(&hadc2, &sConfig) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN ADC2_Init 2 */

/* USER CODE END ADC2_Init 2 */

}

 In my understanding adcData_DMA = ADC_CDR so adcData_DMA bits[31:16] = ADC2 Data and adcData_DMA bits[15:0] = ADC1 data, in that order of ideas this is my callback:

void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc)
{
channels_adc[0] = adc_buff[0] & 0xFFF;
channels_adc[1] = adc_buff[1] & 0xFFF;
channels_adc[2] = adc_buff[0]>>16;
channels_adc[3] = adc_buff[1]>>16;
}

Where:

uint32_t adc_buff[2] = {0};
uint16_t channels_adc[4] = {0};

I have checked and the values are correct in the Common Data Register (I checked it with the debugger), but the are not in my buffer given by the DMAStream0 (adc_buff).

I don't know if I'm misunderstanding something or if I'm overlooking something. I greatly appreciate your collaboration.

Also I attached here the complete main.c file.

Best regards

4 REPLIES 4
Ken_102633
Associate II

Hello,

Do you mean channels_adc != adc_buff?

jutoroa
Associate III

Thank you for the repply Ken.

adc_buff is the DMAbuffer, where it's supose to be the ADC1 data (bits[15:0]) and the ADC2 data (bits[31:16]).

The channels_adc[4] it's just the separate value (with masks) of each adc channel. The problem is that in DMAbuffer (adc_buff) it never have the correct values.

It's more clear?

Ken_102633
Associate II

Hi jutoroa,

The "DMAbuffer (adc_buff) never have the correct values", it means ADC1(channel 6, channel13), ADC2(channel 2, channel 6) never have the correct values or some channel can get the correct values.

I have encountered a situation where, in Dual ADC regular simultaneous mode, the ADC slave channel has a phase shift of one sample being ahead of ADC master. (I am not the only one seeing this issue.)

https://community.st.com/t5/stm32-mcus-products/stm32h7-adc-dual-mode-simultanious-mode-problem/td-p/294976/page/2

I'm not sure whether you have also encountered the same problem.

 

 

Hi Ken, thanks again for the repply. I still have the same issue. The problem is that one channel can't get the correct values into the DMABuffer. I have read the post, and I think it's correlated. ¿Do you know about a possible solution?