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.

F28M35H52C dma mcbsp loopback example



RFRLEN1_XFRLEN1_0.TIF

RFRLEN1_XFRLEN1_3.TIF

I've incorporated the mcbsp dma loopback example in to my project. Basically at the end of an ISR I want to start the dma-mcbsp process where 4 words of 16-bit length are sent. I want 4 words per frame and I want the clock to go low when I'm not using the mcbsp. I'm using DMA ch3 for Tx and DMA Ch4 for Rx. My problem is that when I change the frame length I get some weird results. Also I'm wondering if I'm starting/stopping the mcbsp in the proper way. I've attached some scope shots.

I'm noticing that when I use

McbspaRegs.RCR1.bit.RFRLEN1= 0 

McbspaRegs.XCR1.bit.XFRLEN1 = 0

the received data is correct but my clock stays on longer than 64 cycles (4 words * 16 bits). I guess this is ok but I want to use 4 words per frame.

If I use

 McbspaRegs.RCR1.bit.RFRLEN1 = 3;

McbspaRegs.XCR1.bit.XFRLEN1 = 3;

The clock stops pulsing before the end of the last word and the received data is offset in memory.

In either case I get 4 frame synch pulses, whereas I was expecting one frame sync pulse in the second case.

 

At the end of my ISR I do the following to start the dma-mcbsp:

EALLOW;

McbspaRegs.SPCR2.bit.GRST = 1;

DmaRegs.CH3.CONTROL.bit.RUN = 1;

DmaRegs.CH4.CONTROL.bit.RUN = 1;

EDIS;

Here's the dma isr

//*****************************************************************************

// DMA Channel 3 interrupt service routine for MCBSP Tx

//*****************************************************************************

__interrupt void local_DINTCH3_ISR(void)

{

 EALLOW;

DmaRegs.CH3.CONTROL.bit.HALT = 1;

PieCtrlRegs.PIEACK.all = PIEACK_GROUP7;

MCBSP_DMA_CH3_Count++;

EDIS;

return;

}

//*****************************************************************************

// DMA Channel 4 interrupt service routine for MCBSP Rx

//*****************************************************************************

__interrupt void local_DINTCH4_ISR(void)

{

 EALLOW;

DmaRegs.CH4.CONTROL.bit.HALT = 1;

PieCtrlRegs.PIEACK.all = PIEACK_GROUP7;

McbspaRegs.SPCR2.bit.GRST = 0; //reset sample generator, will get set in another isr

//reset so mcbsp clk goes low until next tx

MCBSP_DMA_CH4_Count++;

 EDIS;

return;

}

Here's my dma and mcbsp init functions:

void init_dma_mcbsp(void)

{

EALLOW;

DmaRegs.DMACTRL.bit.HARDRESET = 1;

__asm(" NOP"); // Only 1 NOP needed per Design

//

// Enable channel 3: will be McBSP-A transmit

// Enable channel 4, will be McBSP-A receive

//

DmaRegs.CH3.MODE.bit.CHINTE = 0; // disables ch int

DmaRegs.CH4.MODE.bit.CHINTE = 0;

//

// 1 word/burst

// For McBSP burst step must be 0 (no increment)

//

DmaRegs.CH3.BURST_SIZE.all = 0;

DmaRegs.CH3.SRC_BURST_STEP = 0;

DmaRegs.CH3.DST_BURST_STEP = 0;

DmaRegs.CH4.BURST_SIZE.all = 0;

DmaRegs.CH4.SRC_BURST_STEP = 0;

DmaRegs.CH4.DST_BURST_STEP = 0;

//

// Interrupt every frame (TRANSFER_BUFFER_SIZE-1 bursts/transfer)

//

DmaRegs.CH3.TRANSFER_SIZE = MCBSP_TX_BUFFER_SIZE-1;

DmaRegs.CH4.TRANSFER_SIZE = MCBSP_TX_BUFFER_SIZE-1;

//

// For transmit, after each burst:

// After each transfer, step to the next source word

// Do not move the destination address

// Set the source to the start of the sdata buffer

// Set the destination to the McBSP DXR1

//

DmaRegs.CH3.SRC_TRANSFER_STEP = 1;

DmaRegs.CH3.DST_TRANSFER_STEP = 0;

//

// For receive, after each burst:

// Do not move the source address

// After each transfer, step to the next destination word

//

DmaRegs.CH4.SRC_TRANSFER_STEP = 0;

DmaRegs.CH4.DST_TRANSFER_STEP = 1;

//

// Clear the McBSP peripheral interrupt, sync, and error flags

//

DmaRegs.CH3.CONTROL.bit.PERINTCLR = 1;

DmaRegs.CH3.CONTROL.bit.ERRCLR = 1;

DmaRegs.CH3.CONTROL.bit.PERINTCLR = 1;

DmaRegs.CH3.CONTROL.bit.ERRCLR = 1;

//

// Do not use the wrap function

// Set the wrap size to the maximum value

// which in effect disables it.

//

DmaRegs.CH3.DST_WRAP_SIZE = 0xFFFF;

DmaRegs.CH3.SRC_WRAP_SIZE = 0xFFFF;

DmaRegs.CH4.DST_WRAP_SIZE = 0xFFFF;

DmaRegs.CH4.SRC_WRAP_SIZE = 0xFFFF;

//

// Enable channel interrupt at end of transfer

// Interrupt at end of the transfer (mode)

// Enable peripheral interrupt event

// Peripheral interrupt for transfer is McBSP MXSYNCA

// Peripheral interrupt for receive is McBSP MREVTA

// Clear any interrupt flags

//

DmaRegs.CH3.MODE.bit.CHINTE = 1;

DmaRegs.CH3.MODE.bit.CHINTMODE = 1;

DmaRegs.CH3.MODE.bit.PERINTE = 1;

DmaRegs.CH3.MODE.bit.PERINTSEL = DMA_MXEVTA;

DmaRegs.CH3.CONTROL.bit.PERINTCLR = 1;

DmaRegs.CH4.MODE.bit.CHINTE = 1;

DmaRegs.CH4.MODE.bit.CHINTMODE = 1;

DmaRegs.CH4.MODE.bit.PERINTE = 1;

DmaRegs.CH4.MODE.bit.PERINTSEL = DMA_MREVTA;

DmaRegs.CH4.CONTROL.bit.PERINTCLR = 1;

EDIS;

}

