Skip to main content
sbstek
Associate
October 29, 2019
Question

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?

  • October 29, 2019
  • 1 reply
  • 626 views

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();
 }

This topic has been closed for replies.

1 reply

sbstek
sbstekAuthor
Associate
October 29, 2019

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);
 
 }
 
}