cancel
Showing results for 
Search instead for 
Did you mean: 

CH2 on ADC1 does not work while CH15 or CH2+CH15 works fine.

fposser
Associate III

Hi, I did a code to select which channel I want to enable in operation according to some parameters when I start the ADC configuration and TMR.

I have the ADC2 with ch5 and ch10, this work fine, both channels, or only 1 of them.

On ADC1 I have ch2 and ch15, both work fine, only ch15 also, but only ch2 I'm getting strange values on the buffer, more or less 4 times less than what's supposed to be.

Someone have any idea of what's happening?

Thank you!

 

void start_TMR_ADC_DMA(void){
    // Reinitialize the ADCs to start fresh
    MX_ADC1_Init();  // Reinitialize ADC1
    MX_ADC2_Init();  // Reinitialize ADC2

    ADC_ChannelConfTypeDef sConfig = {0};

    // Variables to count the number of active ADC channels
    uint8_t adc1_num_channels = 0;
    uint8_t adc2_num_channels = 0;

    // Configure ADC1 channels based on global variables
    if (adc1_channel_2 == 1) {
        // Enable ADC1 Channel 2
        sConfig.Channel = ADC_CHANNEL_2;
        sConfig.Rank = ADC_REGULAR_RANK_1;
        sConfig.SamplingTime = ADC_SAMPLETIME_16CYCLES_5;
        sConfig.SingleDiff = ADC_SINGLE_ENDED;
        sConfig.OffsetNumber = ADC_OFFSET_NONE;
        sConfig.Offset = 0;
        sConfig.OffsetSignedSaturation = DISABLE;
        HAL_ADC_ConfigChannel(&hadc1, &sConfig);
        adc1_num_channels++;  // Increment channel count
    }

    if (adc1_channel_15 == 1) {
        // Enable ADC1 Channel 15
        sConfig.Channel = ADC_CHANNEL_15;
        sConfig.Rank = (adc1_num_channels == 1) ? ADC_REGULAR_RANK_2 : ADC_REGULAR_RANK_1;
        sConfig.SamplingTime = ADC_SAMPLETIME_16CYCLES_5;
        sConfig.SingleDiff = ADC_SINGLE_ENDED;
        sConfig.OffsetNumber = ADC_OFFSET_NONE;
        sConfig.Offset = 0;
        sConfig.OffsetSignedSaturation = DISABLE;
        HAL_ADC_ConfigChannel(&hadc1, &sConfig);
        adc1_num_channels++;  // Increment channel count
    }

    // Configure ADC2 channels based on global variables
    if (adc2_channel_5 == 1) {
        // Enable ADC2 Channel 5
        sConfig.Channel = ADC_CHANNEL_5;
        sConfig.Rank = ADC_REGULAR_RANK_1;
        sConfig.SamplingTime = ADC_SAMPLETIME_16CYCLES_5;
        sConfig.SingleDiff = ADC_SINGLE_ENDED;
        sConfig.OffsetNumber = ADC_OFFSET_NONE;
        sConfig.Offset = 0;
        sConfig.OffsetSignedSaturation = DISABLE;
        HAL_ADC_ConfigChannel(&hadc2, &sConfig);
        adc2_num_channels++;  // Increment channel count
    }

    if (adc2_channel_10 == 1) {
        // Enable ADC2 Channel 10
        sConfig.Channel = ADC_CHANNEL_10;
        sConfig.Rank = (adc2_num_channels == 1) ? ADC_REGULAR_RANK_2 : ADC_REGULAR_RANK_1;
        sConfig.SamplingTime = ADC_SAMPLETIME_16CYCLES_5;
        sConfig.SingleDiff = ADC_SINGLE_ENDED;
        sConfig.OffsetNumber = ADC_OFFSET_NONE;
        sConfig.Offset = 0;
        sConfig.OffsetSignedSaturation = DISABLE;
        HAL_ADC_ConfigChannel(&hadc2, &sConfig);
        adc2_num_channels++;  // Increment channel count
    }

    // Set the number of conversions based on the number of enabled channels
    if (adc1_num_channels > 0) {
        hadc1.Init.NbrOfConversion = adc1_num_channels;
        if (adc1_num_channels == 1) {
        	hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;
        } else {
        	hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE;
        }
        HAL_ADC_Init(&hadc1);  // Reinitialize ADC1 to apply the new configuration
    }

    if (adc2_num_channels > 0) {
        hadc2.Init.NbrOfConversion = adc2_num_channels;
        if (adc2_num_channels == 1) {
        	hadc2.Init.ScanConvMode = ADC_SCAN_DISABLE;
        } else {
        	hadc2.Init.ScanConvMode = ADC_SCAN_ENABLE;
        }
        HAL_ADC_Init(&hadc2);  // Reinitialize ADC2 to apply the new configuration
    }

    // Reinitialize the timers to start fresh
    MX_TIM2_Init();  // Reinitialize TIM2
    MX_TIM3_Init();  // Reinitialize TIM3

    // Start the ADC DMA for both ADCs, ensuring it starts from the beginning of the buffer
    HAL_ADC_Start_DMA(&hadc1, (uint32_t *)adc_i_buffer, ADC_I_BUF_SIZE);  // Start ADC1 DMA
    HAL_ADC_Start_DMA(&hadc2, (uint32_t *)adc_v_buffer, ADC_V_BUF_SIZE);  // Start ADC2 DMA with the first buffer

    // Reset buffer loading state
    v_buf_loaded = 0;

    // Start the timers with interrupts
    HAL_TIM_Base_Start_IT(&htim3);
    HAL_TIM_Base_Start_IT(&htim2);
}
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};

  /* USER CODE BEGIN ADC1_Init 1 */

  /* USER CODE END ADC1_Init 1 */

  /** Common config
  */
  hadc1.Instance = ADC1;
  hadc1.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1;
  hadc1.Init.Resolution = ADC_RESOLUTION_16B;
  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_T3_TRGO;
  hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISING;
  hadc1.Init.ConversionDataManagement = ADC_CONVERSIONDATA_DMA_CIRCULAR;
  hadc1.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN;
  hadc1.Init.LeftBitShift = ADC_LEFTBITSHIFT_NONE;
  hadc1.Init.OversamplingMode = DISABLE;
  hadc1.Init.Oversampling.Ratio = 1;
  if (HAL_ADC_Init(&hadc1) != HAL_OK)
  {
    Error_Handler();
  }

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

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

  /** Configure Regular Channel
  */
