cancel
Showing results for 
Search instead for 
Did you mean: 

ADC3 on STM303F3xx not working (PB0, PB1).

Marius CO
Associate III

I have an old project already using PA 0,1,2,3,5,7 and PC 1,2,3 as analogue inputs, all on ADC 1 and 2. Due the nature of the project I read some of them in a interrupt timer, and some on demand,when a UART command kicks in.

I had to add 3 more ADC's on PB0 PB1 PB2 on ADC3. My code follows same initialization for ADC3 as ADC1/2, which is standard CUBEMX code.

Upon reading, the ADC3 times out waiting for ISR bit.

static HAL_StatusTypeDef ADC_Enable(ADC_HandleTypeDef* hadc)
{
  uint32_t tickstart = 0U;
  
  /* ADC enable and wait for ADC ready (in case of ADC is disabled or         */
  /* enabling phase not yet completed: flag ADC ready not yet set).           */
  /* Timeout implemented to not be stuck if ADC cannot be enabled (possible   */
  /* causes: ADC clock not running, ...).                                     */
  if (ADC_IS_ENABLE(hadc) == RESET)
  {
    /* Check if conditions to enable the ADC are fulfilled */
    if (ADC_ENABLING_CONDITIONS(hadc) == RESET)
    {
      /* Update ADC state machine to error */
      SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL);
      
      /* Set ADC error code to ADC IP internal error */
      SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL);
      
      return HAL_ERROR;
    }
    
    /* Enable the ADC peripheral */
    __HAL_ADC_ENABLE(hadc);
    
    /* Wait for ADC effectively enabled */
    tickstart = HAL_GetTick();  
    
    while(__HAL_ADC_GET_FLAG(hadc, ADC_FLAG_RDY) == RESET)
    {
      if((HAL_GetTick() - tickstart) > ADC_ENABLE_TIMEOUT)
      {
        /* Update ADC state machine to error */
        SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL);
        
        /* Set ADC error code to ADC IP internal error */
        SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL);
      
        return HAL_ERROR; <<<<==== TIMEOUTS
      }
    }
  }
  
  /* Return HAL status */
  return HAL_OK;
}

I disabled all the code around leaving only the ADC3. The flags and timer for ADC3 is started. I am struggling with this issue for a 2 days now. Here is my code for reference. Anyone can spot something wrong would be appreciated.

My Init code (never failed on ADC1 and 2 for few months)

///////////////////////////////////////////
// MAIN
{
	HAL_Init();
	SystemClock_Config();
	MX_GPIO_Init();
	MX_USART3_UART_Init();
	INIT_PWM_TIMERS()   // TIM2(10Khz) TIM3-ch1,ch2 (100Khz) TIM4-ch1,2,3,4 (100Khz) & __HAL_RCC_TIM 2,3,4_CLK_ENABLE
//	MX_ADC1_Init();
//	MX_ADC2_Init();
	MX_ADC3_Init();
//	readPinValue(PA7);  //<- this works on ADC2
	readPinValue(PB0);  //<- this fails
	return 0;
}
 
/////////////////////////////////////////////////////////////
MX_ADC[1..3]_Init()
{
    ADC_ChannelConfTypeDef sConfig;
 
    hadc3.Instance = ADC[1..3];
    myInit_Adc(&hadc[1..3]);
    if (HAL_ADC_Init(&hadc[1..3]) != HAL_OK)
    {
        _Error_Handler(__FILE__, __LINE__);
    }
    myInitChannels(&hadc[1..3], &sConfig);
}
 
/////////////////////////////////////////////////////////////
static void myInit_Adc(ADC_HandleTypeDef* hadc)
{
    hadc->Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1;
    hadc->Init.Resolution = ADC_RESOLUTION_12B;
    hadc->Init.DataAlign = ADC_DATAALIGN_RIGHT;
    hadc->Init.ScanConvMode = ADC_SCAN_DISABLE;
    hadc->Init.EOCSelection = DISABLE; // to turn on once. ADC_EOC_SINGLE_CONV; //ADC_EOC_SEQ_CONV
    hadc->Init.LowPowerAutoWait = DISABLE;
    //hadc->Init.LowPowerAutoPowerOff = DISABLE;
    hadc->Init.ContinuousConvMode = DISABLE;
    hadc->Init.DiscontinuousConvMode = DISABLE;
    hadc->Init.ExternalTrigConv = ADC_SOFTWARE_START;
    hadc->Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
    hadc->Init.DMAContinuousRequests = DISABLE;
    hadc->Init.Overrun = ADC_OVR_DATA_PRESERVED;
}
 
