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.

TMS320F28388D: Missing SPI read events after EPWM + DMA trigger

Part Number: TMS320F28388D
Other Parts Discussed in Thread: SYSCONFIG

Hi,

I'm designing a system where SPI transactions are executed via DMA and triggered by EPWM10SOCA event. This works most of the time but I see periodic cases where the SPI transactions don't happen:

On the image above, we can see that most of the time, on a rising edge of EPWM10, a SPI transaction is starting (like cases 1 and 2). 

But in case 3, the PWM10 rising edge didn't end up triggering anything on the SPI.

My configuration is the following:

- PWM10 is a 7.5kHz square signal (EPWM in counting up mode, CMPA = period / 2)

- PWM10 triggers SOCA event:

EPWM_setADCTriggerSource(EPWM10_BASE, EPWM_SOC_A, EPWM_SOC_TBCTR_ZERO);
EPWM_setADCTriggerEventPrescale(EPWM10_BASE, EPWM_SOC_A, 1);
EPWM_enableADCTriggerEventCountInit(EPWM10_BASE, EPWM_SOC_A);
EPWM_enableADCTrigger(EPWM10_BASE, EPWM_SOC_A);

- DMA is triggered by SOCA event:

DMA_configAddresses(DMA_CH5_BASE, (uint16_t *)(SPIB_BASE + SPI_O_TXBUF), srcAddr);
DMA_configMode(DMA_CH5_BASE, DMA_TRIGGER_EPWM10SOCA, DMA_CFG_ONESHOT_DISABLE | DMA_CFG_CONTINUOUS_ENABLE | DMA_CFG_SIZE_16BIT);

How can I troubleshoot this? Any idea why at specific times the DMA or the SPI peripheral is not doing its job?

Thanks,

Stephane

  • Stephane,

    How can I troubleshoot this? Any idea why at specific times the DMA or the SPI peripheral is not doing its job?

    If other DMA channels are used, it is possible that another DMA channel was active and DMA wasn't able to get to SPI-DMA channel in time. From the waveform provided, Did you try reducing the PWM frequency to see whether the problem disappears. Check whether overflow OVRFLG flag is set when you see the problem?

    Also, is SPI TX FIFO enabled?

    Regards,

    Manoj

  • If other DMA channels are used, it is possible that another DMA channel was active and DMA wasn't able to get to SPI-DMA channel in time.

    I will check, but I don't think any other DMA is used at the same time. Also more than 130µs happen between 2 SOCA events, the DMA should have had plenty of time to react... Will also check for OVRFLG flag, how can I put a breakpoint just at the time the issue happens?

    Also, is SPI TX FIFO enabled?

    Yes FIFO mode is enabled, here is the code generated by SysConfig for the SPI:

    void SPI_init()
    {
    	
    	//mySPIB initialization
    	SPI_disableModule(mySPIB_BASE);
    	SPI_setConfig(mySPIB_BASE, DEVICE_LSPCLK_FREQ, SPI_PROT_POL0PHA1,
    				  SPI_MODE_MASTER, 2500000, 16);
    	SPI_enableFIFO(mySPIB_BASE);
    	SPI_setFIFOInterruptLevel(mySPIB_BASE, SPI_FIFO_TXEMPTY, SPI_FIFO_RX12);
    	SPI_disableLoopback(mySPIB_BASE);
    	SPI_setEmulationMode(mySPIB_BASE, SPI_EMULATION_STOP_MIDWAY);
    	SPI_enableModule(mySPIB_BASE);
    }

  • Putting interrupts at several points in the code, I can see:

    • I see all EPWM10 interrupts, not missing a single one (with interrupt source = EPWM_INT_TBCTR_ZERO, same config as ADC trigger source)
    • When I have no SPI transaction, I see that I have no DMA interrupt (so it didn't write anything in SPI buffers)

    So the SPI peripheral is fine, the issue is between the EPWM module and the DMA:

    • either there was no EPWM10SOCA event triggered by the EPWM module
    • or the SOCA event didn't reach the DMA...
  • I finally found that the SOCA event config wasn't correct. The code I had was:

        EPWM_setADCTriggerSource(EPWM10_BASE, EPWM_SOC_A, EPWM_SOC_TBCTR_ZERO);
        EPWM_setADCTriggerEventPrescale(EPWM10_BASE, EPWM_SOC_A, 1);
        EPWM_enableADCTriggerEventCountInit(EPWM10_BASE, EPWM_SOC_A);
        EPWM_enableADCTrigger(EPWM10_BASE, EPWM_SOC_A);

    The problematic line was:

        EPWM_enableADCTriggerEventCountInit(EPWM10_BASE, EPWM_SOC_A);

    This line was enabling the SOCA counter to get reinitialized on each EPWMxSYNCI events:

    Removing this line solved my issue.

  • Another related issue is that EPWMxSYNCI was not disabled, even though SysConfig mentioned the contrary:

    In the generated code, there is no line managing the EPWMSYNCINSEL register, but the default value of this register at reset is 1 (EPWM1.SYNCOUT), not 0 (Disabled).

    I had to manually add this line to make sure there is no SYNCI signal:

    EPWM_setSyncInPulseSource(base, EPWM_SYNC_IN_PULSE_SRC_DISABLE); 

    This is a bug in SysConfig, I will create another ticket about it

  • I will request EPWM expert to look into this and fix this issue.

    Regards,

    Manoj