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配置SPI主/从模式的数据收发

使用场景是一片C6416和一片C6713通过McBSP相连接

C6416配置McBSP为SPI主模式,C6713配置McBSP为SPI从模式

C6416一直进行数据发送,但是C6713的rrdy一直没有信号,也就是无法读取SPI的DRR数据

用示波器测量了C6416的时钟、片选、数据,都是正常的

请问这是什么问题?

  • C6416的McBSP配置如下

    void init_mcbsp(MCBSP_Handle handle)
    {
        Uint32 spcr, rcr, xcr, srgr, mcr, pcr;
    
        Uint32 rcere0, rcere1, rcere2, rcere3;
        Uint32 xcere0, xcere1, xcere2, xcere3;
    
        /* SPI mode, CLKSTP = 11b and CLKXP = 0: Clock starts with rising edge with delay. */
        spcr = MCBSP_SPCR_RMK(
               MCBSP_SPCR_FREE_DEFAULT,
               MCBSP_SPCR_SOFT_DEFAULT,
               MCBSP_SPCR_FRST_DEFAULT,
               MCBSP_SPCR_GRST_DEFAULT,
               MCBSP_SPCR_XINTM_DEFAULT,
               MCBSP_SPCR_XSYNCERR_DEFAULT,
               MCBSP_SPCR_XRST_DEFAULT,
               MCBSP_SPCR_DLB_DEFAULT,
               MCBSP_SPCR_RJUST_DEFAULT,
               MCBSP_SPCR_CLKSTP_DELAY,         /* CLKSTP = 11b */
               MCBSP_SPCR_DXENA_OFF,
               MCBSP_SPCR_RINTM_DEFAULT,
               MCBSP_SPCR_RSYNCERR_DEFAULT,
               MCBSP_SPCR_RRST_DEFAULT
               );
    
        rcr =  MCBSP_RCR_RMK(
               MCBSP_RCR_RPHASE_SINGLE,
               MCBSP_RCR_RFRLEN2_DEFAULT,
               MCBSP_RCR_RWDLEN2_DEFAULT,
               MCBSP_RCR_RCOMPAND_DEFAULT,
               MCBSP_RCR_RFIG_NO,
               MCBSP_RCR_RDATDLY_1BIT,          /* 1 - (Master) */
               MCBSP_RCR_RFRLEN1_DEFAULT,
               MCBSP_RCR_RWDLEN1_32BIT,
               MCBSP_RCR_RWDREVRS_DISABLE
               );
    
    
        xcr =  MCBSP_XCR_RMK(
               MCBSP_XCR_XPHASE_DEFAULT,
               MCBSP_XCR_XFRLEN2_DEFAULT,
               MCBSP_XCR_XWDLEN2_DEFAULT,
               MCBSP_XCR_XCOMPAND_DEFAULT,
               MCBSP_XCR_XFIG_DEFAULT,
               MCBSP_XCR_XDATDLY_1BIT,          /* 1 - (Master) */
               MCBSP_XCR_XFRLEN1_DEFAULT,
               MCBSP_XCR_XWDLEN1_32BIT,
               MCBSP_XCR_XWDREVRS_DISABLE
               );
    
        srgr = MCBSP_SRGR_RMK(
               MCBSP_SRGR_GSYNC_FREE,
               MCBSP_SRGR_CLKSP_RISING,
               MCBSP_SRGR_CLKSM_INTERNAL,       /* SRGR clock mode from internal source */
               MCBSP_SRGR_FSGM_DEFAULT,
               MCBSP_SRGR_FPER_DEFAULT,
               MCBSP_SRGR_FWID_DEFAULT,
               MCBSP_SRGR_CLKGDV_OF(0)          /* C64X: CLKG = CPU/4 / (CLKGDV+1) */
               );
    
        mcr =  MCBSP_MCR_DEFAULT;
    
        rcere0 = MCBSP_RCERE0_RMK(0);
        rcere1 = MCBSP_RCERE1_RMK(0);
        rcere2 = MCBSP_RCERE2_RMK(0);
        rcere3 = MCBSP_RCERE3_RMK(0);
    
        xcere0 = MCBSP_XCERE0_RMK(0);
        xcere1 = MCBSP_XCERE1_RMK(0);
        xcere2 = MCBSP_XCERE2_RMK(0);
        xcere3 = MCBSP_XCERE3_RMK(0);
    
        pcr =  MCBSP_PCR_RMK(
               MCBSP_PCR_XIOEN_SP,
               MCBSP_PCR_RIOEN_SP,
               MCBSP_PCR_FSXM_INTERNAL,         /* SS output (Master) */
               MCBSP_PCR_FSRM_EXTERNAL,
               MCBSP_PCR_CLKXM_OUTPUT,          /* TX CLK output (Master) */
               MCBSP_PCR_CLKRM_INPUT,
               MCBSP_PCR_CLKSSTAT_0,
               MCBSP_PCR_DXSTAT_0,
               MCBSP_PCR_FSXP_ACTIVELOW,        /* SS polarity: Valid when SS goes low */
               MCBSP_PCR_FSRP_ACTIVELOW,
               MCBSP_PCR_CLKXP_RISING,          /* TX CLK polarity: Sampling at rising edge of clock */
               MCBSP_PCR_CLKRP_FALLING
               );
    
        MCBSP_configArgs(handle, spcr, rcr, xcr, srgr, mcr, rcere0, rcere1,
                         rcere2, rcere3, xcere0, xcere1, xcere2, xcere3, pcr);
    
        return;
    }
  • 因为c6416的发送时序正常,请重点检查一下c6713的SPI slave配置,要跟c6416的时序匹配。

  • C6713的McBSP配置如下

    void init_mcbsp(MCBSP_Handle handle)
    {
        Uint32 spcr, rcr, xcr, srgr, mcr, pcr;
        Uint32 rcer, xcer;
    
        /* SPI mode, CLKSTP = 11b and CLKXP = 0: Clock starts with rising edge with delay. */
        spcr = MCBSP_SPCR_RMK(
               MCBSP_SPCR_FREE_DEFAULT,
               MCBSP_SPCR_SOFT_DEFAULT,
               MCBSP_SPCR_FRST_DEFAULT,
               MCBSP_SPCR_GRST_DEFAULT,
               MCBSP_SPCR_XINTM_DEFAULT,
               MCBSP_SPCR_XSYNCERR_DEFAULT,
               MCBSP_SPCR_XRST_DEFAULT,
               MCBSP_SPCR_DLB_DEFAULT,
               MCBSP_SPCR_RJUST_DEFAULT,
               MCBSP_SPCR_CLKSTP_DELAY,         /* CLKSTP = 11b */
               MCBSP_SPCR_DXENA_OFF,
               MCBSP_SPCR_RINTM_DEFAULT,
               MCBSP_SPCR_RSYNCERR_DEFAULT,
               MCBSP_SPCR_RRST_DEFAULT
               );
    
    
        rcr =  MCBSP_RCR_RMK(
               MCBSP_RCR_RPHASE_SINGLE,
               MCBSP_RCR_RFRLEN2_DEFAULT,
               MCBSP_RCR_RWDLEN2_DEFAULT,
               MCBSP_RCR_RCOMPAND_DEFAULT,
               MCBSP_RCR_RFIG_NO,
               MCBSP_RCR_RDATDLY_0BIT,          /* 0 - (Slave) */
               MCBSP_RCR_RFRLEN1_DEFAULT,
               MCBSP_RCR_RWDLEN1_32BIT,
               MCBSP_RCR_RWDREVRS_DISABLE
               );
    
    
        xcr =  MCBSP_XCR_RMK(
               MCBSP_XCR_XPHASE_DEFAULT,
               MCBSP_XCR_XFRLEN2_DEFAULT,
               MCBSP_XCR_XWDLEN2_DEFAULT,
               MCBSP_XCR_XCOMPAND_DEFAULT,
               MCBSP_XCR_XFIG_DEFAULT,
               MCBSP_XCR_XDATDLY_0BIT,          /* 0 - (Slave) */
               MCBSP_XCR_XFRLEN1_DEFAULT,
               MCBSP_XCR_XWDLEN1_32BIT,
               MCBSP_XCR_XWDREVRS_DISABLE
               );
    
        srgr = MCBSP_SRGR_RMK(
               MCBSP_SRGR_GSYNC_FREE,
               MCBSP_SRGR_CLKSP_RISING,
               MCBSP_SRGR_CLKSM_INTERNAL,       /* SRGR clock mode from internal source */
               MCBSP_SRGR_FSGM_DEFAULT,
               MCBSP_SRGR_FPER_DEFAULT,
               MCBSP_SRGR_FWID_DEFAULT,
               MCBSP_SRGR_CLKGDV_OF(0)          /* C671X: CLKG = CPU/2 / (CLKGDV+1) */
               );
    
        mcr =  MCBSP_MCR_DEFAULT;
    
        rcer = MCBSP_RCER_DEFAULT;
        xcer = MCBSP_XCER_DEFAULT;
    
        pcr =  MCBSP_PCR_RMK(
               MCBSP_PCR_XIOEN_SP,
               MCBSP_PCR_RIOEN_SP,
               MCBSP_PCR_FSXM_EXTERNAL,         /* set SS as input - (Slave) */
               MCBSP_PCR_FSRM_EXTERNAL,
               MCBSP_PCR_CLKXM_INPUT,           /* set TX CLK as input - (Slave) */
               MCBSP_PCR_CLKRM_INPUT,
               MCBSP_PCR_CLKSSTAT_0,
               MCBSP_PCR_DXSTAT_0,
               MCBSP_PCR_FSXP_ACTIVELOW,        /* SS polarity: Valid when SS goes low */
               MCBSP_PCR_FSRP_ACTIVELOW,
               MCBSP_PCR_CLKXP_RISING,          /* TX CLK polarity: Sampling at rising edge of clock */
               MCBSP_PCR_CLKRP_FALLING
               );
    
        MCBSP_configArgs(handle, spcr, rcr, xcr, srgr, mcr, rcer, xcer, pcr);
    
        return;
    }
  • 寄存器配置基本对的,把c6713B的CLKGDV 设成1试试。

  • pcr =  MCBSP_PCR_RMK(
               MCBSP_PCR_XIOEN_SP,
               MCBSP_PCR_RIOEN_SP,
               MCBSP_PCR_FSXM_INTERNAL,         /* SS output (Master) */
               MCBSP_PCR_FSRM_INTERNAL,
               MCBSP_PCR_CLKXM_OUTPUT,          /* TX CLK output (Master) */
               MCBSP_PCR_CLKRM_OUTPUT,
               MCBSP_PCR_CLKSSTAT_0,
               MCBSP_PCR_DXSTAT_0,
               MCBSP_PCR_FSXP_ACTIVELOW,        /* SS polarity: Valid when SS goes low */
               MCBSP_PCR_FSRP_ACTIVELOW,
               MCBSP_PCR_CLKXP_RISING,          /* TX CLK polarity: Sampling at rising edge of clock */
               MCBSP_PCR_CLKRP_FALLING
               );

    如上所示,尝试修改了pcr寄存器的FSRM和CLKRM为输出后,

    可以收到rrdy信号,但是从端收到的数据完全是错误的

    C6416的运行代码

    while(1)
    {
            MCBSP_write(hMcbsp_Master, 0x050A050A);
            while(!(MCBSP_xrdy(hMcbsp_Master)));
    }

    C6713的运行代码

    while(1)
    {
            while(!MCBSP_rrdy(hMcbsp0));
    	readBuff = MCBSP_read(hMcbsp0);
    }

    6416发送的值是0x050A050A,6713的DRR寄存器的值是0x800000F8,

    请问是否还有什么配置是需要注意或修改的?

  • FSR, CLKR在SPI Mode下是不用的,所有的clock, frame sync由CLKX, FSX提供的。

  • 那这样是不是意味着两片 DSP 的连线应该是

    CLKX (6416) - CLKX (6713)

    FSX (6416) - FSX (6713)

    目前在调试的 pcb 板的连线是

    CLKX (6416) - CLKR (6713)

    FSX (6416) - FSR (6713)

    上述连线状态下是不是可以使用非 SPI 模式的 McBSP 通信协议?

  • SPI mode连线是你说的这种。

    你现在板子的接法就不能用SPI mode,用mcbsp通信协议即可。有代码可以参考。

    http://www.ti.com/lit/an/spra455a/spra455a.pdf

  • 问题已解决

    硬件工程师本来是想要在整块板上统一使用 SPI 接口协议

    但是 DSP 之间的连线不匹配 SPI 模式

    改用 McBSP 接口协议很快解决数据收发

    谢谢

  • 没看明白,你的 pcb 板的连线应该是对的呀!

    为什么会说 DSP 之间的连线不匹配 SPI 模式呢???

  • 借楼问一个类似问题,我采用mcbsp模拟SPI与CH432芯片通信;现在遇到的情况是,可以刚上电后可以对寄存器写,反复读没有问题;之后再写,读回来的值,都是0x00;目前很难判定是SPI驱动问题,还是CH432芯片问题?用示波器抓取波形,Tx与SS 的波形没问题。