TI论坛
直播中

温暖镜头

10年用户 1059经验值
擅长:电源/新能源 制造/封装
私信 关注
[问答]

TMS320DM8148 McAsp采用loopback模式,能够收发数据,但是数据引脚上无法捕捉到任何变化,为什么?


  • 【芯片型号】TMS320DM8148
    【开发环境】软件:linux 驱动 硬件:第三方提供的EVM板,相应的引脚已经引出。
    【问题描述】
                实验目的:配置McAsp0为loopback模式,通过cpu轮询发送MCASP0.1,接收MCASP0.0。期望能在RBUF0接收到发送的数据,并在发送引脚MCA0.AXR1测量到发送电平信号。
                实验步骤:编写驱动模块mcasp.ko,加载模块后,配置mcasp引脚复用,时钟选择,工作模式等,用CPU轮询发送,接收数据。
                              1.配置PinMux,将MCASP0相关所有引脚配置为MCASP功能。参考的:tms320dm8172,P153
                              2.配置MCASP0 时钟,采用SYSYCLK22提供AUX_CLK。参考的:SPRUGZ8e ,P458
                              3.配置MCASP0 工作模式,并启动MCASP0开始工作。 参考的:SPRUGZ8e ,P2075
                              4.CPU轮询在XBUF1上发送,在RBUF0上接收。用一个数组recv_array_test存取每一次接收的RBUF0数据。
                  实验结果:recv_array_test数组中显示接收到了XBUF1发送的数据。但是在对应的MCASP0.AXR1引脚上并没有测量到任何的电平变化,同时没有帧同步信号引脚MCASP0.AFS也没有任何变化?
                  疑问:根据SPRUGZ8e ,P2073页中提到,在loopback模式下应该能够在发送引脚上测量到电平的变化,尝试过去掉loopback配置还是没有任何变化。俺是个新手,对DSP零基础,不知道问题出在哪了。恳请各位前辈,指出问题所在,万分感谢!!!!
    【备注】附件中有完整的模块代码,关键操作如下:
    static int mcasp_module_init(void)
    {
    //enable mcasp 0,1,2
    mcasp_device *mcasp0;
    mcasp_device *mcasp1;
    mcasp_device *mcasp2;
    mcasp_device *mcasp3;
    mcasp_device *mcasp4;
    mcasp_device *mcasp5;
    void __iomem * pll_base;
    void __iomem * mux_base;
    void __iomem * pcrm_base;
    g_mcasp_module.mcasp_group = &g_mcasp_device_group[0];
    kdbg_msg(2,"init mcasp module.....n");
    mcasp0 = &g_mcasp_device_group[0];
    mcasp1 = &g_mcasp_device_group[1];
    mcasp2 = &g_mcasp_device_group[2];
    mcasp3 = &g_mcasp_device_group[2];
    mcasp4 = &g_mcasp_device_group[2];
    mcasp5 = &g_mcasp_device_group[2];
    mcasp0->ctl_phy_base = MCASP0_PHY_BASE;
    mcasp0->ctl_reg_len = MCASP0_DATA_SIZE;
    mcasp1->ctl_phy_base = MCASP1_PHY_BASE;
    mcasp1->ctl_reg_len = MCASP1_DATA_SIZE;
    mcasp2->ctl_phy_base = MCASP2_PHY_BASE;
    mcasp2->ctl_reg_len = MCASP2_DATA_SIZE;
    mcasp3->ctl_phy_base = MCASP3_PHY_BASE;
    mcasp3->ctl_reg_len = MCASP3_DATA_SIZE;
    mcasp4->ctl_phy_base = MCASP4_PHY_BASE;
    mcasp4->ctl_reg_len = MCASP4_DATA_SIZE;
    mcasp5->ctl_phy_base = MCASP5_PHY_BASE;
    mcasp5->ctl_reg_len = MCASP5_DATA_SIZE;
    mcasp0->enable_reg = ioremap(CM_ALWON_MCASP0_CLKCTRL,4);
    mcasp1->enable_reg = ioremap(CM_ALWON_MCASP1_CLKCTRL,4);
    mcasp2->enable_reg = ioremap(CM_ALWON_MCASP2_CLKCTRL,4);
    if( (NULL == mcasp0->enable_reg) || (NULL == mcasp0->enable_reg ) || (NULL == mcasp0->enable_reg )){
      kdbg_msg(3,"ioremap error!n");
      return -ERR_MCASP_IOREMAP;
    }
    mcasp_set_reg(mcasp0->enable_reg,0x2);
    mcasp_set_reg(mcasp1->enable_reg,0x2);
    mcasp_set_reg(mcasp2->enable_reg,0x2);

    //set pin mux
    g_mcasp_module.mux_base = ioremap(MUX_MODE_BASE,4*1024);
    mux_base = g_mcasp_module.mux_base;
    mcasp_set_reg((mux_base + PINCNTL17),0x1); //set as mcasp
    mcasp_set_reg((mux_base + PINCNTL18),0x1);
    mcasp_set_reg((mux_base + PINCNTL19),0x1);
    mcasp_set_reg((mux_base + PINCNTL20),0x1);
    mcasp_set_reg((mux_base + PINCNTL21),0x1);
    mcasp_set_reg((mux_base + PINCNTL22),0x1);
    mcasp_set_reg((mux_base + PINCNTL23),0x1);
    mcasp_set_reg((mux_base + PINCNTL24),0x1);
    mcasp_set_reg((mux_base + PINCNTL25),0x1);
    mcasp_set_reg((mux_base + PINCNTL26),0x1);
    mcasp_set_reg((mux_base + PINCNTL27),0x1);
    mcasp_set_reg((mux_base + PINCNTL28),0x1);
    mcasp_set_reg((mux_base + PINCNTL29),0x1);
    mcasp_set_reg((mux_base + PINCNTL30),0x1);
    mcasp_set_reg((mux_base + PINCNTL134),0x20); //set  CLKOUT0
    mcasp_set_reg((mux_base + 0x834),0x4); //set  MCA[0]_AHCLKX
    //set module pll
    g_mcasp_module.module_pll_base = ioremap(TI814X_PLL_BASE,4*1024);
    pll_base = g_mcasp_module.module_pll_base;
    kdbg_msg(2,"ahclk_clksrc org is:%dn",mcasp_get_reg(pll_base+0x2d4));
    mcasp_set_reg((pll_base + 0x2D4),0x4);
    kdbg_msg(2,"ahclk_clksrc set is:%dn",mcasp_get_reg(pll_base+0x2d4));
    #if 0
    mcasp_set_reg((pll_base + AUDIOPLL_CLKCTRL),0x271B080F);
            mcasp_set_reg((pll_base + AUDIOPLL_M2NDIV),0x10004);
            mcasp_set_reg((pll_base + AUDIOPLL_MN2DIV),0xc);
            mcasp_set_reg((pll_base + AUDIOPLL_TENABLEDIV),0x0);
            mcasp_set_reg((pll_base + AUDIOPLL_TENABLEDIV),0x1);
            mcasp_set_reg((pll_base + AUDIOPLL_TENABLE),0x0);
            mcasp_set_reg((pll_base + AUDIOPLL_TENABLE),0x1);
    #endif
    //set pcrm
    g_mcasp_module.pcrm_base = ioremap(TI81XX_PRCM_BASE,4*1024);
    pcrm_base = g_mcasp_module.pcrm_base;
    //set syscllk22 divider as 0x1 [p698]
    kdbg_msg(2,"sysclk22 org is:%xn",mcasp_get_reg(pcrm_base+0x300+0x58));
    mcasp_set_reg((pcrm_base+0x300+0x58),0x0);
    kdbg_msg(2,"sysclk22 set is:%xn",mcasp_get_reg(pcrm_base+0x300+0x58));
    //choose sysclk22 as mcasp aux_clk
    mcasp_set_reg((pcrm_base + CM_AUDIOCLK_MCASP0_CLKSEL),0x2); //CM_AUDIOCLK_MCASP0_CLKSEL Select McASP0 audio clock to be SYSCLK22 [p703]
    mcasp_set_reg((pcrm_base + CM_CLKOUT_CTRL),0x80);
    kdbg_msg(2,"init mcasp module ok.....n");
    return 0;
    }
    static int mcasp_open(int mcasp_instance)
    {
    mcasp_device *mcasp;
    if(mcasp_instance >= MCASP_INSTANCE_NUM || mcasp_instance < 0){
      kdbg_msg(3,"wrong instance num:%d,which should be %d <= num < %dn",mcasp_instance,0,MCASP_INSTANCE_NUM);
      return -ERR_MCASP_WRONG_ARG;
    }
    kdbg_msg(2,"start openn");
    mcasp = &g_mcasp_device_group[mcasp_instance];
    mcasp->ctl_base = ioremap(MCASP0_PHY_BASE,MCASP0_DATA_SIZE);
    if(NULL == mcasp->ctl_base){
      kdbg_msg(3,"ioremap error!n")
      return -ERR_MCASP_IOREMAP;
    }

    kdbg_msg(2,"open endn");
    return 0;
    }
    static int mcasp_set_fmt(int mcasp_instance)
    {
    void __iomem * mcasp_reg_base;
    mcasp_device *mcasp;
    kdbg_msg(2,"start set fmtn");
    mcasp = &g_mcasp_device_group[mcasp_instance];
    mcasp_reg_base = mcasp->ctl_base;
    kdbg_msg(2,"get virtual basen");
            mcasp_set_reg((mcasp_reg_base + GBLCTL), 0);       // Reset
            mcasp_set_reg((mcasp_reg_base + RGBLCTL ), 0);       // Reset RX
            mcasp_set_reg((mcasp_reg_base + XGBLCTL ), 0);       // Reset TX
            //RX
    //Rx.set format
            mcasp_set_reg((mcasp_reg_base + RMASK), 0xffffffff); // No padding used
            mcasp_set_reg((mcasp_reg_base + RFMT), 0x000300F8); // MSB 16bit, 3-delay, no pad, CfgBus port
            mcasp_set_reg((mcasp_reg_base + AFSRCTL), 0x0000102); // 2TDM, 1bit Rising edge INTERNAL FS, word
            mcasp_set_reg((mcasp_reg_base + RTDM), 0x0000003); // Slots 0,1
    //Rx.set clock
            mcasp_set_reg((mcasp_reg_base + ACLKRCTL), 0x20); // INTERNAL CLK
            mcasp_set_reg((mcasp_reg_base + AHCLKRCTL), (1<<15)); // INTERNAL CLK
            mcasp_set_reg((mcasp_reg_base + XCLKCHK), 0x00FF0008); // 255-MAX 0-MIN, div-by-256
    //Rx.interrupt
            mcasp_set_reg((mcasp_reg_base + RINTCTL), 0x00000000); // Not used
            //TX
    //Tx.set format
            mcasp_set_reg((mcasp_reg_base + XMASK), 0xffffffff); // No padding used
            mcasp_set_reg((mcasp_reg_base + XFMT), 0x000300F8); // MSB 16bit, 3-delay, no pad, CfgBus port
            mcasp_set_reg((mcasp_reg_base + AFSXCTL), 0x0000102); // 2TDM, 1bit Rising edge INTERNAL FS, word
            mcasp_set_reg((mcasp_reg_base + XTDM), 0x0000003); // Slots 0,1
    //Tx.set clock
            mcasp_set_reg((mcasp_reg_base + ACLKXCTL), 0x00000020); //INTERNAL CLK Sync mode
            mcasp_set_reg((mcasp_reg_base + AHCLKXCTL), (1<<15)); // INTERNAL CLK
            mcasp_set_reg((mcasp_reg_base + XCLKCHK), 0x00FF0008); // 255-MAX 0-MIN, div-by-256
    //Tx.interrupt
            mcasp_set_reg((mcasp_reg_base + XINTCTL), 0x00000000); // Not used
    //Serializer
            mcasp_set_reg((mcasp_reg_base + SRCTL0), 0x00000002);     // MCASP0.AXR1[2] Recv
            mcasp_set_reg((mcasp_reg_base + SRCTL1), 0x00000001);     // MCASP0.AXR1[3] Send
    //Global Register
            mcasp_set_reg((mcasp_reg_base + PFUNC), 0);          // All MCASPs
            mcasp_set_reg((mcasp_reg_base + PDIR), 0x00000002|(0x3f<<26)); // All inputs except AXR0[1], ACLKX1, AFSX1,AHCLKX,AFSR,AHCKLR,ACLKR
            mcasp_set_reg((mcasp_reg_base + DITCTL), 0x00000000); // Not used
    if(loop_back){
      //setting as loop back mode
      mcasp_set_bits((mcasp_reg_base + DLBCTL),0x1); //enable loop back
      mcasp_set_bits((mcasp_reg_base + DLBCTL),(0x1<<2)); //set as loop back mode
    }else{
      mcasp_set_reg((mcasp_reg_base + DLBCTL),0x0); //Not used
    }
            mcasp_set_reg((mcasp_reg_base + AMUTE), 0x00000000); // Not used
    return 0;
    }
    static int mcasp_start(int mcasp_instance)
    {
    void __iomem * mcasp_reg_base;
    mcasp_device *mcasp;
    int i;
    mcasp = &g_mcasp_device_group[mcasp_instance];
    mcasp_reg_base = mcasp->ctl_base;
        mcasp_set_ctl_reg((mcasp_reg_base + RGBLCTL),GBLCTL_RHCLKRST_ON );                  //HS Clk
        mcasp_set_ctl_reg((mcasp_reg_base + XGBLCTL),GBLCTL_XHCLKRST_ON );                  //HS Clk
            mcasp_set_ctl_reg((mcasp_reg_base + RGBLCTL),GBLCTL_RCLKRST_ON);                    //Bit Clk
            mcasp_set_ctl_reg((mcasp_reg_base + XGBLCTL),GBLCTL_XCLKRST_ON);                    //Bit Clk
            mcasp_set_reg((mcasp_reg_base + RSTAT),0x0000ffff );         // Clear all
            mcasp_set_reg((mcasp_reg_base + XSTAT),0x0000ffff );         // Clear all
            mcasp_set_ctl_reg((mcasp_reg_base + RGBLCTL),GBLCTL_RSRCLR_ON);                     //Serialize
            mcasp_set_ctl_reg((mcasp_reg_base + XGBLCTL),GBLCTL_XSRCLR_ON);                     //Serialize
            mcasp_set_reg((mcasp_reg_base + RBUF0),0x456);         //avoid underrun
            mcasp_set_reg((mcasp_reg_base + XBUF1),0x123);         //avoid underrun
            mcasp_set_ctl_reg((mcasp_reg_base + RGBLCTL ),GBLCTL_RSMRST_ON);                    //State Machine
            mcasp_set_ctl_reg((mcasp_reg_base + XGBLCTL ),GBLCTL_XSMRST_ON);                    //State Machine
            mcasp_set_ctl_reg((mcasp_reg_base + RGBLCTL  ),GBLCTL_RFRST_ON);                    //Frame Sync
            mcasp_set_ctl_reg((mcasp_reg_base + XGBLCTL  ),GBLCTL_XFRST_ON);                    //Frame Sync
    #if 0
            while(!(mcasp_get_reg(mcasp_reg_base + SRCTL3) & 0x10)){}
            mcasp_set_reg((mcasp_reg_base + XBUF3),0x0);
    #endif
    // for test ...
    #if 1
    for(i=0; i

回帖(2)

李桂荣

2024-11-1 14:42:06
我觉得是不是引脚复用的设置有问题,是否借助调试器看看设置后的寄存器
举报

訾存贵

2024-11-1 18:11:59
根据您的描述,您已经成功配置了TMS320DM8148的McAsp0为loopback模式,并通过CPU轮询发送和接收数据。但是,您在数据引脚上无法捕捉到任何变化。以下是一些可能的原因和解决方案:

1. 引脚连接问题:请检查您的硬件连接,确保MCASP0.1(发送引脚)和MCASP0.0(接收引脚)已经正确连接到EVM板上的相应引脚。如果连接不正确,信号可能无法传输。

2. 引脚复用配置:请确保您已经正确配置了引脚复用,以便MCASP0.1和MCASP0.0能够正常工作。您可以查阅TMS320DM8148的数据手册,了解如何配置引脚复用。

3. 时钟配置:请检查您的时钟配置是否正确。McAsp需要一个时钟信号来驱动数据传输。请确保您已经正确配置了时钟源和时钟频率。

4. 驱动模块问题:请检查您的驱动模块mcasp.ko是否正确实现。您可以尝试使用其他驱动模块或示例代码来验证驱动模块是否正确。

5. 信号测量工具:请确保您使用的信号测量工具(如示波器)能够正确测量MCASP0.1引脚上的信号。请检查示波器的设置,确保其能够捕捉到信号。

6. 代码问题:请检查您的代码,确保您已经正确配置了McAsp0的工作模式、发送和接收通道。此外,请确保您已经正确处理了数据发送和接收的逻辑。

综上所述,您需要检查硬件连接、引脚复用配置、时钟配置、驱动模块、信号测量工具和代码。通过逐一排查这些问题,您应该能够找到导致数据引脚上无法捕捉到任何变化的原因,并采取相应的解决方案。
举报

更多回帖

×
20
完善资料,
赚取积分