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.

5509A的MCBSP接口通信问题

感谢您查看我的问题贴,谢谢!

我在用DSP的5509A的mcbsp接口和FPGA做通信测试,测试过程是:

mcbsp1发送一个16bit的数据到fpga,mcbsp只发送不接收,只发送一次。

现在的问题出现在mcbsp这里,debug时检测不到xrdy位置1。这个问题困扰我很久了,测试一直不成功,万般无奈特来求助,望技术人员指点思路,万分感谢!期待您的回复!

下面我贴出我的配置代码,main函数不复杂很简单,都是些配置。

我觉得应该是PCR的配置和mcbsp写入数据那里有问题,其他的我感觉问题不大。我想配置的初衷是:接收帧同步由FSR脚提供,接收/发送时钟由内部的采样率发生器提供,发送帧同步脉冲由采样率发生器提供。

#include <csl.h>
#include <csl_i2c.h>
#include <stdio.h>
#include <csl_pll.h>
#include <csl_mcbsp.h>

/*锁相环的设置CPU144mhz*/
PLL_Config myConfig = {
0, 
1, 
12, 
1
};

/*采样率发生器的输入时钟源 CPU
CPU2分频得到CLKG
单相,一帧一个字节,每字节16bit
发送/接收帧1bit延迟
发送数据在上升沿,接收数据在下降沿
发送/接收帧同步脉冲高电平使能
发送/接收时钟由内部发生器产生
发送同步脉冲由mcbsp产生,当DXR拷贝数据到XSR时产生
接收同步脉冲由外部FSR脚产生
*/
MCBSP_Config Mcbsp1Config = {
MCBSP_SPCR1_RMK(
MCBSP_SPCR1_DLB_OFF,                            /* DLB = 0,禁止自闭环方式 */
MCBSP_SPCR1_RJUST_LZF,                        /* RJUST = 2左对齐低位补0 */
MCBSP_SPCR1_CLKSTP_DISABLE,            /* CLKSTP = 0 ,禁止clock stop模式*/
MCBSP_SPCR1_DXENA_ON,                         /* DXENA = 1 ,发送延迟使能*/
0,                                                                             /* ABIS = 0 */
MCBSP_SPCR1_RINTM_RRDY,                    /* RINTM = 0 mcbsp给cpu发送中断使能*/
0,                                                                            /* RSYNCER = 0 */
MCBSP_SPCR1_RRST_DISABLE /* RRST = 0 */
),
MCBSP_SPCR2_RMK(
MCBSP_SPCR2_FREE_NO,                            /* FREE = 0 */
MCBSP_SPCR2_SOFT_NO,                             /* SOFT = 0 */
MCBSP_SPCR2_FRST_FSG,                          /* FRST = 0 */
MCBSP_SPCR2_GRST_CLKG,                       /* GRST = 0 */
MCBSP_SPCR2_XINTM_XRDY,                       /* XINTM = 0 */
0,                                                                               /* XSYNCER = N/A */
MCBSP_SPCR2_XRST_DISABLE                   /* XRST = 0 */
),

MCBSP_RCR1_RMK(
MCBSP_RCR1_RFRLEN1_OF(0),                  /* RFRLEN1 = 0 ,接收帧长1个字节*/
MCBSP_RCR1_RWDLEN1_16BIT                  /* RWDLEN1 = 2 ,一个字节16bit*/
),
MCBSP_RCR2_RMK(
MCBSP_RCR2_RPHASE_SINGLE,                 /* RPHASE = 0 ,单相*/
MCBSP_RCR2_RFRLEN2_OF(0),                  /* RFRLEN2 = 0 */
MCBSP_RCR2_RWDLEN2_8BIT,                    /* RWDLEN2 = 0 */
MCBSP_RCR2_RCOMPAND_MSB,                /* RCOMPAND = 0 */
MCBSP_RCR2_RFIG_YES,                               /* RFIG = 0 */
MCBSP_RCR2_RDATDLY_1BIT                      /* RDATDLY = 1 ,接收帧1bit数据延迟*/
),
MCBSP_XCR1_RMK(
MCBSP_XCR1_XFRLEN1_OF(0),                      /* XFRLEN1 = 0,发送帧长1个字节 */
MCBSP_XCR1_XWDLEN1_16BIT                    /* XWDLEN1 = 2 ,一个字节16bit*/

),
MCBSP_XCR2_RMK(
MCBSP_XCR2_XPHASE_SINGLE,                    /* XPHASE = 0 */
MCBSP_XCR2_XFRLEN2_OF(0),                     /* XFRLEN2 = 0 */
MCBSP_XCR2_XWDLEN2_8BIT,                       /* XWDLEN2 = 0 */
MCBSP_XCR2_XCOMPAND_MSB,                    /* XCOMPAND = 0 */
MCBSP_XCR2_XFIG_YES,                                    /* XFIG = 0 */
MCBSP_XCR2_XDATDLY_1BIT                           /* XDATDLY = 1 ,发送帧1bit延迟*/
),
MCBSP_SRGR1_DEFAULT,                                /*默认值是帧脉冲宽度是1个CLKG周期,输入频率2分频得到CLKG*/
MCBSP_SRGR2_DEFAULT,                                /*CLKSM=1*/
MCBSP_MCR1_DEFAULT,
MCBSP_MCR2_DEFAULT,
MCBSP_PCR_RMK(
MCBSP_PCR_IDLEEN_RESET,                          /* IDLEEN = 0 , 当PERIPH域空闲时,MCBSP保持使能 */
MCBSP_PCR_XIOEN_SP,                                   /* XIOEN = 0 , CLKX,FSX,DX,CLKS脚是串口脚 */
MCBSP_PCR_RIOEN_SP,                                   /* RIOEN = 0 , CLKR,FSR,DR,CLKS脚是串口脚*/
MCBSP_PCR_FSXM_INTERNAL,                        /* FSXM = 1 , 发送帧同步脉冲由内部mcbsp提供 */
MCBSP_PCR_FSRM_EXTERNAL,                       /* FSRM = 0 , 接收帧同步脉冲由外部FSR脚提供 */
0, /* DXSTAT = N/A */
MCBSP_PCR_CLKXM_OUTPUT,                        /* CLKXM = 1, 发送器时钟由采样率发生器获得,CLKX脚作为输出脚 */
MCBSP_PCR_CLKRM_INPUT,                            /* CLKRM = 0 , 接收器时钟由CLKR引脚获得*/
MCBSP_PCR_SCLKME_NO,                                /* SCLKME = 0 , 采样率时钟源来自CPU或者CLKS */
MCBSP_PCR_FSXP_ACTIVEHIGH,                       /* FSXP = 0 , 发送帧脉冲高电平使能 */
MCBSP_PCR_FSRP_ACTIVEHIGH,                     /* FSRP = 0 ,接收帧脉冲高电平使能 */
MCBSP_PCR_CLKXP_RISING,                            /* CLKXP = 0 , 发送数据被驱动在CLKX的上升沿 */
MCBSP_PCR_CLKRP_FALLING                             /* CLKRP = 0 接收数据在CLKR下降沿沿采样 */
),
MCBSP_RCERA_DEFAULT,
MCBSP_RCERB_DEFAULT,
MCBSP_RCERC_DEFAULT,
MCBSP_RCERD_DEFAULT,
MCBSP_RCERE_DEFAULT,
MCBSP_RCERF_DEFAULT,
MCBSP_RCERG_DEFAULT,
MCBSP_RCERH_DEFAULT,
MCBSP_XCERA_DEFAULT,
MCBSP_XCERB_DEFAULT,
MCBSP_XCERC_DEFAULT,
MCBSP_XCERD_DEFAULT,
MCBSP_XCERE_DEFAULT,
MCBSP_XCERF_DEFAULT,
MCBSP_XCERG_DEFAULT,
MCBSP_XCERH_DEFAULT
};

