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.

[参考译文] TMS320F280039C:PMBus 模块从器件地址问题的手动 ACK/NACK

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1281070/tms320f280039c-manual-ack-nack-of-slave-address-of-pmbus-module-issue

器件型号:TMS320F280039C

您好!

我使用具有手动从器件地址确认模式(MAN_SLAVE_ACK = 1)的 PMBus 模块

以下代码已启用

//初始 PMBus_A 配置(PEC 启用、手动地址和命令、RX 字节手动 ACK 设置为1)
PMBUS_configTarget (PMBUSA_BASE、
PMBus_target_enable_PEC_processing |
PMBus_target_enable_manual_ACK |
PMBus_target_enable_manual_CMD_ACK |
PMBus_TARGET_AUTO_ACK_1_BYTE);

//初始 PMBus_A 中断触发类型
PMBus_enableInterrupt (PMBUSA_BASE、
PMBUS_INT_TARGET_ADDR_READY |
PMBUS_INT_DATA_READY |
PMBUS_INT_DATA_REQUEST |
PMBUS_INT_EOM);

================================

在 PMBus_A 中断 ISR 中、当发生从器件地址接收中断时、我会使用以下源代码发送 ACK:

//获取当前 PMBus_A 状态
G_PMBus_CTRL_VAR.PMBus_A_sta = PMBus_getStatus (PMBUSA_base);

