cancel
Showing results for 
Search instead for 
Did you mean: 

How to configure Sigma Delta ADC 16-bit in STM32CubeIDE

DMårt
Senior II

Hi!

I think there is a lack of information to configure a Sigma Delta ADC 16-bit in STM32CubeIDE and I want to configure:

  • 2 Single ended zero reference
  • 3 Differential ended

So I have a lot of questions for the STM32 Team here.

I begin first to configure on SDADC1.

0693W000006EzhIQAS.png 

Then I select 3 conversions because I have 1 Single ended and 2 Differential ended

0693W000006EzljQAC.pngI want VDD = 3.3v to be my reference voltage and I don't want low power mode and fast conversions mode.

0693W000006EzmNQAS.pngDen I select my conversions:

0693W000006EzzlQAC.png 

Question:

What is "Common mode"? I have read the document AN4207 and I don't know what Common Mode has to do with Differential mode? I know that VSSA är analog ground.

0693W000006F04lQAC.png 

Now it's time to configure the settings.

0693W000006F05PQAS.pngQuestion:

What should I select?

Assume that I'm selecting Regular and I want my SDADC1 to sample values continuously.

0693W000006F06wQAC.pngQuestion:

What is Mulimode type?

Assume that I'm selecting Injected.

0693W000006F0DYQA0.png 

Question:

What is Configuration Index?

What is Injected Delay?

Assume that I'm selecting an external trigger, instead of letting the processor handles when I should sample for SDADC1.

0693W000006F0HpQAK.png 

Question:

Why have the other ADC have External Trigger source as Output but SDADC1 have Output Compare as trigger source?

Is it better to select an external trigger source for SDADC1 in this case?

Does Output Compare means that every time there have been a change in the differential inputs, or single ended zero reference input, the SDADC1 should take a sample?

This picture is from ADC1 and not SDADC1.

0693W000006F0HWQA0.png 

And if I want to connect the SDADC to DMA I can write this code:

// DMA SD ADC
  uint8_t SD_ADC1_element_size = sizeof(SD_ADC1_VALUES)/sizeof(SD_ADC1_VALUES[0]);
  uint8_t SD_ADC3_element_size = sizeof(SD_ADC3_VALUES)/sizeof(SD_ADC3_VALUES[0]);
  HAL_SDADC_Start_DMA(&hsdadc1, (uint32_t *) SD_ADC1_VALUES, (uint32_t) SD_ADC1_element_size);
  HAL_SDADC_Start_DMA(&hsdadc3, (uint32_t *) SD_ADC3_VALUES, (uint32_t) SD_ADC3_element_size);

Question:

Where the arrays SD_ADC1_VALUES and SD_ADC3_VALUES will be updated continuously?

Edit:

Here is my example code. Complete code can be found here: https://pastebin.com/qYaSN080

volatile uint16_t SD_ADC1_VALUES[3] = {0};
volatile uint16_t SD_ADC3_VALUES[2] = {0};
 
int main(void)
{
  MX_SDADC1_Init();
  MX_SDADC3_Init();
 
  uint8_t SD_ADC1_element_size = sizeof(SD_ADC1_VALUES)/sizeof(SD_ADC1_VALUES[0]);
  uint8_t SD_ADC3_element_size = sizeof(SD_ADC3_VALUES)/sizeof(SD_ADC3_VALUES[0]);
  HAL_SDADC_Start_DMA(&hsdadc1, (uint32_t *) SD_ADC1_VALUES, SD_ADC1_element_size);
  HAL_SDADC_Start_DMA(&hsdadc3, (uint32_t *) SD_ADC3_VALUES, SD_ADC3_element_size);
 
  while (1)
  {
     // Here I'm trying to read SD_ADC1_VALUES and SD_ADC3_VALUES from the ST-LINKV2 Debugging mode. All elements in these arrays are 0. 
  }
}
 
/**
  * @brief SDADC3 Initialization Function
  * @param None
  * @retval None
  */
