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.

TMS320F28377D DMA and McBSP

Other Parts Discussed in Thread: TMS320F28377D, CONTROLSUITE

Hey,

Anyone how can help me? I am struggling with a TMS320F28377D, rev B, McBSP transmits, controlled by DMA:
The idea is to send "Buffer" from RAM via DMA to McBSP DX. The buffer is filled with non-zero data.
I followed the example from the controlsuite, studied the manual for both DMA and McBSP.
But the output I see on my scope only shows 0x0000 and not the expected data.
Here's my code:

#define DataSize 300
Uint32 Buffer[DataSize+1];


void mcbsp_init()
{
 EALLOW;
  CpuSysRegs.PCLKCR11.bit.McBSP_A = 1; // enable McBSP-A peripheral
 EDIS;
 udelay(1);

 McbspaRegs.SPCR2.all  = 0x0000; // Reset FS generator, sample rate generator & transmitter.
 McbspaRegs.SPCR1.all  = 0x0000; // Reset Receiver, Right justify word
    udelay(1);

    McbspaRegs.SPCR2.bit.FREE = 1;
    McbspaRegs.SPCR2.bit.SOFT  = 1;

 McbspaRegs.MFFINT.all   = 0x0; // Disable all interrupts
 McbspaRegs.MFFINT.bit.XINT  = 1;
 McbspaRegs.SPCR2.bit.XINTM = 2; // on every FSX
    udelay(1);

    McbspaRegs.RCR2.all = 0x0;   // Single-phase frame, 1 word/frame, No companding
    McbspaRegs.RCR1.all = 0x0;
    udelay(1);

    McbspaRegs.XCR1.all = 0x0040;  // frame length = 1 word, word length = 16 bit
 McbspaRegs.XCR2.all = 0x0240;
 udelay(1);

    McbspaRegs.SRGR2.bit.CLKSM  = 1; // SCLKME=0, so clock to SRG is LSPCLK
 McbspaRegs.SRGR2.bit.FPER  = 20; // FPER = 20 CLKG periods
 McbspaRegs.SRGR2.bit.FSGM  = 1;
    udelay(1);

    McbspaRegs.SRGR1.bit.FWID  = 15;   // Frame Width = 16 CLKG period
    McbspaRegs.SRGR1.bit.CLKGDV = 255; // CLKG frequency = LSPCLK/(CLKGDV+1) = 14.28M/256 = 55.8KHz
    udelay(1);

    McbspaRegs.PCR.bit.FSXM  = 1; // FSX generated internally
 McbspaRegs.PCR.bit.CLKXM = 1; // CLKX generated internally
    udelay(1);

    McbspaRegs.SPCR2.bit.GRST = 1;  // Enable the sample rate generator
    udelay(1);
    McbspaRegs.SPCR2.bit.FRST = 1;  // Frame Sync Generator enabled
    udelay(1);

    return;
}