//接收到从地址
if (g_PMBus_CTRL_VAR.PMBus_A_sta &(uint32_t) PMBUS_INTSRC_TARGET_ADDR_READY)
{
  // PMBus 初始 Re 缓冲器
  Initial_Ctrl_Buffer ();

  PMBUS_ackAddress (PMBUSA_BASE、(PMBUS_SLAVE_ADDR >> 1)、
                    G_PMBus_CTRL_VAR.PMBus_A_sta、
                    &G_PMBUS_CTRL_VAR.rev_slave_addr);

 

但从器件始终向 I2C 主器件发送 NACK。

是否需要签出任何配置/操作?

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

    您好!

    在发送 ACK 时、您是否仔细研究了数据/时钟线路、以确保那里有 ACK? 您是否需要使用手动 ACK 而不是 PMBus over I2C 示例中使用的默认自动 ACK?

    此致、

    阿米尔·奥马尔

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

    1.我需要在同一个 I2C 总线上实施 PMBus 和  FRU 功能,因此我需要使用手动方法来判断 PMBus 或 FRU 的从地址

    下图展示了从器件地址的 NACK (黄色为 SCL、绿色为 SDA)

     

    另一个图 说明 SCL 保持低电平是因为我在 PMBus_ackAddress ()的"Acknowoldege"  

    当我向从器件发送正确的从器件地址

    if((buffer[0] & 0x7FU) == address)
    {
        //
        // Acknowledge
        //
        HWREG(base + PMBUS_O_PMBACK) |= PMBUS_PMBACK_ACK;
    }
    else
    {
        //
        // NACK
        //
        HWREG(base + PMBUS_O_PMBACK) &= ~(uint32_t)PMBUS_PMBACK_ACK;
    }

    我  

    这意味着在发送 ACK 之前 SCL 保持低电平。

    以下代码是初始 PMBus_A 供参考

    #define PMBUS_SLAVE_ADDR 0xB0 // Basic slave address(8-bit address)
    #define SLAVE_ADDR_MASK 0xEF // Mask bit 4 to implement 0xBx(PMBus) & 0xAx(FRU)(8-bit address)
    
    void PMBus_A_init(void)
    {
        uint32_t moduleFreq = 0U;
    
        // Disable PMBus_A bus first
        PMBus_disableModule(PMBUSA_BASE);
    
        // Initial PMBus_A Module clock
        moduleFreq = PMBus_configModuleClock(PMBUSA_BASE, PMBUS_MODULE_FREQ_MAX,
                                              PMBUS_SYS_FREQ_MAX);
        // Initial PMBus_A support fast mode
        PMBus_configBusClock(PMBUSA_BASE, PMBUS_CLOCKMODE_FAST, moduleFreq);
    
    
        // Initial PMBus_A Target mode(Enable target mode, Slave address mask, and default slave address)
        PMBus_initTargetMode(PMBUSA_BASE,(PMBUS_SLAVE_ADDR >> 1), (SLAVE_ADDR_MASK >> 1) );
    
        // Enable I2C mode
        PMBus_enableI2CMode(PMBUSA_BASE);
    
        // Initial PMBus_A Configuration(PEC enabled, manual address & command, manual ACK for RX byte set to 1)
        PMBus_configTarget(PMBUSA_BASE,
                           PMBUS_TARGET_ENABLE_PEC_PROCESSING |
                           PMBUS_TARGET_ENABLE_MANUAL_ACK |
                           PMBUS_TARGET_ENABLE_MANUAL_CMD_ACK |
                           PMBUS_TARGET_AUTO_ACK_1_BYTES);
    
        // Initial PMBus_A interrupt triggered types
        PMBus_enableInterrupt(PMBUSA_BASE,
                              PMBUS_INT_TARGET_ADDR_READY |
                              PMBUS_INT_DATA_READY |
                              PMBUS_INT_DATA_REQUEST |
                              PMBUS_INT_EOM);
    
    
        // Initial PMBus_A driver control variable
        Initial_Control_Variable();
    
        // Register PMBus interrupt
        Interrupt_register(INT_PMBUSA, PMBus_A_ISR);
    
        // ACK any pending group interrupts
        Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP8);
    
        // Enable PMBus_A interrupt
        Interrupt_enable(INT_PMBUSA);
    
        // Enable PMBus_A module
        PMBus_enableModule(PMBUSA_BASE);

    用于参考的 PMBus_A 中断代码

    void PMBus_A_handler(void)
    {
        // Get Current PMBus_A State
        g_PMBus_CTRL_VAR.pmbus_a_sta = PMBus_getStatus(PMBUSA_BASE);
    
        // Slave address received
        if(g_PMBus_CTRL_VAR.pmbus_a_sta & (uint32_t)PMBUS_INTSRC_TARGET_ADDR_READY)
        {
            // Re-initial PMBus Buffer
            Initial_Ctrl_Buffer();
            //HWREG(GPIODATA_BASE + GPIO_O_GPATOGGLE) = GPIO_GPATOGGLE_GPIO20;
            // Get Current slave address(7-bit address)
            g_PMBus_CTRL_VAR.rev_slave_addr = PMBus_getOwnAddress_all_8_bits(PMBUSA_BASE);
    
            // Address check
            if (g_PMBus_CTRL_VAR.rev_slave_addr == (PMBUS_SLAVE_ADDR >> 1))
            {
                // Send Ack
    //           // PMBus_ackAddress(PMBUSA_BASE, (PMBUS_SLAVE_ADDR >> 1), g_PMBus_CTRL_VAR.pmbus_a_sta,
    //             //                        &g_PMBus_CTRL_VAR.rx_data[g_PMBus_CTRL_VAR.rx_cnt++]);
                PMBus_ackTransaction(PMBUSA_BASE);
    //
                // Read address in RX buffer
                (void)PMBus_getTargetData(PMBUSA_BASE,
                                          &g_PMBus_CTRL_VAR.rev_slave_addr,
                                          g_PMBus_CTRL_VAR.pmbus_a_sta);
                //HWREG(GPIODATA_BASE + GPIO_O_GPATOGGLE) = GPIO_GPATOGGLE_GPIO20;
            }
    
    //        PMBus_ackAddress(PMBUSA_BASE, (PMBUS_SLAVE_ADDR >> 1),
    //                         g_PMBus_CTRL_VAR.pmbus_a_sta,
    //                         &g_PMBus_CTRL_VAR.rev_slave_addr);
        }
        // Receive a data
        else if(g_PMBus_CTRL_VAR.pmbus_a_sta & (uint32_t)PMBUS_INTSRC_DATA_READY)
        {
            // Read slave address again due to complete address can be read in after address ACK sent
            g_PMBus_CTRL_VAR.rx_data[g_PMBus_CTRL_VAR.rx_cnt++] = PMBus_getOwnAddress_all_8_bits(PMBUSA_BASE);
    
            // Command check
            if(g_PMBus_CTRL_VAR.rx_cnt == 1)
            {
                PMBus_ackCommand(PMBUSA_BASE, 0x00, g_PMBus_CTRL_VAR.pmbus_a_sta,
                                 &g_PMBus_CTRL_VAR.rx_data[g_PMBus_CTRL_VAR.rx_cnt++]);
            }
            else
            {
                //Read General data
                PMBus_getTargetData(PMBUSA_BASE,
                                    &g_PMBus_CTRL_VAR.rx_data[g_PMBus_CTRL_VAR.rx_cnt++],
                                    g_PMBus_CTRL_VAR.pmbus_a_sta);
    
                // Send Acknowledge
                PMBus_ackTransaction(PMBUSA_BASE);
    
            }
        }
        // End of Message
        else if(g_PMBus_CTRL_VAR.pmbus_a_sta & (uint32_t)PMBUS_INTSRC_EOM)
        {
            // PEC valid check
            if (PMBus_isPECValid(g_PMBus_CTRL_VAR.pmbus_a_sta))
            {
                // Store PEC
                g_PMBus_CTRL_VAR.ctrl_sta_byte.bits.pec_valid = 1;
            }
        }
    }
    
    // PMBus_A ISR
    __interrupt void PMBus_A_ISR(void)
    {
        PMBus_A_handler();
    
        Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP8);
    }

    PMBus I/O 初始

        /* Enable I2C-B on GPIO14 - GPIO15 */
        GPIO_setPadConfig(14, GPIO_PIN_TYPE_PULLUP);     // Enable pull-up on GPIO14
        GPIO_setPadConfig(15, GPIO_PIN_TYPE_PULLUP);     // Enable pull-up on GPIO15
        GPIO_setQualificationMode(26, GPIO_QUAL_ASYNC);  // asynch input
        GPIO_setQualificationMode(27,GPIO_QUAL_ASYNC);   // asynch input
        GPIO_setPinConfig(GPIO_14_PMBUSA_SDA);             // GPIO14 = SDAB
        GPIO_setPinConfig(GPIO_15_PMBUSA_SCL);             // GPIO15 = SCLB

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

    根据您的代码和问题、假设您将 F28003x 用作 PMBus 控制器接收器、目标是某个发送器。  没有收到 ACK 的原因是、您的目标发送器没有释放 SDA 线、以便 F28003x 可以将其拉低(这是 ACK 所必需的)。 据我所知、SCL 也可以保持低电平以确保 ACK 可以 正确计时、但要点是来自发送器的数据线必须被释放、以便通过 I2C 的 PMBus 可以发送 ACK。

    请确保您将目标发送器配置为从 F28003x 接收器接收到的 ACK。 如果它到达 您用于确认的代码中的断点、这意味着 F28003x 正在尝试按预期进行确认。

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

    您好、Omer:

    我 澄清了 F28003x 的角色。 一个 PMBus 目标器件。 PMBus 控制器来自带 PC 的 I2C 通信卡。

    我的主要问题:我使用  PMBus_ackTransaction (PMBUSA_BASE)、设置 PMBACK 的 ACK、  尝试 在 F28003x 接收到有效的从器件 地址但 F28003x 仍向控制器发送 NACK 时向控制器发送 ACK。

    我 正在考虑降低一些重要的 配置、请帮助我检查它、谢谢。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我 澄清了 F28003x 的角色。 一个 PMBus 目标器件。 PMBus 控制器来自带 PC
    的 I2C 通信卡

    F28003x 是目标发送器还是目标接收器? 如果它是接收器、则发送器必须释放 SDA 线:

    (摘自《了解 I2C 总线》应用报告)

    我的主要问题:我使用  PMBus_ackTransaction (PMBUSA_BASE)、设置 PMBACK 的 ACK、   当 F28003x 接收到有效的从器件 地址但 F28003x 仍向控制器发送 NACK 时、尝试向控制器发送 ACK。[/报价]

    要发送 ACK、PMBus 外设将尝试将 SDA 线拉低。 如果它无法将其拉低、除非 硬件损坏或其他东西将 SDA 上拉或将其驱动为高电平、唯一的另一个原因是发送器未释放 SDA 线。 这 不太可能与 F28003x 器件相关、如果您认为这是这样、则可以使用发送 ACK 时已知正常的东西来测试发送器。 在尝试找到该 NACK 的一些其他源之前、需要检查此项。

     要降低一些重要的 配置,请帮我检查,谢谢。

    我不确定我是否理解您在这里试图说的内容。

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

    尊敬的 Omer Amir:

     我使用 SUB20 作为 I2C 主器件、它可以与其他平台(Microchip、ST 等)进行 I2C 通信 通过软件进行手动 ACK 控制的应用。

    所以、我认为这块通信卡没有问题。

    示波器图为基础、 在设置 PMBACK 的 ACK 时、可能不会拉低 SDA 作者  F28003x   

    我 怀疑 我的初始 PMBus 配置有误。 我可以帮助您检查我提供的源代码。

    感谢您的支持。

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

    您可以检查一些事项、以帮助我确认此处发生的情况。 首先、我注意到您在 SUB20链接中包含的用户指南说明有状态、这是您可以在 PC 上查看的内容吗? 它可能有助于调试网络中正在发生的情况、

    我还想确认的是、F28003x 实际上已识别出正确的地址、您能否确认 您的代码已到达 ISR、以及手动确认函数的执行不会引发错误或陷入任何类型的循环? 您是否还可以验证在控制器将目标地址发送到 F28003x 后是否设置了地址确认位? 此外、您能否验证何时 PMBus_ackTransaction 函数执行 PMBACK 寄存器中的 ACK 位是否已设置? 您可以在 CCS 调试会话中使用"Registers"(寄存器)视图查看器件的寄存器位("View">"Registers"(视图>寄存器))。

    我仔细检查了您的 PMBus 目标配置、在使用目标地址/掩码值为目标模式进行配置时、它看起来是正确的。

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

    请参阅下图、我在 PMBus_A ISR 的"接收到从器件地址"时设置了断点。

    当我向  F28003x 发送从器件地址时、FW 会执行相应的 功能。

    然后,接收到的从地址有效, 执行 PMBUS_ackTransaction ()。 PMBACK 的 ACK 被置位。

    我认为、当  F28003x 从器件地址从器件地址接收到一个从器件地址时、PMBus_A ISR 没有任何错误、

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    然后,收到的从地址有效, 执行 PMBus_ackTransaction ()。 已设置 PMBACK 的 ACK。[/报价]

    寄存器位已设置、但在调试期间将其范围扩大的同时、您看不到 SDA 线路上的 ACK 吗?

    您可以检查一些事项,以帮助我确认此处发生了什么。 首先、我注意到您在 SUB20链接中包含的用户指南说明有状态、这是您可以在 PC 上查看的内容吗? 它可能有助于调试正在发生的情况

    您是否还能确认我之前提到的这一点?

    [/quote]
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    因此设置了寄存器位,但当您在调试期间同时对其进行寻址时,您在 SDA 行上看不到 ACK?

    是的、在我设置  PMBACK 的 ACK 后、SDA 仍为"高电平"

    您是否还能确认我之前提到的这一点?

    SUB 仅提供用于基本 I2C 操作的驱动器。 我看不到驱动程序的源代码、所以以后再也无法分析低于20的操作。

    但根据其他平台的经验、SDA 在向  F28003x 发送从器件地址后不保持高电平

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

    此时、我不确定为目标配置 F28003x PMBus I2C 模式时可能会出现什么问题、因为地址看起来已正确加载(如果尚未加载、我建议在 CCS 调试会话的"Register"视图中仔细检查)。

    我将尝试请设计专家了解可能会出现什么情况。 他们可能需要一些时间才能联系我、因此、在此期间 、如果您有另一个 F28003x 器件可用(或另一个上面有 PMBus 的 C2000器件)、 您能否尝试将其配置 为控制器、看看您是否可以让另一个 F28003x 器件将其视为 ACK? 如果此操作有效、请尝试反转两个器件上的配置。 这将是确定 F28003x 存在问题以及是只存在其中一个还是两个问题的最佳方法。

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

    尊敬的 Omer:

    您有任何更新吗?

    在这种情况下使用 PMBACK (PMBus 目标发送器)时是否有考虑因素?

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

    没有更新、我仍在与设计专家积极合作、但到目前为止、他们对此处可能发生的情况没有任何理论。

    在这种情况下使用 PMBACK (PMBus 目标发送器)时是否考虑过此问题?

    如果您说的是手动 ACK 与自动 ACK 配置、我不确定。 我将与设计专家确认可能发生的情况、并告知您。

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

    尊敬的 Omer:

    您有任何更新吗?

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

    设计团队使用自己的代码进行了测试、发现现在存在问题、手动 ACK 工作正常。 我看了一下他们使用的源代码、这些是他们的配置:

        PMBus_enableModule(PMBUSA_BASE);
        PMBus_initSlaveMode(PMBUSA_BASE,0x5A,PMBUS_SLAVE_DISABLE_ADDRESS_MASK);
        PMBus_enableI2CMode(PMBUSA_BASE);
    
        PMBus_configSlave(PMBUSA_BASE,
                          PMBUS_SLAVE_ENABLE_MANUAL_ACK|
                          PMBUS_SLAVE_AUTO_ACK_4_BYTES);
    
        PMBus_configModuleClock(PMBUSA_BASE,10000000,200000000);
        PMBus_enableInterrupt(PMBUSA_BASE,PMBUS_INT_DATA_READY| PMBUS_INT_EOM | PMBUS_INT_SLAVE_ADDR_READY);

    从 ISR 调用的函数(我删除了与此无关的部分):

    void PMBUS_EOM_SLAVE(void) {
        uint16_t ui32Index;
        uint32_t ix;
        uint16_t num_rx_bytes = 0;
        uint32_t status_check =0;
        status_check = HWREG(PMBUSA_BASE + PMBUS_O_PMBSTS);
        if(status_check & PMBUS_INT_STATUS_ADDR_READY)
        {
            slave_addr=HWREG(PMBUSA_BASE + PMBUS_O_PMBRXBUF);
            if(slave_addr==0x5A)
            {
                HWREG(PMBUSA_BASE+PMBUS_O_PMBACK)|=PMBUS_PMBACK_ACK;
            }
            address_ack_int++;
        }
    
        if(status_check & PMBUS_INT_STATUS_DATA_READY)
        {
            HWREG(PMBUSA_BASE + PMBUS_O_PMBACK) |= PMBUS_PMBACK_ACK;
            int_count++;
    
        }
    
        if( status_check & PMBUS_PMBSTS_EOM)
        {
            int_count++;
        }
    }

    我将请他们尝试此处提供的配置、以查看这些配置是否有效、或者这是不是导致问题的原因。

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

    遗憾的是、看起来他们无法重现问题。 如果这对您来说仍然是个问题、并且您已经在我的上一篇文章(第一个代码片段)中检查了配置、请告诉我。

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

    您好、Omer:

    感谢您的支持。 我认为根本原因已经找到。

    I 在 F280039C 上进行测试。 SCL 连接到 J13的 EQEP2A、并且 QEP2 SEL 设置为0

    EQEP2A 为5.0V 电平。 但 PMBus 主器件是3.3V 电平。 在始终模式下使 NACK 状态为

    我将 SCL 更改为 J4的 PIN32。 这是可行的。

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

    您好、Omer:

    新问题需要 澄清:

    PMBus 主设备发送数据包、 "wr_addr (0x58)-cmd (0x00)-data (0x01)-PEC (0xED)" 至从器件(F280039C)。 这就是成功。 请参阅下图:

    然后、我尝试再次向从器件发送相同的数据包。 发生错误。 它是"从器件地址 NACK"。  请参阅下图:

    我仔细检查  F280039C 接收到的从器件地址。 它是0xD8、而非0x58。

    地址的波形为0x58。 但 PMBSHA 和 PMBRXBUFF 为0xD8。

    然后、我尝试再次向从器件发送相同的数据包。 这是可行的。

    状态为 OK-FAIL-OK-FAIL 切换。 如果之前是正常的、则接下来是失败的。

    否则、前面是失败的、接下来是正常的。

    当 EOM 中断 发生时我执行某操作:复位 PMBus 模块。 总是可以的。 不发生从器件地址

    请参考以下源代码:

    PMBus 初始值:

    void PMBus_A_init(void)
    {
        uint32_t moduleFreq = 0U;
    
        // Disable PMBus_A bus first
        PMBus_disableModule(PMBUSA_BASE);
    
        // Initial PMBus_A Module clock
        moduleFreq = PMBus_configModuleClock(PMBUSA_BASE, PMBUS_SYS_FREQ_MIN,
                                              PMBUS_SYS_FREQ_MAX);
        // Initial PMBus_A support fast mode
        PMBus_configBusClock(PMBUSA_BASE, PMBUS_CLOCKMODE_FAST, moduleFreq);
    
    
        // Initial PMBus_A Target mode(Enable target mode, Slave address mask, and default slave address)
        PMBus_initTargetMode(PMBUSA_BASE,(PMBUS_SLAVE_ADDR >> 1), PMBUS_SLAVE_DISABLE_ADDRESS_MASK );
    
        // Enable I2C mode
        PMBus_enableI2CMode(PMBUSA_BASE);
    
        // Initial PMBus_A Configuration(PEC enabled, manual address & command, manual ACK for RX byte set to 1)
        PMBus_configTarget(PMBUSA_BASE,
                           PMBUS_TARGET_ENABLE_PEC_PROCESSING |
                           PMBUS_TARGET_ENABLE_MANUAL_ACK |
                           PMBUS_TARGET_ENABLE_MANUAL_CMD_ACK |
                           PMBUS_TARGET_AUTO_ACK_1_BYTES);
    
        // Initial PMBus_A interrupt triggered types
        PMBus_enableInterrupt(PMBUSA_BASE,
                              PMBUS_INT_TARGET_ADDR_READY |
                              PMBUS_INT_DATA_READY |
                              PMBUS_INT_DATA_REQUEST |
                              PMBUS_INT_EOM);
    
    
        // Initial PMBus_A driver control variable
        Initial_Control_Variable();
    
        // Register PMBus interrupt
        Interrupt_register(INT_PMBUSA, PMBus_A_ISR);
    
        // ACK any pending group interrupts
        Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP8);
    
        // Enable PMBus_A interrupt
        Interrupt_enable(INT_PMBUSA);
    
        // Enable PMBus_A module
        PMBus_enableModule(PMBUSA_BASE);
    }
    

    2. PMBus ISR:

    void PMBus_A_handler(void)
    {
        // Get Current PMBus_A State
        g_PMBus_CTRL_VAR.pmbus_a_sta = PMBus_getStatus(PMBUSA_BASE);
    
        // Slave address received
        if(g_PMBus_CTRL_VAR.pmbus_a_sta & (uint32_t)PMBUS_INTSRC_TARGET_ADDR_READY)
        {
            // Reset "8-bits address get" state
            g_PMBus_CTRL_VAR.spe_byte.bits.addr_8_bits_get = 0;
    
            // Get Current slave address(7-bit address), doesn't include R/W bit
            g_PMBus_CTRL_VAR.rev_slave_addr = PMBus_Received_Address(PMBUSA_BASE);
    
            // 7-bit Address check
            if (g_PMBus_CTRL_VAR.rev_slave_addr == (PMBUS_SLAVE_ADDR >> 1))
            {
                HWREG(GPIODATA_BASE + GPIO_O_GPATOGGLE) = GPIO_GPATOGGLE_GPIO20;
                // Send ACK
                PMBus_ackTransaction(PMBUSA_BASE);
            }
            else
            {
                // Send NACK
                PMBus_nackTransaction(PMBUSA_BASE);
            }
        }
        // Receive a data
        else if(g_PMBus_CTRL_VAR.pmbus_a_sta & (uint32_t)PMBUS_INTSRC_DATA_READY)
        {
            // Read slave address again due to complete address can be read in after address ACK sent
            if (g_PMBus_CTRL_VAR.spe_byte.bits.addr_8_bits_get == 0)
            {
                // Read 8-bits address
                g_PMBus_CTRL_VAR.rev_slave_addr = PMBus_Received_Address_all_8bits(PMBUSA_BASE);
    
                // Initial control buffer
                Initial_Ctrl_Buffer();
    
                // Set get addressed done
                g_PMBus_CTRL_VAR.spe_byte.bits.addr_8_bits_get = 1;
    
                // Update to data buffer
                g_PMBus_CTRL_VAR.rx_data[g_PMBus_CTRL_VAR.rx_cnt++] = g_PMBus_CTRL_VAR.rev_slave_addr;
            }
    
            // Read data
            PMBus_getTargetData(PMBUSA_BASE,
                                &g_PMBus_CTRL_VAR.rx_data[g_PMBus_CTRL_VAR.rx_cnt++],
                                g_PMBus_CTRL_VAR.pmbus_a_sta);
    
            // Read Data
            if(g_PMBus_CTRL_VAR.rx_cnt == 2)
            {
                // Command check
                if(g_PMBus_CTRL_VAR.rx_data[g_PMBus_CTRL_VAR.rx_cnt - 1] == 0x00)
                {
                    HWREG(GPIODATA_BASE + GPIO_O_GPATOGGLE) = GPIO_GPATOGGLE_GPIO20;
                    PMBus_ackTransaction(PMBUSA_BASE);
                }
                else
                {
                    PMBus_nackTransaction(PMBUSA_BASE);
                }
            }
            else
            {
                // Send Acknowledge
                PMBus_ackTransaction(PMBUSA_BASE);
            }
        }
        // End of Message
        else if(g_PMBus_CTRL_VAR.pmbus_a_sta & (uint32_t)PMBUS_INTSRC_EOM)
        {
            // PEC valid check
            if (PMBus_isPECValid(g_PMBus_CTRL_VAR.pmbus_a_sta))
            {
                HWREG(GPIODATA_BASE + GPIO_O_GPATOGGLE) = GPIO_GPATOGGLE_GPIO20;
                // Store PEC
                g_PMBus_CTRL_VAR.ctrl_sta_byte.bits.pec_valid = 1;
                command_00_data =g_PMBus_CTRL_VAR.rx_data[2];
            }
            else
            {
                command_00_data = 0xFF;
            }
    
            // Re-initial PMBus module
            PMBus_disableModule(PMBUSA_BASE);
            PMBus_enableModule(PMBUSA_BASE);
        }
    }
    
    __interrupt void PMBus_A_ISR(void)
    {
        PMBus_A_handler();
    
        Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP8);
    }

    请帮助检查2个问题:

    为什么 当主器件始终发送正确的从器件地址时 F280039C 会逐周期接收错误 PMBus 地址?

    2.继续 Q1、为什么可通过复位 PMBus 模块解决该问题? 该方法是否 合适?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    然后,我再次尝试向从属设备发送相同的数据包。 发生错误。 它是"从器件地址 NACK"。  请参考下图:

    是否可以拍摄放大率更高且分辨率更高的屏幕截图? 我想尝试查看是否存在任何可能的噪声或其他差异(还请针对目标地址为 ACK 的屏幕截图执行此操作、但仅针对目标地址部分)。

    我仔细检查  F280039C 接收到的从器件地址。 它是0xD8、而非0x58。

    地址的波形为0x58。 但 PMBSHA 和 PMBRXBUFF 为0xD8。

    [/报价]

    您能否在工作案例中查看接收到的目标地址并发送相关的屏幕截图? 如果它不是同一个地址、它是否总是0x6C 被视为错误地址、或者地址是否不一致?

    2. 续第 Q1节、为什么可通过复位 PMBus 模块解决该问题? 该方法是否 合适?

    这更像是针对系统应用的一个问题;如果类似这样的东西不影响系统其余部分的功能、则 PMBus 外设复位没有问题。 然而、由于您必须复位、我想知道是否有某些未被适当清除的标志或状态、这些标志或状态由目标地址的 NACK 进行了修复。 您是否验证了 正常和故障情况的所有 PMBus 状态和标志都相同(除 NACK 之外)?

    [/quote]
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    是否可以采用更放大和更高分辨率的屏幕截图? 我想尝试查看是否存在任何可能的噪声或其他差异(还请针对目标地址为 ACK 的屏幕截图执行此操作、但仅针对目标地址部分)。

    请参阅下图:

    I SET CLK 频率为400KHZ。  看起来"数据设置时间"比 SMBus 3.0的规定值短

    我放大这一部分。  "数据设置时间"为110ns。

    SMBus 3.0将 "数据设置时间"定义为100ns、频率为400kHz。 它是如此的 裕度。 它不确定 它是否是根本原因。

    BTW、 PMBACK 置1后 CLK 释放多少次?

    注意:我使用 GPIO 低驱动来测量  在 PMBACK 设置1后 DAT 方向变为低电平的时间。 约为100ns。

    您能否在工作案例中查看接收的目标地址并发送其屏幕截图? 如果它不是同一个地址,是被视为不正确地址的0x6C 还是地址不一致?

    请参见下图。 地址为0x58、而非0x6C

    您是否已验证所有 PMBus 状态和标志 对于正常和失败情况都是相同的(除了 NACK)?

    我验证 PMBSTS 值。 它是0x00143401。 正常和失败之间是一样的

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

    除了您指出的数据设置时间之外、没有什么地方可以看出来、我将与设计团队确认这是否可能导致您遇到的问题、以及为什么会发生这种情况。

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

    尊敬的 Amir:  

    您是否有来自设计团队的任何更新?  

    此致、

    约翰尼

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

    不、我昨天再次向他们发送了电子邮件、但没有得到回复。 我一直在向他们传达消息、但由于其他项目、这些消息被延迟了。 我会在收到回复后通知您。

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

    您可以将您的项目发送给我吗? 您可以在此处填写、或者如果您拥有专有信息、您可以通过提出朋友请求来私下发送。 设计人员无法在最终复制这些内容、因此我需要为他们提供 导致您的程序出现状况的代码。

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

    请参阅随附的文件

    e2e.ti.com/.../PMBus_5F00_test_5F00_code.zip

    我仔细检查  F280039C 接收到的从器件地址。 它是0xD8、而非0x58。

    地址的波形为0x58。 但 PMBSHA 和 PMBRXBUFF 为0xD8。

    [/报价]

    我仔细检查了这个问题、当主机写入数据0x8D、然后主机发送手动模式的读取请求时、它可以重新生成。

    我尝试禁用手动地址 ACK/NACK 模式。 此问题不能生成

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

    谢谢、我会将其交给设计人员进行仿真。

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

    Jen、您好!

    设计团队仍然无法重现您在使用您 提供的配置时看到的问题。 您是否可以以低频(100kHz)运行 PMBus、以查看故障是否是由于违反时序造成的? 您是否还能共享确切的 I2C 主器件配置?