eFlexPWM EXTSYNC mode pwm update err

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

eFlexPWM EXTSYNC mode pwm update err

873 Views
xfmcux
Contributor I

Hi,man

   I used eFlexPWM for motor control. when I used EXT_SYNC signal , I find some pwm update problem in , In pic red circle, you can see pwm change Incorrect。

xfmcux_1-1689305295359.png

 

another pic show correct pwm update, NOT IN EXT_SYNC mode.

xfmcux_0-1689305198235.png

So, when I used EXT_SYNC mode, 

__________________________________________________________________________________

there is the pwm config IN EXT_SYNC mode , Can you help me find what wrong?

Thanks!

_____________________________________________________________________________

void PWM1_Config(void)
{    
    /* PWM base pointer (affects the entire initialization) */
    PWM_Type *PWMBase = (PWM_Type *)PWM1;
 
/* PWM_MCTRL: IPOL = 0,RUN = 0,CLDOK = 0xF,LDOK = 0 */
PWMBase->MCTRL = PWM_MCTRL_IPOL(0) | PWM_MCTRL_RUN(0) | PWM_MCTRL_CLDOK(0xFU) | PWM_MCTRL_LDOK(0);
 
/* PWM_SMaINTEN: ??=0,??=0,REIE=0,RIE=0,CA1IE=0,CA0IE=0,CB1IE=0,CB0IE=0,CX1IE=0,CX0IE=0,CMPIE=0 */
PWMBase->SM[0].INTEN = 0x00U;
PWMBase->SM[1].INTEN = 0x00U;
PWMBase->SM[2].INTEN = 0x00U;
PWMBase->SM[3].INTEN = 0x00U;
  
/* PWM_FCTRL0: FLVL=0,FAUTO=0,FSAFE=0,FIE=0 */
PWMBase->FCTRL = 0x00U;
 
    /* Full cycle reload */
    // relaod when counter matche VAL1                       
    PWMBase->SM[0].CTRL |= PWM_CTRL_FULL_MASK;
    PWMBase->SM[1].CTRL |= PWM_CTRL_FULL_MASK;
PWMBase->SM[2].CTRL |= PWM_CTRL_FULL_MASK;
    PWMBase->SM[3].CTRL |= PWM_CTRL_FULL_MASK;
    //add half cycle reload
    PWMBase->SM[0].CTRL |= PWM_CTRL_HALF_MASK;
    PWMBase->SM[1].CTRL |= PWM_CTRL_HALF_MASK;
PWMBase->SM[2].CTRL |= PWM_CTRL_HALF_MASK;
    PWMBase->SM[3].CTRL |= PWM_CTRL_HALF_MASK;   
 
    /* Value register initial values, duty cycle 50% */
    PWMBase->SM[0].INIT = PWM_INIT_INIT((uint16_t)(-PWM_INIT_VAL1));
    PWMBase->SM[1].INIT = PWM_INIT_INIT((uint16_t)(-PWM_INIT_VAL1));
PWMBase->SM[2].INIT = PWM_INIT_INIT((uint16_t)(-PWM_INIT_VAL1));
    PWMBase->SM[3].INIT = PWM_INIT_INIT((uint16_t)(-PWM_INIT_VAL1));
 
    PWMBase->SM[0].VAL0 = PWM_VAL0_VAL0((uint16_t)(0));//half the pwm cycle sync of second motor
    PWMBase->SM[1].VAL0 = PWM_VAL0_VAL0((uint16_t)(0));
PWMBase->SM[2].VAL0 = PWM_VAL0_VAL0((uint16_t)(0));
    PWMBase->SM[3].VAL0 = PWM_VAL0_VAL0((uint16_t)(0));
 
    PWMBase->SM[0].VAL1 = PWM_VAL1_VAL1((uint16_t)(PWM_INIT_VAL1 - 1));
    PWMBase->SM[1].VAL1 = PWM_VAL1_VAL1((uint16_t)(PWM_INIT_VAL1 - 1));
    PWMBase->SM[2].VAL1 = PWM_VAL1_VAL1((uint16_t)(PWM_INIT_VAL1 - 1));
    PWMBase->SM[3].VAL1 = PWM_VAL1_VAL1((uint16_t)(PWM_INIT_VAL1 - 1));
 
    PWMBase->SM[0].VAL2 = PWM_VAL2_VAL2((uint16_t)((-PWM_VAL2_VAL3)));
    PWMBase->SM[1].VAL2 = PWM_VAL2_VAL2((uint16_t)((-PWM_VAL2_VAL3)));
    PWMBase->SM[2].VAL2 = PWM_VAL2_VAL2((uint16_t)((-PWM_VAL2_VAL3)));
    PWMBase->SM[3].VAL2 = PWM_VAL2_VAL2((uint16_t)((-PWM_VAL2_VAL3)));
 
    PWMBase->SM[0].VAL3 = PWM_VAL3_VAL3((uint16_t)(PWM_VAL2_VAL3));
    PWMBase->SM[1].VAL3 = PWM_VAL3_VAL3((uint16_t)(PWM_VAL2_VAL3));
PWMBase->SM[2].VAL3 = PWM_VAL3_VAL3((uint16_t)(PWM_VAL2_VAL3));
    PWMBase->SM[3].VAL3 = PWM_VAL3_VAL3((uint16_t)(PWM_VAL2_VAL3));
 
    /* Trigger for ADC synchronization */
    PWMBase->SM[0].VAL4 = PWM_VAL4_VAL4((uint16_t)(0));
    PWMBase->SM[1].VAL4 = PWM_VAL4_VAL4((uint16_t)((PWM_INIT_VAL1-450)));
    PWMBase->SM[2].VAL4 = PWM_VAL4_VAL4((uint16_t)(0));
    PWMBase->SM[3].VAL4 = PWM_VAL4_VAL4((uint16_t)(0));
 
    PWMBase->SM[0].VAL5 = PWM_VAL5_VAL5((uint16_t)(0));
    PWMBase->SM[1].VAL5 = PWM_VAL5_VAL5((uint16_t)(-450));
PWMBase->SM[2].VAL5 = PWM_VAL5_VAL5((uint16_t)(0));
    PWMBase->SM[3].VAL5 = PWM_VAL5_VAL5(0);
 
    PWMBase->SM[0].TCTRL = PWM_TCTRL_OUT_TRIG_EN(1);   //PWM_OUT_TRIG0 IN SM1
 
    //in this clear all trig config
 
    /* Set dead-time register */
    PWMBase->SM[0].DTCNT0 = PWM_DTCNT0_DTCNT0(PWM_DEADTIME);
    PWMBase->SM[1].DTCNT0 = PWM_DTCNT0_DTCNT0(PWM_DEADTIME);
PWMBase->SM[2].DTCNT0 = PWM_DTCNT0_DTCNT0(PWM_DEADTIME);
    PWMBase->SM[3].DTCNT0 = PWM_DTCNT0_DTCNT0(PWM_DEADTIME);
    PWMBase->SM[0].DTCNT1 = PWM_DTCNT1_DTCNT1(PWM_DEADTIME2);
    PWMBase->SM[1].DTCNT1 = PWM_DTCNT1_DTCNT1(PWM_DEADTIME2);
PWMBase->SM[2].DTCNT1 = PWM_DTCNT1_DTCNT1(PWM_DEADTIME2);
    PWMBase->SM[3].DTCNT1 = PWM_DTCNT1_DTCNT1(PWM_DEADTIME2);
 
    /* Channels A and B disabled when fault 0 occurs */
    PWMBase->SM[0].DISMAP[0] = ((PWMBase->SM[0].DISMAP[0] & ~PWM_DISMAP_DIS0A_MASK) | PWM_DISMAP_DIS0A(0x1));
    PWMBase->SM[1].DISMAP[0] = ((PWMBase->SM[0].DISMAP[0] & ~PWM_DISMAP_DIS0A_MASK) | PWM_DISMAP_DIS0A(0x1));
    PWMBase->SM[2].DISMAP[0] = ((PWMBase->SM[0].DISMAP[0] & ~PWM_DISMAP_DIS0A_MASK) | PWM_DISMAP_DIS0A(0x1));
    PWMBase->SM[3].DISMAP[0] = ((PWMBase->SM[0].DISMAP[0] & ~PWM_DISMAP_DIS0A_MASK) | PWM_DISMAP_DIS0A(0x1));
 
PWMBase->SM[0].DISMAP[0] = ((PWMBase->SM[0].DISMAP[0] & ~PWM_DISMAP_DIS0B_MASK) | PWM_DISMAP_DIS0B(0x1));
    PWMBase->SM[1].DISMAP[0] = ((PWMBase->SM[0].DISMAP[0] & ~PWM_DISMAP_DIS0B_MASK) | PWM_DISMAP_DIS0B(0x1));
    PWMBase->SM[2].DISMAP[0] = ((PWMBase->SM[0].DISMAP[0] & ~PWM_DISMAP_DIS0B_MASK) | PWM_DISMAP_DIS0B(0x1));
    PWMBase->SM[3].DISMAP[0] = ((PWMBase->SM[0].DISMAP[0] & ~PWM_DISMAP_DIS0B_MASK) | PWM_DISMAP_DIS0B(0x1));
 
    /* Modules one and two gets clock from module zero */
    PWMBase->SM[0].CTRL2 = (PWMBase->SM[0].CTRL2 & ~PWM_CTRL2_CLK_SEL_MASK) ;
    PWMBase->SM[1].CTRL2 = (PWMBase->SM[1].CTRL2 & ~PWM_CTRL2_CLK_SEL_MASK) ;
PWMBase->SM[2].CTRL2 = (PWMBase->SM[2].CTRL2 & ~PWM_CTRL2_CLK_SEL_MASK) ;
    PWMBase->SM[3].CTRL2 = (PWMBase->SM[3].CTRL2 & ~PWM_CTRL2_CLK_SEL_MASK) ;
 
    /* Master reload is generated every one opportunity */
    PWMBase->SM[0].CTRL = (PWMBase->SM[0].CTRL & ~PWM_CTRL_LDFQ_MASK) | PWM_CTRL_LDFQ(M1_FOC_FREQ_VS_PWM_FREQ - 1);
    PWMBase->SM[0].CTRL2 = (PWMBase->SM[0].CTRL2 & ~PWM_CTRL2_INIT_SEL_MASK) | PWM_CTRL2_INIT_SEL(0x3);
    /* Master sync active for modules one and three*/
    PWMBase->SM[1].CTRL2 = (PWMBase->SM[1].CTRL2 & ~PWM_CTRL2_INIT_SEL_MASK) | PWM_CTRL2_INIT_SEL(0x3);
PWMBase->SM[2].CTRL2 = (PWMBase->SM[2].CTRL2 & ~PWM_CTRL2_INIT_SEL_MASK) | PWM_CTRL2_INIT_SEL(0x3);
    PWMBase->SM[3].CTRL2 = (PWMBase->SM[3].CTRL2 & ~PWM_CTRL2_INIT_SEL_MASK) | PWM_CTRL2_INIT_SEL(0x3);
 
 
    /* Fault 0 active in logic level one, automatic clearing */
    PWMBase->FCTRL = (PWMBase->FCTRL & ~PWM_FCTRL_FLVL_MASK) | PWM_FCTRL_FLVL(0x1);
    PWMBase->FCTRL = (PWMBase->FCTRL & ~PWM_FCTRL_FAUTO_MASK) | PWM_FCTRL_FAUTO(0x0);
 
    /* Clear fault flags */
    PWMBase->FSTS = (PWMBase->FCTRL & ~PWM_FSTS_FFLAG_MASK) | PWM_FSTS_FFLAG(0xF);
 
    /* PWMs are re-enabled at PWM full cycle */
    PWMBase->FSTS = (PWMBase->FSTS & ~PWM_FSTS_FFULL_MASK) | PWM_FSTS_FFULL(0x1);
 
    /* PWM fault filter - 5 Fast peripheral clocks sample rate, 5 agreeing
       samples to activate */
    PWMBase->FFILT = (PWMBase->FFILT & ~PWM_FFILT_FILT_PER_MASK) | PWM_FFILT_FILT_PER(0);
    PWMBase->FFILT = (PWMBase->FFILT & ~PWM_FFILT_FILT_CNT_MASK) | PWM_FFILT_FILT_CNT(0);
 
    /* Enable A&B PWM outputs for submodules zero, one and three */
//output disable
    PWMBase->OUTEN = 0; // (PWMBase->OUTEN & ~PWM_OUTEN_PWMA_EN_MASK) | PWM_OUTEN_PWMA_EN(0xB);
/* Repeat Config */
/* Clear Status, RUF=0,REF=1,RF=1,CFA1=1,CFA0=1,CFB1=1,CFB0=1,CFX1=1,CFX0=1,CMPF=0x3F */
PWMBase->SM[0].STS = 0x3FFFU;
PWMBase->SM[1].STS = 0x3FFFU;
PWMBase->SM[2].STS = 0x3FFFU;
PWMBase->SM[3].STS = 0x3FFFU;
 
    /* Start PWMs (set load OK flags and run) */
    PWMBase->MCTRL = (PWMBase->MCTRL & ~PWM_MCTRL_CLDOK_MASK) | PWM_MCTRL_CLDOK(0xF);
    PWMBase->MCTRL = (PWMBase->MCTRL & ~PWM_MCTRL_LDOK_MASK) | PWM_MCTRL_LDOK(0xF);
    PWMBase->MCTRL = (PWMBase->MCTRL & ~PWM_MCTRL_RUN_MASK) | PWM_MCTRL_RUN(0xF);
 
    /* Interrupt Enable, CMPIE=0x20 */
  PWMBase->SM[0].INTEN = 0x00U;
  PWMBase->SM[1].INTEN = PWM_INTEN_CMPIE(0x20U);  //for VAL5 INT
    /* Initialize MC driver */
}

 

 

