Skip to main content
Visitor II
February 5, 2024
Question

How to setup STM32F373 SDADC with multiple channels over DMA

  • February 5, 2024
  • 2 replies
  • 1852 views

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.

    2 replies

    Super User
    February 5, 2024

    > 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?

    BPutt.1Author
    Visitor II
    February 5, 2024

    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.

    Super User
    February 5, 2024

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

    BPutt.1Author
    Visitor II
    February 5, 2024

    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.