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.

McBSP



用McBSP采集AD的信号,CLKR,DR,FSR都由AD芯片产生输入给C6748,请问这样采样率发生器还需要使用么?TI有没有类似的历程啊?

  • CLKR, FSR都由外部提供的话,采样发生器就不需要了。

  • 有没有例程啊?为什么DRR寄存器有时候可以接收到数据,有时候接收不到啊?

  • 这方面的例程没有。

    可以量一下时序看是AD没发出来还是DSP这边收有问题。

  • AD数据时钟和数据都发出来了,是DSP这边接收不到………………

  • 检查一下收不到数据时,RRDY标志位是否置1?

  • 是的,RRDY一直置1,读取也不清除RRDY什么原因啊?

  • 有没有发生overrun? RFULL=1?

  • 是的,RFULL=1。偶尔DRR可以接收,有时候就接收不到,不能接收时RRDY=1,RFULL=1

  • 有使用FIFO收吗?

  • 没有使用FIFO,现在就是我我把外部AD信号线拔了,RFULL和RRDY都是1(YES)

  • 你是说没有A/D发送数据给DSP, RRDY, RFULL也会置1?

    有没有试过DLB自环模式?

  • 刚说错了,是在C6748运行时,拔掉数据线,RRDY, RFULL一直置1,拔掉线重启就清零了,每次只接受一个数据,然后RRDY就一直置1,无法采数了

  • overrun是来不及接收数据导致的。使能一下FIFO或者EDMA看看。

  • 恩恩,我就是用edma3进行数据接收哒

  • 这是程序,您看看是不是哪里少了设置,还是设置错了?

    /*

    * main.c
    *
    * Created on: 2016-8-15
    * Author: s52
    */
    #include "hw_psc_C6748.h"
    #include "uartStdio.h"
    #include "edma.h"
    #include "psc.h"
    #include "main.h"
    #include "hw_types.h" // 宏命令
    #include "hw_syscfg0_C6748.h" // 系统配置模块寄存器
    #include "soc_C6748.h" // DSP C6748 外设寄存器
    #include "psc.h" // 电源与睡眠控制宏及设备抽象层函数声明
    #include "gpio.h" // 通用输入输出口宏及设备抽象层函数声明
    #include "interrupt.h" // DSP C6748 中断相关应用程序接口函数声明及系统事件号定义
    #include "hw_mcbsp.h" // MCBSP相关的宏
    #include "uartStdio.h" // 串口标准输入输出终端函数声明
    #include "edma_event.h"

    #define MAX_ACOUNT (4u) // 最大 ACOUNT
    #define MAX_BCOUNT (2u) // 最大 BCOUNT
    #define MAX_CCOUNT (500u) // 最大 CCOUNT
    #define MAX_BUFFER_SIZE (MAX_ACOUNT * MAX_BCOUNT * MAX_CCOUNT/4)
    #define CHTYPE_DMA // 使用 DMA
    #define SW_BREAKPOINT asm(" SWBP 0 ");// 软件断点
    volatile int irqRaised;

    // 参数
    unsigned int chType = EDMA3_CHANNEL_TYPE_DMA;
    unsigned int chNum = EDMA3_CHA_MCBSP0_RX;
    unsigned int tccNum = EDMA3_CHA_MCBSP0_RX;
    unsigned int edmaTC = 0;
    unsigned int syncType = EDMA3_SYNC_A;
    unsigned int trigMode = EDMA3_TRIG_MODE_EVENT;
    unsigned int evtQ = 0; // 使用的事件队列


    volatile unsigned int _dstBuff0[MAX_BUFFER_SIZE];

    volatile unsigned int *srcBuff;
    volatile unsigned int *dstBuff0;

    void EDMA3InterruptInit(void);
    void InterruptInit(void);
    void EDMA3CCComplIsr(void);
    void EDMA3CCErrIsr(void);
    void InterruptInit(void);
    void McBSP0Init(void);// McBSP 初始化

    // McBSP 事件接受函数
    static void McBSPReceiveData(unsigned int tccNum, unsigned int chNum,volatile unsigned int *buffer);

    unsigned char i = 0;
    unsigned char j = 0;
    unsigned int z = 0;

    void (*cb_Fxn[EDMA3_NUM_TCC])(unsigned int tcc, unsigned int status, void *appData); // 回调函数
    /* 回调函数 */
    void callback(unsigned int tccNum, unsigned int status, void *appData)
    {
    (void)tccNum;
    (void)appData;

    if(EDMA3_XFER_COMPLETE == status)
    {
    irqRaised = 1; // 传输成功
    }
    else if(EDMA3_CC_DMA_EVT_MISS == status)
    {
    irqRaised = -1; // 传输导致 DMA 事件丢失错误
    }
    else if(EDMA3_CC_QDMA_EVT_MISS == status)
    {
    irqRaised = -2; // 传输导致 QDMA 事件丢失错误
    }

    }

    void PSCInit(void)
    {
    PSCModuleControl(SOC_PSC_0_REGS, 0, 0, PSC_MDCTL_NEXT_ENABLE); // 使能 EDMA3CC_0
    PSCModuleControl(SOC_PSC_0_REGS, 1, 0, PSC_MDCTL_NEXT_ENABLE); // 使能 EDMA3TC_0
    PSCModuleControl(SOC_PSC_1_REGS, HW_PSC_MCBSP0, PSC_POWERDOMAIN_ALWAYS_ON, PSC_MDCTL_NEXT_ENABLE);
    SYSCFG0Regs.PINMUX2.all=0x02222220; // McBSP 管脚复用配置
    }
    int main(void)
    {
    for(z = 0; z < 1000; z++)
    {
    _dstBuff0[z] = 100+z;

    }
    dstBuff0 =_dstBuff0;


    volatile unsigned int status = FALSE;
    PSCInit();
    UARTStdioInit();
    InterruptInit();
    UARTPuts("Tronlong EDMA / QDMA Application......\r\n\r\n", -1);

    EDMA3Init(SOC_EDMA30CC_0_REGS, evtQ);
    EDMA3InterruptInit();

    //EDMA3RequestChannel(SOC_EDMA30CC_0_REGS, EDMA3_CHANNEL_TYPE_DMA,EDMA3_CHA_MCBSP0_TX, EDMA3_CHA_MCBSP0_TX, evtQ);

    // cb_Fxn[EDMA3_CHA_MCBSP0_TX] = &callback;

    //McBSPTransmitData(EDMA3_CHA_MCBSP0_TX, EDMA3_CHA_MCBSP0_TX,srcBuff, MAX_BCOUNT);

    //EDMA3EnableDmaEvt(SOC_EDMA30CC_0_REGS,EDMA3_CHA_MCBSP0_TX);

    EDMA3RequestChannel(SOC_EDMA30CC_0_REGS, EDMA3_CHANNEL_TYPE_DMA, EDMA3_CHA_MCBSP0_RX, EDMA3_CHA_MCBSP0_RX,evtQ);

    cb_Fxn[EDMA3_CHA_MCBSP0_RX] = &callback;

    McBSPReceiveData(EDMA3_CHA_MCBSP0_RX, EDMA3_CHA_MCBSP0_RX,dstBuff0);

    EDMA3EnableDmaEvt(SOC_EDMA30CC_0_REGS,EDMA3_CHA_MCBSP0_RX);

    McBSP0Init(); // MCBSP 控制器初始化

    //EDMA3Deinit(SOC_EDMA30CC_0_REGS, evtQ);
    for(z = 0; z < 100; z++)
    {
    UARTprintf("%d\r\n", _dstBuff0[z]);
    }

    while(1)
    {

    }
    }

    static void McBSPReceiveData(unsigned int tccNum, unsigned int chNum,
    volatile unsigned int *buffer)
    {

    //Parameter 64
    *(unsigned int *)0x01c04800 = 0x0010D004;
    *(unsigned int *)0x01c04804 = 0x01D10000;
    *(unsigned int *)0x01c04808 = (2<<16|4);
    *(unsigned int *)0x01c0480c = (unsigned int) buffer;
    *(unsigned int *)0x01c04810 = (4000<<16|0);
    *(unsigned int *)0x01c04814 = ((2<<16)|0x4820);
    *(unsigned int *)0x01c04818 = ((4<<16)|0);
    *(unsigned int *)0x01c0481c = 500;

    //Parameter 65
    *(unsigned int *)0x01c04820 = 0x0010D004;
    *(unsigned int *)0x01c04824 =0x01D10000;
    *(unsigned int *)0x01c04828 = ((2<<16)|4);
    *(unsigned int *)0x01c0482c = (unsigned int) buffer;
    *(unsigned int *)0x01c04820 = ((4000<<16)|0);
    *(unsigned int *)0x01c04824 = ((2<<16)|0x4800);
    *(unsigned int *)0x01c04828 = ((4<<16)|0);
    *(unsigned int *)0x01c0482c = 500;

    EDMA3CCPaRAMEntry paramSet;

    /* Fill the PaRAM Set with transfer specific information */
    paramSet.srcAddr = 0x01D10000; //McBSP DRR寄存器地址
    paramSet.destAddr = (unsigned int) buffer;
    paramSet.aCnt = MAX_ACOUNT;
    paramSet.bCnt = MAX_BCOUNT;
    paramSet.cCnt = MAX_CCOUNT;

    /* The src index should not be increment since it is a h/w register*/
    paramSet.srcBIdx = 0;
    /* The dest index should incremented for every byte */
    paramSet.destBIdx = 4000;

    /* A sync Transfer Mode */
    paramSet.srcCIdx = 0;
    paramSet.destCIdx =4;
    paramSet.linkAddr = (unsigned short)0x4800u;
    paramSet.bCntReload = 2;
    paramSet.opt=0x0010D004;
    /*
    paramSet.opt = 0x00000000u;
    paramSet.opt |= ((EDMA3CC_OPT_SAM) << EDMA3CC_OPT_SAM_SHIFT);
    paramSet.opt |= ((tccNum << EDMA3CC_OPT_TCC_SHIFT) & EDMA3CC_OPT_TCC);
    paramSet.opt |= (1 << EDMA3CC_OPT_TCINTEN_SHIFT);*/

    /* Now write the PaRAM Set */
    EDMA3SetPaRAM(SOC_EDMA30CC_0_REGS, chNum, &paramSet);

    /* Enable EDMA Transfer */
    EDMA3EnableTransfer(SOC_EDMA30CC_0_REGS, chNum, EDMA3_TRIG_MODE_EVENT);
    }


    /* EDMA3 中断初始化 */

    void EDMA3InterruptInit()
    {
    // 传输完成中断
    IntRegister(C674X_MASK_INT4, EDMA3CCComplIsr);
    IntEventMap(C674X_MASK_INT4, SYS_INT_EDMA3_0_CC0_INT1);
    IntEnable(C674X_MASK_INT4);

    // 传输错误中断
    IntRegister(C674X_MASK_INT5, EDMA3CCErrIsr);
    IntEventMap(C674X_MASK_INT5, SYS_INT_EDMA3_0_CC0_ERRINT);
    IntEnable(C674X_MASK_INT5);
    }

    /* EDMA3 中断完成服务函数 */

    void EDMA3CCComplIsr()
    {
    volatile unsigned int pendingIrqs;
    volatile unsigned int isIPR = 0;

    unsigned int indexl;
    unsigned int Cnt = 0;
    indexl = 1u;

    IntEventClear(SYS_INT_EDMA3_0_CC0_INT1);

    isIPR = EDMA3GetIntrStatus(SOC_EDMA30CC_0_REGS);
    if(isIPR)
    {
    while ((Cnt < EDMA3CC_COMPL_HANDLER_RETRY_COUNT)&& (indexl != 0u))
    {
    indexl = 0u;
    pendingIrqs = EDMA3GetIntrStatus(SOC_EDMA30CC_0_REGS);
    while (pendingIrqs)
    {
    if(TRUE == (pendingIrqs & 1u))
    {
    // 如果没有指定回调函数 就无法清除 IPR 相应位
    // 写 ICR 清除 IPR 相应位
    EDMA3ClrIntr(SOC_EDMA30CC_0_REGS, indexl);
    (*cb_Fxn[indexl])(indexl, EDMA3_XFER_COMPLETE, NULL);
    }

    ++indexl;
    pendingIrqs >>= 1u;
    }

    Cnt++;
    }
    }
    }

    /****************************************************************************/
    /* */
    /* EDMA3 中断错误服务函数 */
    /* */
    /****************************************************************************/
    void EDMA3CCErrIsr()
    {
    volatile unsigned int pendingIrqs;
    unsigned int Cnt = 0u;
    unsigned int index;
    unsigned int evtqueNum = 0; // 事件队列数目

    pendingIrqs = 0u;
    index = 1u;

    IntEventClear(SYS_INT_EDMA3_0_CC0_ERRINT);

    if((EDMA3GetErrIntrStatus(SOC_EDMA30CC_0_REGS) != 0 )
    || (EDMA3QdmaGetErrIntrStatus(SOC_EDMA30CC_0_REGS) != 0)
    || (EDMA3GetCCErrStatus(SOC_EDMA30CC_0_REGS) != 0))
    {
    // 循环 EDMA3CC_ERR_HANDLER_RETRY_COUNT 次
    // 直到没有等待中的中断时终止
    while ((Cnt < EDMA3CC_ERR_HANDLER_RETRY_COUNT) && (index != 0u))
    {
    index = 0u;
    pendingIrqs = EDMA3GetErrIntrStatus(SOC_EDMA30CC_0_REGS);

    while (pendingIrqs)
    {
    // 执行所有等待中的中断
    if(TRUE == (pendingIrqs & 1u))
    {
    // 清除 SER
    EDMA3ClrMissEvt(SOC_EDMA30CC_0_REGS, index);
    }
    ++index;
    pendingIrqs >>= 1u;
    }

    index = 0u;
    pendingIrqs = EDMA3QdmaGetErrIntrStatus(SOC_EDMA30CC_0_REGS);

    while (pendingIrqs)
    {
    // 执行所有等待中的中断
    if(TRUE == (pendingIrqs & 1u))
    {
    // 清除 SER
    EDMA3QdmaClrMissEvt(SOC_EDMA30CC_0_REGS, index);
    }
    ++index;
    pendingIrqs >>= 1u;
    }

    index = 0u;
    pendingIrqs = EDMA3GetCCErrStatus(SOC_EDMA30CC_0_REGS);

    if (pendingIrqs != 0u)
    {
    // 执行所有等待中的 CC 错误中断
    // 事件队列 队列入口错误
    for (evtqueNum = 0u; evtqueNum < SOC_EDMA3_NUM_EVQUE; evtqueNum++)
    {
    if((pendingIrqs & (1u << evtqueNum)) != 0u)
    {
    // 清除错误中断
    EDMA3ClrCCErr(SOC_EDMA30CC_0_REGS, (1u << evtqueNum));
    }
    }

    // 传输完成错误
    if ((pendingIrqs & (1 << EDMA3CC_CCERR_TCCERR_SHIFT)) != 0u)
    {
    EDMA3ClrCCErr(SOC_EDMA30CC_0_REGS, (0x01u << EDMA3CC_CCERR_TCCERR_SHIFT));
    }

    ++index;
    }

    Cnt++;
    }
    }
    }

    /* DSP 中断初始化 */
    void InterruptInit(void)
    {
    IntDSPINTCInit();// 初始化 DSP 中断控制器
    IntGlobalEnable(); // 使能 DSP 全局中断
    }
    void McBSP0Init(void)
    {
    // McBSP0 串行口控制寄存器
    McBSP0Regs.SPCR.bit.FREE=1;
    McBSP0Regs.SPCR.bit.SOFT=1;

    // 禁用 FRST GRST XRST RRST
    McBSP0Regs.SPCR.bit.FRST=0;
    McBSP0Regs.SPCR.bit.GRST=0;
    McBSP0Regs.SPCR.bit.XRST=0;
    McBSP0Regs.SPCR.bit.RRST=0;

    // McBSP0 管脚控制寄存器
    McBSP0Regs.PCR.bit.FSXM=1;// 发送帧同步信号由内部采样率生成器输出
    McBSP0Regs.PCR.bit.FSRM=0;// 接收帧同步信号外部输入
    McBSP0Regs.PCR.bit.CLKXM=1;// 发送时钟信号由内部采样率生成器产生
    McBSP0Regs.PCR.bit.CLKRM=0;// 接收时钟信号由外部器件产生
    McBSP0Regs.PCR.bit.SCLKME=0;// 内部采样率生成器时钟信号由 McBSP 内部输入时钟产生(DSP 时钟频率 1/2)
    McBSP0Regs.PCR.bit.FSXP=0;// 发送帧同步信号高电平有效
    McBSP0Regs.PCR.bit.FSRP=0;// 接收帧同步信号高电平有效
    McBSP0Regs.PCR.bit.CLKXP=0;// 发送数据在时钟信号上降沿采样
    McBSP0Regs.PCR.bit.CLKRP=0;// 接收数据在时钟信号下降沿采样

    /*McBSP0 采样率生成寄存器
    McBSP0Regs.SRGR.bit.GSYNC=0; // 采样率生成寄存器自由运行
    McBSP0Regs.SRGR.bit.CLKSP=0;// CLKS上升沿产生CLKG和FSG
    McBSP0Regs.SRGR.bit.CLKSM=1; // 采样率生成器时钟信号由 McBSP 内部输入时钟产生(DSP 时钟频率 1/2)
    McBSP0Regs.SRGR.bit.FPER=63;// 指定帧周期值(+1) 一帧总共有64bit
    McBSP0Regs.SRGR.bit.FWID=31;// 指定帧宽度值(+1)
    McBSP0Regs.SRGR.bit.CLKGDV=227;// 采样率生成器时钟分频*/

    // McBSP0 接收控制寄存器
    McBSP0Regs.RCR.bit.RPHASE=1;// 多相位帧
    McBSP0Regs.RCR.bit.RFRLEN2=0; // 指定相位 2 接收帧长度(1个字)
    McBSP0Regs.RCR.bit.RWDLEN2=0x5;// 指定相位 2 接收字长度(32 位)
    McBSP0Regs.RCR.bit.RCOMPAND=0;// 无压缩 MSB(最高有效位)
    McBSP0Regs.RCR.bit.RFIG=1; // 忽略第一个接收帧同步脉冲
    McBSP0Regs.RCR.bit.RDATDLY=1;// 无接收数据延迟位
    McBSP0Regs.RCR.bit.RFRLEN1=0;// 指定相位 1 接收帧长度(1 个字)
    McBSP0Regs.RCR.bit.RWDLEN1=0x5;// 指定相位 1 接收字长度(32 位)
    McBSP0Regs.RCR.bit.RWDREVRS=0;// 无数据位倒置


    // 延时等待内部同步
    unsigned char i;
    for(i=0;i<100;i++)
    asm (" nop");

    McBSP0Regs.SPCR.bit.RRST=1; // 使能 接收
    for(i=0;i<100;i++)
    asm (" nop ");
    McBSP0Regs.SPCR.bit.FRST=1;// 使能 接收帧同步信号
    //McBSP0Regs.SPCR.bit.GRST=1;// 使能 内部采样率生成器
    // McBSP0Regs.SPCR.bit.XRST=1;// 使能 发送

    for(i=0;i<100;i++)
    asm (" nop ");
    }

  • 再把fifo使能,中断函数要尽量简单,不要做复杂的数据处理。