static void MX_SDADC3_Init(void)
{
 
  /* USER CODE BEGIN SDADC3_Init 0 */
 
  /* 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_EXT;
  hsdadc3.InjectedTrigger = SDADC_SOFTWARE_TRIGGER;
  if (HAL_SDADC_Init(&hsdadc3) != HAL_OK)
  {
    Error_Handler();
  }
  /** Configure the Injected Mode
  */
  if (HAL_SDADC_SelectInjectedDelay(&hsdadc3, SDADC_INJECTED_DELAY_NONE) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_SDADC_SelectInjectedTrigger(&hsdadc3, SDADC_SOFTWARE_TRIGGER) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_SDADC_InjectedConfigChannel(&hsdadc3, SDADC_CHANNEL_6|SDADC_CHANNEL_8, SDADC_CONTINUOUS_CONV_ON) != HAL_OK)
  {
    Error_Handler();
  }
  /** Set parameters for SDADC configuration 0 Register
  */
  ConfParamStruct.InputMode = SDADC_INPUT_MODE_SE_ZERO_REFERENCE;
  ConfParamStruct.Gain = SDADC_GAIN_1;
  ConfParamStruct.CommonMode = SDADC_COMMON_MODE_VSSA;
  ConfParamStruct.Offset = 0;
  if (HAL_SDADC_PrepareChannelConfig(&hsdadc3, SDADC_CONF_INDEX_0, &ConfParamStruct) != HAL_OK)
  {
    Error_Handler();
  }
  /** Set parameters for SDADC configuration 1 Register
  */
  ConfParamStruct.InputMode = SDADC_INPUT_MODE_DIFF;
  if (HAL_SDADC_PrepareChannelConfig(&hsdadc3, SDADC_CONF_INDEX_1, &ConfParamStruct) != HAL_OK)
  {
    Error_Handler();
  }
  /** Configure the Injected Channel
  */
  if (HAL_SDADC_AssociateChannelConfig(&hsdadc3, SDADC_CHANNEL_6, SDADC_CONF_INDEX_0) != HAL_OK)
  {
    Error_Handler();
  }
  /** Configure the Injected Channel
  */
  if (HAL_SDADC_AssociateChannelConfig(&hsdadc3, SDADC_CHANNEL_8, SDADC_CONF_INDEX_1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN SDADC3_Init 2 */
 
  /* USER CODE END SDADC3_Init 2 */
 
}
 
/**
  * @brief SDADC1 Initialization Function
  * @param None
  * @retval None
  */
static void MX_SDADC1_Init(void)
{
 
  /* USER CODE BEGIN SDADC1_Init 0 */
 
  /* USER CODE END SDADC1_Init 0 */
 
  SDADC_ConfParamTypeDef ConfParamStruct = {0};
 
  /* USER CODE BEGIN SDADC1_Init 1 */
 
  /* USER CODE END SDADC1_Init 1 */
  /** Configure the SDADC low power mode, fast conversion mode,
  slow clock mode and SDADC1 reference voltage
  */
  hsdadc1.Instance = SDADC1;
  hsdadc1.Init.IdleLowPowerMode = SDADC_LOWPOWER_NONE;
  hsdadc1.Init.FastConversionMode = SDADC_FAST_CONV_DISABLE;
  hsdadc1.Init.SlowClockMode = SDADC_SLOW_CLOCK_DISABLE;
  hsdadc1.Init.ReferenceVoltage = SDADC_VREF_EXT;
  hsdadc1.InjectedTrigger = SDADC_SOFTWARE_TRIGGER;
  if (HAL_SDADC_Init(&hsdadc1) != HAL_OK)
  {
    Error_Handler();
  }
  /** Configure the Injected Mode
  */
  if (HAL_SDADC_SelectInjectedDelay(&hsdadc1, SDADC_INJECTED_DELAY_NONE) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_SDADC_SelectInjectedTrigger(&hsdadc1, SDADC_SOFTWARE_TRIGGER) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_SDADC_InjectedConfigChannel(&hsdadc1, SDADC_CHANNEL_4|SDADC_CHANNEL_8
                              |SDADC_CHANNEL_6, SDADC_CONTINUOUS_CONV_ON) != HAL_OK)
  {
    Error_Handler();
  }
  /** Set parameters for SDADC configuration 0 Register
  */
  ConfParamStruct.InputMode = SDADC_INPUT_MODE_SE_ZERO_REFERENCE;
  ConfParamStruct.Gain = SDADC_GAIN_1;
  ConfParamStruct.CommonMode = SDADC_COMMON_MODE_VSSA;
  ConfParamStruct.Offset = 0;
  if (HAL_SDADC_PrepareChannelConfig(&hsdadc1, SDADC_CONF_INDEX_0, &ConfParamStruct) != HAL_OK)
  {
    Error_Handler();
  }
  /** Set parameters for SDADC configuration 1 Register
  */
  ConfParamStruct.InputMode = SDADC_INPUT_MODE_DIFF;
  if (HAL_SDADC_PrepareChannelConfig(&hsdadc1, SDADC_CONF_INDEX_1, &ConfParamStruct) != HAL_OK)
  {
    Error_Handler();
  }
  /** Configure the Injected Channel
  */
  if (HAL_SDADC_AssociateChannelConfig(&hsdadc1, SDADC_CHANNEL_4, SDADC_CONF_INDEX_0) != HAL_OK)
  {
    Error_Handler();
  }
  /** Configure the Injected Channel
  */
  if (HAL_SDADC_AssociateChannelConfig(&hsdadc1, SDADC_CHANNEL_8, SDADC_CONF_INDEX_1) != HAL_OK)
  {
    Error_Handler();
  }
  /** Configure the Injected Channel
  */
  if (HAL_SDADC_AssociateChannelConfig(&hsdadc1, SDADC_CHANNEL_6, SDADC_CONF_INDEX_1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN SDADC1_Init 2 */
 
  /* USER CODE END SDADC1_Init 2 */
 
}

2 REPLIES 2
DMårt
Senior II

Nobody knows?

DMårt
Senior II

Now I have got an ERROR. But I don't understand what it means.

Se comment "HERE I GOT THE ERROR" below.

HAL_StatusTypeDef HAL_SDADC_Start_DMA(SDADC_HandleTypeDef *hsdadc, uint32_t *pData,
                                      uint32_t Length)
{
  HAL_StatusTypeDef status;
 
  /* Check parameters */
  assert_param(IS_SDADC_ALL_INSTANCE(hsdadc->Instance));
  assert_param(pData != ((void*) 0));
  assert_param(Length != 0UL);
 
  /* Check that DMA is not enabled for injected conversion */
  if((hsdadc->Instance->CR1 & SDADC_CR1_JDMAEN) == SDADC_CR1_JDMAEN)
  {
    status = HAL_ERROR;
  }
  /* Check parameters compatibility */
  else if((hsdadc->RegularTrigger == SDADC_SOFTWARE_TRIGGER) && \
          (hsdadc->RegularContMode == SDADC_CONTINUOUS_CONV_OFF) && \
          (hsdadc->hdma->Init.Mode == DMA_NORMAL) && \
          (Length != 1U))
  {
    status = HAL_ERROR;
  }
  else if((hsdadc->RegularTrigger == SDADC_SOFTWARE_TRIGGER) && \
          (hsdadc->RegularContMode == SDADC_CONTINUOUS_CONV_OFF) && \
          (hsdadc->hdma->Init.Mode == DMA_CIRCULAR))
  {
    status = HAL_ERROR; <<<------ HERE I GOT THE ERROR
  }
  /* Check SDADC state */
  else if((hsdadc->State == HAL_SDADC_STATE_READY) || \
          (hsdadc->State == HAL_SDADC_STATE_INJ))
  {
    /* Set callbacks on DMA handler */
    hsdadc->hdma->XferCpltCallback = SDADC_DMARegularConvCplt;
    hsdadc->hdma->XferErrorCallback = SDADC_DMAError;
    if(hsdadc->hdma->Init.Mode == DMA_CIRCULAR)
    {
      hsdadc->hdma->XferHalfCpltCallback = SDADC_DMARegularHalfConvCplt;
    }
    
    /* Set RDMAEN bit in SDADC_CR1 register */
    hsdadc->Instance->CR1 |= SDADC_CR1_RDMAEN;
 
    /* Start DMA in interrupt mode */
    if(HAL_DMA_Start_IT(hsdadc->hdma, (uint32_t)&hsdadc->Instance->RDATAR, \
                        (uint32_t) pData, Length) != HAL_OK)
    {
      /* Set SDADC in error state */
      hsdadc->State = HAL_SDADC_STATE_ERROR;
      status = HAL_ERROR;
    }
    else
    {
      /* Start regular conversion */
      status = SDADC_RegConvStart(hsdadc);
    }
  }
  else
  {
    status = HAL_ERROR;
  }
  /* Return function status */
  return status;
}