//*****************************************************************************

// Initialize the McBSP.

//*****************************************************************************

void mcbsp_init_dlb(void)

{

// Reset FS generator, sample rate generator & transmitter

// Reset Receiver, Right justify word

// Enable digital loopback (DLB) mode

// Comment out for non-DLB mode

//todo: disable loopback mode

McbspaRegs.SPCR2.all=0x0000;

McbspaRegs.SPCR1.all=0x0000;

McbspaRegs.SPCR1.bit.DLB = 1;

//

// Disable all McBSP interrupts

McbspaRegs.MFFINT.all=0x0;

McbspaRegs.RCR2.all=0x0; // single phase Rx frame

McbspaRegs.RCR1.bit.RFRLEN1 = 0; // Rx frame length minus 1

McbspaRegs.RCR1.bit.RWDLEN1 = 2; // Rx word length is 16 bits

McbspaRegs.XCR2.all=0x0; // single phase Tx frame

McbspaRegs.XCR1.bit.XFRLEN1 = 0; // Tx frame length minus 1

McbspaRegs.XCR1.bit.XWDLEN1 = 2; // Tx word length is 16 bits

//

// CLKSM=1 (If SCLKME=0, i/p clock to SRG is LSPCLK)

// FPER = 32 CLKG periods

//

McbspaRegs.SRGR2.bit.CLKSM = 1; // sample rate generator clock taken from LSPCLK signal or MCLKX pin

McbspaRegs.SRGR2.bit.FPER = 255; // FPER+1 is the period between frame sync pulses

//

// Frame Width = 1 CLKG period

// CLKG frequency = LSPCLK/(CLKGDV+1)

McbspaRegs.SRGR1.bit.FWID = 0;

McbspaRegs.SRGR1.bit.CLKGDV = 0;

//

// FSX generated internally, FSR derived from an external source

// CLKX generated internally, CLKR derived from an external source

//

McbspaRegs.PCR.bit.FSXM = 1;

McbspaRegs.PCR.bit.CLKXM = 1;

//

// Enable the sample rate generator

// Wait at least 2 SRG clock cycles

// Release TX from Reset

// Release RX from Reset

// Frame Sync Generator reset

//

McbspaRegs.SPCR2.bit.GRST=1;

delay_loop();

McbspaRegs.SPCR2.bit.XRST=1;

McbspaRegs.SPCR1.bit.RRST=1;

McbspaRegs.SPCR2.bit.FRST=1;

}

Thank you

  • In the scope shots dark blue is the clock, green is the frame sync pulse, and magenta is the data. I'm sending 0, 1, 2, 3. I indicated with the vertical marker where the end of the data occurs.
  • Hello,

    First of all, the Mcbsp will constantly clock regardless of data being available to be sent. Have you considered using the McBSP in SPI mode? Do you require a pulse on FSX, or will it be more like a SPI Frame where the CS must be driven low in between frames?

    From what you are describing, you require a single frame with 4 words transmitted. Please set the SRGR2.FSGM bit to 1. This will generate a FSX pulse based on the Sample Rate Generator rather than the content being copied from the DXR to the XSR. Program FPER to 63 (64 cycles -1) for the period between frame sync pulses.

    I think your idea of stopping the clock in between frames will work, but you will get extra pulses on either side of the transmission and there is no guarantee that the clock will be forced inactive low. If you truly want the clock to stop in between transmissions, look into the SPI mode (Clock Stop Mode) if you can live with not having the FSX pulse between frames.

    Thanks,
    Mark
  • Thanks for your reply. I will look in to SPI mode and try your suggestions.
  • I would like to amend my statement. 

    In SPI mode, the McBSP will pulse the FSX pin between every word transferred. this is similar to what you are seeing already with McBSP mode. If you require the FSX pin to be low throughout the entire frame, you can use a GPIO and manually control it in SW.

    -Mark