cancel
Showing results for 
Search instead for 
Did you mean: 

I am working on H743. I have trouble getting ADC3 to work in continuous DMA transfer mode. I have ADC1 working fine but ADC3 wont work. Is there something wrong in my config?

sbstek
Associate

After doing debugging i have found that the error code is set by DMA config function :

HAL_StatusTypeDef HAL_DMA_Start_IT(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
{
.
.
.
.
.    
  else
  {
    /* Process unlocked */
    __HAL_UNLOCK(hdma);
 
    /* Set the error code to busy */
    hdma->ErrorCode = HAL_DMA_ERROR_BUSY;  //< this line is setting error code >
 
    /* Return error status */
    status = HAL_ERROR;
  }
 
  return status;
}

here are my configs for ADC1 and ADC2:

  hadc1.Instance          = ADC1;
  if (HAL_ADC_DeInit(&hadc1) != HAL_OK)
  {
    /* ADC de-initialization Error */
    Error_Handler();
  }
 
  hadc1.Init.ClockPrescaler           = ADC_CLOCK_ASYNC_DIV2;          /* Asynchronous clock mode, input ADC clock divided by 2*/
  hadc1.Init.Resolution               = ADC_RESOLUTION_16B;            /* 16-bit resolution for converted data */
  hadc1.Init.ScanConvMode             = ADC_SCAN_ENABLE;                       /* Sequencer disabled (ADC conversion on only 1 channel: channel set on rank 1) */
  hadc1.Init.EOCSelection             = ADC_EOC_SINGLE_CONV;           /* EOC flag picked-up to indicate conversion end */
  hadc1.Init.LowPowerAutoWait         = DISABLE;                       /* Auto-delayed conversion feature disabled */
  hadc1.Init.ContinuousConvMode       = ENABLE;                        /* Continuous mode enabled (automatic conversion restart after each conversion) */
  hadc1.Init.NbrOfConversion          = 3;                             /* Parameter discarded because sequencer is disabled */
  hadc1.Init.DiscontinuousConvMode    = DISABLE;                       /* Parameter discarded because sequencer is disabled */
  //hadc1.Init.NbrOfDiscConversion      = 1;                             /* Parameter discarded because sequencer is disabled */
  hadc1.Init.ExternalTrigConv         = ADC_SOFTWARE_START;            /* Software start to trig the 1st conversion manually, without external event */
  hadc1.Init.ExternalTrigConvEdge     = ADC_EXTERNALTRIGCONVEDGE_NONE; /* Parameter discarded because software trigger chosen */
  hadc1.Init.ConversionDataManagement = ADC_CONVERSIONDATA_DMA_CIRCULAR; /* ADC DMA circular requested */
  hadc1.Init.Overrun                  = ADC_OVR_DATA_OVERWRITTEN;      /* DR register is overwritten with the last conversion result in case of overrun */
  hadc1.Init.OversamplingMode         = DISABLE;                       /* No oversampling */
  /* Initialize ADC peripheral according to the passed parameters */
 
  if (HAL_ADC_Init(&hadc1) != HAL_OK)
  {
    Error_Handler();
  }
 
 
  /* ### - 2 - Start calibration ############################################ */
  if (HAL_ADCEx_Calibration_Start(&hadc1, ADC_CALIB_OFFSET, ADC_SINGLE_ENDED) != HAL_OK)
  {
    Error_Handler();
  }
 
  /* ### - 3 - Channel configuration ######################################## */
  /** Configure Regular Channel
  */
  sConfig.Channel = ADC_CHANNEL_15;
  sConfig.Rank = ADC_REGULAR_RANK_1;
  sConfig.SamplingTime = ADC_SAMPLETIME_1CYCLE_5;
  sConfig.SingleDiff = ADC_SINGLE_ENDED;
  sConfig.OffsetNumber = ADC_OFFSET_NONE;
  sConfig.Offset = 0;
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /** Configure Regular Channel
  */
  sConfig.Channel = ADC_CHANNEL_10;
  sConfig.Rank = ADC_REGULAR_RANK_2;
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }
 
  sConfig.Channel = ADC_CHANNEL_5;
  sConfig.Rank = ADC_REGULAR_RANK_2;
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /** Configure Regular Channel
  */
