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.

TMS320F28335: Setting ePWM ETS ADC trigger selection to counter == 0 does not trigger the DMA ISR that is connected to the ADC (EPwm3Regs.ETSEL.bit.SOCASEL = ET_CTR_ZERO;).

Part Number: TMS320F28335


I'd like to start ADC and its connected DMA as soon as the PWM clock is enabled (SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;).

This does not work:

EPwm3Regs.ETSEL.bit.SOCASEL = ET_CTR_ZERO;

My work around is using the CMPA register and setting it to 1 because 0 does not work there either:

EPwm3Regs.CMPA.half.CMPA = 1;
EPwm3Regs.ETSEL.bit.SOCASEL = ET_CTRU_CMPA;

PWM frequency is 100 MHz.

Did anybody come across a similar issue?

Best wishes,

Günter

  • Günter,

    Your workaround seems reasonable to me. What I think is happening: You need to enable the clock to setup the PWM, as soon as you do that TBCTR begins counting, by the time you enable SOCASEL the TBCTR has counted past zero and SOCA is missed until the next cycle.

    If your goal is to start SOCA and the PWM at the same time, you could try loading TBPHS with 0 and using a SWFSYNC to align the everything immediately after starting the PWM.

    Does that help?

    Regards,
    Cody 

  • Hi Cody,

    thank you for the quick and very helpful reply.

    Since I have the work-around in place, I'll try your suggestion in a less busy week. I would like to mention though that setting up the PWM channels is surrounded by disabling and enabling the clock. That's why I expected that a counter 0 will trigger SOC. But I can imagine that not the value of the counter but its transition triggers SOC.

    Best wishes,

    Günter

        EALLOW;
        SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0;
        EDIS;
    
    	// PWM channel 1 is used to control VGN1.
        EPwm1Regs.TBPRD = PWM_VGN_PERIOD;
        // Start with 50% duty cycle.
    //    EPwm1Regs.CMPA.half.CMPA = PWM_VGN_PERIOD / 2;
        // Start with 0% duty cycle.
        EPwm1Regs.CMPA.half.CMPA = 0;
        EPwm1Regs.TBPHS.all = 0;
        EPwm1Regs.TBCTR = 0;
        EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_DISABLE;
        EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE;
        EPwm1Regs.TBCTL.bit.FREE_SOFT = 2;
        EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;
        EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN;
        EPwm1Regs.TBCTL.bit.PRDLD = TB_SHADOW;
        EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
        EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR;
        EPwm1Regs.AQCTLA.bit.CAD = AQ_SET;
    
    	// PWM channel 2 is used to control VGN2.
        EPwm2Regs.TBPRD = PWM_VGN_PERIOD;
        // Start with 50% duty cycle.
    //    EPwm2Regs.CMPA.half.CMPA = PWM_VGN_PERIOD / 2;
        // Start with 0% duty cycle.
        EPwm2Regs.CMPA.half.CMPA = 0;
        EPwm2Regs.TBPHS.all = 0;
        EPwm2Regs.TBCTR = 0;
        EPwm2Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_DISABLE;
        EPwm2Regs.TBCTL.bit.PHSEN = TB_DISABLE;
        EPwm2Regs.TBCTL.bit.FREE_SOFT = 2;
        EPwm2Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;
        EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN;
        EPwm2Regs.TBCTL.bit.PRDLD = TB_SHADOW;
        EPwm2Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
        EPwm2Regs.AQCTLA.bit.CAU = AQ_CLEAR;
        EPwm2Regs.AQCTLA.bit.CAD = AQ_SET;
    
        // PWM channel 3 is used to enable / disable the H-Bridge (set SD high on U7 and U9)
        // and to setup ADC conversion.
        EPwm3Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN;
        EPwm3Regs.TBCTL.bit.PHSEN = TB_ENABLE;
        EPwm3Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;
        EPwm3Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN;
        EPwm3Regs.AQCTLA.all = 0;
        EPwm3Regs.ETSEL.bit.INTSEL = ET_CTR_PRD;
        EPwm3Regs.CMPA.half.CMPA = 1;
        EALLOW;
        PieVectTable.EPWM3_INT = &epwm3_isr;
        EDIS;
    
        // PWM channel 4 is used to drive phase 0 of the H-Bridge.
        EPwm4Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN;
        EPwm4Regs.TBCTL.bit.PHSEN = TB_ENABLE;
        EPwm4Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;
        EPwm4Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN;
    
        if (burstConfiguration.pulseCount > 1)
        {
    		// PWM channel 5 is used to finish the burst by changing the action qualifiers.
    		EPwm5Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN;
    		EPwm5Regs.TBCTL.bit.PHSEN = TB_ENABLE;
    		EPwm5Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;
    		EPwm5Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP;
    		// Generate interrupt on counter == zero event.
    		EPwm5Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO;
    		// Disable interrupt for now. Enable it in StartBurst().
    		EPwm5Regs.ETSEL.bit.INTEN = 0;
    		EALLOW;
    		PieVectTable.EPWM5_INT = &epwm5_isr;
    		EDIS;
        }
        // PWM channel 6 is used to drive phase 180 of the H-Bridge.
        EPwm6Regs.TBCTL.bit.PHSEN = TB_DISABLE;
        EPwm6Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;
        EPwm6Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN;
    
        // Enable PWM clock to support setting the signal gain.
        EALLOW;
        SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;
        EDIS;
    

  • Günter,

    My previous post was only a theory, I'm not sure if it is true. Even if you enable and disable the clocks, it's possible that on the first cycle you are creating a race condition. If this is true it at least seems to be consistent that TBCTR is incrementing first.

    I'm glad your code is working! If you get a chance to test out the other workaround I suggested I would love to know if it works!

    Thanks,
    Cody