cancel
Showing results for 
Search instead for 
Did you mean: 

Nucleo-H755 and confusion with timers

TOlli
Senior

Hi,

I'm using the nucleo-h755xi for testing purposes and I'm doing configuration by using CubeMX.

I have opted to using the FreeRTOS middleware for both cores, CM7 will be using TIM6 and CM4 will be using TIM7 to generate ticks for the OS.

Now my question is, looking at the generated code and my settings over at CubeMX. The configuration looks as follows (I've underlined one result with red for future reference):0693W000000U6IqQAK.jpg

Now, in the reference manual it says:

0693W000000U6JTQA0.jpgThis is how the Timer6 is supposed to look like.

The generated code for HAL_InitTick looks like this:

HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)
{
  RCC_ClkInitTypeDef    clkconfig;
  uint32_t              uwTimclock = 0;
  uint32_t              uwPrescalerValue = 0;
  uint32_t              pFLatency;
  
  /*Configure the TIM6 IRQ priority */
  HAL_NVIC_SetPriority(TIM6_DAC_IRQn, TickPriority ,0); 
  
  /* Enable the TIM6 global Interrupt */
  HAL_NVIC_EnableIRQ(TIM6_DAC_IRQn); 
  
  /* Enable TIM6 clock */
  __HAL_RCC_TIM6_CLK_ENABLE();
  
  /* Get clock configuration */
  HAL_RCC_GetClockConfig(&clkconfig, &pFLatency);
  
  /* Compute TIM6 clock */
  uwTimclock = 2*HAL_RCC_GetPCLK1Freq();
   
  /* Compute the prescaler value to have TIM6 counter clock equal to 1MHz */
  uwPrescalerValue = (uint32_t) ((uwTimclock / 1000000) - 1);
  
  /* Initialize TIM6 */
  htim6.Instance = TIM6;
  
  /* Initialize TIMx peripheral as follow:
  + Period = [(TIM6CLK/1000) - 1]. to have a (1/1000) s time base.
  + Prescaler = (uwTimclock/1000000 - 1) to have a 1MHz counter clock.
  + ClockDivision = 0
  + Counter direction = Up
  */
  htim6.Init.Period = (1000000 / 1000) - 1;
  htim6.Init.Prescaler = uwPrescalerValue;
  htim6.Init.ClockDivision = 0;
  htim6.Init.CounterMode = TIM_COUNTERMODE_UP;
  if(HAL_TIM_Base_Init(&htim6) == HAL_OK)
  {
    /* Start the TIM time Base generation in interrupt mode */
    return HAL_TIM_Base_Start_IT(&htim6);
  }
  
  /* Return function status */
  return HAL_ERROR;
}

I have stepped through the code with the debugger and obtained the following values:

line 21:

HAL_RCC_GetPCLK1Freq() == 64 000 000

uwTimclock == 128 000 000

First question:

Where does that 64 MHz come from? It is not in my configuration and I don't see dividers being able to accomplish this if you look at the CubeMX configuration.

0693W000000U6MDQA0.jpg

Above is a screenshot (again) from the reference manual. And showing the default values which do not scale the sys_ck at all to get close to 64MHz.

Is this scaling to 64MHz done during HAL_init -function call? It seems to have some macros in it.

My second question is: What are the clock frequencies in CubeMX used for (for example the one I underlined)? As I though these would be used for the timer frequency.

