2020-04-01 07:21 AM
I am trying to use Tim6 with ADC and DMA2 to save 100 ADC values in a buffer. It seems to be working, DMA counter decreases and I get DMA interrupt, but only the first value in the array is stored, the rest are 0 (init values). Can someone help me understanding what is wrong?
void main()
....
for(i = 0; i < ADC_CONVERTED_DATA_BUFFER_SIZE; i++)
{
aADCxConvertedData[i] = 0;
}
Configure_ADC();
Configure_DMA();
Configure_TIM_TimeBase_ADC_trigger();
__HAL_RCC_ADC_CLK_ENABLE();
__HAL_RCC_DMA2_CLK_ENABLE();
PrintDMA();
HAL_TIM_Base_Start(&htim6);
err = HAL_ADC_Start_DMA(&hadc1,(uint32_t *)aADCxConvertedData, ADC_CONVERTED_DATA_BUFFER_SIZE);
if (err != HAL_OK)
{
printf("DMA err %d\n\r", err);
}
PrintDMA();
HAL_NVIC_SetPriority(DMA2_Channel3_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA2_Channel3_IRQn);
HW_TIM_Delay(100); // wait 100 ms
for(i = 0; i < 10; i++)
{
printf("%d\n\r", aADCxConvertedData[i]);
}
}
void PrintDMA()
{
printf("TIM6: %d: DMA2: %d: %d/%d\n\r", (int)htim6.Instance->CNT, (int)LL_DMA_IsActiveFlag_TC3(DMA2), LL_DMA_GetDataLength(DMA2, LL_DMA_CHANNEL_3), ADC_CONVERTED_DATA_BUFFER_SIZE);
printf("En %d. Flags %d %d\n\r", LL_DMA_IsEnabledChannel(DMA2, LL_DMA_CHANNEL_3), (int)LL_DMA_IsActiveFlag_TE1(DMA2), (int)LL_DMA_IsActiveFlag_TE2(DMA2));
}
void Configure_ADC(void)
{
//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_12B;
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 = DISABLE;
hadc1.Init.NbrOfConversion = 1;
hadc1.Init.DiscontinuousConvMode = DISABLE;
hadc1.Init.NbrOfDiscConversion = 1;
hadc1.Init.ExternalTrigConv = ADC_EXTERNALTRIG_T6_TRGO;
hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISING;
hadc1.Init.DMAContinuousRequests = DISABLE;
hadc1.Init.Overrun = ADC_OVR_DATA_PRESERVED;
hadc1.Init.OversamplingMode = DISABLE;
hadc1.Init.ContinuousConvMode = ENABLE;
hadc1.Init.DiscontinuousConvMode = DISABLE;
hadc1.Init.DMAContinuousRequests = ENABLE;
if (HAL_ADC_Init(&hadc1) != HAL_OK)
{
//Error_Handler();
}
if (HAL_ADC_ConfigChannel(&hadc1, ADC_CHANNEL_13) != HAL_OK)
{
//Error_Handler();
}
}
void Configure_DMA(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
HAL_DMA_DeInit(&hdma_adc1);
__HAL_RCC_DMA2_FORCE_RESET();
__HAL_RCC_DMA2_RELEASE_RESET();
__HAL_RCC_ADC_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
/**ADC1 GPIO Configuration
PC4 ------> ADC1_IN13
*/
GPIO_InitStruct.Pin = GPIO_PIN_4;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG_ADC_CONTROL;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
/* ADC1 DMA Init */
/* ADC1 Init */
hdma_adc1.Instance = DMA2_Channel3;
hdma_adc1.Init.Request = DMA_REQUEST_0;
hdma_adc1.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_adc1.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_adc1.Init.MemInc = DMA_MINC_ENABLE;
hdma_adc1.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
hdma_adc1.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
hdma_adc1.Init.Mode = DMA_NORMAL;
hdma_adc1.Init.Priority = DMA_PRIORITY_LOW;
if (HAL_DMA_Init(&hdma_adc1) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(&hadc1,DMA_Handle,hdma_adc1);
}
void Configure_TIM_TimeBase_ADC_trigger(void)
{
TIM_MasterConfigTypeDef sMasterConfig = {0};
/* USER CODE BEGIN TIM6_Init 1 */
__HAL_RCC_TIM6_CLK_ENABLE();
/* USER CODE END TIM6_Init 1 */
htim6.Instance = TIM6;
htim6.Init.Prescaler = 20; //timer_prescaler-1;
htim6.Init.CounterMode = TIM_COUNTERMODE_UP;
htim6.Init.Period = 1000;
htim6.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
htim6.Init.RepetitionCounter = 0;
if (HAL_TIM_Base_Init(&htim6) != HAL_OK)
{
Error_Handler();
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim6, &sMasterConfig) != HAL_OK)
{
Error_Handler();
}
}
Solved! Go to Solution.
2020-04-01 08:49 PM
Well, for one, you need to enable the ADC/DMA clocks before you start using them. __HAL_RCC_ADC_CLK_ENABLE(); should be before Configure_ADC, not after.
2020-04-01 08:49 PM
Well, for one, you need to enable the ADC/DMA clocks before you start using them. __HAL_RCC_ADC_CLK_ENABLE(); should be before Configure_ADC, not after.
2020-04-02 01:30 AM
Thanks, it solved it!
However if I want to do a new DMA transfer i get error when running HAL_ADC_Start_DMA(&hadc1,(uint32_t *)aADCxConvertedData, ADC_CONVERTED_DATA_BUFFER_SIZE); and it this line causes it if (LL_ADC_REG_IsConversionOngoing(hadc->Instance) == 0UL).
Even if I run
HAL_ADC_Stop_DMA(&hadc1);
HAL_DMA_Abort(&hdma_adc1);
HAL_ADC_Stop(&hadc1);
It is same result. Only way to do new transfer is to reset ADC. I would like to do a new transfer without reinit all modules
2020-04-02 07:06 AM
It works with HAL_ADC_Stop_DMA(&hadc1); but if I want to reinit ADC I must reset it. So no issue for now.