Hi,
We are using both channel A and B of a PWM submodule with a different duty cycle each. Also the application requires an duty cylce update of both channels at a certain time frame. Since the update time is much longer than the PWM period, the update is done asynchronous and the PWM period interrupt is not used for this. Therefore the update is just done somewhere within the PMW period.
The duty cycle update function first sets the new values for VAL2 - VAL5 and then request register update with setting LDOK. Note that for configuration and duty cycle update the flexPWM driver functions are used.
We found out, that sometimes the PWM update does not work and the PWM stays running with the old duty cycle. In case of this it seems that the PWM module miss or ignores the LDOK trigger. After some deeper investigations to this issue we found out, that setting the LDOK bit twice will solve this. Note that even stopping and restarting the PWM timer while setting new values does not helps.
We do not have any glue why we meed to set the LDOK bit twice.
Do we miss something within the PWM configuration? Is the procedure for the PWM update correct for this use case? Does any one already sees the same behaviour and have an explanation for this?
Or is this a known behaviour?
This are the code snipped for update and confiugration of the PWM:
/* update PWM duty cycle */
PWM_UpdatePwmDutycycleHighAccuracy(config->base, config->index, kPWM_PwmA, config->mode, dcA);
PWM_UpdatePwmDutycycleHighAccuracy(config->base, config->index, kPWM_PwmB, config->mode, dcB);
PWM_SetPwmLdok(config->base, 1U << config->index, true);
/* second update trigger */
PWM_SetPwmLdok(config->base, 1U << config->index, true); <--- solves the occasionaly update issue
/* configure the PWM */
PWM_GetDefaultConfig(&pwm_config);
pwm_config.prescale = kPWM_Prescale_Divide_8;
pwm_config.reloadLogic = kPWM_ReloadImmediate;
pwm_config.clockSource = kPWM_BusClock;
pwm_config.reloadFrequency = kPWM_LoadEveryOportunity;
Kind regards
Andreas
Hi @AndreasM,
The registers that change the frequency related features of the PWM are buffered because the calculations that the PWM module does have to be synchronized. This synchronization is required by specification, an prevents errors on the PWM signal. Due to the unsynchronized nature of your application, the updated duty cycles are probably being buffered and that is why you are not seeing the updated values on the PWM signal until you set the "Load Okay" field. This field ensures that the values of the registers have been written on the buffers correctly, and can therefore be passed on to the PWM on the next synchronized PWM reload. But again, this is to ensure a proper and synchronized functionality of the module.
BR,
Edwin.
Hi Edwin,
thank you very much for the fast response!
Yes, I am aware of the buffered registers and the synchronisation mechanism of the PWM to ensure a proper signal output. It is clear to me that the PWM registers for the timing are buffered and must be transfered to the working registers with the corresponding bit of the "Load Okay" field.
From your explanation I would expect the following sequence for proper duty cycle changes, and that is what we have first implemented in our application:
This sequence generally works well, but even sometimes not. Sometimes we see that the new duty cycle is not taken into effect. It seems that the PWM hardware occasionally does not transfer the buffered register content to the working register set, even the corresponding LDOK bit was set in the "Load Okay" field.
We overcome this with setting the LDOK bit a second time, therefore our sequence looks now like this:
Please note, that we also try different load opportunities with no difference: kPWM_ReloadImmediate, kPWM_ReloadPwmFullCycle
We are wondering why steps 1 - 3 are not sufficient to reliable set the requested duty cycle.
Again, do we miss something within our PWM configuration?
Kind regards,
Andreas