What is the frequency of timers 16 and 17 in this instance (since I can't trust my own reasoning apparently)?

Are there any detailed resources that go over these configurations? It seems that for me, the manuals are too difficult to understand, all the changing notations and different pictures with no correlation from the previous one seem a bit too much.

Any help is appreciated, thanks!

Best regards,

1 ACCEPTED SOLUTION

Accepted Solutions
TDK
Guru

I agree, it can be a bit complicated. Your understanding is correct--you shouldn't be seeing 64MHz based on your clock settings shown.

Is your clock set up prior to calling HAL_InitTick? Sometimes this is called prior to setting up the clock, and again after it is set up. Obviously the clock is different between the two cases.

Post your SystemClock_Config function, which configures the clock.

The timer clock frequencies should be as you expected--240MHz in this case. But only after the clock is set.

Is it possible you didn't hit "Generate Code" after you changed the clock settings?

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

View solution in original post

4 REPLIES 4
TDK
Guru

I agree, it can be a bit complicated. Your understanding is correct--you shouldn't be seeing 64MHz based on your clock settings shown.

Is your clock set up prior to calling HAL_InitTick? Sometimes this is called prior to setting up the clock, and again after it is set up. Obviously the clock is different between the two cases.

Post your SystemClock_Config function, which configures the clock.

The timer clock frequencies should be as you expected--240MHz in this case. But only after the clock is set.

Is it possible you didn't hit "Generate Code" after you changed the clock settings?

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

Hi,

And thank you for taking the time to answer.

I have regenerated the project a couple of times already, so I don't believe I have changed the clock settings and not generated the code. If it matters ( I don't think it should, but I'm using a SW4STM32 project type).

void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
  RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
 
  /** Supply configuration update enable 
  */
  HAL_PWREx_ConfigSupply(PWR_DIRECT_SMPS_SUPPLY);
  /** Configure the main internal regulator output voltage 
  */
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE0);
 
  while(!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {}
  /** Initializes the CPU, AHB and APB busses clocks 
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLM = 1;
  RCC_OscInitStruct.PLL.PLLN = 120;
  RCC_OscInitStruct.PLL.PLLP = 2;
  RCC_OscInitStruct.PLL.PLLQ = 20;
  RCC_OscInitStruct.PLL.PLLR = 2;
  RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_3;
  RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE;
  RCC_OscInitStruct.PLL.PLLFRACN = 0;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
  /** Initializes the CPU, AHB and APB busses clocks 
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2
                              |RCC_CLOCKTYPE_D3PCLK1|RCC_CLOCKTYPE_D1PCLK1;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV2;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV2;
  RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV2;
 
  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK)
  {
    Error_Handler();
  }
  PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USART3|RCC_PERIPHCLK_USB;
  PeriphClkInitStruct.Usart234578ClockSelection = RCC_USART234578CLKSOURCE_D2PCLK1;
  PeriphClkInitStruct.UsbClockSelection = RCC_USBCLKSOURCE_PLL;
  if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
  /** Enable USB Voltage detector 
  */
  HAL_PWREx_EnableUSBVoltageDetector();
}

This function is indeed called after the HAL_Init() which calls the HAL_InitTick -function.

So maybe that is the reason for all this, since the 64MHz actually corresponds to the HSI RC on the nucleo, which is part of the basic configuration.

Maybe the code generation is fixed (so the examples work properly on it), since below is the picture for a nucleo project without changes (to peripherals or clock configuration.

0693W000000UAreQAG.jpg

Here, 64MHz or the HSI RC, is selected as the bus frequency.

This is also the default configuration for just the chip based project as well.

Now, this is the picture from under project manager:

0693W000000UAsmQAG.jpg

Shouldn't the SystemClock_Config be higher? Like the highest one? Or you could argue that GPIO settings should be done first (to get access to HSE and LSE?), then SystemClock_Config, and finally setting up HAL_Init with ticks and the like.

Best regards.

TOlli
Senior

I did a little digging.

If I follow deep enough into SystemClock_Config it calls for HAL_RCC_ClockConfig, which configures the correct settings from the CubeMX project.

After configuring the bus dividers and whatnot, it calls for HAL_InitTick() again, which would then produce the correct settings in the calculations.

So you are right, it is normally called first, then clock is configured, and a call to the init_tick is called again, setting up correct operation.

I guess it makes sense: configuring HSI RC (as it is guaranteed to exist) first into use to provide a way to continue, and then setting up correct values based on project configuration.

I have to say, that was an interesting find.

Thank you for your help! I think it really helped to write this out, and your message did point me in the right direction.

TDK
Guru

Glad you figured it out. I also find writing out questions helps me to solve problems. Thanks for the well written question. I wish we had more posts like these rather than the mass of "it doesn't work" posts with no info. Cheers.

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