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.

TMS320F280025C: Event trigger Interrupt generation

Part Number: TMS320F280025C

Hi,

I've a issue with the event trigger interrupt generation, I want generate an interrupt  triggered by ePWM1 when CTR = 0. So you can see my configuration bellow.

And question : ETSEL.INTSEL equal 1 so it's good for CTR = 0  and INTEN = 1 to enable interrupt. Problem with the ETPS config I want to select ETPS.INTPRD because I want to generate event at each trigger.

So ETPS.INTPRD will be equal to 1 no ? and in the CCS window debugger you can see ETPS.INTPRD = 0. How select this bit by driverlib please ? because this function EPWM_setInterruptEventCount(EPWM1_BASE, 1) select ETINTPS.INTPRD2.

What's the problem with my configuration because I see shift timing between ePWM1 and INT_EPWM1 ? I want synchronize ePWM1 rising edge with INTePWM1 rising edge.

Pink signal : ePWM1

Yellow signal : INT_EPWM1 (1 enter in interrupt, 0 out)

What's the different between ETPS.INTPRD and ETINTPS.INTPRD2 if I select interrupt at each event ? 

#include "device.h"

__interrupt void isr_read_adc(void);

void main(void)
{
    /// Initialize device clock and peripherals
    Device_init();
    /// Disable pin locks and enable internal pullups.
    Device_initGPIO();
    /// Initialize PIE and clear PIE (for pie multiplexer) and IFR (for cpu) registers (IER for pie table).
    Interrupt_initModule();
    /// Initialize the PIE vector table with pointers to the shell Interrupt Service Routines (ISR).
    Interrupt_initVectorTable();

    /// Disable sync and clock to PWM
    SysCtl_disablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);

    /// Parameters
    EPWM_setTimeBaseCounterMode(EPWM1_BASE, EPWM_COUNTER_MODE_UP);
    EPWM_setTimeBaseCounter(EPWM1_BASE, 0U);
    /// To have around 0.05% (See ePWM chapter in Chapter 17 Technical reference manual page 1798) do point for ePWM precision who is the maximum precision with the ePWM module.
    /// If we want more precision use the HRPWM module.
    EPWM_setClockPrescaler(EPWM1_BASE, EPWM_CLOCK_DIVIDER_1, EPWM_HSCLOCK_DIVIDER_1);
    /// Set up shadowing
    EPWM_setCounterCompareShadowLoadMode(EPWM1_BASE, EPWM_COUNTER_COMPARE_A, EPWM_COMP_LOAD_ON_CNTR_ZERO);
    /// Set actions for boost assembly
    EPWM_setActionQualifierAction(EPWM1_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);
    EPWM_setActionQualifierAction(EPWM1_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_LOW, EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);
    /// For buck assembly
    EPWM_setActionQualifierAction(EPWM1_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPB);
    EPWM_setActionQualifierAction(EPWM1_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_LOW, EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);

    EPWM_setTimeBasePeriod(EPWM1_BASE, 2499);
    EPWM_setCounterCompareValue(EPWM1_BASE, EPWM_COUNTER_COMPARE_B, 1250);

    /// Interrupt where we will change the Compare Values
    /// Select INT on Time base counter zero event,
    /// Enable INT, generate INT on 1rd event
    EPWM_setInterruptSource(EPWM1_BASE, EPWM_INT_TBCTR_ZERO);
    EPWM_enableInterrupt(EPWM1_BASE);
    /// To trigger the interrupt at each event, maximum value equal to 15.
    EPWM_setInterruptEventCount(EPWM1_BASE, 1);

    EPWM_setPhaseShift(EPWM1_BASE, 0);
    EPWM_disablePhaseShiftLoad(EPWM1_BASE);

    GPIO_setPinConfig(GPIO_42_GPIO42);
    GPIO_setDirectionMode(42, GPIO_DIR_MODE_OUT);
    GPIO_setPadConfig(42, GPIO_PIN_TYPE_STD);
    GPIO_writePin(42, 0);

    /// GPIO initialization EPWM1
    EALLOW;
    GPIO_setPinConfig(GPIO_0_EPWM1_A);
    GPIO_setPinConfig(GPIO_1_EPWM1_B);
    EDIS;

    Interrupt_register(INT_EPWM1, &isr_read_adc);
    Interrupt_enable(INT_EPWM1);
    /// Enable sync and clock to PWM
    SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);

    /// Enable Global Interrupt (INTM) and realtime interrupt (DBGM)
    EINT;
    ERTM;

    while(1)
    {

    }
}

__interrupt void isr_read_adc(void)
{
    EPWM_clearEventTriggerInterruptFlag(EPWM1_BASE);

    GPIO_writePin(42, 1);
    DEVICE_DELAY_US(2);
    GPIO_writePin(42, 0);

    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP3);
}

Thanks

Damien

  • Hi,

    I have found a part of the issue : It is due to the action qualifier  for ePWM1 : HIGH on time base zero and LOW up CMPB.

    But I have always a delay between ePWM1 rising edge and INTEPWM1 interrupt rising edge, around 1µs it's a lot, why ? 

    I run in RAM.

    Thanks

    Damien

  • Hello Damien,

    A colleague and I have looked into this, and as far as we are able to tell, the delay here is the just time it takes for your system to branch into the ISR- there are quite a few commands that need to be executed at the assembly level before it reaches the command to actually write to the pin. For example, if you move the EPWM_clearEventTriggerInterruptFlag function to the line after the write, there will be a notable decrease in the delay you're seeing.

    Regards,

    Jason Osborn

  • Hi Jason,

    Yes it's a delay for my system, I've make a test with a toggle pin via GPIO_writePin() function and I see 700ns of delay between two set pin it is a lot !!

    When I see C code in this function and assembly code it is not at all optimal the driverlib, very useful however to start it is time for me to switch to bitfield to better master. 

    Can you explain me this point please : What's the different between ETPS.INTPRD and ETINTPS.INTPRD2 if I select interrupt at each event ? 

    Thanks

    Damien

  • Hello Damien,

    ETPS.INTPRD is limited to a value between 0-3, while ETINTPS.INTPRD2 ranges from 0-15. Driverlib only utilizes the latter due to its broader range. I'm not certain if there's any resultant timing differences between using them, though I doubt there is, particularly with driverlib only using one of them.

    Regards,

    Jason Osborn