cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H7S3V8T6 TIM1 prescaler clock clarification

JShro
Associate III

Hi All, 

Hoping someone can clarify my confusion on the clock input for the TIM1 counter...

background:

I am testing Tim1 output compare by toggling PA8 on the micro... - the timer settings are

period = 1600, no clock divisor or prescaler and my clock config is below

JShro_0-1759285004047.png

On the scope I see PA8 toggling with a period of 25us which seems kind a strange... 

So even if I assume a counter clock of 150Mhz (APB1, APB2 peripheral clocks) and the formula of clock/2*(period+1) as the frequency I should see it toggle at 21.34 us?

 

Why this discrepancy??

 

Thanks!

 

1 ACCEPTED SOLUTION

Accepted Solutions
waclawek.jan
Super User

At this point it appears that your clocks are not set up as you expect.

What's your primary clock source? Have you checked it e.g. by outputting it to a MCO pin?

JW

View solution in original post

11 REPLIES 11
waclawek.jan
Super User

> by toggling PA8

How?

What's your primary clock source? Have you checked it e.g. by outputting it to a MCO pin?

JW

 

I am using a 16 MHZ crystal (HSE) - I have not checked the output from there good point - I will check it today and report back...

 

Thanks

so 16MHZ xtal connected to pins (5,6) - MCO configured for HSE via the  code attached here (Generated via Cube MX)

I measured 16MHZ on the PA8 output so looks like the crystal frequency is correct 

My clock configuration has PLL configured to output the following frequencies to the peripherals 

JShro_0-1759331890447.png

 

 

void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Configure the main internal regulator output voltage
  */
  if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE0) != HAL_OK)
  {
    Error_Handler();
  }

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI|RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSIDiv = RCC_HSI_DIV1;
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  RCC_OscInitStruct.PLL1.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL1.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL1.PLLM = 1;
  RCC_OscInitStruct.PLL1.PLLN = 37;
  RCC_OscInitStruct.PLL1.PLLP = 1;
  RCC_OscInitStruct.PLL1.PLLQ = 2;
  RCC_OscInitStruct.PLL1.PLLR = 2;
  RCC_OscInitStruct.PLL1.PLLS = 2;
  RCC_OscInitStruct.PLL1.PLLT = 2;
  RCC_OscInitStruct.PLL1.PLLFractional = 4096;
  RCC_OscInitStruct.PLL2.PLLState = RCC_PLL_NONE;
  RCC_OscInitStruct.PLL3.PLLState = RCC_PLL_NONE;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2
                              |RCC_CLOCKTYPE_PCLK4|RCC_CLOCKTYPE_PCLK5;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV2;
  RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV2;
  RCC_ClkInitStruct.APB5CLKDivider = RCC_APB5_DIV2;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_7) != HAL_OK)
  {
    Error_Handler();
  }
  HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_HSE, RCC_MCODIV_1);
}

  

waclawek.jan
Super User

I then repeat my question: toggle how?

Even if 1600 cycles sounds like quite a lot; if you toggle the pin as GPIO Output in an interrupt from the timer, using Cube/HAL code compiled without optimization, suboptimal system (e.g. cache) setup, execution from slow (external) memory, it's quite possible this is the good old "that's just too slow" case.

As a first experiment, try 16000 instead of 1600.

Note, that the total period of waveform of a pin being *toggled* is twice as much as the time between successive changes.

JW

Sorry I thought I made it clear but obviously not...

So I have TIM1 configured with a period of 1600 and it is setup to toggle PA8 as the output (via the OUTPUT_COMPARE_CH1) setting - see below

I think you might be right though - maybe it's just latencies - I will try increasing the period and test as you suggested - thanks for all the suggestions

JShro_0-1759333509182.png

Oh the settings for the output toggle are as below

JShro_1-1759333967375.png

 

 

> So even if I assume a counter clock of 150Mhz (APB1, APB2 peripheral clocks) 

That is the clock to the timer's APB bus interface.  The timers themselves clock at 2x that rate (i.e. 300 MHz), as shown in the clocking diagram you posted.  I don't know the STM32H7S3V8T6 specifically, but presuming TIM1 is on the APB1/2 bus like other STM32 families.

That doesn't fix your measured vs calculated discrepancy, but makes the calculated period 10.67us.

 

 

JShro
Associate III

@Bob S Thanks for the clarification - Yes I was a bit confused by that considering my measured values I figured maybe the documentation was off and I had to use the bus clock - I do see that the timers appear to be at 300 MHZ input clock - so that's another mystery 

You are right if indeed the clock is at 300 Mhz I should be getting 10.67 us which makes this even more strange - Not sure what to make of it - will keep diggging...

BTW - The tim1 block diagram is pretty confusing for me - it shows the tim_ker_ck and the tim_pck as the clock inputs and then the tim_psc_ck as the final clock to the counter - but not really sure what the source of the tim_psc_ck is I am assuming the 300 MHZ based on your comment but would have been useful to clarify it in the diagram :(

JShro_0-1759336739111.png

 

 

Thanks

waclawek.jan
Super User

At this point, in debugger or using some other means (printf?), read out and check/post content of TIM1 registers.

You can also try to output the system clock onto MCO (perhaps divided down not to have too high frequency) and check that.

JW

Sorry got dragged into another project - just getting around to this again...

So I have a breakpoint prior to timer init and all registers are 0

immediately after timer init 

Non zero Registers are as below

TIM1_CCMR1_INPUT = 0x30

TIM1_CCMR1_OUTPUT = 0x30

TIM1_ARR = 0x64

TIM1_BDTR = 0x2002000

TIM1_AF1 = 0x01

TIM1_AF2 = 0x01

Subsequent to that I call  - HAL_TIM_OC_Start(&htim1,TIM_CHANNEL_1);

 

and then the TIM1_CR1 is set to 0x01

 

So still stumped on why the time discrepancy - with the setting of ARR register at 0x64 - I am calculating that the pulse time would be 0.33 us, however I am measuring ~ 1.64 us

 

BTW: I did try a period of 16000 and that gave me a measured pulse time of 252 us, calculated time should be 53.33 us (I think) so looks like it's off by a factor of 5 but that makes no sense to me