/*
  sConfig.Channel = ADC_CHANNEL_5;
  sConfig.Rank = ADC_REGULAR_RANK_3;
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }
*/
 
 
  /* ### - 4 - Start conversion in DMA mode ################################# */
 
  if (HAL_ADC_Start_DMA(&hadc1,
        (uint32_t *)aADCxConvertedData,
        ADC_CONVERTED_DATA_BUFFER_SIZE
       ) != HAL_OK)
  {
	Error_Handler();
  }
 
  /**************************************ADC3*********************************************/
  hadc3.Instance          = ADC3;
  if (HAL_ADC_DeInit(&hadc3) != HAL_OK)
  {
    /* ADC de-initialization Error */
    Error_Handler();
  }
 
  hadc3.Init.ClockPrescaler           = ADC_CLOCK_ASYNC_DIV2;          /* Asynchronous clock mode, input ADC clock divided by 2*/
  hadc3.Init.Resolution               = ADC_RESOLUTION_12B;            /* 16-bit resolution for converted data */
  hadc3.Init.ScanConvMode             = ADC_SCAN_ENABLE;                       /* Sequencer disabled (ADC conversion on only 1 channel: channel set on rank 1) */
  hadc3.Init.EOCSelection             = ADC_EOC_SINGLE_CONV;           /* EOC flag picked-up to indicate conversion end */
  hadc3.Init.LowPowerAutoWait         = DISABLE;                       /* Auto-delayed conversion feature disabled */
  hadc3.Init.ContinuousConvMode       = ENABLE;                        /* Continuous mode enabled (automatic conversion restart after each conversion) */
  hadc3.Init.NbrOfConversion          = 3;                             /* Parameter discarded because sequencer is disabled */
  hadc3.Init.DiscontinuousConvMode    = DISABLE;                       /* Parameter discarded because sequencer is disabled */
  //AdcHandle.Init.NbrOfDiscConversion      = 1;                             /* Parameter discarded because sequencer is disabled */
  hadc3.Init.ExternalTrigConv         = ADC_SOFTWARE_START;            /* Software start to trig the 1st conversion manually, without external event */
  hadc3.Init.ExternalTrigConvEdge     = ADC_EXTERNALTRIGCONVEDGE_NONE; /* Parameter discarded because software trigger chosen */
  hadc3.Init.ConversionDataManagement = ADC_CONVERSIONDATA_DMA_CIRCULAR; /* ADC DMA circular requested */
  hadc3.Init.Overrun                  = ADC_OVR_DATA_OVERWRITTEN;      /* DR register is overwritten with the last conversion result in case of overrun */
  hadc3.Init.OversamplingMode         = DISABLE;                       /* No oversampling */
  /* Initialize ADC peripheral according to the passed parameters */
 
  if (HAL_ADC_Init(&hadc3) != HAL_OK)
  {
    Error_Handler();
  }
 
 
  /* ### - 2 - Start calibration ############################################ */
  if (HAL_ADCEx_Calibration_Start(&hadc3, ADC_CALIB_OFFSET, ADC_SINGLE_ENDED) != HAL_OK)
  {
    Error_Handler();
  }
 
  /* ### - 3 - Channel configuration ######################################## */
  /** Configure Regular Channel
  */
  sConfig3.Channel = ADC_CHANNEL_9;
  sConfig3.Rank = ADC_REGULAR_RANK_1;
  sConfig3.SamplingTime = ADC_SAMPLETIME_1CYCLE_5;
  sConfig3.SingleDiff = ADC_SINGLE_ENDED;
  sConfig3.OffsetNumber = ADC_OFFSET_NONE;
  sConfig3.Offset = 0;
  if (HAL_ADC_ConfigChannel(&hadc3, &sConfig3) != HAL_OK)
  {
    Error_Handler();
  }
  /** Configure Regular Channel
  */
  sConfig3.Channel = ADC_CHANNEL_4;
  sConfig3.Rank = ADC_REGULAR_RANK_2;
  if (HAL_ADC_ConfigChannel(&hadc3, &sConfig3) != HAL_OK)
  {
    Error_Handler();
  }
 
  sConfig3.Channel = ADC_CHANNEL_8;
  sConfig3.Rank = ADC_REGULAR_RANK_2;
  if (HAL_ADC_ConfigChannel(&hadc3, &sConfig3) != HAL_OK)
  {
    Error_Handler();
  }
  /** Configure Regular Channel
  */
/*
  sConfig.Channel = ADC_CHANNEL_5;
  sConfig.Rank = ADC_REGULAR_RANK_3;
  if (HAL_ADC_ConfigChannel(&AdcHandle, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }
*/
 
  /* ### - 4 - Start conversion in DMA mode ################################# */
 
  if (HAL_ADC_Start_DMA(&hadc3,
                        (uint32_t *)aADC3ConvertedData,
                        ADC_CONVERTED_DATA_BUFFER_SIZE
                       ) != HAL_OK)
  {
    Error_Handler();
  }

1 REPLY 1
sbstek
Associate

here is the HAL_Msp_Init() function:

