2023-02-20 07:46 AM
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)
{
}
Solved! Go to Solution.
2023-02-20 11:55 PM
Isn't this another case of CubeMX improperly ordering the init functions?
JW
2023-02-20 08:40 AM
> The application runs the error callback at the first conversion start.
What is the source of that error? DMA? ADC?
Read out and check/post content of ADC and relevant DMA and DMAMUX registers.
JW
2023-02-20 12:25 PM
I managed to eliminate the fault at the start time so now I can run conversions but the array buffer adc_result is still not filled with any value. I checked into the registers and it seems to me that the ADC is working in fact fine. I can see the value of the last conversion inside the ADC_DR DATA register at every iteration changin while i move the potentiometer.
Then when I check the register of the DMA I see things that seem strange to me, for instance the MSIZE bits inside the CCR1 register should be 01 for half word size configured in the MX where i see 00.
Dont know it seems to me that it's a bit early for these C0 drivers....
Cheers,
Filippo
2023-02-20 02:02 PM
>Then when I check the register of the DMA I see things that
>seem strange to me, for instance the MSIZE bits inside the CCR1 register
>should be 01 for half word size configured in the MX where i see 00.
MINC should be set, too.
Next step is to set a breakpoint at the beginning of function which sets up DMA and observe, why are those value set incorrectly.
JW
2023-02-20 03:12 PM
I did at the DMA init function and what I see, for instance, is that the hdma structure contains correctly values, for instance MINC one... but after the BITSET the CCN register still remains completely empty.
I even try to execute a simple bitwise operation to set one single bit straight to the CCN register but again it stays empty. So my guess is that the issue is there, maybe the peripheral is simply off cause something goes wrong in setting up the clock or i don't know... here I stop cause it goes too deep in the st driver and I let them debug.
As said previously for me for the moment C0 is KO.
Cheers and thanks,
Filippo
2023-02-20 08:23 PM
This typically happens if the DMA does not have enabled clocks in RCC. Check RCC registers content. Also you should see code to enable the DMA clock somewhere at the beginning of that initialization routine.
JW
2023-02-20 11:55 PM
Isn't this another case of CubeMX improperly ordering the init functions?
JW
2023-02-21 04:51 AM
Nope, the AHB enable register seems correctly set for DMA1
Filippo
2023-02-21 04:59 AM
yep! you got it man!
Thanks so much!
Only issue i have is that the post you linked is saying that he issue was fixed on version 6.4 of MX where I am at version 6.6... so clearly a vicious regression!
Cheers,
Filippo
2023-02-21 05:19 AM
Hi Filippo,
it appears that there's already v6.7 https://community.st.com/s/question/0D53W00001yFCKTSA4/stm32cubemx-670-released
JW