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.

OMAP3530 McBSP & TX DMA Problems

Other Parts Discussed in Thread: OMAP3530

Hi there,

I've been searching high and low for help on this but have reached a brick wall so to speak and am hoping someone out there can help!

I'm trying to use McBSP3 on the OMAP3530 to TX a bunch of data using the SDMA block and am having problems. I'm trying to run the example code given in

http://e2e.ti.com/support/dsp/omap_applications_processors/f/447/t/47984.aspx?PageIndex=3

specifically the TXRX example code but modified for use with McBSP3. I'm monitoring the RXBUFF1/2/3 and don't see anything changing. I noticed that the DMA_CCR14.ENABLE does not go high (ie, is not enabled) even after explicitly writing to it. It doesn't seem to like to be enabled when the MCBSPLP_SPCR2_REG.XRST is enabled?? If I do not set the XRST bit then the DMA_CCR14.ENABLE bit can be set but if XRST is enabled then it doesn't seem like I can set the DMA ENABLE bit. I checked the CSR register and don't see anything out of the ordinary.

I'm running this on Angstrom Linux but have modified the example code to support that. The TXRX code is below. I also had to 'fix' the original sample file mcbsp_lib.c/mcbspEnableFclk and mcbspEnableIClk --> SETBIT_REGL selects the wrong MCBSPs for MCBSP3 and MCBSP4.

I'm sure that I'm doing something stupid but I can't seem to figure it out....

Thanks in advance for any help.

Robin

-------

#include "MCBSP.h"
#include "PRCM.h"
#include "CONTROL.h"
#include "operations.h"
#include "mcbsp_lib.h"
#include "DMA.h"
#include "dma_lib.h"
#include <stdio.h>


#define MY_MCBSP  MCBSP3


