cancel
Showing results for 
Search instead for 
Did you mean: 

ADC read in DMA regular mode

reedomneck
Associate III
I've requirement of reading 100 samples of ADC data using DMA whenever it's needed in regular mode and I see the read buffer is not having right values and also HAL_ADC_ConvCpltCallback is not hitting.
But same if I try just with one sample data is proper and HAL_ADC_ConvCpltCallback is hitting but when I retrigger ADC_DMA_READ I see HAL_BUSY.
I'm using NUCLEO-545REQ board
 
/*GLOBAL VARIABLE*/ #define ADC_CONVERTED_DATA_BUFFER_SIZE ((uint32_t) 100) /* Size of array aADCxConvertedData[] */ /* Variable containing ADC conversions data */ uint32_t aADCxConvertedData[ADC_CONVERTED_DATA_BUFFER_SIZE]; int isADCFinished = 0; #define VDDA_APPLI (3300UL) uint16_t uhADCxConvertedData_Voltage_mVolt = 0; /* Value of voltage calculated from ADC conversion data (unit: mV) */ /* Init variable out of expected ADC conversion data range */ #define VAR_CONVERTED_DATA_INIT_VALUE (__LL_ADC_DIGITAL_SCALE(ADC1, LL_ADC_RESOLUTION_14B) + 1) /*************************************************************************************************/ int main(void) { /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ /* MCU Configuration--------------------------------------------------------*/ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init(); /* USER CODE BEGIN Init */ /* USER CODE END Init */ /* Configure the System Power */ SystemPower_Config(); /* Configure the system clock */ SystemClock_Config(); /* USER CODE BEGIN SysInit */ /* USER CODE END SysInit */ /* Initialize all configured peripherals */ MX_GPIO_Init(); MX_GPDMA1_Init(); MX_ADC1_Init(); MX_ICACHE_Init(); /* USER CODE BEGIN 2 */ /* USER CODE END 2 */ /* Initialize led */ BSP_LED_Init(LED_GREEN); /* Initialize USER push-button, will be used to trigger an interrupt each time it's pressed.*/ BSP_PB_Init(BUTTON_USER, BUTTON_MODE_EXTI); /* Initialize COM1 port (115200, 8 bits (7-bit data + 1 stop bit), no parity */ BspCOMInit.BaudRate = 115200; BspCOMInit.WordLength = COM_WORDLENGTH_8B; BspCOMInit.StopBits = COM_STOPBITS_1; BspCOMInit.Parity = COM_PARITY_NONE; BspCOMInit.HwFlowCtl = COM_HWCONTROL_NONE; if (BSP_COM_Init(COM1, &BspCOMInit) != BSP_ERROR_NONE) { Error_Handler(); } if (HAL_ADC_Start_DMA(&hadc1, (uint32_t *)aADCxConvertedData, (ADC_CONVERTED_DATA_BUFFER_SIZE) ) != HAL_OK) { Error_Handler(); } /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { if(isADCFinished == 1) { isADCFinished = 0; uhADCxConvertedData_Voltage_mVolt = __LL_ADC_CALC_DATA_TO_VOLTAGE(ADC1, VDDA_APPLI, aADCxConvertedData[0], LL_ADC_RESOLUTION_14B); if (HAL_ADC_Start_DMA(&hadc1, (uint32_t *)aADCxConvertedData, (ADC_CONVERTED_DATA_BUFFER_SIZE) ) != HAL_OK) { Error_Handler(); } } /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ } /* USER CODE END 3 */ } void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc) { isADCFinished = 1; } static void MX_ADC1_Init(void) { /* USER CODE BEGIN ADC1_Init 0 */ /* USER CODE END ADC1_Init 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_14B; hadc1.Init.GainCompensation = 0; hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT; hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE; hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV; hadc1.Init.LowPowerAutoWait = DISABLE; hadc1.Init.ContinuousConvMode = ENABLE; hadc1.Init.NbrOfConversion = 1; hadc1.Init.DiscontinuousConvMode = DISABLE; hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START; hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; hadc1.Init.DMAContinuousRequests = ENABLE; hadc1.Init.TriggerFrequencyMode = ADC_TRIGGER_FREQ_HIGH; hadc1.Init.Overrun = ADC_OVR_DATA_PRESERVED; hadc1.Init.LeftBitShift = ADC_LEFTBITSHIFT_NONE; hadc1.Init.ConversionDataManagement = ADC_CONVERSIONDATA_DMA_CIRCULAR; hadc1.Init.OversamplingMode = DISABLE; if (HAL_ADC_Init(&hadc1) != HAL_OK) { Error_Handler(); } /** Configure Regular Channel */ sConfig.Channel = ADC_CHANNEL_1; sConfig.Rank = ADC_REGULAR_RANK_1; sConfig.SamplingTime = ADC_SAMPLETIME_5CYCLE; sConfig.SingleDiff = ADC_SINGLE_ENDED; sConfig.OffsetNumber = ADC_OFFSET_NONE; sConfig.Offset = 0; if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) { Error_Handler(); } /* USER CODE BEGIN ADC1_Init 2 */ /* USER CODE END ADC1_Init 2 */ } /** * @brief GPDMA1 Initialization Function * @PAram None * @retval None */ static void MX_GPDMA1_Init(void) { /* USER CODE BEGIN GPDMA1_Init 0 */ /* USER CODE END GPDMA1_Init 0 */ /* Peripheral clock enable */ __HAL_RCC_GPDMA1_CLK_ENABLE(); /* GPDMA1 interrupt Init */ HAL_NVIC_SetPriority(GPDMA1_Channel15_IRQn, 0, 0); HAL_NVIC_EnableIRQ(GPDMA1_Channel15_IRQn); /* USER CODE BEGIN GPDMA1_Init 1 */ /* USER CODE END GPDMA1_Init 1 */ /* USER CODE BEGIN GPDMA1_Init 2 */ /* USER CODE END GPDMA1_Init 2 */ }
View more

Edited to apply source code formatting - please see How to insert source code for future reference.

1 ACCEPTED SOLUTION

Accepted Solutions
TDK
Super User

If resolution is 14 bits, the buffer data type should be uint16_t and the dma word size should be half-word.

If you feel a post has answered your question, please click "Accept as Solution".

View solution in original post

3 REPLIES 3
reedomneck
Associate III

This data not proper problem I've fixed. Now I've problem in reading 100 samples, I don't knwo why maximum 32 samples it's able to read

TDK
Super User

If resolution is 14 bits, the buffer data type should be uint16_t and the dma word size should be half-word.

If you feel a post has answered your question, please click "Accept as Solution".
reedomneck
Associate III

@TDK  Thanks for your reply I'm able to get it working