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.

interrupt safety check update

Hi, I am running ePWM 1-6 using eCAP 1-6...all at different phases and duties.  I would now like to run some code to check if its safe for the PWM to be active each cycle of the PWM...so I need an interup that triggers every time the ePWM is executed...I am I right to think the below code can run from flash ok...is this the correct approach? I would then repeat each interrupt for every pwm channel...Thanks

// ISR interrupt

interrupt void epwm1_timer_isr(void)

{

   if(GPIOxx == 1){ //system safe...run

EPwm1Regs.AQCSFRC.bit.CSFA=11;     // PWM active A

EPwm1Regs.AQCSFRC.bit.CSFB=11;     // PWM active B

}else{ //system unsafe...disable

EPwm1Regs.AQCSFRC.bit.CSFA=01; // PWM disabled A

EPwm1Regs.AQCSFRC.bit.CSFB=01; // PWM disabled B

}

   EPwm1Regs.ETCLR.bit.INT = 1;   // Clear INT flag for this timer

   PieCtrlRegs.PIEACK.all = PIEACK_GROUP3; // Acknowledge this interrupt to receive more interrupts from group 3

}

  • It is hard to tell at the moment as ePWM has a number of modes as you will well know.  Whether it uses the timer interrupt for each one I am not sure.  I think it will be helpful if you can post your initialization of your ePWM code so that I and others can have the full information and help you fully.

    On a second point, this is more personal opinion and it may be the opinion of others, but I would recommend you run your interrupts from RAM.  Flash is slower and it can influence interrupt latency.  The code for the interrupt is reasonably small so should not take that much RAM space.  However, if RAM is tight and interrupt latency is not a real concern running the interrupt from Flash would still definitely work.

    After writing all that, I thought of another way that you could do it which would be way more efficient, not rely on your ePWM modes and decrease shutdown time.  This would involve triggering an external interrupt (XINT) off your GPIO line and in its ISR you disable/enable all your ePWMs.  This would mean the moment the GPIO line went low/high, the system would shutdown/restart. Having this single interrupt would reduce latency and code space considerably to having an ISR for each of the ePWMs.

     

    Tim

     

  • Hi Tim, thanks for your comments...

    1) pwm below, sorry its expanded

    2) OK I will run ISR from RAM might need help.

    3) each PWM (1-6) A-B has an independent safety line that is unique...so I would either need 6 XINT or run each code snipet inside the ewm isr...I think for safety I would like to see the exact gpio check inside the PWM call so there can be no 'software coding errors' - wrong pins for wrong pwm...unless there are significant savings...

    so would now like a ram based ISR for pwm 1 to 6, triggered from epwm (how can I do this?)

    ---

    EPwm1Regs.TBCTL.bit.CTRMODE = 0x3; // Disable the timer

    EPwm1Regs.TBPRD = KPWM_PERIOD;

    EPwm1Regs.TBPHS.half.TBPHS = pd_1;    

    EPwm1Regs.TBCTR = 0x0000; // clear TB counter

    EPwm1Regs.CMPA.half.CMPA = KEPWM_CMPA; // Compare A = 350 TBCLK counts

    EPwm1Regs.CMPB = KEPWM_CMPB; // Compare B = 200 TBCLK counts PWM_HALF_PERIOD

    EPwm1Regs.TBCTL.bit.FREE_SOFT = 0x3;

    EPwm1Regs.TBCTL.bit.PHSDIR = 0x0;

    EPwm1Regs.TBCTL.bit.CLKDIV = 0x0;

    EPwm1Regs.TBCTL.bit.HSPCLKDIV = 0x0;

    EPwm1Regs.TBCTL.bit.SWFSYNC = 0x0;

    EPwm1Regs.TBCTL.bit.SYNCOSEL = 0x1; // ctr0=1 //dis=3, ctr0=1,pwmync=0

    EPwm1Regs.TBCTL.bit.PRDLD = 0x0;

    EPwm1Regs.TBCTL.bit.PHSEN = 0x1; // dis 0, en 1 for phase adjust

    EPwm1Regs.CMPCTL.bit.SHDWBMODE = 0x0;

    EPwm1Regs.CMPCTL.bit.SHDWAMODE = 0x0;

    EPwm1Regs.CMPCTL.bit.LOADBMODE = 0x0; // load on CTR = Zero

    EPwm1Regs.CMPCTL.bit.LOADAMODE = 0x0; // load on CTR = Zero

    EPwm1Regs.AQCTLA.bit.CBD = 0x0;   // dn

    EPwm1Regs.AQCTLA.bit.CBU = 0x0; // dn

    EPwm1Regs.AQCTLA.bit.CAD = 0x1;   // Clear 

    EPwm1Regs.AQCTLA.bit.CAU = 0x1; // Clear

    EPwm1Regs.AQCTLA.bit.PRD=  0x0; // dn

    EPwm1Regs.AQCTLA.bit.ZRO = 0x2; // set high


    EPwm1Regs.AQCTLB.bit.CBD = 0x0;   // dn

    EPwm1Regs.AQCTLB.bit.CBU = 0x2; // clear //set

    EPwm1Regs.AQCTLB.bit.CAD = 0x0;   // dn

    EPwm1Regs.AQCTLB.bit.CAU = 0x0; // dn

    EPwm1Regs.AQCTLB.bit.PRD=  0x0; // dn

    EPwm1Regs.AQCTLB.bit.ZRO = 0x1; // set high  //low

    EPwm1Regs.ETPS.all = 0x0100; // Configure SOCA

    EPwm1Regs.ETSEL.all = 0x0A00; // Enable SOCA to ADC

    EPwm1Regs.TBCTL.bit.CTRMODE = 0x0; // Enable the timer in count up mode

    EPwm1Regs.PCCTL.bit.CHPEN = 0; // PWM chopper unit disabled

  • Looking at the initialization code your original solution should do the trick.  You will just have to enable the timer interrupt for each PWM set.  I would use interrupt on timer=0 or timer=period.

    As for running it from RAM it is best to look at Chapter 4 of: http://focus.ti.com/lit/an/spra958i/spra958i.pdf  (Running a program from Flash in F28s).  It should tell you the necessary steps for running it from RAM.  Typically it involves a small change to the linker file and a memcpy at initialization time.  After that the linker takes care of the rest so the rest of the code does not need to change at all.

    Tim

  • //pwm setup

    EPwm1Regs.ETSEL.bit.INTSEL = 1;     // Select INT on Zero event

        EPwm1Regs.ETSEL.bit.INTEN = 1;   // Enable INT

        EPwm1Regs.ETPS.bit.INTPRD = 1;          // Generate INT on 1st event

    // Main

    #pragma CODE_SECTION(epwm1_timer_isr, "ramfuncs");

    interrupt void epwm1_timer_isr(void);

     EALLOW;  // This is needed to write to EALLOW protected registers

       PieVectTable.EPWM1_INT = &epwm1_timer_isr;

       EDIS;    // This is needed to disable write to EALLOW protected registers

     

    // Initalize counters:

       EPwm1TimerIntCount = 0;

       LoopCount = 0;

     

    // Enable CPU INT3 which is connected to EPWM1-3 INT:

       IER |= M_INT3;

    ..rock and roll :)