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.

C5500 I2C调试问题

Other Parts Discussed in Thread: PCM1864, TMS320C5517

在使用c55_csl_3.06 CSL_I2C_CodecTestExample调试过程中,当DSP作为Master模式下,通过添加打印log,发现第一次I2C卡在

statusByte = CSL_FEXT(i2cHandle->i2cRegs->ICSTR,I2C_ICSTR_ICRRDY);下,无法ICRRDY为1的信号。后续在I2C_ICSTR_BB就一直timeout、

时钟输入是按照晶振配置为12M 输出频率为10K。请问有可能是哪里出了问题?

  • 请问用的是EVM板还是自己的板子?这个例程是先通过I2C写codec寄存器,再去读这些配置后的寄存器值。您现在的问题是能写不能读?还是写也不行?
  • 目前是不能写,写入出错都是超时,但是第一次写寄存器和后续写寄存器的超时所卡在步骤是不一样的,如提问中那样

  • “无法ICRRDY为1的信号”这个是接收ready信号,发送的话是“ICXRDY”信号。
    另外,请说明使用的是EVM板还是自己的板子?如果是自己的板子,codec芯片是否和EVM板一样?
  • 板子使用的是自己的板子,codec使用的是PCM1864 修改回I2C_ICSTR_ICXRDY验证,结果与之前一致。用示波器抓取SCL,SDA信号都为高电平
    另想问下如果为主模式,ownAddr是否需要设置
    i2cSetup.ownAddr = CSL_I2C_OWN_ADDR;
  • 主模式,ownAddr不是必须设的。

    先运行一下CSL_I2C_LoopbackExample例程,看内部自环是否可以。
  • CSL_I2C_LoopbackExample_Out正常,打印如下:

    I2C LOOPBACK TEST!

    I2C Loopback Data Write and Read Complete
    Read Write Buffers Match!!

    I2C LOOPBACK TEST PASSED!!

  • 请问在GEL文件里有没有设置PSRCR,PRCR寄存器来使能peripheral clocks?

    SDA, SCL管脚是否上拉了?

    代码打印信息是什么?能运行到下面这块代码么?
    CSL_Status CSL_testRegister(int regAddr, int regValue)
    {
    CSL_Status status;
    Uint16 startStop;
    CSL_Status result;
    Uint16 testWrBuffer[2];
    Uint16 testRdBuffer[2];
    volatile Uint16 looper;

    result = CSL_I2C_TEST_FAILED;
    startStop = ((CSL_I2C_START) | (CSL_I2C_STOP));

    testWrBuffer[0] = regAddr;
    testWrBuffer[1] = regValue;

    /* Write data */
    status = I2C_write(testWrBuffer, 2,
    CSL_I2C_CODEC_ADDR, TRUE, startStop,
    CSL_I2C_MAX_TIMEOUT);
    if(status != CSL_SOK)
    {
    printf("I2C Write Failed!!\n");
    return(result);
    }

    printf("I2C Write Complete\n");
  • 没有在GEL文件中设置。请问GEL文件指的具体是哪一个文件,我这边没有看到gel对应后缀的文件

    SDA SCL管脚已上拉3.3v

    可以运行到CSL_testRegister

    以下为我修改的I2C_write函数

    CSL_Status I2C_write(Uint16 *i2cWrBuf,
    Uint16 dataLength,
    Uint16 slaveAddr,
    Bool masterMode,
    Uint16 startStopFlag,
    Uint16 timeout)
    {
    volatile Uint16 looper;
    Uint16 dataCount;
    Uint16 statusByte;

    if((i2cWrBuf != NULL) && (dataLength !=0))
    {
    /* check for bus busy */
    for(looper = 0; looper < timeout; looper++)
    {
    statusByte = CSL_FEXT(i2cHandle->i2cRegs->ICSTR, I2C_ICSTR_BB);
    if(statusByte == FALSE)
    {
    printf("bus busy\n");
    break;
    }
    }

    if(looper >= timeout)
    {
    printf("bus busy timeout\n");
    /* bus busy timeout error */
    return(CSL_I2C_BUS_BUSY_ERR);
    }

    /* Set the Tx mode */
    CSL_FINST(i2cHandle->i2cRegs->ICMDR, I2C_ICMDR_TRX, SET);

    /* Set the data length */
    CSL_FINS(i2cHandle->i2cRegs->ICCNT, I2C_ICCNT_ICDC, dataLength);

    if(masterMode == TRUE)
    {
    printf("masterMode\n");
    /* Set the slave address */
    CSL_FINS(i2cHandle->i2cRegs->ICSAR, I2C_ICSAR_SADDR, slaveAddr);

    /* Enable Master mode */
    CSL_FINST(i2cHandle->i2cRegs->ICMDR, I2C_ICMDR_MST, SET);

    /* Set the stop bit */
    if((startStopFlag & CSL_I2C_STOP) == CSL_I2C_STOP)
    {
    printf("set stop bit\n");
    CSL_FINST(i2cHandle->i2cRegs->ICMDR, I2C_ICMDR_STP, SET);
    }

    /* Set the start bit */
    if((startStopFlag & CSL_I2C_START) == CSL_I2C_START)
    {
    printf("set start bit\n");
    CSL_FINST(i2cHandle->i2cRegs->ICMDR, I2C_ICMDR_STT, SET);
    }
    }
    else
    {
    printf("slave mode\n");
    /* Disable Master mode */
    CSL_FINST(i2cHandle->i2cRegs->ICMDR, I2C_ICMDR_MST, CLEAR);
    }

    for(dataCount = 0; dataCount < dataLength; dataCount++)
    {
    /* Check for ICXRDY status */
    for(looper = 0; looper < timeout; looper++)
    {
    statusByte = CSL_FEXT(i2cHandle->i2cRegs->ICSTR,
    I2C_ICSTR_ICXRDY);
    // statusByte = CSL_FEXT(i2cHandle->i2cRegs->ICSTR,
    // I2C_ICSTR_ICRRDY);
    if(statusByte == TRUE)
    {
    break;
    }
    }

    if(looper >= timeout)
    {
    printf("CSL_I2C_TIMEOUT_ERROR\n");
    return(CSL_I2C_TIMEOUT_ERROR);
    }

    /* Write data to the data Tx register */
    CSL_FINS(i2cHandle->i2cRegs->ICDXR, I2C_ICDXR_D, *i2cWrBuf++);

    for(looper = 0; looper < timeout; looper++)
    {
    /* Check for NACK status */
    statusByte = CSL_FEXT(i2cHandle->i2cRegs->ICSTR,
    I2C_ICSTR_NACK);
    if(statusByte == FALSE)
    {
    break;
    }
    }

    if(looper >= timeout)
    {
    printf("CSL_I2C_NACK_ERR\n");
    return(CSL_I2C_NACK_ERR);
    }
    }
    }
    else
    {
    printf("CSL_ESYS_INVPARAMS\n");
    return(CSL_ESYS_INVPARAMS);
    }

    return(CSL_SOK);
    }

    第一次可以运行等待data received 超时 后面在bus busy 超时

    Log如下

    CSL_testRegister

    I2C CODEC CONFIGURING IN POLLED MODE TEST!

    pscValue:8
    clock:57
    CSL_testRegister
    bus busy
    masterMode
    set stop bit
    set start bit
    CSL_I2C_TIMEOUT_ERROR
    I2C Write Failed!!
    Read Write Buffers Don't Match for Register:0 with Value:0
    CSL_testRegister Failed!!

    CSL_testRegister
    bus busy timeout
    I2C Write Failed!!
    Read Write Buffers Don't Match for Register:65 with Value:81
    CSL_testRegister Failed

  • gel文件在C:\ti\ccsv8\ccs_base\emulation\boards\ezdsp5535_v1目录下,您自己的板子要做相应的修改。

    为什么要修改I2C_write源码?I2C_write是CSL库里的API函数。
  • 那gel文件需要导入操作吗?
    I2C_write只添加一些打印,方便调试
  • 在target configuration file里有配置GEL文件的地方。
  • 当前项目如图所示,我的ccs不安装在C盘下,是否需要别的设置操作

  • 请问target configuration file在哪里?没有找到。。
  • 看了一下,使用别的demo有target configuration file,但是目前使用的c55_csl_3.06没有看到对应的ccxml文件
  • 在代码中有I2C_init函数,有对PSRCR ,PRCR寄存器进行设置,但是查看规格书不明白这两个值应该设置为什么
    CSL_Status I2C_init(Uint16 instanceNum)
    {
    CSL_Status status;
    volatile Uint16 looper;

    status = CSL_SOK;

    switch(instanceNum)
    {
    case CSL_I2C0 :
    i2cHandle = &gI2cObj[CSL_I2C0];
    i2cHandle->i2cRegs = CSL_I2C_0_REGS;
    i2cHandle->sysCtrlRegs = CSL_SYSCTRL_REGS;

    /* Enable I2C module in Idle PCGCR */
    CSL_FINST(i2cHandle->sysCtrlRegs->PCGCR1,
    SYS_PCGCR1_I2CCG, ACTIVE);

    /* Reset I2C module */
    CSL_FINS(i2cHandle->sysCtrlRegs->PSRCR, SYS_PSRCR_COUNT,
    CSL_I2C_RESET_COUNT_VAL);

    CSL_FINST(i2cHandle->sysCtrlRegs->PRCR, SYS_PRCR_I2C_RST, RST);

    /* Give some delay for the device to reset */
    for(looper = 0; looper < CSL_I2C_RESET_DELAY; looper++)
    {;}

    break;

    default :
    status = CSL_ESYS_INVPARAMS;
    break;
    }

    return(status);
    }
  • 看了一下,使用别的demo有target configuration file,但是目前使用的c55_csl_3.06没有看到对应的ccxml文件

    您连仿真器的时候需要新建target configuration file来配置仿真器驱动,如下图

  • 请看1.7.5 Peripheral Reset寄存器定义
    www.ti.com/.../spruh87h.pdf
  • 找到I2C无法配置的原因是因为写入字节大小CSL_I2C_DATA_SIZE与codec配置的不一致,前期CSL_I2C_SYS_CLK配置的也不对

    目前使用示波器抓取SDA SCL有对应写入数据,但是好像存在大小端问题,例如I2C地址0x94,抓取到的数据为0010 1001,请问这个怎么设置呢?

  • I2C是先发最高位MSB的,抓取到的数据没问题。
    The data is always transferred with the mostsignificant bit (MSB) first. 
    www.ti.com/.../spruh87h.pdf

  • 目前I2C配置正常可以成功读写。总结一下I2C调试相关内容:
    环境 CCS6.1.3 demo库使用c55_csl_3.06的CSL_I2C_CodecTestExample。硬件使用的是TMS320C5517+PCM1864
    1.修改CSL_I2C_DATA_SIZE的定义,由64修改为16(参考codec数据手册对应修改)
    2.修改CSL_I2C_SYS_CLK为100(M),C5517支持0~175M时钟,保证I2C presaler 6.7M-13.3M区间,CSL_I2C_CodecTestExample是12分频,分频后为8M(整型)。
    3.CSL_I2C_CODEC_ADDR地址配置,PCM1864为7bit slave地址,但是写的为8bit地址 所以写入时需要右移一位。I2C address 0x94 配置为0x4A

  • 数据没问题,是我写入了0x94 但是数据只有7bit,所以最高位丢失
  • 谢谢Shine的耐心解答
  • 客气,感谢总结解决方法。
  • 配置文件描述准确吗?
  • 现在写不了,会显示错误,但是首次设置不一样
  • 波特率调试CODEC出现了问题,重新试下。
  • 不行,可以考虑重置