/*定义McBSP的句柄*/
MCBSP_Handle hMcbsp;

void main(void)
{
int a;
CSL_init();

/*设置系统的运行速度为140MHz*/
PLL_config(&myConfig);

/*初始化McBSP1在使用MCBSP之前必须要做的一步*/
hMcbsp = MCBSP_open(MCBSP_PORT1,MCBSP_OPEN_RESET);

/*设置McBSP1*/
MCBSP_config(hMcbsp,&Mcbsp1Config);

/* Start Sample Rate Generator and Frame Sync */
MCBSP_start(hMcbsp, MCBSP_SRGR_START | MCBSP_SRGR_FRAMESYNC,0x300);

/* Enable MCBSP transmit and receive */
MCBSP_start(hMcbsp, MCBSP_RCV_START | MCBSP_XMIT_START, 0);

a = MCBSP_rrdy(hMcbsp);                                 /*定义a变量的目的是在ccs中观察a的值,即查看xrdy位是否能够为1*/
while(!a)
{}
MCBSP_write16(hMcbsp,0x1234);/*向发送寄存器DXR1写入0x1234,没有接收只发送*/     

}

  • mcbsp只发送不接收,只发送一次的话,只配置transmitter部分就可以了。为什么下面的代码还要先接收再发送啊?
     

    “a = MCBSP_rrdy(hMcbsp);                                 /*定义a变量的目的是在ccs中观察a的值,即查看xrdy位是否能够为1*/
    while(!a)
    {} 
    MCBSP_write16(hMcbsp,0x1234);/*向发送寄存器DXR1写入0x1234,没有接收只发送*/     ”

    }


  • 谢谢您能耐心看完这么多东西,万分感谢!

    是a = MCBSP_xrdy(hMcbsp);,我复制的时候写错了,定义a的目的就是想在CCS中观察a的值看看能不能变成1。

     我想我的具体问题应该是对SPCR寄存器的RINTM,XINTM,RRDY,XRDY位的理解。我设置的是RINTM,XINTM为00,

    1、那就是说 数据传输是中断方式,当DXR,DRR寄存器有8bit(假设是一字是8)时就产生中断,不用判断rrdy,xrdy的值,CPU就能进行读写操作,即可用代码:      MCBSP_write16(hMcbsp,0x1234);MCBSP_read16(hMcbsp);来直接进行读写操作,不用while语句来判断rrdy,xrdy的值了,这样理解对吗?

    2、MCBSP具体指的是这两个传输路径对吗?:CPU/DMA->DXR->XSR->DX,DR->RSR->RBR->DRR-CPU/DMA

    3、函数:MCBSP_write16(hMcbsp,0x1234);    是指的将0x1234从cpu写入 DXR还是从DXR写入XSR?

    4、我的设置是:接收帧同步脉冲由外部提供(FPGA提供),此时需要将SPCR1.RRST位设置为1吗?

    5、我使用MCBSP1,我的配置是:采样率发生器使用内部CPU时钟,有采样率发生器产生的CLKG时钟跟MCBSP1的CLKX,CLKR的关系是什么?

    6、假设:MCBSP1,2的CLKR,CLKX都是由MCBSP0的CLKR提供,对于MCBSP0来说,应该设置哪个寄存器的哪些位来指明这个MCBSP0的CLKR脚是做为时钟输出脚?

    问题有点多,这些基本上就是我这几天来操作MCBSP遇到的疑问,虽然看手册心里也明白点,但是我想得到一个很准确权威的答案!期待您的回复!谢谢   

  • 晚上好!

    我配置的mcbsp的PCR.CLKXM=1,即发送时钟由采样率发生器提供,

    采样率发生器时钟源是CPU,CPU频率为144mhz,CLKGDV=1,即CPU二分频得到CLKG=72MHZ,

    手册上说CLKG用于DR,DX的位移,那CLKG不就是CLKX,CLKR的时钟吗,测量CLKX脚频率应该等于72mhz左右,但是示波器显示结果很不稳定,FSX脚频率是62.3khz倒是挺稳定的;我修改CLKGDV=11,CPU12分频得到CLKG=12MHZ,示波器测量CLKX脚依然不稳定跟之前几乎一样,测量FSX脚频率依然是62.3khz,对于这种现象不知道该怎么解释?

  • 1. 对,mcbsp发送和接收可以采用轮询(判断rrdy, xrdy=1?)和中断方式。

    2. 对。

    3.  从cpu写入DXR, 后面DXR写入XSR是自动完成的。

    4.  需要。

    5. CLKG可以产生CLKX, CLKR时钟信号。

    6.  CLKRM=1。
     

  • 不稳定具体是怎么不稳定?能发送数据吗?DSP的CLKOUT能稳定输出吗?

  • 、CLKOUT脚在速率十几M的时候波形不是太好有失真,上了20M以后速率越大波形越好越稳定。.

    2、我将PCR.CLKXM置1,那就是说明CLKX是由内部采样率提供且CLKX此时是输出脚。

    采样率发生器时钟源是CPU,CPU频率为144mhz,CLKGDV=11,即CPU12分频得到CLKG=12MHZ,

    此时用示波器观察CLKX脚,那么CLKX脚应该<=12MHZ,可是波形显示:频率在跳动,跳动范围几百KHZ——几十Mhz之间,最大值是肯定大于12MHZ的,电压峰峰值只有几百mv;当CLKG配置为72MZH时示波器显示情况基本跟12mhz时相同。

    3、PCR.FSXM=1,示波器显示发送帧同步脉冲脚FSX的信号波形还是挺好的,是间隔相同的脉冲,我没设置SRGR2.FPER,是默认的0,那就是说脉冲的周期是FPER+1个CLKG周期,当我设置FPER=11时,两个脉冲之间的间距应该扩大到12个CLKG周期,但是示波器上并没有变化。我用quartusII上的sigaltap(FPGA的开发工具)抓取FSX信号,跟示波器情况是一样的,不管怎么设置无变化。

    4、我对CLKG和CLKX.CLKR的关系理解还是不透彻,手册上并没有讲他们之间的关系,我只能明确知道CLKG是多大,不知道CLKX,CLKR是多大,这样我用示波器测量CLKX,CLKR时会很难判断CLKX,CLKR应该是多少。

  • 1. CLKOUT没有稳定的波形输出的话,说明DSP没有稳定的跑起来。你查一下电源的纹波是否在手册范围内。

    2. CLKR, CLKX直接由CLKG提供,频率一样。

    3. 你现在能收发数据吗?

  • 我用的发送程序如下:

    这个while的功能应该是不停的发送0x1234,但是在FPGA端通过signaltap查看只能采样到发送同步脉冲FSX的波形,DX一直为高。

    我正在写另外一个测试,即:FPGA提供FSR,FPGA不停的发送数据0x1234给DSP的DR脚,CLKR、CLKX、FSX由DSP提供,DSP收到数据后等待xrdy置1后再发送给FPGA,fpga对DSP的发送脚DX进行数据采样,看看不是0x1234。用FPGA产生FSR脉冲时,脉冲宽度该怎么确定呢?不一定非要跟mcbsp的FWID,FPER的配置相一致,我只要能保证这个同步脉冲的高电平持续时钟足够长,脉冲间隔足够大就行了,我这个思路是对吗

    while(1)
     {
      while (!MCBSP_xrdy(hMcbsp));
      MCBSP_write16(hMcbsp,0x1234);
     }  

  • 1,建议先跑个自环的程序(DLB),看DSP端这边的内部收发有没有问题。

    2. FSR由FPGA产生的话,mcbsp不用设置FWID, FPER,脉冲宽度没有限制,mcbsp检测到FSR信号从inactive-active的变化就表示一个帧同步信号。 

  •    讲真,DSP的技术支持是我见过的最及时最耐心的,感谢shine Zhang这几天对我的帮助!

  • 客气了,应该的。

  • 中秋快乐!

    我仿真了我的晶振电路,接到X2/CLKIN那一点的仿真结果是:

    我的晶振电路在之前的帖子里上传过, 你也看到过了是晶振输出经过电阻电容一级隔离接到X2/CLKIN的,DSP的VIN最小2V,仿真的结果V(rms)S 是2.4V,但是峰峰值不管怎么调节电阻都是3.57V,不知道这样满足VIN的条件不

  • 峰峰值大于2.8v就可以了吧

    但是你要看一下高电平要>2v, 低电平要<0.8v。

  • 下午好!

    好消息:DSP和FPGA之间可以通过MCBSP收发数据了。

    但是,坏消息是:FPGA除了发送1可以正确收发外其他数据都是乱码。

    信号连接如下,CLKX,FSX,DX,CLKR,FSR全部由FPGA提供。

    DSP               FPGA

    CLKX   <——CLKR

    FSX     <——FSR

    DX       ——>DR

    CLKR<——CLKX

    FSR   <——FSX

    DR     <——DX

    收发过程是:

    FPGA发送数据data——FPGA实现并转串——DSP的DR脚——等待rrdy=1——data=mcbsp_read(hmcbsp)——等待xrdy=1——mcbsp_write(hmcbsp,data)——DSP的DX脚——FPGA接收并实现串转并data_out——signaltap采样daat_out——和FPGA发送的data做比较看是否一致;

    这个过程都是FPGA发送同样的数据。

    现在的情况是:

    现象1、不管FPGA发送什么数据,在DSP的DX脚上都是有数据的并且也能够被FPGA的signaltap抓取,当FPGA发送0x1时,整个收发过程是正确的,FPGA发送到FPGA接收数据比较是相同的。

    现象2、但是发其他的数据时DSP的DX脚却不是正确的串行数据,DX数据错误导致FPGA串转并之后的数据是错误的,更多的情况下是0(但是这至少说明FPGA发送过来的确实是被DSP接收了,只是在DSP执行发送的过程中数据错乱了)。

    现象3、我在CCS中打印接收的数据时,显示接收的数据一直为0;

     while(1)
     {

      while(!MCBSP_rrdy(hMcbsp))
      {
       printf("Sorry,rrdy=0\n");  
      };
      printf("Good,rrdy=1\n");                       //目的是验证rrdy手否置1了
      data = MCBSP_read16(hMcbsp);
      printf("data_receive=%x\n",data);    //打印接收的数据,然而一直是0
      for(temp=3000;temp>0;temp--);
      
      while(!MCBSP_xrdy(hMcbsp))
      {
       printf("Sorry,xrdy=0\n");
      };
      printf("Good,xrdy=1\n");                 //验证xrdy是否置1了
      MCBSP_write16(hMcbsp,data);
     }

    PCR寄存器的配置:

    MCBSP_PCR_RMK(
       MCBSP_PCR_IDLEEN_RESET,                 /* IDLEEN   = 0 ,当PERIPH域空闲时,MCBSP保持使能  */
       MCBSP_PCR_XIOEN_SP,                     /* XIOEN    = 0 ,CLKX,FSX,DX,CLKS脚是串口脚  */
       MCBSP_PCR_RIOEN_SP,                     /* RIOEN    = 0 ,CLKR,FSR,DR,CLKS脚是串口脚*/
       MCBSP_PCR_FSXM_EXTERNAL,                /* FSXM     = 0 ,  发送帧同步脉冲由外部FSR脚提供  */
       MCBSP_PCR_FSRM_EXTERNAL,                /* FSRM     = 0 ,接收帧同步脉冲由外部FSR脚提供  */
       0,                                      /* DXSTAT = N/A   */
       MCBSP_PCR_CLKXM_INPUT,                  /* CLKXM    = 0, 发送器时钟从CLKX脚由外部源提供  */
       MCBSP_PCR_CLKRM_INPUT,                  /* CLKRM    = 0 ,  接收器时钟是一个输入脚,并提供给内部的接收时钟CLKR */
       MCBSP_PCR_SCLKME_NO,                    /* SCLKME   = 0 ,采样率时钟源来自CPU或者CLKS */
       MCBSP_PCR_FSXP_ACTIVEHIGH,              /* FSXP     = 0  ,   发送帧脉冲高电平使能 */
       MCBSP_PCR_FSRP_ACTIVEHIGH,              /* FSRP     = 0  ,  接收帧脉冲高电平使能 */
       MCBSP_PCR_CLKXP_FALLING,                /* CLKXP    = 1  ,在CLKX的下降沿发送数据 */
       MCBSP_PCR_CLKRP_RISING                 /* CLKRP    =1  ,   在CLKR的上升沿采样 */
     ),

    现象4、FPGA提供FSX,CLKX。DSP的DX脚是串行数据,而且是在CLKX的时钟下进行移位的,理论上应该是DX脚数据的上升沿跟CLKX的上升沿应该是对齐的,而且DX脚一位数据的宽度应该是一个CLKX周期,但是signaltap上显示的是DX数据跟CLKX是不对齐的,而且宽度要比CLKX周期要小。猜测:会不会是DSP在发送数据的时候并没有按照FPGA提供的CLKX时钟来移位,而是按照内部的采样率时钟进行移位,矛盾的是我在PCR寄存器里已经配置了CLKXM=0,不知为何。

    总结:总体来说是可以进行收发数据的,出问题的地方应该是DSP的发送过程和FPGA的接收过程。(我设置的FSR是16个CLKR,FSX是16个CLKX,CLKR和CLKX,FSR和FSX的产生方法相同)。

    希望您能就我这种现象给我的测试做一个评估,看看哪里出问题了。

  • 建议先单向测试一下。

    FPGA->DSP,DSP是否能接收1以外的数据,不要用printf打印,直接开个buffer保存数据,看一下收到的数据如果错误的话,是否有规律如错位,或者还是乱码。

  • 你的建议很好!

    1、FPGA->DSP的话那就要使用while(!rrdy=1);MCBSP_read16(hmcbsp);这个函数了;那MCBSP_read16这个函数读出来的数是个完整的16位数;

    2、昨天晚上做了个测试:DSP->FPGA,在FPGA上波形抓取,接收进来的串行数据跟DSP的CLKX(此CLKX由FPGA提供)上升沿并不是对齐的,而且,比如说移位了一个1,那这个1的高电平持续时间应该是一个CLKX的周期,实际情况是1的持续时间只有CLKX的一半;

    因此我猜测:在DSP发送的时候,移位时钟并没有按照FPGA提供的CLKX来进行移位。但是mcbsp的配置是CLKX由外部提供。

  • 我已经进行了FPGA->DSP的单向测试,DSP依然收到的是0;

    我用AIC23的例程,mcbsp是可以工作的,我在FPGA端就是模拟的aic23的时序。

    AIC23时序如下:

    FPGA端发送时序如下:

    从上到下的波形名字为:CLKX,FSX,DX分别接到DSP的CLKR,FSR,DR。

    FPGA发送数据:0xaaaa;

    DSP测试代码如下:N=50;

    MCBSP只有检测到FSR有效后并且在DRR寄存器中有数据时rrdy才会置1;既然已经置1了,FPGA也发来了串行数据,为什么读出来的数一直是0?

    关于printf打印的:我用AIC23的例程,也是用的printf打印的方法,就可以打印出来mcbs_read16读进来的不同的数值;

  • 你好。我想请问下,你这个问题解决了吗?

    我也碰到了跟你一样的问题。

  • 能说下怎么解决的吗?

    我也碰到这个问题,是不是哪里配置有问题?谢谢