2017-07-21 03:10 AM
Hi there,
I have a Nucleo F746ZG board and am experimenting with the peripherals. I'm trying to get a regular timer interrupt at a given frequency, and am seeing a huge amount of jitter.
Here's my configuration:
In the interrupt I do this:
void HAL_TIM_OC_DelayElapsedCallback(TIM_HandleTypeDef *htim)
{
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_11);
}
I am then analysing pin B11 on a scope. I would expect to see a frequency of 172.26528.
What I'm measuring is anywhere between 174.6 - 174.9 Hz. It's all over the place.
The SPI interrupt is a lower priority, so shouldn't affect it, but I've tried disabling it anyway, and that didn't help. No other timers or timer channels are enabled, so it should only be TIM3 channel 1 triggering this interrupt.
There's nothing else happening on the chip. I presume it's possible to get better accuracy than this!
Any help would be greatly appreciated.
Matt
2017-07-21 03:25 AM
I do not use Cube / HAL, exactly for behind-my-back reasons like this.
It seizes other interrupts as well, e.g. SysTick. Check what else it does in interrupts.
2017-07-21 03:43 AM
I've just noticed that:
I would expect to see a frequency of 172.26528. What I'm measuring is anywhere between 174.6 - 174.9 Hz.
The average period being longer than you expect sounds like you try to reload/restart the timer in in the ISR. If you do so, don't; leave the timer free running.
If you don't do that, you may be misloading ARR/PSC - both count from 0 to N inclusive, so they need to be set to one less than you'd calculate from plainly dividing input clock by output clock.
JW
2017-07-21 05:32 AM
Hey, thanks for the reply.
Good thinking - I just tried setting every other interrupt I can to a lower priority, and I get the same result.
2017-07-21 05:37 AM
Even if you'd not use Cube, there are many other sources of jitter for interrupt and software-driven events in 32-bitters, especially in caches-laden superscalars as F7 is. This can range anywhere from a few clocks (i.e. tens of ns) up to hundreds of clocks (i.e. a few us). You see some 10us which is one order of magnitude more, but that's probably the impact of the 'library' and , as AvaTar said.
This may come as a shock, but yes, the multi-megahertz 32-bitters are worse in precise timing terms than the venerable 8-bitters.
For any more precise timing resort to pure hardware (even there you have to be careful if the 'action' happens through interaction between several IP blocks). For starter, just output PWM from the timer and measure the jitter of that one.
JW
2017-07-21 05:45 AM
This may come as a shock, but yes, the multi-megahertz 32-bitters are worse in precise timing terms than the venerable 8-bitters.
That is pretty counter intuitive, and I wouldn't expect the frequency to stay completely still past about 3 decimal places, but an error margin of +/- of 0.15Hz is bad enough for me to assume I'm making a mistake somewhere.
I'm only using the pin toggle as a way of visualising the interrupt, eventually I will be using it to trigger the generation of 128 audio samples which are then sent over DMA to a DAC.
M
2017-07-21 05:55 AM
All I'm doing in the interrupt is toggling the pin, so it's not that.
Here's another example - I want an interrupt frequency of 375Hz
(18MHz Timer Clock / 375 ) = 48000
Set period to 47999
By measuring the pin, actual frequency is ~380.2 - ~380.8
I'm not overly worried about the offset, It's not unusual for a peripheral clock to be slightly less or more than it is specified, but it is unusual for it to jitter like this.
M
2017-07-21 06:25 AM
That is pretty counter intuitive,
It is not, once you realize that the 32-bitters are NOT microcontrollers, they are SoC.
They are thrown together from various IPs and stitched more or less loosely by a fabric of buses and clock domain synchronizers. In the 80s/90s, you'd think of a board with a 32-bit processor, memories, control chips and peripheral chips; this is absolutely the same thing just crammed together onto one single chip.
Even the execution core itself is too complex to be easily timing-analyzed - especially the 'M7 which is superscalar; then you have all sorts of latencies due to slow memory (FLASH), buses with multiple masters causing various collisions, caches, and a bunch of registers at various places in between.
The 8-bitters were purposely-built for precise timing control; the 32-bitters are not, they are built for performance (and marketing). The processing performance comes at the cost of uncertainties in software execution; precise timing is to be achieved by employing hardware, the 32-bitters have that plenty, not without reason.
It's not unusual for a peripheral clock to be slightly less or more than it is specified,
It *is* worrisome here - the timer clock is directly divided from the system clock. Jitter at the output driven from ISR/software is expected (see for example
https://community.st.com/thread/42053-stm32f746-instruction-cache
), but frequency deviation is not. Are you sure the primary source is HSE, not some of the internal RC oscillators?I'm only using the pin toggle as a way ofvisualising the interrupt, eventually I will be using it to trigger the generation of 128 audio samples which are then sent over DMA to a DAC.
Then 'benchmark' using DMA too. That's the case of 'IPs interaction' I mentioned above - some jitter will still remain, but in the order of few clocks, as result of various clock domain interactions and bus contentions.
JW