void dma_init(void)
{
 // configure DMA:
 EALLOW;
  CpuSysRegs.PCLKCR0.bit.DMA  = 1;
  udelay(10);
  DmaRegs.DMACTRL.bit.HARDRESET = 1;
  udelay(10);

  // Channel 1, McBSPA transmit only
  DmaRegs.CH1.MODE.bit.CHINTE  = 0;  // no interrupts to CPU
  DmaRegs.CH1.BURST_SIZE.all  = 0;  // 1 word/burst
  DmaRegs.CH1.SRC_BURST_STEP  = 0;  // no effect when using 1 word/burst
  DmaRegs.CH1.DST_BURST_STEP  = 0;  // no effect when using 1 word/burst
  DmaRegs.CH1.TRANSFER_SIZE  = DataSize; // number of transfers
  DmaRegs.CH1.SRC_TRANSFER_STEP = 1;  // Move to next word (move address pointer 2 bytes)
  DmaRegs.CH1.DST_TRANSFER_STEP = 0;  // Don't move destination address
  DmaRegs.CH1.SRC_ADDR_SHADOW  = (Uint32 )&Buffer[0];    // Start address = buffer
  DmaRegs.CH1.DST_ADDR_SHADOW  = (Uint32) &McbspaRegs.DXR1.all; // Start address = McBSPA DXR
  DmaRegs.CH1.CONTROL.bit.PERINTCLR = 1;  // Clear peripheral interrupt event flag
  DmaRegs.CH1.CONTROL.bit.SYNCCLR = 1;  // Clear sync flag
  DmaRegs.CH1.CONTROL.bit.ERRCLR = 1;  // Clear sync error flag
  DmaRegs.CH1.DST_WRAP_SIZE  = DmaRegs.CH1.TRANSFER_SIZE + 10; // disable wrapping by setting wrap_size higher than Transfer_Size.
  DmaRegs.CH1.SRC_WRAP_SIZE  = DmaRegs.CH1.TRANSFER_SIZE + 10; // disable wrapping by setting wrap_size higher than Transfer_Size.
  DmaRegs.CH1.MODE.bit.SYNCE  = 0;        // No sync signal
  DmaRegs.CH1.MODE.bit.SYNCSEL = 0;        // No sync signal
  DmaRegs.CH1.MODE.bit.ONESHOT = 1;  // multiple sends per transfer.
  DmaRegs.CH1.MODE.bit.CONTINUOUS = 1;  // keep on going during debug
  DmaRegs.CH1.MODE.bit.PERINTE = 1;  // Enable peripheral interrupt event
  DmaRegs.CH1.MODE.bit.PERINTSEL = 1;  // simply CH1.   old-> //DMA_MXEVTA; // Peripheral interrupt select = McBSP MXSYNCA
  DmaClaSrcSelRegs.DMACHSRCSEL1.bit.CH1 = DMA_MXEVTA;
  DmaRegs.DEBUGCTRL.bit.FREE = 1;

  DmaRegs.CH1.CONTROL.bit.PERINTCLR = 1;
  udelay(1);
 EDIS;
 udelay(1);
 return;
}


void main(void)
{
 int i;

 EALLOW;
  IER = 0x0000;
  IFR = 0x0000;
  DINT;
 EDIS;

 InitSysCtrl();

 for (i=0;i<DataSize;i++) Buffer[i] =( (Uint32)(0x1201+i)<<16)+(0xF0F0-i); // generate non-zero sort-of recognizable data.

 EALLOW;
  ClkCfgRegs.LOSPCP.bit.LSPCLKDIV = 7; // 200MHz/14 = 14.28MHz
 EDIS;

 // configure pins for McBSP peripheral:
 EALLOW;
  GpioCtrlRegs.GPCMUX2.bit.GPIO84 = 3;
  GpioCtrlRegs.GPCMUX2.bit.GPIO85 = 3;
  GpioCtrlRegs.GPCMUX2.bit.GPIO86 = 3;
  GpioCtrlRegs.GPCMUX2.bit.GPIO87 = 3;
  GpioCtrlRegs.GPCGMUX2.bit.GPIO84 = 3;
  GpioCtrlRegs.GPCGMUX2.bit.GPIO85 = 3;
  GpioCtrlRegs.GPCGMUX2.bit.GPIO86 = 3;
  GpioCtrlRegs.GPCGMUX2.bit.GPIO87 = 3;
 EDIS;

 dma_init();

 // Start DMA:
 EALLOW;
  DmaRegs.CH1.CONTROL.bit.RUN = 1;          // Start DMA Transmit from McBSP-A
 EDIS;
 udelay(1);

 // Configure McBSP
 mcbsp_init();
 udelay(1);

 // start McBSP:
    McbspaRegs.SPCR2.bit.XRST=1; // Release TX from Reset

 for (;;)
 {
  // check scope.
 }

}

  • Alex,
    Can you swap the order of the GPxMUXy and GPxGMUXy operations? In the TRM, we have a note to always set the GPxMUXy to 0 before setting GPxGMUXy to avoid glitching on the muxes. See #1 of section 7.2 Configuration Overview in the GPIO section of the TRM.

    Other than that, I do not see anything outstanding in the code. I will keep looking. Please try out the above suggestion and reply with your results
  • Hello Mark,
    You are right about swapping the order of the mux. I didn't effect the operation.
    Thanks for taking this issue seriously. I hope you come up with a solution soon.
    Best regards,
    Alex.
  • Hello Mark,
    Any suggestion yet?
    Alex.
  • Alex, 

    I have not been able to take a look at this yet. Have you tried running the ControlSuite example "out of the box"? i.e. Run the McBSP dma transmit example without making any modifications?

    -Mark