cancel
Showing results for 
Search instead for 
Did you mean: 

HRTIM repetition counter resets on stop/start but ADC Postscaler does not - is there a way to manually reset the postscaler?

SGree.2
Associate II

Hi there!!

I'm currently working on a high frequency GaN brushless motor control application using the HRTIM's complementary outputs (CHB1/2, CHE1/2, CHF1/2), with the timer in up-down counting mode, and ADC1/2/3/4 on the STM32G474RE for inline phase current and bus voltage sense.

My PWM frequency is 96kHz, and I'm running my FOC control loop at 8kHz - so my repetition counter and ADC prescaler is 96k/8k = 12 (written value to registers is 12-1=11).

Both the HRTIM repetition counter and ADC postscaler counter is set to decrement on period ("top" of the up-down count cycle) (ADROM_CREST and ROM_CREST).

As each HRTIM update triggers the FOC calculations (which relies on the previous ADC value), it's important that the ADC sampling always happens consistently each cycle.

However, I noticed that when disabling and then re-enabling the HRTIM (using WaveformOutputStop/Start and WaveformCountStop/Start), the ADCs sample at different points. Here are three scope shots (with logic analyzer) to illustrate - just probing GPIO outputs that I'm toggling during interrupts. I stopped and then started the HRTIM (WaveformOutputStop/Start and WaveformCountStop/Start as well as zeroing the counter values) between each scope capture, and you can see that the ADC sampling point is different within the 12 PWM cycles between each HRTIM update.

First line is the HRTIM update interrupt, second line is the ADC conversion complete interrupt (ignore the multiple pulses on that one, that's for debugging something else haha). Note that 12 PWM cycles happen between each HRTIM update interrupt - so it appears that the PWM cycle where the ADC is being triggered changes. I believe that this is because stopping and starting the HRTIM clears the internal repetition counter, but does not clear the ADC postscaler counter.

Is my guess here correct? Or is the ADC postscaler actually being reset, and this is some sort of other issue in my code?

If this is an issue with the ADC postscaler value carrying over to the next HRTIM, is there a way to reset it? I didn't see any corresponding registers in the reference manual. Do I need to e.g. only stop the timer directly after ADC sampling?

1 ACCEPTED SOLUTION

Accepted Solutions

Hello,

Yes, I confirm your guess, stopping and restarting the HRTIM won't clear the ADC postscaler counter, so the first trigger will "finish" the old value of the postscaler counter, before updating on the new programmed value.

My proposal is to stop the HRTIMER "just" before an ADC trigger: I used something like this:

if ((ext_evt_mod%5 == 4)) /* PostScaler value is 4 and ext_evt_mod is a variable incremented on HRTIM periods */

HAL_HRTIM_WaveformCounterStop_IT(&hhrtim1, HRTIM_TIMERID_MASTER);

This will ensure an ADC trigger at the first period and then with the right new postscaler.

Best regards.

View solution in original post

2 REPLIES 2

Hello,

Yes, I confirm your guess, stopping and restarting the HRTIM won't clear the ADC postscaler counter, so the first trigger will "finish" the old value of the postscaler counter, before updating on the new programmed value.

My proposal is to stop the HRTIMER "just" before an ADC trigger: I used something like this:

if ((ext_evt_mod%5 == 4)) /* PostScaler value is 4 and ext_evt_mod is a variable incremented on HRTIM periods */

HAL_HRTIM_WaveformCounterStop_IT(&hhrtim1, HRTIM_TIMERID_MASTER);

This will ensure an ADC trigger at the first period and then with the right new postscaler.

Best regards.

Thank you for your suggestion! That's a fine workaround. So this would require blocking a number of PWM periods whenever looking to stop the HRTIM, correct? It would be nice if there was a mention of this in the reference manual or errata sheet - just a suggestion. Unfortunately, blocking multiple PWM periods isn't possible with this implementation - I switched to an approach where I'm just using injected conversion each period, since the ADC is fast enough. A little dirty but it works haha. I'll keep this workaround in mind for the future.