Synchronize flexPWM-Modules

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

Synchronize flexPWM-Modules

1,752 Views
Masmiseim
Senior Contributor I

Hello,

 

how can I synchronize the four flexPWM-Modules on the iMXRT Controller? I haven´t found a way to do so. Synchronizing the four Submodules of one Module seems to be easy, but not synchronizing several Modules.

I like to start and stop them simultaneously and have them running synchronized. Is there an Application Note or some code-examples available?

 

Thanks and best regards

 

Markus

Labels (2)
0 Kudos
9 Replies

1,219 Views
Edmund
Contributor I

It is an old question and I could not find a solution.

After some time I found the solution to bring a signal from the AOI unit by XBARA1 to Ext_Force Input of any PWM-Module, in my case 2 and 4.

FLEXPWM2_SM0CTRL2 |= FLEXPWM_SMCTRL2_FORCE_SEL(6); // 110b - The external force signal, EXT_FORCE, from outside the PWM module causes updates.
FLEXPWM4_SM0CTRL2 |= FLEXPWM_SMCTRL2_FORCE_SEL(6);

The signal from AOI is routed via XBARA 1:

xbar_init();
xbar_connect( XBARA1_IN_AOI1_OUT0, XBARA1_OUT_FLEXPWM2_EXT_FORCE);
xbar_connect( XBARA1_IN_AOI1_OUT0, XBARA1_OUT_FLEXPWM4_EXT_FORCE);

A positive edge is created by:

delay(1);
AOI1_BFCRT010 = 0xFF; // positive edge as Ext_Force via XBARA AOI to PMW 2 and 4

A delay of ~100 µs between routing and signal seems to be essential, why so ever.

The idea to use the AOI unit came from LAtimes in the PJRC forum.

0 Kudos

1,351 Views
Hui_Ma
NXP TechSupport
NXP TechSupport

Hi Markus,

Sorry for the later reply.

From RT1060 eFlexPWM module [Counter Synchronization] Figure, the external FORCE_OUT signal can force all submodules counter initialization.

pastedImage_1.png

More detailed info, please check RT1060 reference manual chapter 54.4.1.7 <Synchronous Switching of Multiple Outputs> and chapter 54.4.2.3 <Counter Synchronization>.

Wish it helps.


Have a great day,
Mike

-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

0 Kudos

1,351 Views
Masmiseim
Senior Contributor I

Hello Hui Ma,

 

Thanks for the feedback.

To clarify if I understood correctly.

For synchronizing all PWM-Outputs I can use the FORCE-OUT Signal. For this I can configure

PWMx->SM0CTRL2[FORCE_SEL] = 0; // The local force signal, CTRL2[FORCE], from this submodule is used to force updates.

PWMx->SM1CTRL2[FORCE_SEL] = 1;// The master force signal from submodule 0 is used to force updates.

PWMx->SM2CTRL2[FORCE_SEL] = 1; // The master force signal from submodule 0 is used to force updates.

PWMx->SM3CTRL2[FORCE_SEL] = 1; // The master force signal from submodule 0 is used to force updates.

 

 

For the actual synchronization, I´ve to call

PWM1->SM0CTRL2[FORCE] = 1;

PWM2->SM0CTRL2[FORCE] = 1;

PWM3->SM0CTRL2[FORCE] = 1;

PWM4->SM0CTRL2[FORCE] = 1;

 

Am I wrong or is this not synchronal as it is started with sequential commands.

 

Next approach:
I can configure all Submodules to use the external Force-Signal by setting

PWMx->SMxCTRL2[FORCE_SEL]= 6; // For all submodules of the four modules

Now I can use the Xbar with the output signals

kXBARA1_OutputFlexpwm1ExtForce

kXBARA1_OutputFlexpwm2ExtForce

kXBARA1_OutputFlexpwm3ExtForce

kXBARA1_OutputFlexpwm4ExtForce

 

However, which Input to choose? When using kXBARA1_InputLogicHigh /  kXBARA1_InputLogicLow I have to reconfigure the four XBar-Channels which will also lead to a unsynchronized PWM.

 

 

Maybe I have overlooked something. Could you help me out?

 

Thanks and best regards

0 Kudos

1,351 Views
Hui_Ma
NXP TechSupport
NXP TechSupport

