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.

TMS320F28379D: SPI transmission using EPWM triggered DMA

Part Number: TMS320F28379D

Hello,

I'm trying to drive an external DAC using an EPWM triggered DMA to write from a 24-point sine wave table to my SPI transmit buffer. I've mapped my EPWM to a GPIO to monitor its output. I'm seeing the SPI peripheral transmit 16 clock pulses and drive chip select low on the rising edge of each EPWM pulse, however, no data is being transmitted over MOSI (see picture, first few SPI writes are manual).

image.png

This would indicate to me that the DMA is being triggered by my EPWM, but for some reason the data is not transferring correctly between the DMA and SPI. I'm also confused because I'm monitoring some of the DMA flags in the debug, and I see the following flags remain the same during runtime:

  • DMA_getTransferStatusFlag = DMA_getRunStatusFlag = 1
  • DMA_getTriggerFlagStatus = 0

So I'm not sure if the DMA is actually being triggered or not.

I'm wondering if somebody can take a look at my DMA config and point out if there's something obvious I'm missing. I suspect my issue is very similar to what's described in this thread but unfortunately this user doesn't elaborate what changes they made (Sinewave generation using EPWM, DMA, and DAC). Here's my config:

extern uint16_t waveformDATA[24];
#define mySPI0_TX_DMA_ADDRESS (SPIA_BASE + SPI_O_TXBUF)
void DMA_init(){
    DMA_initController();
	myDMA0_init();
}

void myDMA0_init(){
    DMA_setEmulationMode(DMA_EMULATION_STOP);
    DMA_configAddresses(myDMA0_BASE, (const void *)mySPI0_TX_DMA_ADDRESS, (const void *)waveformDATA);
    DMA_configBurst(myDMA0_BASE, 1U, 1, 0);
    DMA_configTransfer(myDMA0_BASE, 24U, 1, 0);
    DMA_configWrap(myDMA0_BASE, 24U, -24, 65535U, 0);
    DMA_configMode(myDMA0_BASE, DMA_TRIGGER_EPWM6SOCA, DMA_CFG_ONESHOT_DISABLE | DMA_CFG_CONTINUOUS_ENABLE | DMA_CFG_SIZE_16BIT);
    //DMA_stopChannel(myDMA0_BASE);
	DMA_enableInterrupt(myDMA0_BASE);
    DMA_setInterruptMode(myDMA0_BASE, DMA_INT_AT_END);
	//DMA_clearTriggerFlag(myDMA0_BASE);
	DMA_enableTrigger(myDMA0_BASE);
}

Best,

Malcolm

  • Hi Malcolm, 

    Apologies for the delayed response. A couple things:

    • Is your waveformDATA buffer being placed in GSRAM? DMA only has access to GSRAM areas of memory.
    • What is the data type defined for the waveformDATA buffer? I would suggest using uint16_t. Can you share your definition of the waveformDATA array and I can recommend the DMA settings needed (burst, transfer, and wrap settings)?
    • If you are using the EPWM to trigger the DMA, it's possible that the SPI TX buffer could get overrun. I would suggest switching to the SPI TX trigger or using a EPWM ISR where you check the SPI TX buffer status before software triggering the DMA. I don't think this is the cause of your current issue, but it may cause issues later.

    Best Regards,

    Delaney

  • Hi Delaney,

    Thanks for your help. I changed my declaration of waveformDATA to the following and this got the data transferring properly from the DMA. I was wondering if this is how you usually place the buffer in a specific section of memory, or if there's a better way to do it:

    #pragma DATA_SECTION(waveformDATA, "ramgs0")
    extern uint16_t waveformDATA[WAVEFORM_SIZE];

    Here's what my output looks like now:

    As far as the EPWM vs. SPI trigger, feasibly for my application I will want to change the sample rate dynamically, so I will probably look into the EPWM ISR approach.

    Best,

    Malcolm

  • Hi Malcolm,

    Glad to hear your DMA transfers are working now. Yes, that is the best way to allocate the buffer to GSRAM. I will close this thread, but please feel free to create another one if you have any more questions.

    Best Regards,

    Delaney