Problem with multiple HRTIMER synced operation due to missing HRTIMER updates
We found a weird behavior on the STM32F334 device:
The requirement is to have 2 HRTIMER's which are locked in phase to generate output PWM's.
Currently we use HRTIMER1A and HRTIMER1B for the PWM's. The master timer is used to generate reset on MST period event.
The problem we found, is that sometimes the registers seem not to be updated.
It is really weird, but can be seen on all our devices, therefore it has to be something with the configuration.
Details about the configuration:
HRTIMERA and HRTIMERB uses CMP1,2,3,4 to generate PWM pulses on the two outputs.
HRTIMERMST and HRTIMERA and B have all the same clock with pre-scaler of 8.
All timers use the same period (period is changing constantly during operation).
All timers have preload enabled:
HRTIM_TimerCfg.PreloadEnable = HRTIM_PRELOAD_ENABLED;
HRTIMERA and B have update on roll over enabled:
HRTIM_TimerCfg.RepetitionUpdate = HRTIM_UPDATEONREPETITION_ENABLED;
HRTIMERMST is used to generate HRTIMERA and B reset with update enable:
HRTIM_TimerCfg.ResetTrigger = HRTIM_TIMRESETTRIGGER_MASTER_PER;
HRTIM_TimerCfg.ResetUpdate = HRTIM_TIMUPDATEONRESET_ENABLED;
For the timer register update I turn off all TIMER updates to write multiple registers:
#define MG_REG_HRTIMER1_UPDATE_EN (HRTIM1->sCommonRegs.CR1 &= ~(HRTIM_CR1_MUDIS | HRTIM_CR1_TAUDIS | HRTIM_CR1_TBUDIS))
#define MG_REG_HRTIMER1_UPDATE_DIS (HRTIM1->sCommonRegs.CR1 |= (HRTIM_CR1_MUDIS | HRTIM_CR1_TAUDIS | HRTIM_CR1_TBUDIS))
MG_REG_HRTIMER1_UPDATE_DIS;
//Write registers here.....
MG_REG_HRTIMER1_UPDATE_EN;
What is happening now, is that when I read back the period registers PERxR I can see that they change constantly, however the applied frequency of output PWM stays the same. This happens sporadically and not all the time, but randomly over time. It is enought to cause a serious PWM displacement which will cause a device fail / shutdown.
The PWM's stay in phase, but the missing update is a serious problem!
Right now I found a working setup, BUT it can't be the final solution, cuz it has drawbacks.It's just good enough to keep our devices running without fail, but it causes component stress which we need to avoid.
When I do not stop the MST update, the HRTIMER's will be always updated with the prelaoded values. But it can happen, that the MST timer is out of sync for one cycle which can cause the duty cycle to be incorrect for this particular cycle.
Only disable HRTIMERA and B update:
#define MG_REG_HRTIMER1_UPDATE_EN (HRTIM1->sCommonRegs.CR1 &= ~(HRTIM_CR1_TAUDIS | HRTIM_CR1_TBUDIS))
#define MG_REG_HRTIMER1_UPDATE_DIS (HRTIM1->sCommonRegs.CR1 |= (HRTIM_CR1_TAUDIS | HRTIM_CR1_TBUDIS))
