Problem with STM32C031K6 and ADC DMA
Hello,
I am testing a STM32C0 MCU to see if it might be good for a project I'm working on attracted by the price point, but I have to say that I have some unexpected problem.
Among several the most relevant is multichannel DMA based ADC conversion that, no matter what I do, I can't have working.
The application runs the error callback at the first conversion start.
The ADC is in single conversion mode triggered by software and I have set a timer running every 50 milliseconds to run the conversion. I have also tried to connect the timer directly to the ADC to trigger automatically the conversion but the result is absolutely the same.
The system is running at 48MHz.
The conversion works correctly in interrupt mode on a single channel.
Can anyone help?
This is my code:
#define ADC_CONVERTED_DATA_BUFFER_SIZE ( 2UL)
/* Init variable out of expected ADC conversion data range */
#define VAR_CONVERTED_DATA_INIT_VALUE (__LL_ADC_DIGITAL_SCALE(LL_ADC_RESOLUTION_12B) + 1)
extern TIM_HandleTypeDef htim3;
extern TIM_HandleTypeDef htim14;
extern ADC_HandleTypeDef hadc1;
extern DMA_HandleTypeDef hdma_adc1;;
uint16_t adc_result[ADC_CONVERTED_DATA_BUFFER_SIZE];
/* Variable to report status of DMA transfer of ADC group regular conversions */
/* 0: DMA transfer is not completed */
/* 1: DMA transfer is completed */
/* 2: DMA transfer has not yet been started yet (initial state) */
__IO uint8_t ubDmaTransferStatus = 2U; /* Variable set into DMA interruption callback */
/* Variable to report number of ADC group regular sequence completed */
uint32_t ubAdcGrpRegularSequenceConvCount = 0UL; /* Variable set into ADC interruption callback */
int app_main()
{
uint8_t tmp_index;
/* Initialize ADC group regular data buffer values */
for (tmp_index = 0; tmp_index < ADC_CONVERTED_DATA_BUFFER_SIZE; tmp_index++)
{
adc_result[tmp_index] = VAR_CONVERTED_DATA_INIT_VALUE;
}
/* Perform ADC calibration */
if (HAL_ADCEx_Calibration_Start(&hadc1) != HAL_OK)
{
/* Calibration Error */
APP_Error_Handler();
}
/* Start ADC group regular conversion */
/* Note: First start with DMA transfer initialization, following ones with basic ADC start. */
if (HAL_ADC_Start_DMA(&hadc1,(uint32_t *)adc_result, ADC_CONVERTED_DATA_BUFFER_SIZE) != HAL_OK)
{
/* Error: ADC conversion start could not be performed */
APP_Error_Handler();
}
HAL_TIM_Base_Start_IT(&htim3);
HAL_TIM_Base_Start_IT(&htim14);
HAL_GPIO_WritePin(LED_PWR_GPIO_Port, LED_PWR_Pin, GPIO_PIN_SET);
while(1)
{
/* If ADC conversions and DMA transfer are completed, then process data */
if(ubDmaTransferStatus == 1)
{
//DO SOMETTHING
/* Update status variable of DMA transfer */
ubDmaTransferStatus = 0;
}
}
}
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if(htim->Instance == TIM14)
{
HAL_GPIO_TogglePin(LED_HB_GPIO_Port, LED_HB_Pin);
}
else if(htim->Instance == TIM3)
{
/* Start ADC group regular conversion */
if (HAL_ADC_Start(&hadc1) != HAL_OK)
{
/* Error: ADC conversion start could not be performed */
APP_Error_Handler();
}
}
}
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc)
{
//adc_result = HAL_ADC_GetValue(&hadc1);
/* Update status variable of DMA transfer */
ubDmaTransferStatus = 1;
}
/**
* @brief This function is executed in case of error occurrence.
* @retval None
*/
void APP_Error_Handler(void)
{
}


