LAUNCHXL-F28P65X: F28P65 related issues

Part Number: LAUNCHXL-F28P65X

Hello,

The customer has configured PWM center point trigger ADC conversion


EPWM_setADCTriggerSource(CB_PWM_BASE_V, EPWM_SOC_A, EPWM_SOC_TBCTR_PERIOD);
EPWM_setADCTriggerEventPrescale(CB_PWM_BASE_V, EPWM_SOC_A, 1);
EPWM_enableADCTrigger(CB_PWM_BASE_V, EPWM_SOC_A);
EPWM_setInterruptSource(CB_PWM_BASE_V, EPWM_INT_TBCTR_PERIOD);
EPWM_enableInterrupt(CB_PWM_BASE_V);
EPWM_setInterruptEventCount(CB_PWM_BASE_V, 1);


Then enable the ADC conversion of the channel to complete interrupt INT4


ADC_setInterruptSource(ADCA_BASE, ADC_INT_NUMBER4, ADC_SOC_NUMBER3);
ADC_clearInterruptStatus(ADCA_BASE, ADC_INT_NUMBER4);
ADC_enableContinuousMode(ADCA_BASE, ADC_INT_NUMBER4);
ADC_enableInterrupt(ADCA_BASE, ADC_INT_NUMBER4);


And wait for the interrupt flag to set during the PWM cycle interrupt


while (!AdcaRegs.ADCINTFLG.bit.ADCINT4);


It was found that waiting for the flag to be set on the first attempt would freeze the entire interrupt. But if there is no problem skipping the first interrupt and starting from the second interrupt, what is the reason?

Thanks.

  • Hi,

    I will get back to you with in next 24 hrs.

    Thanks

    Srikanth

  • Hi,

    Analysis: EPWM ADC Trigger with ADCINT4 Flag Polling Issue

    This is a well-known timing/sequencing issue on TMS320F28xxx devices. Here's a detailed explanation:

    Root Cause: First PWM Cycle Timing Race Condition

    What happens on the first interrupt:

    When the PWM counter reaches PERIOD for the first time:
    1. The EPWM SOC_A trigger fires → ADC conversion starts
    2. Simultaneously, the EPWM interrupt fires → CPU enters the ISR
    3. Inside the ISR, the code immediately polls:
      while (!AdcaRegs.ADCINTFLG.bit.ADCINT4);
    The problem is that on the first occurrence, the ADC conversion may not have been fully armed/started before the interrupt is serviced. Specifically:

    Detailed Explanation of the Freeze

    1. ADC Initialization Latency

    After calling:
    ADC_enableInterrupt(ADCA_BASE, ADC_INT_NUMBER4);
    ADC_enableContinuousMode(ADCA_BASE, ADC_INT_NUMBER4);
    There is a pipeline/register propagation delay. The ADC interrupt flag logic may not be fully synchronized on the very first trigger event.

    2. SOC Trigger vs. Interrupt Arrival Race

    • The EPWM PERIOD event simultaneously triggers:
      • The ADC SOC (hardware trigger)
      • The CPU interrupt (via PIE)
    • The CPU interrupt latency through the PIE is typically ~6–14 cycles
    • During the first cycle, the ADC conversion has a startup overhead and the
      ADCINT4
      flag may never assert (or asserts after the polling window), causing
      while(!ADCINT4)
      to loop foreversystem freeze

    3. Continuous Mode Behavior on First Trigger

    With
    ADC_enableContinuousMode
    ,
    ADCINT4
    is configured to re-trigger SOC3 automatically. On the very first trigger:
    • ADCINT4
      flag starts as cleared
    • The SOC fires, conversion begins
    • But if the interrupt ISR polls before conversion completes, it hangs

    4. Why the Second Interrupt Works

    By the second PWM PERIOD interrupt:
    • The ADC has already completed its first full conversion cycle
    • ADCINT4
      continuous mode has already re-armed SOC3
    • The ADC pipeline is fully primed and synchronized
    • When the second SOC trigger fires, the conversion completes quickly and
      ADCINT4
      sets within the expected window

    Summary Table

    Event First PWM Period Second PWM Period
    ADC SOC trigger Fires Fires
    ADC pipeline state Cold/unprimed Primed
    ADCINT4 flag May never set → freeze Sets correctly White check mark
    Continuous mode re-arm Not yet established Fully established White check mark

    Recommended Fixes

    Option 1: Skip the first interrupt (your current workaround)

    static uint16_t skipFirst = 0;
    if (skipFirst == 0) { skipFirst = 1; return; }
    while (!AdcaRegs.ADCINTFLG.bit.ADCINT4);

    Option 2: Force a software SOC trigger before enabling PWM interrupt

    // Manually trigger SOC3 once to prime the ADC pipeline
    ADC_forceSOC(ADCA_BASE, ADC_SOC_NUMBER3);
    // Wait for first conversion to complete
    while (!ADC_getInterruptStatus(ADCA_BASE, ADC_INT_NUMBER4));
    ADC_clearInterruptStatus(ADCA_BASE, ADC_INT_NUMBER4);
    // Now enable PWM interrupt
    EPWM_enableInterrupt(CB_PWM_BASE_V);

    Option 3: Add timeout guard to prevent freeze

    uint32_t timeout = 10000;
    while (!AdcaRegs.ADCINTFLG.bit.ADCINT4 && (--timeout > 0));

    Option 4: Use ADC interrupt-driven approach instead of polling

    Rather than polling inside the PWM ISR, configure a dedicated ADCINT4 ISR to handle the result — this avoids blocking the PWM ISR entirely and is the recommended architecture for production code.

    Key Takeaway

    The freeze on the first interrupt is caused by a timing race between the EPWM SOC trigger and CPU interrupt arrival, combined with ADC pipeline cold-start latency. The ADC has not completed its first conversion before the ISR begins polling, resulting in an infinite wait. From the second cycle onward, the ADC is fully synchronized and operates correctly.
    Thanks
    Srikanth