/*  sConfig.Channel = ADC_CHANNEL_2;
  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 */

}

/**
  * @brief ADC2 Initialization Function
  * @PAram None
  * @retval None
  */
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_16B;
  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.ExternalTrigConv = ADC_EXTERNALTRIG_T3_TRGO;
  hadc2.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISING;
  hadc2.Init.ConversionDataManagement = ADC_CONVERSIONDATA_DMA_CIRCULAR;
  hadc2.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN;
  hadc2.Init.LeftBitShift = ADC_LEFTBITSHIFT_NONE;
  hadc2.Init.OversamplingMode = DISABLE;
  hadc2.Init.Oversampling.Ratio = 1;
  if (HAL_ADC_Init(&hadc2) != HAL_OK)
  {
    Error_Handler();
  }

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

  /** Configure Regular Channel
  */
/*  sConfig.Channel = ADC_CHANNEL_10;
  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 */

}

 

2 REPLIES 2
STTwo-32
ST Employee

Hello @fposser 

Could you check the errata 2.10.11 of the ES0491. It may be give a discription of the same issue that you are facing.

Best Regards.

STTwo-32 

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

But would not be this case here?

ADC1 and ADC2 are not impacted when running in dual mode, as they operate sampling and conversion at the same time.

 

And it would not explain why when I select only the CH15 or both it works fine. When I select only Ch2 that I have the wrong value.