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.

发送状态寄存器XSTAT的XDATA字段一直为0

Other Parts Discussed in Thread: TMS320DM642, TLV320AIC23B

        通过DSP向音频芯片TLV320AIC23B发送数据,从而实现声音的播放。DSP选型为TMS320DM642,DSP与AIC23B通过DM642的音频端口McASP进行连接。设计中使用1片AIC23B,设计的目的是通过McASP的AXR[0](设计中AXR[0]引脚配置为输出,发送数据)向AIC23B发送数据从而达到AIC23B输出报警声的目的。具体到实程序设计中就是查询XSTATE寄存器中的XDATA字段:若XDATA为1,向XBUF[0]发送新的数据;否则进行等待。

        在调试的过程中发现在对McASP进行配置并第一次写入数据后,XDATA字段就一直为0(XSTAT的值一直为155H或15DH),使得后续数据不能写入。不知道哪位大神遇到过类似的情况,能告知问题的所在和解决方案。

       最后附注一下:设计中的TLV320AIC23B工作在主模式下,位时钟和帧信号由AIC23B生成。在McASP配置前,利用I2C接口对AIC23B进行寄存器配置。通过示波器对位时钟和帧信号进行测试,显示AIC23B的配置是有效的。

  • 你的问题是第一次McASP能发送数据,后面就不能发送了?XSTAT一直为0?

  •        是的!McASP配置后只能写一次数据,XSTAT寄存器的之后XDATA字段一直为0,但是整个XSTAT的值为155H或者15DH。而且我发现McASP口利用MCASP_OPEN()打开后,XSTAT寄存器的值为10CH(根据我的理解,打开后该寄存器难道不应该为0000H吗?)。

  • XUNDRN置位了:underrun,表示没有及时给数,同时XDATA又不置1,是不是使能了不只一条数据线,但只送了一次数据?

  • 没有啊!我在MCASP_ConfigSrctl结构体中只激活了作为数据发送的SRCTL0和作为数据接收的SRCTL0。

  • 上面说错了,是作为数据发送的SRCTL0和作为数据接收的SRCTL1。

  • 检查一下是否按照下面McASP user guide上的步骤配置的。

    3.1.1 Transmit/Receive Section Initialization
    http://www.ti.com/lit/ug/spru041j/spru041j.pdf
     

  • 给你看一下我的配置过程:

    MCASP_ConfigGbl mcaspCfgDataGbl = {
    0x00000000, // PFUNC - All pins as McASP ,所有的管脚均为McAPS功能
    0x00000001, // PDIR - 0,2,4,6 transmit,为output;1,3,5,7 receive,为input
    0x00000000, // DITCTL - DIT mode disable
    0x00000000, // DLBCTL - Loopback disabled
    0x00000000 // AMUTE - Never drive AMUTE
    };

    MCASP_ConfigRcv mcaspCfgDataRcv = {
    0xffffffff, // RMASK - Use all 32 bits,左声道与右声道各16位
    0x00018078, // RFMT - 1bit 延时,高位在前,0填充,slot为16位,配置总线读数据
    0x00000200, // AFSRCTL - TDM模式,4 slots,帧同步高电平为1bit,外部帧同步信号输入,帧信号上升沿表明帧开始
    0x00000080, // ACLKRCTL - 接收器在串行时钟上升沿采集数据,外部输入接收时钟
    0x00000000, // AHCLKRCTL - 外部高频时钟
    0x00000003, // RTDM - slot0,1 active
    0x00000000, // RINTCTL - interrupts disable
    0x00000000 // RCLKCHK - Not used
    };

    MCASP_ConfigXmt mcaspCfgDataXmt = {
    0xffffffff, // XMASK - Use all 32 bits,左声道与右声道各16位
    0x00018078, // XFMT - 1bit 延时,高位在前,0填充,slot为16位,配置总线写数据
    0x00000200, // AFSXCTL - TDM模式,4 slots,帧同步高电平为1bit,外部帧同步信号输入,帧信号上升沿表明帧开始
    0x000000c0, // ACLKXCTL - 发送器在串行时钟的下降沿发送数据,发送与接收异步,外部输入发送时钟
    0x00000000, // AHCLKXCTL - 外部高频时钟
    0x00000003, // XTDM - slot0,1 active
    0x00000000, // XINTCTL - interrupts disable
    0x00000000 // XCLKCHK - Not used
    };

    MCASP_ConfigSrctl mcaspCfgDataSrctl = {
    0x0000000d, // SRCTL0 - transmit, active high
    0x0000000e, // SRCTL1 - receive, active high
    0x00000000, // SRCTL2 - transmit
    0x00000000, // SRCTL3 - receive
    0x00000000, // SRCTL4 - transmit
    0x00000000, // SRCTL5 - receive
    0x00000000, // SRCTL6 - transmit
    0x00000000 // SRCTL7 - receive
    };

    MCASP_Handle VMD642_AIC23_openCodec()
    {
    Uint32 regval=0xffff;
    MCASP_Handle hMcasp;
    //打开McASP端口
    hMcasp = MCASP_open(MCASP_DEV0, MCASP_OPEN_RESET);
    //下面开始按照McASP端口初始化步骤配置McASP
    //step1:通过设置GBLCTL=0使McASP复位到默认值
    MCASP_reset(hMcasp);

    //step2:配置除了GBLCTL外的McASP寄存器
    // MCASP_config(hMcasp,&mcaspCfgData);
    MCASP_configRcv(hMcasp, &mcaspCfgDataRcv);
    MCASP_configXmt(hMcasp, &mcaspCfgDataXmt);
    MCASP_configSrctl(hMcasp, &mcaspCfgDataSrctl);
    MCASP_configGbl(hMcasp, &mcaspCfgDataGbl);


    //step3:启动相应的高频串行时钟AHCLKX和/或AHCLKR并进行回读检查
    //不管使用外部还是内部产生高频时钟,该步都是必须的
    MCASP_enableHclk(hMcasp,MCASP_XMTRCV);
    while(!MCASP_FGETH(hMcasp, GBLCTL, XHCLKRST));
    while(!MCASP_FGETH(hMcasp, GBLCTL, RHCLKRST));

    //step4:启动相应的串行时钟ACLKX和/或ACLKR并进行回读检查
    //如果使用外部时钟,该步可以忽略
    MCASP_enableClk(hMcasp,MCASP_XMTRCV);
    while(!MCASP_FGETH(hMcasp, GBLCTL, XCLKRST));
    while(!MCASP_FGETH(hMcasp, GBLCTL, RCLKRST));

    //step5:根据需要设置数据获取方式
    //本程序使用CPU查询方式,该步可以忽略;其他方式需要进行设置

    //step6:激活串行器
    //a.开始前,通过向XSTAT和RSTAT寄存器写FFFFH达到清零发送和接收状态寄存器的目的
    /*********************************
    MCASP_RSETH(hMcasp,XSTAT,0xFFFF);
    MCASP_RSETH(hMcasp,RSTAT,0xFFFF);
    **********************************/
    *((unsigned long *)(0x01B4C0C0)) =regval;
    *((unsigned long *)(0x01B4C080)) =regval;
    //MCASP_FSETH(hMcasp ,XSTAT ,XERR ,1);
    //MCASP_FSETH(hMcasp ,XSTAT ,XDMAERR ,1);
    //MCASP_FSETH(hMcasp ,XSTAT ,XSTAFRM ,1);
    //MCASP_FSETH(hMcasp ,XSTAT ,XDATA ,1);
    //MCASP_FSETH(hMcasp ,XSTAT ,XLAST ,1);
    //MCASP_FSETH(hMcasp ,XSTAT ,XTDMSLOT ,1);
    //MCASP_FSETH(hMcasp ,XSTAT ,XCKFAIL ,1);
    //MCASP_FSETH(hMcasp ,XSTAT ,XSYNCERR ,1);
    //MCASP_FSETH(hMcasp ,XSTAT ,XUNDRN ,1);
    //b.激活相应的发送和接收串行器并进行回读检查
    MCASP_enableSers(hMcasp, MCASP_XMTRCV);
    while(!MCASP_FGETH(hMcasp, GBLCTL, XSRCLR));
    while(!MCASP_FGETH(hMcasp, GBLCTL, RSRCLR));

    //step7:验证发送串行在工作状态
    //发送串行器一旦激活,XSTAT寄存器中的XDATA字段被置位,表明串行缓冲区为空,等待数据的写入
    while(!MCASP_FGETH(hMcasp, XSTAT, XDATA));
    //如果使用CPU查询方式,XBUF应当在这步写入数据
    //MCASP_RSETH(hMcasp, XBUF0, 5000);

    //step8:激活状态机并回读检查
    MCASP_enableSm(hMcasp,MCASP_XMTRCV);
    while(!MCASP_FGETH(hMcasp, GBLCTL, XSMRST));
    while(!MCASP_FGETH(hMcasp, GBLCTL, RSMRST));

    //step9:激活帧同步产生器并回读检查
    //即使帧同步信号由外部输入,该步也是必须的
    MCASP_enableFsync(hMcasp,MCASP_XMTRCV);
    while(!MCASP_FGETH(hMcasp, GBLCTL, XFRST));
    while(!MCASP_FGETH(hMcasp, GBLCTL, RFRST));

    //返回McASP模块句柄
    return hMcasp;
    }