int main (void)
{

  unsigned int loop;
  unsigned int read_data, read_data2;
  unsigned int RXBUFF1[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
  unsigned int RXBUFF2[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
  unsigned int RXBUFF3[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
  unsigned int TXBUFF1[16] = {0x1f,0x1e,0x1d,0x1c,0x1b,0x1a,0x19,0x18,0x17,0x16,0x15,0x14,0x13,0x12,0x11,0x10};
  unsigned int TXBUFF2[16] = {0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F};
  unsigned int allrxbuff[3] = {(unsigned int)&RXBUFF1[0], (unsigned int)&RXBUFF2[0], (unsigned int)&RXBUFF3[0]};
  unsigned int alltxbuff[2] = {(unsigned int)&TXBUFF1[0], (unsigned int)&TXBUFF2[0]};
  unsigned int i, j;

  // Setup the RX DMA - 3 buffers
  dmaSetCsdp(CHAN11, SRC_LITTLE_ENDIAN, SRC_ENDIAN_ADAPT, DST_LITTLE_ENDIAN, DST_ENDIAN_ADAPT,
             WRITE_POSTED, DST_NO_BURST, DST_UNPACKED, SRC_NO_BURST, SRC_UNPACKED, SCALAR_32BITS);
  dmaSetCsdp(CHAN12, SRC_LITTLE_ENDIAN, SRC_ENDIAN_ADAPT, DST_LITTLE_ENDIAN, DST_ENDIAN_ADAPT,
             WRITE_POSTED, DST_NO_BURST, DST_UNPACKED, SRC_NO_BURST, SRC_UNPACKED, SCALAR_32BITS);
  dmaSetCsdp(CHAN13, SRC_LITTLE_ENDIAN, SRC_ENDIAN_ADAPT, DST_LITTLE_ENDIAN, DST_ENDIAN_ADAPT,
             WRITE_POSTED, DST_NO_BURST, DST_UNPACKED, SRC_NO_BURST, SRC_UNPACKED, SCALAR_32BITS);
  dmaSetCcr(CHAN11, LOW_WR_PRIORITY, EN_BUFF, TRG_SRC, NO_PREFETCH, DIS_SUPER, DIS_TRANS_COPY, DIS_CONST_FILL,
            DST_AMODE_POST_INC, SRC_AMODE_CONST, DIS_SUSPEND, DIS_CHANNEL, LOW_RD_PRIORITY, TRANS_FRAME, DMA_MCBSP3_DMA_RX );
  dmaSetCcr(CHAN12, LOW_WR_PRIORITY, EN_BUFF, TRG_SRC, NO_PREFETCH, DIS_SUPER, DIS_TRANS_COPY, DIS_CONST_FILL,
            DST_AMODE_POST_INC, SRC_AMODE_CONST, DIS_SUSPEND, DIS_CHANNEL, LOW_RD_PRIORITY, TRANS_FRAME, DMA_MCBSP3_DMA_RX );
  dmaSetCcr(CHAN13, LOW_WR_PRIORITY, EN_BUFF, TRG_SRC, NO_PREFETCH, DIS_SUPER, DIS_TRANS_COPY, DIS_CONST_FILL,
            DST_AMODE_POST_INC, SRC_AMODE_CONST, DIS_SUSPEND, DIS_CHANNEL, LOW_RD_PRIORITY, TRANS_FRAME, DMA_MCBSP3_DMA_RX );
  dmaConfigTransfer(CHAN11, 16, 1, (MY_MCBSP+MCBSPLP_DRR_REG), (unsigned int)RXBUFF1, 1, 0, 1, 0);
  dmaConfigTransfer(CHAN12, 16, 1, (MY_MCBSP+MCBSPLP_DRR_REG), (unsigned int)RXBUFF2, 1, 0, 1, 0);
  dmaConfigTransfer(CHAN13, 16, 1, (MY_MCBSP+MCBSPLP_DRR_REG), (unsigned int)RXBUFF3, 1, 0, 1, 0);
  dmaSetChannelLink(CHAN11, CHAN12, EN_CHAN_LINK);
  dmaSetChannelLink(CHAN12, CHAN13, EN_CHAN_LINK);
  dmaSetChannelLink(CHAN13, CHAN11, EN_CHAN_LINK);
  dmaEnableChannel(CHAN11);

  // Setup the TX DMA - 2 buffers
  dmaSetCsdp(CHAN14, SRC_LITTLE_ENDIAN, SRC_ENDIAN_ADAPT, DST_LITTLE_ENDIAN, DST_ENDIAN_ADAPT,
             WRITE_POSTED, DST_NO_BURST, DST_UNPACKED, SRC_NO_BURST, SRC_UNPACKED, SCALAR_32BITS);
  dmaSetCcr(CHAN14, LOW_WR_PRIORITY, EN_BUFF, TRG_DEST, NO_PREFETCH, DIS_SUPER, DIS_TRANS_COPY, DIS_CONST_FILL,
            DST_AMODE_CONST, SRC_AMODE_POST_INC, DIS_SUSPEND, DIS_CHANNEL, LOW_RD_PRIORITY, TRANS_FRAME, DMA_MCBSP3_DMA_TX );
  dmaConfigTransfer(CHAN14, 16, 1, (unsigned int)TXBUFF1, (MY_MCBSP+MCBSPLP_DXR_REG), 1, 0, 1, 0);
  dmaSetChannelLink(CHAN14, CHAN15, EN_CHAN_LINK);

  dmaSetCsdp(CHAN15, SRC_LITTLE_ENDIAN, SRC_ENDIAN_ADAPT, DST_LITTLE_ENDIAN, DST_ENDIAN_ADAPT,
             WRITE_POSTED, DST_NO_BURST, DST_UNPACKED, SRC_NO_BURST, SRC_UNPACKED, SCALAR_32BITS);
  dmaSetCcr(CHAN15, LOW_WR_PRIORITY, EN_BUFF, TRG_DEST, NO_PREFETCH, DIS_SUPER, DIS_TRANS_COPY, DIS_CONST_FILL,
            DST_AMODE_CONST, SRC_AMODE_POST_INC, DIS_SUSPEND, DIS_CHANNEL, LOW_RD_PRIORITY, TRANS_FRAME, DMA_MCBSP3_DMA_TX );
  dmaConfigTransfer(CHAN15, 16, 1, (unsigned int)TXBUFF2, (MY_MCBSP+MCBSPLP_DXR_REG), 1, 0, 1, 0);

  // For this example, disable the automatic linking of channel 15 to channel 14 so that it will be easier to set a breakpoint
  // and view the changes to the RX buffers. Channel 14 will be enabled later as part of a continuious loop.

  //dmaSetChannelLink(CHAN15, CHAN14, EN_CHAN_LINK);
  //dmaEnableChannel(CHAN14);



  /////////////////////////////////////////////////////////////
  // Select clock sources and switch on Switch on the clocks
  cmEnableClock96M();
  mcbspEnableIclk(MY_MCBSP);
  mcbspSelectClksSource(MY_MCBSP, INTERNAL_FCLK);
  mcbspEnableFclk(MY_MCBSP);

  mcbspSet4Pin(MY_MCBSP);  // Sets McBSP1 to 4 pin mode.

  /////////////////////////////////////////////////////////////
  // reset module
  mcbspReset(MY_MCBSP, 1);

  /////////////////////////////////////////////////////////////
  // Configure transmitter and receiver
  mcbspSetRxMode(MY_MCBSP, CLK_EXTERNAL, CLKR_SAMPLE_FALL, SYNC_EXTERNAL, SYNC_ACTIVE_HIGH, FULL_CYCLE);
  mcbspSetTxMode(MY_MCBSP, CLK_INTERNAL, CLKX_DRIVE_RISE,  SYNC_INTERNAL, SYNC_ACTIVE_HIGH, HALF_CYCLE, DXENA_OFF, XCLK_FREE, FSX_GATED);

  /////////////////////////////////////////////////////////////
  // Set up frames
  mcbspRxFrameSetup(MY_MCBSP, SINGLE_PHASE, MSB_FIRST, DELAY_0BIT, 4, WORD_8BITS, 1, WORD_8BITS, RIGHT_JUST_ZERO);
  mcbspTxFrameSetup(MY_MCBSP, SINGLE_PHASE, MSB_FIRST, DELAY_0BIT, 4, WORD_8BITS, 1, WORD_8BITS);

  /////////////////////////////////////////////////////////////
  // Program the Sample Rate generator
  mcbspSetupSrg(MY_MCBSP, CLKS, CLKS_RISE, SRG_FREE, 32, 8, 255);

  /////////////////////////////////////////////////////////////
  // Configure the loopback
  mcbspLoopback(MY_MCBSP, DIGITAL_LOOPBACK);

  /////////////////////////////////////////////////////////////
  // Set the buffer thresholds
  mcbspSetRxThresh(MY_MCBSP, 16);
  mcbspSetTxThresh(MY_MCBSP, 16);
  mcbspEnableTxDma(MY_MCBSP);
  mcbspEnableRxDma(MY_MCBSP);

  /////////////////////////////////////////////////////////////
  // Delay to allow settings to sync
  //
  for (loop=0; loop <0XFF; loop++);

  /////////////////////////////////////////////////////////////
  // Configure the pins
  //
  OUT_REGL(CONTROL_PADCONF_MCBSP3_CLKX, 0x01080108);                       // 31:16 = mcbsp1_fsr         15:0 = mcbsp1_clkr
  OUT_REGL(CONTROL_PADCONF_MCBSP3_DX, 0x01080008);                           // 31:16 = mcbsp1_dr          15:0 = mcbsp1_dx

  /////////////////////////////////////////////////////////////
  // Remove Resets
  mcbspRemoveResetSrg(MY_MCBSP);
  mcbspRemoveResetFsg(MY_MCBSP);
  mcbspRemoveResetRx(MY_MCBSP);
  mcbspRemoveResetTx(MY_MCBSP);


// For each breakpoint halt you can observe 2 of the 3 RX buffers update with the TX data.
// The RX buffer updates will cycle through all 3 buffers.

  while (1) {
      read_data2 = IN_REGL(DMA_CSRi + (CHAN14 * 0x60));
      read_data = IN_REGL(DMA_CCRi + (CHAN14 * 0x60));
      dmaEnableChannel(CHAN14);
    printf("reg value is 0x%x (CSR = 0x%x)\n", (unsigned int)read_data, (unsigned int)read_data2);
      for (loop=0; loop <0XF; loop++)
      {

          printf("**************\n\n");
          // Set breakpoint here
          for (i=0; i<=2; i++)
          {
              for (j=0; j<=15; j++)
              {
                  printf("RXBUFF%d[%d] = 0x%x\n", i, j, ((unsigned int *)allrxbuff[i])[j]);
              }
                printf("-----------\n");
          }
/*
          printf("-----------\n");
          for (i=0; i<=1; i++)
          {
              for (j=0; j<=15; j++)
              {
                  printf("TXBUFF%d[%d] = 0x%x\n", i, j, ((unsigned int *)alltxbuff[i])[j]);
              }
          }

          getchar();
*/
      }
  }
}

  • FWIW I figured out the problem. It was a basic Linux issue with virtual memory addresses vs physical memory addresses. Basically, the buffers were allocated with virtual memory addresses, and (I'm assuming) the DMA blocks need physical memory addresses.