2024-07-09 07:55 AM
ADC1 clocked @ 65 MHz, pre-scaler of 8, 7 channels active, 640.5 cycles/conversion, 256 oversampling, interrupts, scan mode. The numbers suggest all channels will be converted 1x in (8/65000000) * 640.5 * 7 * 256 = 141 ms. But when I look at uwTick before HAL_ADC_Start_IT() and after 7 conversions complete, I get 37 ms. Why the discrepancy?
2024-07-11 04:00 PM - edited 2024-07-17 10:24 AM
Which is exactly what you'd expect if HCLK was around 250Mhz, and there's no mystery x4.
So It still looks like (in async clock mode) the clock going to ADC is not at 65Mhz, but 4 times that.
Can you paste the contents of the HAL_ADC_MspInit() function (it's in Core/src/xxx_hal_msp.c)? and your .ioc file?
Also, please unaccept the solution - we're not there yet and it's in your interest to have others on the forum look at this, they may recognize the issue immediately.
2024-07-12 05:57 AM - edited 2024-07-12 06:18 AM
HAL_ADC_MspInit() follows
/**
* @brief ADC MSP Initialization
* This function configures the hardware resources used in this example
* hadc: ADC handle pointer
* @retval None
*/
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(hadc->Instance==ADC1)
{
/* USER CODE BEGIN ADC1_MspInit 0 */
/* USER CODE END ADC1_MspInit 0 */
/* Peripheral clock enable */
HAL_RCC_ADC_CLK_ENABLED++;
if(HAL_RCC_ADC_CLK_ENABLED==1){
__HAL_RCC_ADC_CLK_ENABLE();
}
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/**ADC1 GPIO Configuration
PC0 ------> ADC1_INP10
PC1 ------> ADC1_INP11
PC2 ------> ADC1_INP12
PC3 ------> ADC1_INP13
PA6 ------> ADC1_INP3
PC4 ------> ADC1_INP4
PB1 ------> ADC1_INP5
*/
GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3
|GPIO_PIN_4;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_6;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &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);
/* ADC1 interrupt Init */
HAL_NVIC_SetPriority(ADC1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(ADC1_IRQn);
/* USER CODE BEGIN ADC1_MspInit 1 */
/* USER CODE END ADC1_MspInit 1 */
}
else if(hadc->Instance==ADC2)
{
/* USER CODE BEGIN ADC2_MspInit 0 */
/* USER CODE END ADC2_MspInit 0 */
/* Peripheral clock enable */
HAL_RCC_ADC_CLK_ENABLED++;
if(HAL_RCC_ADC_CLK_ENABLED==1){
__HAL_RCC_ADC_CLK_ENABLE();
}
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
/**ADC2 GPIO Configuration
PC3 ------> ADC2_INP13
PA6 ------> ADC2_INP3
PA7 ------> ADC2_INP7
PC5 ------> ADC2_INP8
*/
GPIO_InitStruct.Pin = GPIO_PIN_3|GPIO_PIN_5;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* ADC2 interrupt Init */
HAL_NVIC_SetPriority(ADC2_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(ADC2_IRQn);
/* USER CODE BEGIN ADC2_MspInit 1 */
/* USER CODE END ADC2_MspInit 1 */
}
}
2024-07-12 06:27 AM - edited 2024-07-12 06:28 AM
Whoa, that's one busy little chip you have there. I'm sorry, everything looks OK to me. You do know that it's something that has to do with async vs. sync (PLL vs. HCLK), but I don't have an idea on what the next stop for debugging is.
You can un-accept the solution using the little down-arrow menu button at the top-right of the accepted solution. I hope someone else can offer more help.
(Turns out HAL_ADC_MspInit is irrelevant on this family. On other familes that's where PLL2 conf code is generated)
2024-07-12 09:57 AM - edited 2024-07-12 10:02 AM
One weak test that comes to mind, use RCC Master Clock Oot (MCO) to route out the generate PLL clock and check the frequency with scope. You can't route PLL2R out to MCO, but you can duplicate its PLL config to whatever PLL can be sent out to MCO and check. If the freq is wrong, you've learned something, if it's OK you've learned nothing.
For that matter, sending HCLK out through MCO (use the MCO divider for easier measurement) and verifying that its frequency matches what you expect is also a worthwhile test. You've already measured it indirectly using the ADC tick measurement, but using the MCO is a direct test and therefore preferred.