Hi Markus,

Sorry for the delay reply.

For synchronizing all PWM-Outputs I can use the FORCE-OUT Signal.

For this I can configure

PWMx->SM0CTRL2[FORCE_SEL] = 0; // The local force signal, CTRL2[FORCE], from this submodule is used to force updates.

PWMx->SM1CTRL2[FORCE_SEL] = 1;// The master force signal from submodule 0 is used to force updates.

PWMx->SM2CTRL2[FORCE_SEL] = 1; // The master force signal from submodule 0 is used to force updates.

PWMx->SM3CTRL2[FORCE_SEL] = 1; // The master force signal from submodule 0 is used to force updates.

 

 

For the actual synchronization, I´ve to call

PWM1->SM0CTRL2[FORCE] = 1;

PWM2->SM0CTRL2[FORCE] = 1;

PWM3->SM0CTRL2[FORCE] = 1;

PWM4->SM0CTRL2[FORCE] = 1;

I couldn't find your configuration with any problem.

Please check each PWM submodule INIT register value. If those INIT register value are same?


Have a great day,
Mike

-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

0 Kudos

1,351 Views
Masmiseim
Senior Contributor I

Hello Hui Ma,

 

sorry, I can’t get it working, not even for a single module.

I altered the PWM Example from the SDK slightly. See below, I’ve highlighted my changes.

After calling

   PWM1->SM[0].CTRL2 |= PWM_CTRL2_FORCE_MASK;

the Counter are not going to the init Value.

 

Thanks and best regards

 

Markus

/*!
 * @brief Main function
 */
