This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
Tool/software: Code Composer Studio
Dear TI community,
I found a strange behavior when I use shadow load for AQCTLA & AQTCLB registers. (AQCTL.bit.SHDWAQyMODE = 1)
I wan't to create a single PWM one pulse, so i config the ePWM module for normal operation, with the addition that i config the AQCTLA register to clear the A output in any case. With shadowed load this settings gets active after the first pulse (shadowed to active load when TBCTR == zero).
Here is my pwm start function:
void pfc_pwm_start( uint16_t generate_onepulse){ EALLOW; uint16_t j; for (j=0;j<1;j++) { /* * Set Action Qualifier register for normal operation * * Main switch: set - counter == compare A (during up count) * clear - counter == zero * * Sub switch: set - counter == compare A (during up count) * clear - counter == compare B (during up count) * * Configure register first for immediate load, to make changes immediately active */ (*ePWM[j]).AQCTL.bit.SHDWAQAMODE = 0; // immediate load for ACTLA register (*ePWM[j]).AQCTL.bit.SHDWAQBMODE = 0; // immediate load for ACTLB register (*ePWM[j]).AQCTLA.bit.CAU = AQ_SET; (*ePWM[j]).AQCTLA.bit.ZRO = AQ_CLEAR; (*ePWM[j]).AQCTLB.bit.CAU = AQ_SET; (*ePWM[j]).AQCTLB.bit.CBU = AQ_CLEAR; /* * Set Action Qualifier register for One Pulse operation - If enabled * * Clear both switches at all actions * * Configure register first for shadowed load, to make changes active after next counter reset * -> first pulse normal operation (configuration above), * after first pulse clear all (configuration below) -> one shot function */ if(generate_onepulse){ GpioDataRegs.GPASET.bit.GPIO6 = 1; GpioDataRegs.GPACLEAR.bit.GPIO6 = 1; (*ePWM[j]).AQCTL.bit.SHDWAQAMODE = 1; // enable shadow load for ACTLA register (*ePWM[j]).AQCTL.bit.SHDWAQBMODE = 1; // enable shadow load for ACTLB register (*ePWM[j]).AQCTL.bit.LDAQASYNC = 0; (*ePWM[j]).AQCTL.bit.LDAQBSYNC = 0; (*ePWM[j]).AQCTLA.bit.CAU = AQ_CLEAR; (*ePWM[j]).AQCTLA.bit.ZRO = AQ_CLEAR; (*ePWM[j]).AQCTLB.bit.CAU = AQ_CLEAR; (*ePWM[j]).AQCTLB.bit.CBU = AQ_CLEAR; } /* * Force a one time action qualifier event to guarantee a low level for * both switches at timer start */ (*ePWM[j]).AQSFRC.bit.OTSFA = 1; (*ePWM[j]).AQSFRC.bit.OTSFB = 1; /* * Clear permanent trip zone low level and start timer */ (*ePWM[j]).TZCLR.bit.OST = 1; // clear one shot event (*ePWM[j]).TBCTL.bit.CTRMODE = TB_COUNT_UP; // start counter } EDIS; }
When I write
(*ePWM[j]).AQCTL.bit.LDAQASYNC = 1; // shadowed to active load @ LDAQAMODE (LDAQAMODE = 0) or SYNCIN event
(*ePWM[j]).AQCTL.bit.LDAQBSYNC = 1;
I will have the expected behavior (only one ePWM1A pulse CH4):
But when I write
(*ePWM[j]).AQCTL.bit.LDAQASYNC = 0; // shadowed to active load only @ LDAQAMODE (LDAQAMODE = 0) (*ePWM[j]).AQCTL.bit.LDAQBSYNC = 0;
I will have a strange behavior
In my opinion, there should be no difference between the two configurations, because shadowed to active load is in both cases @ TBCTR = zero and the DCAEVT1 will reset the TBCTR and the TBPHS register is zero! I have plot the EPWMSYNCO on CH2 for verification that a TBCTR zero event will be generated. After the first EPWMSYNCO pulse, the shadowed registers should transfered to the active registers. But in the second behavior, the active register gets never updated from the shadowed register.
Is it possible that this note causes this behavior:
Because resetting the pin and shadowed to active load is on the same clock cycle? (TBCTR == zero)
Thank you!
Thank you for your fast reply!
I've checked the AQCTRL[LDAQAMODE] from debugger with a breakpoint before I'm starting the counter with
(*ePWM[n]).TBCTL.bit.CTRMODE = TB_COUNT_UP;
The value is zero
When I'm changing the value of the AQCTRL[LDAQAMODE] register during debugging between 0 and 1, I will get the to different behaviors.
I've found another inexplicable behavior:
If I write the following code, all works perfect:
EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR; EPwm1Regs.AQCTLA.bit.ZRO = AQ_CLEAR; EPwm1Regs.AQCTLB.bit.CAU = AQ_CLEAR; EPwm1Regs.AQCTLB.bit.CBU = AQ_CLEAR;
If I write the following (clear A & B outputs after single pulse on every event):
EPwm1Regs.AQCTLA.all = 0x555; EPwm1Regs.AQCTLB.all = 0x555;
than the pulse look like this:
So it looks like the CAU event is shadowed but the CBU event is not shadowed?
I've created a project for you to test the behavior. I've used the LAUNCHXL-F280049C board. The EPwm1 module is configured in upcount. The PWM is turned off at TBCTR == 0 and turned on at TBCTR == CAU. The CMPSS1H comparator can reset the counter, so pwm is turned off after a comparator trip or when the period value is reached.
Pleas make a connection between Pin 70 (DACA_OUT) & Pin 64 (CMP1SSH input) to simulate a current flow to with the DAC.
With the following configuration the PWM works as expected:
#define AQCTL_LDAQAMODE 1 #define AQCTLA_CLEAR_ALL 0
With this configuration the shadowed registers never updates the active register (=> no onepulse):
#define AQCTL_LDAQAMODE 0 #define AQCTLA_CLEAR_ALL 0
With this configuration CAU is shadowed and CBU not. (=> PWM on time is always 200ns, independent of the comparator trip)
#define AQCTL_LDAQAMODE 1 #define AQCTLA_CLEAR_ALL 1
Thank you for your help!
What are you attempting by having the global load codes below?
// global shadow load control EPwm1Regs.GLDCTL.bit.GLDMODE = 0xF; // shadow to active register load @ GLDCTL2[GFRCLD] EPwm1Regs.GLDCTL.bit.GLD = 1; // enable global shadow load EPwm1Regs.GLDCTL.bit.GLDPRD = 1; EPwm1Regs.GLDCFG.bit.TBPRD_TBPRDHR = 1; // enable global load for TBPRD register EPwm1Regs.GLDCFG.bit.CMPA_CMPAHR = 1; // enable global load for CMPA register EPwm1Regs.GLDCFG.bit.CMPB_CMPBHR = 1; // enable global load for CMPB register
Can we remove these and try again?
Hi Nima,
thank you for your support!
Sorry for the delay.
The global reload code was planed for further implementation, to disable all shadow loads during a specific time window. (TBPRD & CMPA & CMPB).
There is no difference if I remove the global reload support or not.
It is good that I have a workaround for this problem, but I would appreciate if I understand the problem.
can you help with this? I cannot seem to identify why this is behaving as mentioned above.
CHA will clear when the counter reach zero. The length is controlled either through the period value or, in future, when the comparator reset the counter.
Tobias,
I just sent you a friend request on E2E. This way we can exchange email and continue to work on this since this is taking a very long time to resolve.
I just noticed that taking out this section of the code,
// digital compare submodule EPwm1Regs.TZDCSEL.bit.DCAEVT1 = TZ_DCAH_HI; // source select for DCAEV1: DCAH = high, DCAL = don't care EPwm1Regs.TZCTL.bit.DCAEVT1 = TZ_NO_CHANGE; // no trip zone change @ DCAEVT1 EPwm1Regs.TZCTL.bit.DCAEVT1 = TZ_NO_CHANGE; // no trip zone change @ DCAEVT1 EPwm1Regs.DCACTL.bit.EVT1SRCSEL = DC_EVT1; // DCEVTFILT is source for DCAEVT1.sync EPwm1Regs.DCACTL.bit.EVT1FRCSYNCSEL = DC_EVT_SYNC; // event is synchronized EPwm1Regs.DCACTL.bit.EVT1SYNCE = 1; // sync pulse generation enabled (needed for counter reset) EPwm1Regs.DCFCTL.bit.SRCSEL = DC_SRC_DCAEVT1; // source for filter block is DCAEVT1 signal (CMPSS1H) EPwm1Regs.DCFCTL.bit.BLANKE = DC_BLANK_ENABLE; // enable blanking EPwm1Regs.DCFCTL.bit.BLANKINV = DC_BLANK_NOTINV; // blanking signal not inverted EPwm1Regs.DCFCTL.bit.PULSESEL = DC_PULSESEL_ZERO; // blanking aligned to zero // capture EPwm1Regs.DCCAPCTL.bit.CAPE = 1; // enable digital capture unit // trip zone module EPwm1Regs.TZCTL.bit.TZA = TZ_FORCE_LO; EPwm1Regs.TZCTL.bit.TZB = TZ_FORCE_LO; EPwm1Regs.TZFRC.bit.OST = 1; // force a one shot event
I checked that setting to LDAQASYNC to 1 or 2 works as you want it to. Seems like the load only occurs on DCEVT and not the CTR=0 or any other CTR event. Seems like we are skipping over PRD and ZERO with this configuration. Again, if we take out the DC code above, everything will work as expected.
AS far as the AQCTLA and AQCTLB, I have never actually used the .all to write to all at once. I will also continue to see what I can find on this and let you know once I find some information.
Please accept my friend request so we can continue working on this.