cancel
Showing results for 
Search instead for 
Did you mean: 

How to setup STM32F373 SDADC with multiple channels over DMA

BPutt.1
Associate II

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;
}

 

 

4 REPLIES 4
TDK
Guru

> 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".

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
Guru

> 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".

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.