Skip to main content
BPutt.1
Associate II
Feb 5, 2024 12:32 PM UTC
Question

How to setup STM32F373 SDADC with multiple channels over DMA

I am struggling with the SDADC of the STM32F373
My goal is to read 3 different channels of the SDADC3 using DMA. I was able to get a single channel working, but as soon as I add the other channels, the data seems not to be ok.

I used the following code to initialise SDADC3:

 

static uint32_t	sadc3_buf[3];

 

 

 

void HAL_SDADC_MspInit(SDADC_HandleTypeDef* sdadcHandle)
{

 GPIO_InitTypeDef GPIO_InitStruct = {0};
 if(sdadcHandle->Instance==SDADC3)
 {
 /* USER CODE BEGIN SDADC3_MspInit 0 */

 /* USER CODE END SDADC3_MspInit 0 */
 /* SDADC3 clock enable */
 __HAL_RCC_SDADC3_CLK_ENABLE();

 __HAL_RCC_GPIOB_CLK_ENABLE();
 __HAL_RCC_GPIOD_CLK_ENABLE();
 /**SDADC3 GPIO Configuration
 PB14 ------> SDADC3_AIN8P
 PB15 ------> SDADC3_AIN7P
 PD8 ------> SDADC3_AIN6P
 */
 GPIO_InitStruct.Pin = UI3_1_Pin|UI2_1_Pin;
 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
 GPIO_InitStruct.Pull = GPIO_NOPULL;
 HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

 GPIO_InitStruct.Pin = UI1_1_Pin;
 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
 GPIO_InitStruct.Pull = GPIO_NOPULL;
 HAL_GPIO_Init(UI1_1_GPIO_Port, &GPIO_InitStruct);

 /* SDADC3 DMA Init */
 /* SDADC3 Init */
 hdma_sdadc3.Instance = DMA2_Channel5;
 hdma_sdadc3.Init.Direction = DMA_PERIPH_TO_MEMORY;
 hdma_sdadc3.Init.PeriphInc = DMA_PINC_DISABLE;
 hdma_sdadc3.Init.MemInc = DMA_MINC_ENABLE;
 hdma_sdadc3.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
 hdma_sdadc3.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
 hdma_sdadc3.Init.Mode = DMA_NORMAL;
 hdma_sdadc3.Init.Priority = DMA_PRIORITY_LOW;
 if (HAL_DMA_Init(&hdma_sdadc3) != HAL_OK)
 {
 Error_Handler();
 }

 __HAL_LINKDMA(sdadcHandle,hdma,hdma_sdadc3);

 /* USER CODE BEGIN SDADC3_MspInit 1 */

 /* USER CODE END SDADC3_MspInit 1 */
 }
}

void MX_SDADC3_Init(void)
{

 /* USER CODE BEGIN SDADC3_Init 0 */
//	MX_SDADC3_Init_Celsius();
//	return;
 /* USER CODE END SDADC3_Init 0 */

 SDADC_ConfParamTypeDef ConfParamStruct = {0};

 /* USER CODE BEGIN SDADC3_Init 1 */

 /* USER CODE END SDADC3_Init 1 */

 /** Configure the SDADC low power mode, fast conversion mode,
 slow clock mode and SDADC1 reference voltage
 */
 hsdadc3.Instance = SDADC3;
 hsdadc3.Init.IdleLowPowerMode = SDADC_LOWPOWER_NONE;
 hsdadc3.Init.FastConversionMode = SDADC_FAST_CONV_DISABLE;
 hsdadc3.Init.SlowClockMode = SDADC_SLOW_CLOCK_DISABLE;
 hsdadc3.Init.ReferenceVoltage = SDADC_VREF_VREFINT1;
 if (HAL_SDADC_Init(&hsdadc3) != HAL_OK)
 {
 Error_Handler();
 }

 /** Configure The Regular Mode
 */
 if (HAL_SDADC_SelectRegularTrigger(&hsdadc3, SDADC_SOFTWARE_TRIGGER) != HAL_OK)
 {
 Error_Handler();
 }

 /** Set parameters for SDADC configuration 0 Register
 */
 ConfParamStruct.InputMode = SDADC_INPUT_MODE_SE_OFFSET;
 ConfParamStruct.Gain = SDADC_GAIN_1;
 ConfParamStruct.CommonMode = SDADC_COMMON_MODE_VDDA;
 ConfParamStruct.Offset = 0;
 if (HAL_SDADC_PrepareChannelConfig(&hsdadc3, SDADC_CONF_INDEX_0, &ConfParamStruct) != HAL_OK)
 {
 Error_Handler();
 }
 /* USER CODE BEGIN SDADC3_Init 2 */
 if (HAL_SDADC_AssociateChannelConfig(&hsdadc3, SDADC_CHANNEL_6, SDADC_CONF_INDEX_0) != HAL_OK)
 {
 Error_Handler();
 }

 if (HAL_SDADC_ConfigChannel(&hsdadc3, SDADC_CHANNEL_6, SDADC_CONTINUOUS_CONV_ON) != HAL_OK)
 {
 Error_Handler();
 }

 if (HAL_SDADC_AssociateChannelConfig(&hsdadc3, SDADC_CHANNEL_7, SDADC_CONF_INDEX_0) != HAL_OK)
 {
	 Error_Handler();
 }

 if (HAL_SDADC_ConfigChannel(&hsdadc3, SDADC_CHANNEL_7, SDADC_CONTINUOUS_CONV_ON) != HAL_OK)
 {
	 Error_Handler();
 }

 if (HAL_SDADC_AssociateChannelConfig(&hsdadc3, SDADC_CHANNEL_8, SDADC_CONF_INDEX_0) != HAL_OK)
 {
	 Error_Handler();
 }

 if (HAL_SDADC_ConfigChannel(&hsdadc3, SDADC_CHANNEL_8, SDADC_CONTINUOUS_CONV_ON) != HAL_OK)
 {
	 Error_Handler();
 }
 /* USER CODE END SDADC3_Init 2 */

}