0 Kudos
Reply
6 Replies

265 Views
AZigliotto
Contributor I

Hi xfmcux,

I'm usign LPC5536 and I'm trying to sychronize the two eFlexPWM units via EXT_SYNC signal. I have seen a strange behaviour like you, with time delay in the syncronization!! Also in my opinion the EXT_SYNC mode of the eFlexPWM has some design problems. Have you solved the issue? Thank you

0 Kudos
Reply

252 Views
xfmcux
Contributor I

I think it's a problem with the PWM update and SYNC update mechanisms. The values of SM[x].VALx need to be above -3 for normal operation.

0 Kudos
Reply

834 Views
_Leo_
NXP TechSupport
NXP TechSupport

Hi,

Thank you so much for your interest in our products and for using our community.

Can you tell us which i.MX RT you are using please?

0 Kudos
Reply

747 Views
xfmcux
Contributor I

RT1052

0 Kudos
Reply

708 Views
_Leo_
NXP TechSupport
NXP TechSupport

Thank you for your patient.

I recommend you refer to the app note AN12200 (Associated File: AN12200SW), which describes a dual servo application with the RT1020, it uses eFlexPWM just like the RT1052. Here it is described how the EXT_SYNC signal of PWM1 triggers the initialization of the counters of PWM2 to achieve a 180° lag between the PWM waveforms of the two motors.

Hope it helps you.

Have a nice day!

0 Kudos
Reply

671 Views
xfmcux
Contributor I

Yes, I referred to the code of AN12200 to modify the CTRL2 register, but it did not solve my problem. I think the EXT_SYNC mode of the eflexPWM module may have design problems itself, or it needs special handling when used.

Due to the tight schedule of our project, please arrange for the local AE support team to provide support. Thank you!

0 Kudos
Reply