int main(void)
{
    /* Structure of initialize PWM */
    pwm_config_t pwmConfig;
    static uint16_t delay;
    uint32_t pwmVal = 4;
    uint16_t i;

    /* Board pin, clock, debug console init */
    BOARD_ConfigMPU();
    BOARD_InitPins();
    BOARD_BootClockRUN();
    BOARD_InitDebugConsole();

    CLOCK_SetDiv(kCLOCK_AhbDiv, 0x2); /* Set AHB PODF to 2, divide by 3 */
    CLOCK_SetDiv(kCLOCK_IpgDiv, 0x3); /* Set IPG PODF to 3, divede by 4 */

    /* Set the PWM Fault inputs to a low value */
    XBARA_Init(XBARA1);
    XBARA_SetSignalsConnection(XBARA1, kXBARA1_InputLogicHigh, kXBARA1_OutputFlexpwm1Fault0);
    XBARA_SetSignalsConnection(XBARA1, kXBARA1_InputLogicHigh, kXBARA1_OutputFlexpwm1Fault1);
    XBARA_SetSignalsConnection(XBARA1, kXBARA1_InputLogicHigh, kXBARA1_OutputFlexpwm1234Fault2);
    XBARA_SetSignalsConnection(XBARA1, kXBARA1_InputLogicHigh, kXBARA1_OutputFlexpwm1234Fault3);

    PRINTF("FlexPWM driver example\n");

    /*
     * pwmConfig.enableDebugMode = false;
     * pwmConfig.enableWait = false;
     * pwmConfig.reloadSelect = kPWM_LocalReload;
     * pwmConfig.faultFilterCount = 0;
     * pwmConfig.faultFilterPeriod = 0;
     * pwmConfig.clockSource = kPWM_BusClock;
     * pwmConfig.prescale = kPWM_Prescale_Divide_1;
     * pwmConfig.initializationControl = kPWM_Initialize_LocalSync;
     * pwmConfig.forceTrigger = kPWM_Force_Local;
     * pwmConfig.reloadFrequency = kPWM_LoadEveryOportunity;
     * pwmConfig.reloadLogic = kPWM_ReloadImmediate;
     * pwmConfig.pairOperation = kPWM_Independent;
     */
    PWM_GetDefaultConfig(&pwmConfig);

    /* Use full cycle reload */
    pwmConfig.reloadLogic = kPWM_ReloadPwmFullCycle;
    /* PWM A & PWM B form a complementary PWM pair */
    pwmConfig.pairOperation = kPWM_ComplementaryPwmA;
    pwmConfig.enableDebugMode = false;

    /* Initialize submodule 0 */
    if (PWM_Init(BOARD_PWM_BASEADDR, kPWM_Module_0, &pwmConfig) == kStatus_Fail)
    {
        PRINTF("PWM initialization failed\n");
        return 1;
    }

    /* Initialize submodule 1 */
    pwmConfig.clockSource = kPWM_Submodule0Clock;
    pwmConfig.initializationControl = kPWM_Initialize_MasterSync;
    pwmConfig.forceTrigger = kPWM_Force_Master;
    if (PWM_Init(BOARD_PWM_BASEADDR, kPWM_Module_1, &pwmConfig) == kStatus_Fail)
    {
        PRINTF("PWM initialization failed\n");
        return 1;
    }
    BOARD_PWM_BASEADDR->SM[kPWM_Module_1].CTRL2 |= PWM_CTRL2_FRCEN_MASK;

    /* Initialize submodule 2 the same way as submodule 1 */
    if (PWM_Init(BOARD_PWM_BASEADDR, kPWM_Module_2, &pwmConfig) == kStatus_Fail)
    {
        PRINTF("PWM initialization failed\n");
        return 1;
    }
    BOARD_PWM_BASEADDR->SM[kPWM_Module_2].CTRL2 |= PWM_CTRL2_FRCEN_MASK;

    /* Call the init function with demo configuration */
    PWM_DRV_Init3PhPwm();

    /* Set the load okay bit for all submodules to load registers from their buffer */
    PWM_SetPwmLdok(BOARD_PWM_BASEADDR, kPWM_Control_Module_0 | kPWM_Control_Module_1 | kPWM_Control_Module_2, true);

    /* Start the PWM generation from Submodules 0, 1 and 2 */
    PWM_StartTimer(BOARD_PWM_BASEADDR, kPWM_Control_Module_0 | kPWM_Control_Module_1 | kPWM_Control_Module_2);

    delay = 0x0fffU;

    while (1U)
    {
        for (i = 0U; i < delay; i++)
        {
            __ASM volatile("nop");
        }
        pwmVal = pwmVal + 4;

        /* Reset the duty cycle percentage */
        if (pwmVal > 100)
        {
            pwmVal = 4;
            PWM1->SM[0].CTRL2 |= PWM_CTRL2_FORCE_MASK;
        }

        /* Update duty cycles for all 3 PWM signals */
        PWM_UpdatePwmDutycycle(BOARD_PWM_BASEADDR, kPWM_Module_0, kPWM_PwmA, kPWM_SignedCenterAligned, pwmVal);
        PWM_UpdatePwmDutycycle(BOARD_PWM_BASEADDR, kPWM_Module_1, kPWM_PwmA, kPWM_SignedCenterAligned, (pwmVal >> 1));
        PWM_UpdatePwmDutycycle(BOARD_PWM_BASEADDR, kPWM_Module_2, kPWM_PwmA, kPWM_SignedCenterAligned, (pwmVal >> 2));

        /* Set the load okay bit for all submodules to load registers from their buffer */
        PWM_SetPwmLdok(BOARD_PWM_BASEADDR, kPWM_Control_Module_0 | kPWM_Control_Module_1 | kPWM_Control_Module_2, true);
    }
}

0 Kudos

1,351 Views
Hui_Ma
NXP TechSupport
NXP TechSupport

Hi Markus,

I get the eFlexPWM module validation code, for the NXP community is public and we don't allowed to post module validation code at here.

Could you help to submit an online support case? And then I can share that validation code with that case.

Please check here to submit an online support case and please let me know the case number. Thanks.


Have a great day,
Mike

-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

0 Kudos

1,351 Views
Masmiseim
Senior Contributor I

Hello Hui Ma,

the case Number is

Case 00219602

thanks and best regards

Markus

0 Kudos

1,351 Views
Hui_Ma
NXP TechSupport
NXP TechSupport

Hi Markus,

Thanks.

best regards,

Mike

0 Kudos

1,351 Views
Hui_Ma
NXP TechSupport
NXP TechSupport

Hi Markus,

First of all, sorry for the so later reply.

I tested with your code at IMXRT1050-EVKB board and couldn't find [Counter Synchronization] working.

I need to check with i.MXRT product team and check if they could provide some info about eFlexPWM submodules synchronize. I will let you know when there with any feedback.

Thanks for the patience.


Have a great day,
Mike

0 Kudos