HAL_StatusTypeDef start_ad_conversion(uint8_t number)
{
	HAL_StatusTypeDef result = 0;
	result = HAL_SDADC_Start_DMA(&hsdadc3, &sadc3_buf[0],3);
	return result;
}

 

 

This topic has been closed for replies.

4 replies

TDK
Feb 5, 2024 1:32 PM UTC

> static uint32_t sadc3_buf[3];

> DMA_MDATAALIGN_HALFWORD

Probably should be a uint16_t array, to match your DMA settings, yes?

> the data seems not to be ok.

What is the data? What data are you expecting? When in a single working channel, what is the data?

"If you feel a post has answered your question, please click ""Accept as Solution""."
BPutt.1
BPutt.1Author
Associate II
Feb 5, 2024 3:21 PM UTC

Thanks for the reply Guru,

I already changed the buffer to uint16_t.

In case of selecting a single channel with:

if (HAL_SDADC_AssociateChannelConfig(&hsdadc3, SDADC_CHANNEL_6, SDADC_CONF_INDEX_0) != HAL_OK)
 {
	 Error_Handler();
 }

 if (HAL_SDADC_ConfigChannel(&hsdadc3, SDADC_CHANNEL_6, SDADC_CONTINUOUS_CONV_ON) != HAL_OK)
 {
	 Error_Handler();
 }

 I receive values like 0x1C2.

When changing the above code to:

 if (HAL_SDADC_AssociateChannelConfig(&hsdadc3, SDADC_CHANNEL_6 | SDADC_CHANNEL_7 | SDADC_CHANNEL_8, SDADC_CONF_INDEX_0) != HAL_OK)
 {
 Error_Handler();
 }

 if (HAL_SDADC_ConfigChannel(&hsdadc3, SDADC_CHANNEL_6 | SDADC_CHANNEL_7 | SDADC_CHANNEL_8, SDADC_CONTINUOUS_CONV_ON) != HAL_OK)
 {
 Error_Handler();
 }

 I receive values like 0xFEC9 on all 3 channels, also the non connected (hardware) pins.

TDK
Feb 5, 2024 3:38 PM UTC

> SDADC_CHANNEL_6 | SDADC_CHANNEL_7 | SDADC_CHANNEL_8

This is not a valid channel selection. Configure channels one at a time.

Why does the code in your last post not match your original post? Hard to debug if things are changing unexpectedly.

"If you feel a post has answered your question, please click ""Accept as Solution""."
BPutt.1
BPutt.1Author
Associate II
Feb 5, 2024 4:03 PM UTC

Hi Guru,

Separate channel selection was tried before, but with the same result.

While seeking for a solution, IU constantly try an alternative approach and modify the code, I need to get forward...
If it is helpful I can post the original code and keep it as it is, except for the changes you advised.