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.

[参考译文] J721EXSOMXEVM:I2C5 在 I2C_v1_waitForPin 处挂起;轮询模式、裸机放大器;/FreeRTOS

Guru**** 2551110 points


请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1555131/j721exsomxevm-i2c5-hangs-at-i2c_v1_waitforpin-polling-mode-baremetal-freertos

器件型号:J721EXSOMXEVM


工具/软件:

您好、

我遇到 I2C5 模块的问题、无法与来自该 IFC 的从器件建立通信;在示波器上、我看到两个引脚均设置为逻辑低电平

我已将 MDIO_MDC_SEL0 设置为高电平、并通过示波器进行了物理验证。

为相应的 SCL、SDA 引脚配置了引脚多路复用、
HW_WR_REG32 ((0x0011C150)、PIN_MODE (2)|((PIN_PULL_DISABLE | PIN_INPUT_ENABLE) (~PIN_PULL_DIRECTION));
HW_WR_REG32 ((0x0011C154)、PIN_MODE (2)|((PIN_PULL_DISABLE | PIN_INPUT_ENABLE)&(~PIN_PULL_DIRECTION));

Padconfig、

CTRL_MMR0_CTRLMMR_PADCONFIG84
00050002
CTRL_MMR0_CTRLMMR_PADCONFIG85
00050002

static bool i2c5_basic_comm_test(void *test)
{
    uint32_t       busFrequency;
    I2C_Params      i2cParams;
    I2C_Handle      handle = NULL;
    I2C_Transaction i2cTransaction;
    int16_t         status = 0;
    char            txBuf[2] = {0x00, 0x00};
    char            rxBuf[2] = {0x00, 0x00};
    I2C_Tests      *i2cTest = (I2C_Tests *)test;

    I2C_initConfig(5, i2cTest);

    I2C_Params_init(&i2cParams);

    /* Set bitRate */
    //i2cParams.bitRate = bitRate;
    handle = I2C_open(5, &i2cParams);
    if (handle == NULL)
    {
        goto Err;
    }

    busFrequency = I2C_100kHz;
    I2C_control(handle, I2C_CMD_SET_BUS_FREQUENCY, &busFrequency);
    i2cTransaction.masterMode = BTRUE;

    /* Configure the I2C5 */
    txBuf[0] = 0x00; // 0F
    memset(rxBuf, 0, 2);
    I2C_transactionInit(&i2cTransaction);
    i2cTransaction.slaveAddress = 0xBE; //BF
    i2cTransaction.writeBuf = (uint8_t *)&txBuf[0];
    i2cTransaction.writeCount = 1;
    i2cTransaction.readBuf = (uint8_t *)&rxBuf[0];
    i2cTransaction.readCount = 1;
    i2cTransaction.timeout   = I2C_TRANSACTION_TIMEOUT;
    status = I2C_transfer(handle, &i2cTransaction);

    if (I2C_STS_SUCCESS != status)
    {
        I2C_log("\n I2C5 Test: ");
        I2C_log(": Failed to read \n");
        // testStatus and Err label are not defined in this scope
    }
    else
    {
        I2C_log("\nData from 0x00 is: %02x", rxBuf[0]);
    }

Err:
    if (handle)
    {
        I2C_close(handle);
    }

    return (status == I2C_STS_SUCCESS);
}

事务执行后的 I2C5 寄存器、

I2C5_CFG
I2C_REVNB_LO 0x0000080C 修订版号寄存器(低)【存储器已映射】
I2C_REVNB_HI 0x00005040 修订版本号寄存器(高)【已映射存储器】
I2C_SYSC 0x00000000 系统配置寄存器【存储器已映射】
I2C_EOI 0x00000000 中断编号规范结束 EOI 寄存器用于重新触发脉冲中断信号、以确保处理任何嵌套中断事件。 软件中断处理程序必须在当前中断处理例程结束时写入 EOI 寄存器、以便新事件可以再次重新触发脉冲中断信号。 对于电平中断信号、EOI 寄存器不起作用、不得使用。 【已映射内存】
I2C_IRQSTATUS_RAW 0x00000000 每事件原始中断状态矢量【存储器已映射】
I2C_IRQSTATUS 0x00000000 每事件启用的中断状态矢量【存储器已映射】
I2C_IRQENABLE_SET 0x00000000 每事件中断使能位矢量。 【已映射内存】
I2C_IRQENABLE_CLR 0x00000000 每事件中断清除位矢量。 【已映射内存】
I2C_WE 0x00000000 I2C 唤醒使能矢量(旧)。 【已映射内存】
I2C_DMARXENABLE_SET 0x00000000 每事件 DMA RX 启用设置。 【已映射内存】
I2C_DMATEXENABLE_SET 0x00000000 每事件 DMA TX 启用设置。 【已映射内存】
I2C_DMARXENABLE_CLR 0x00000000 每事件 DMA RX 启用清除。 【已映射内存】
I2C_DMATEXENABLE_CLR 0x00000000 每事件 DMA TX 启用清除。 【已映射内存】
I2C_DMARXWAKE_EN 0x00000000 每次事件 DMA RX 唤醒启用。 【已映射内存】
I2C_DMATXWAKE_EN 0x00000000 每事件 DMA TX 唤醒启用。 【已映射内存】
I2C_IE 0x00000000 I2C 中断启用矢量(旧)。 【已映射内存】
I2C_STAT 0x00000000 I2C 中断状态矢量(旧)。 【已映射内存】
I2C_SYSS 0x00000001 系统状态寄存器【存储器已映射】
I2C_BUF 0x00000000 缓冲器配置寄存器【存储器已映射】
I2C_CNT 0x00000001 数据计数器寄存器【存储器已映射】
I2C_DATA 0x00000000 数据访问寄存器【存储器已映射】
I2C_CON 0x00008600 I2C 配置寄存器。 【已映射内存】
I2C_OA 0x00000000 自己的地址寄存器【存储器已映射】
I2C_SA 0X000000BE 从器件地址寄存器【存储器映射】
I2C_PSC 0x00000017 I2C 时钟预分频器寄存器【存储器已映射】
I2C_SCLL 0x0000000D I2C SCL 低电平时间寄存器。 【已映射内存】
I2C_SCLH 0x0000000F I2C SCL 高电平时间寄存器。 【已映射内存】
I2C_SYSTEST 0x00004080 I2C 系统测试寄存器。 【已映射内存】
I2C_BUFSTAT 0x00008000 I2C 缓冲器状态寄存器。 【已映射内存】
I2C_OA1 0x00000000 I2C 自身的地址 1 寄存器【已映射存储器】
I2C_OA2 0x00000000 I2C 自身地址 2 寄存器【已映射存储器】
I2C_OA3 0x00000000 I2C 自身地址 3 寄存器【已映射存储器】
I2C_ACTOA 0x00000000 I2C 活动自身地址寄存器。 【已映射内存】
I2C_SBLOCK 0x00000000 I2C 时钟阻断使能寄存器。 【已映射内存】

PDK 11.00.00.21
J721E SOM

测试应用程序;
- Baremetal 和/ freeRTOS
- MCU2_0
- 没有 DMA
-无中断
-没有回叫

如果我在这里遗漏了一些内容、您能告诉我吗?

谢谢。

此致、
摩西

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Moses:

    您的应用程序的日志是什么? 事务是否无法从器件读取?

    此外、I2C_OPEN () 是否成功返回? 能否提供关于 I2C_PROBE () 结果的详细信息?

    谢谢、

    Neehar

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    嗨、Neehar、

    您的应用程序的日志是什么? 事务是否无法从从从器件读取?

    是、在超时之后。

    此外、I2C_open () 是否成功返回? [/报价]

    是的、看起来像这样、句柄中填充了信息。

    [报价 userid=“574070" url="“ url="~“~/support/processors-group/processors/f/processors-forum/1555131/j721exsomxevm-i2c5-hangs-at-i2c_v1_waitforpin-polling-mode-baremetal-freertos/5984734

    能否提供关于 I2C_PROBE () 结果的详细信息?

    [/报价]

    看起来探头在从 0x00 - 0xFF 开始的每个地址上都成功、这很奇怪。
    探头检查如下所示:

        for(uint32_t slaveAddress=0; slaveAddress<=0xFF; slaveAddress++)
        {
            controlStatus = I2C_control(handle, I2C_CMD_PROBE, &slaveAddress);
    
            if(I2C_STATUS_SUCCESS == controlStatus) {
                I2C_log("\n I2C5 Test [%02x]: Probe Success!\n", slaveAddress);
            } else {
                I2C_log("\n I2C5 Test [%02x]: Probe Err\n", slaveAddress);
            }
            AppDelay(10);
        }
        

    同一环路、可  与 I2C0 一起工作。

    谢谢。

    此致、
    摩西

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Moses:

    感谢您提供此信息!

    您能否提供对 I2C_v1_waitForPin() 的函数调用、该挂起发生在哪里? 它在传递函数中的什么位置?

    谢谢、

    Neehar

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    嗨、Neehar、

    基本上、它是在 while 循环中等待超时过期。 超时时间越长、等待时间越长、但最终无论发生什么情况、事务都会失败。

    while ((uint32_t) 0U == (status & flag))
            {
                if ((uint32_t) 0U != timeout)
                {
                    I2C_v1_udelay(I2C_DELAY_USEC);
                    if (I2C_checkTimeout(&uSecTimeout))
                    {
                        timeout--;
                    }
                    status = I2CMasterIntRawStatus(hwAttrs->baseAddr);
                }
                else
                {
                    break;
                }
            }
    

    谢谢。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Moses:

    我理解超时发生在 I2C_v1_waitForPin() 函数中。 但是、该函数在 I2C_primeTransfer_v1() 函数中的何处被调用?

    我想了解驱动器中挂起发生的位置。

    谢谢、

    Neehar

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Moses:

    接下来、该问题是否仍然存在?

    谢谢、

    Neehar