/////////////////////////////////////////////////////////////
static void myInitChannels(ADC_HandleTypeDef* hadc,
                           ADC_ChannelConfTypeDef* sConfig)
{
    struct AnalogPin* pp =  &Anals[0];
    for(; pp->typ!=PNA; pp++)
    {
        if(pp->adc == hadc)
        {
            sConfig->Channel      = pp->channel;  // from PIN right channel
            sConfig->Rank         = pp->rank;	  // allways ADC_RANK_CHANNEL_NUMBER
            sConfig->SingleDiff   = ADC_SINGLE_ENDED;
            sConfig->SamplingTime = ADC_SAMPLETIME_1CYCLE_5;
            sConfig->OffsetNumber = ADC_OFFSET_NONE;
            sConfig->Offset       = 0;
            if (HAL_ADC_ConfigChannel(hadc, sConfig) != HAL_OK)
            {
                _Error_Handler(__FILE__, __LINE__);
            }
        }
    }
}

///
///  MSP INIT
///
 
void HAL_ADC_MspInit(ADC_HandleTypeDef* adcHandle)
{
 
    GPIO_InitTypeDef GPIO_InitStruct;
    if(adcHandle->Instance==ADC1)
    {
        HAL_RCC_ADC12_CLK_ENABLED++;
        if(HAL_RCC_ADC12_CLK_ENABLED==1){
            __HAL_RCC_ADC12_CLK_ENABLE();
        }
 
        /**ADC1 GPIO Configuration
    PC0     ------> ADC1_IN6
    PC1     ------> ADC1_IN7
    PC2     ------> ADC1_IN8
    PC3     ------> ADC1_IN9
    PA0     ------> ADC1_IN1
    PA1     ------> ADC1_IN2
    PA2     ------> ADC1_IN3
    PA3     ------> ADC1_IN4
    */
        GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3;
        GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
        GPIO_InitStruct.Pull = GPIO_NOPULL;
        HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
 
        GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3;
        GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
        GPIO_InitStruct.Pull = GPIO_NOPULL;
        HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
    }
    else if(adcHandle->Instance==ADC2)
    {
        HAL_RCC_ADC12_CLK_ENABLED++;
        if(HAL_RCC_ADC12_CLK_ENABLED==1){
            __HAL_RCC_ADC12_CLK_ENABLE();
        }
 
        /**ADC2 GPIO Configuration
    PA5     ------> ADC2_IN2
    PA6     ------> ADC2_IN3
    PA7     ------> ADC2_IN4
    PB2     ------> ADC2_IN12
    */
        GPIO_InitStruct.Pin = GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7;
        GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
        GPIO_InitStruct.Pull = GPIO_NOPULL;
        HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
 
        GPIO_InitStruct.Pin = GPIO_PIN_2;
        GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
        GPIO_InitStruct.Pull = GPIO_NOPULL;
        HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
    }
    else if(adcHandle->Instance==ADC3)
    {
        /* USER CODE BEGIN ADC3_MspInit 0 */
        HAL_RCC_ADC34_CLK_ENABLED++;
        if(HAL_RCC_ADC34_CLK_ENABLED==1){
            __HAL_RCC_ADC34_CLK_ENABLE();
        }
        /**ADC3 GPIO Configuration
    PB0     ------> ADC3_IN12
    PB1     ------> ADC3_IN1
    */
        GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1;
        GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
        GPIO_InitStruct.Pull = GPIO_NOPULL;
        HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
    }
}

My read code:

 
    //
    //  SELECT ADC
    //
    ADC_ChannelConfTypeDef sConfig;
    sConfig.Channel = ADC_CHANNEL_[FOR PIN];  (11 for ADC3 PB0)
    sConfig.Rank = ADC_REGULAR_RANK_1;
    sConfig.SingleDiff = ADC_SINGLE_ENDED;
    sConfig.SamplingTime = ADC_SAMPLETIME_1CYCLE_5;
    sConfig.OffsetNumber = ADC_OFFSET_NONE;
    sConfig.Offset = 0;
    HAL_ADC_ConfigChannel(HADC, &sConfig);
	//
	//  START
	//
	HAL_ADC_Start(HADC);   /// <<<<  fails for ADC3 as described above
	//
	// rewad
	//
	HAL_ADC_PollForConversion(...)
	HAL_ADC_GetValue(...)
	HAL_ADC_Stop(HADC);

0 REPLIES 0