void HAL_ADC_MspInit(ADC_HandleTypeDef *hadc)
{
  GPIO_InitTypeDef          GPIO_InitStruct;
  static DMA_HandleTypeDef         DmaHandle;
  static DMA_HandleTypeDef 		  hdma_adc3;
  
  /*##-1- Enable peripherals and GPIO Clocks #################################*/
  /* Enable GPIO clock ****************************************/
 
 
  /*##- 3- Configure DMA #####################################################*/
 
  /*********************** Configure DMA parameters ***************************/
  if(hadc->Instance == ADC1){
	  __HAL_RCC_ADC_CONFIG(RCC_ADCCLKSOURCE_CLKP);
 
	  ADCx_CLK_ENABLE();
 
	  __HAL_RCC_GPIOA_CLK_ENABLE();
	  __HAL_RCC_GPIOC_CLK_ENABLE();
	  __HAL_RCC_GPIOB_CLK_ENABLE();
	  /* ADC Channel GPIO pin configuration */
	  GPIO_InitStruct.Pin = ADCx_CHANNEL_PIN;
	  GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
	  GPIO_InitStruct.Pull = GPIO_NOPULL;
	  HAL_GPIO_Init(ADCx_CHANNEL_GPIO_PORT, &GPIO_InitStruct);
 
	  GPIO_InitStruct.Pin = GPIO_PIN_0;
	  GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
	  GPIO_InitStruct.Pull = GPIO_NOPULL;
	  HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
 
	  GPIO_InitStruct.Pin = GPIO_PIN_1;
	  GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
	  GPIO_InitStruct.Pull = GPIO_NOPULL;
	  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
 
	  DMAx_CHANNELx_CLK_ENABLE();
 
 
  DmaHandle.Instance                 = DMA1_Stream1;
  DmaHandle.Init.Request             = DMA_REQUEST_ADC1;
  DmaHandle.Init.Direction           = DMA_PERIPH_TO_MEMORY;
  DmaHandle.Init.PeriphInc           = DMA_PINC_DISABLE;
  DmaHandle.Init.MemInc              = DMA_MINC_ENABLE;
  DmaHandle.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
  DmaHandle.Init.MemDataAlignment    = DMA_MDATAALIGN_HALFWORD;
  DmaHandle.Init.Mode                = DMA_CIRCULAR;
  DmaHandle.Init.Priority            = DMA_PRIORITY_MEDIUM;
  DmaHandle.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
 
  /* Deinitialize  & Initialize the DMA for new transfer */
  HAL_DMA_DeInit(&DmaHandle);
  HAL_DMA_Init(&DmaHandle);
  
  /* Associate the DMA handle */
  __HAL_LINKDMA(hadc, DMA_Handle, DmaHandle);
 
  /* NVIC configuration for DMA Input data interrupt */
  HAL_NVIC_SetPriority(DMA1_Stream1_IRQn, 0, 1);
  HAL_NVIC_EnableIRQ(DMA1_Stream1_IRQn);
  }
 
  if(hadc->Instance == ADC3){
 
 
	  __HAL_RCC_GPIOF_CLK_ENABLE();
 
	  /* ADC Periph clock enable */
	  __HAL_RCC_ADC3_CLK_ENABLE();
	  /* ADC Periph interface clock configuration */
	  /* Enable DMA clock */
	  __HAL_RCC_DMA2_CLK_ENABLE();
 
	  /*##- 2- Configure peripheral GPIO #########################################*/
 
 
	  GPIO_InitStruct.Pin = GPIO_PIN_6 | GPIO_PIN_4 | GPIO_PIN_5;
	  GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
	  GPIO_InitStruct.Pull = GPIO_NOPULL;
	  HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);
 
	  hdma_adc3.Instance = DMA1_Stream2;
	  hdma_adc3.Init.Request = DMA_REQUEST_ADC3;
	  hdma_adc3.Init.Direction = DMA_PERIPH_TO_MEMORY;
	  hdma_adc3.Init.PeriphInc = DMA_PINC_DISABLE;
	  hdma_adc3.Init.MemInc = DMA_MINC_ENABLE;
	  hdma_adc3.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
	  hdma_adc3.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
	  hdma_adc3.Init.Mode = DMA_CIRCULAR;
	  hdma_adc3.Init.Priority = DMA_PRIORITY_HIGH;
	  hdma_adc3.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
/*
	  hdma_adc3.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
	  hdma_adc3.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_3QUARTERSFULL;
*/
 
	  __HAL_LINKDMA(hadc,DMA_Handle,hdma_adc3);
	  HAL_NVIC_SetPriority(DMA1_Stream2_IRQn, 0, 1);
	  HAL_NVIC_EnableIRQ(DMA1_Stream2_IRQn);
 
  }
 
}