i.MX RT1021, flexPWM, Update of duty cycle sometimes have no effect

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

i.MX RT1021, flexPWM, Update of duty cycle sometimes have no effect

458 Views
AndreasM
Contributor I

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

 

 

Labels (1)
Tags (3)
0 Kudos
2 Replies

441 Views
EdwinHz
NXP TechSupport
NXP TechSupport

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.

0 Kudos

415 Views
AndreasM
Contributor I

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:

  1. Check LDOK bit and clear it, if still set
  2. Set new duty cycle: write new duty cycle to VAL2 to VAL5
  3. Set corresponding LDOK bit in the "Load Okay" field

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:

  1. Check LDOK bit and clear it, if still set
  2. Set new duty cycle: write new duty cycle to VAL2 to VAL5
  3. Set corresponding LDOK bit in the "Load Okay" field
  4. Set corresponding LDOK bit in the "Load Okay" field a second time

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

 

 

 

 

0 Kudos