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.

OMAPL138, C6748 McBSP示例程序。

由于EVM板的BSL没有提供McBSP样例(因为EVM板上的AIC codec是接在McASP口上的),而很多用户有同样的需求。所以写了这么一个简单的McBSP接口的中断例程。

由于EVM板上没有外设与McBSP相连,所以配置为内部产生帧同步,时钟(频率随便配了一个),这仅是一个接口使用的例子,听不到声音的。

DSP_McBSP_demo_edma_works.zip
  • hi,

       能否通过邮件形式提供下DSP_McBSP_demo.zip,此处没法下载。

       请发送到:uijinnomichi@gmail.com

  • 谢谢!

    最近在调试 mcbsp_test 驱动的时候,发现word_len为8,frame_len为8或16时都正常,但frame_len如果>=32会出现发送错误,按照“MODULE_PARM_DESC(frame_len, "Frame Length: 1-128 (default:2)");”的说明,frame_len应该可以达到128的,请教下这会什么原因呢,有什么解决方法或思路吗?关于mcbsp驱动编写请做些指导。

    源代码如下

    #include <linux/module.h>
    #include <linux/init.h>
    #include <linux/errno.h>
    #include <linux/types.h>
    #include <linux/interrupt.h>
    #include <linux/io.h>
    #include <linux/moduleparam.h>
    #include <linux/sysctl.h>
    #include <linux/mm.h>
    #include <linux/dma-mapping.h>
    #include <linux/delay.h>

    #include <mach/memory.h>
    #include <mach/hardware.h>
    #include <mach/irqs.h>
    #include <mach/edma.h>
    #include <mach/mcbsp.h>

    static dma_addr_t physsrc = 0;
    static char *bufsrc = NULL;
    static dma_addr_t physdest = 0;
    static char *bufdest = NULL;

    static int device_id = 1;
    static int buf_size = (1 * 1024);
    static int buf_fmt = 0;
    static int num_pkts = 1;
    static int word_len = 8;
    static int frame_len = 32;
    static int freq = 48000;
    static bool dlb = 1;
    static int numevt = 0;
    static int mc_mode = 0;
    static int master = 1;
    static int tx_rx = 3;

    module_param(device_id, int, S_IRUGO);
    module_param(buf_size, int, S_IRUGO);
    module_param(buf_fmt, int, S_IRUGO);
    module_param(num_pkts, int, S_IRUGO);
    module_param(word_len, int, S_IRUGO);
    module_param(frame_len, int, S_IRUGO);
    module_param(freq, int, S_IRUGO);
    module_param(dlb, bool, S_IRUGO);
    module_param(numevt, int, S_IRUGO);
    module_param(mc_mode, int, S_IRUGO);
    module_param(master, int, S_IRUGO);
    module_param(tx_rx, int, S_IRUGO);

    MODULE_PARM_DESC(device_id, "McBSP instance (default:1)");
    MODULE_PARM_DESC(buf_size, "Buffer Size (default:1KB)");
    MODULE_PARM_DESC(buf_fmt, "Buffer format (default:Interleaved)");
    MODULE_PARM_DESC(buf_size, "Packet count (default:1)");
    MODULE_PARM_DESC(word_len, "Word Length: 8, 16, 24, 32 bits (default:32)");
    MODULE_PARM_DESC(frame_len, "Frame Length: 1-128 (default:2)");
    MODULE_PARM_DESC(freq, "Sample Frequency (default:48kHz)");
    MODULE_PARM_DESC(dlb, "Digital Loopback (default: disabled)");
    MODULE_PARM_DESC(numevt, "NUMEVT (default: 0)");
    MODULE_PARM_DESC(mc_mode, "Multi-channel mode (default: 0)");
    MODULE_PARM_DESC(master, "Master/Slave mode (default: master)");
    MODULE_PARM_DESC(tx_rx, "Transmit, Receive or both (default: both)");

    static int __init mcbsp_test_init(void)
    {
     struct davinci_mcbsp_dev *dev = NULL;
     int i;
     int loopcnt = 0;
     int errcnt;

     if (tx_rx & 0x01) {
      bufsrc = dma_alloc_coherent(NULL, buf_size, &physsrc, 0);
      if (!bufsrc) {
       printk ("dma_alloc_coherent failed for physsrc\n");
       return -ENOMEM;
      }

      for (i = 0; i < buf_size; i++)
       bufsrc[i] = i % 256;
     }

     if (tx_rx & 0x02) {
      bufdest = dma_alloc_coherent(NULL, buf_size, &physdest, 0);
      if (!bufdest) {
       printk ("dma_alloc_coherent failed for physdest\n");
       return -ENOMEM;
      }
     }

     printk("Starting McBSP test\n");
     davinci_mcbsp_request(device_id, &dev);
     do {
      /* configure rcr and xcr */
      dev->tx_params.word_length1 = word_len; /* 32 bits */
      dev->tx_params.frame_length1 = frame_len;

      dev->rx_params.word_length1 = word_len; /* 32 bits */
      dev->rx_params.frame_length1 = frame_len;

      dev->rx_params.buf_fmt = buf_fmt;
      dev->tx_params.buf_fmt = buf_fmt;

      if (mc_mode > 0  && mc_mode < 8) {
       dev->rx_params.intr_mode = 1;
       dev->tx_params.intr_mode = 1;
      }

      davinci_mcbsp_config_params(dev, master);

      /* sample rate generator conifguration */
      davinci_mcbsp_config_clock(dev, freq);

      dev->tx_params.numevt = numevt;
      dev->rx_params.numevt = numevt;
      dev->tx_params.numdma = 1;
      dev->rx_params.numdma = 1;
      davinci_mcbsp_config_fifo(dev);


      dev->tx_params.mc_mode = mc_mode;
      dev->rx_params.mc_mode = mc_mode;

      dev->tx_params.cer[0] = 0x5555;
      dev->tx_params.cer[1] = 0x5555;
      dev->tx_params.cer[2] = 0x5555;
      dev->tx_params.cer[3] = 0x5555;
      dev->tx_params.cer[4] = 0x5555;
      dev->tx_params.cer[5] = 0x5555;
      dev->tx_params.cer[6] = 0x5555;
      dev->tx_params.cer[7] = 0x5555;

      dev->rx_params.cer[0] = 0x5555;
      dev->rx_params.cer[1] = 0x5555;
      dev->rx_params.cer[2] = 0x5555;
      dev->rx_params.cer[3] = 0x5555;
      dev->rx_params.cer[4] = 0x5555;
      dev->rx_params.cer[5] = 0x5555;
      dev->rx_params.cer[6] = 0x5555;
      dev->rx_params.cer[7] = 0x5555;

      davinci_mcbsp_config_multichannel_mode(dev);

      /* DMA Mode */
      dev->op_mode = DAVINCI_MCBSP_DMA_MODE;
      if (dlb) {
       printk("Setting DLB mode \n");
       dev->op_mode |= DAVINCI_MCBSP_DLB_MODE;
      } else {
       printk("No DLB mode \n");
      }

      if (tx_rx & 0x01) {
       printk("Transmitting Packet %d\n", loopcnt + 1);
       for (i = 0; i < buf_size; i++)
        bufsrc[i] = (i + loopcnt) % 256;

       printk("Starting McBSP TX\n");
       davinci_mcbsp_start_tx(dev);
      }

      if (tx_rx & 0x02) {
       printk("Starting McBSP RX\n");
       davinci_mcbsp_start_rx(dev);
      }

      printk("McBSP started\n");
      if (tx_rx & 0x02) {
       printk("Receving data...\n");
       davinci_mcbsp_recv_buf(dev, physdest, buf_size);
      }

      if (tx_rx & 0x01) {
       printk("Transmitting data...\n");
       davinci_mcbsp_xmit_buf(dev, physsrc, buf_size);
      }

      if (dev->op_mode & DAVINCI_MCBSP_DLB_MODE) {
       wait_for_completion(&dev->tx_params.dma_completion);
       printk("...TX complete\n");
       wait_for_completion(&dev->rx_params.dma_completion);
       printk("...RX complete\n");
      }

      if (tx_rx & 0x01) {
       davinci_mcbsp_stop_tx(dev);
       printk("TX stopped\n");
      }

      if (tx_rx & 0x02) {
       davinci_mcbsp_stop_rx(dev);
       printk("RX stopped\n");
      }

      if (tx_rx & 0x02 || (dev->op_mode & DAVINCI_MCBSP_DLB_MODE)) {
       printk("Testing data integrity for Packet %d: ", loopcnt + 1);
       errcnt = 0;
       for (i = 0; i < buf_size; i++) {
        if (bufdest[i] != ((i + loopcnt) % 256)) {
         errcnt = i + 1;
         break;
        }
       }

       if (errcnt) {
    #if 1 /* debug */
        for (i = 0; i < buf_size; i++) {
         if (!(i % 10))
          printk("\nbufdest[%d]: ", i);
         printk("%d\t", bufdest[i]);
        }
        printk("\n");
    #endif
        printk("Error found at Byte %d location\n", errcnt);
        davinci_mcbsp_dump_reg(dev);

       } else
        printk("Passed\n");

       memset(bufdest, 0 , buf_size);
      } else {
       mdelay(100);
       /* more time to compare data for large buffers */
       if (buf_size > 16 * 1024)
        mdelay(1000);
       if (buf_size >= 32 * 1024)
        mdelay(1000);
      }

      printk("-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.");
      printk("-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.\n");

     } while (++loopcnt < num_pkts);

    #if 0 /* debug */
     davinci_mcbsp_dump_reg(dev);
    #endif
     return 0;
    }

    static void mcbsp_test_exit(void)
    {
     davinci_mcbsp_free(device_id);
     if (tx_rx & 0x01)
      dma_free_coherent(NULL, buf_size, bufsrc, physsrc);

     if (tx_rx & 0x02)
      dma_free_coherent(NULL, buf_size , bufdest, physdest);

     printk("McBSP test done... exiting\n");
    }
    module_init(mcbsp_test_init);
    module_exit(mcbsp_test_exit);

    MODULE_AUTHOR("Texas Instruments");
    MODULE_LICENSE("GPL");

  • 最近调试MCBSP的DLB模式,发现发送数据出现这种现象

    发送     0xAAAA          1                 2               3          4       5         6        7........

    接收      0xAAAA    0xAAAA     0xAAAA          1          2       3        4        5........

    而且SPCR参数中的值为0x03C38007,即RFULL一直为1。上面的现象与手册中的描述如附件图所示。如何才能解决这种现象呢?

  • 你好,我用你的例子,l138为主fpga为从,时钟用外部时钟,出现的问题是当发送一次后,那个数会连续的一直发,外部时钟需要停止吗?

  • McBSP使能后是由帧同步触发的,所以当外部时钟存在时,McBSP会一直工作。

    停止外部时钟或者disable McBSP。

x 出现错误。请重试或与管理员联系。
x 出现错误。请重试或与管理员联系。