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.

TMS320F28386D: PEC_VALID bit of PMBSTS register in PMBus peripheral is never set

Part Number: TMS320F28386D
Other Parts Discussed in Thread: TMS320F28388D, UCD9090, , UCD9090-Q1

Hello,

We are using the TMS320F28388D evaluation board to communicate with an UCD9090 through the PMBus.

We send a write byte command with PEC enabled (command PAGE of the UCD with data byte set to 1) to the UCD.

We read back the current page of the UCD by sending a read byte command with PEC enabled. We expect to check the PEC code by reading the PEC_VALID bit of PMBSTS register but this bit is never set.

The data byte received is 1 as expected.

When looking at the signal on scope we can see that the PEC byte sent back by the UCD is 0x93 (which is the expected CRC that we previously computed).

PMBus peripheral is used as follow:

  • ALERT and CONTROL pins not used
  • Registers initial values:
  • We launch the read byte command (command PAGE of the UCD) as described in the TRM
  • We wait for the EOM by polling the status register then check the PEC_VALID bit (without re-reading the status register).

We should be able to check the PEC_VALID bit. Have we done anything wrong ?

Best regards,

Clément

  • Is UCD9090 master? PMBRXBUF doesn't seem to have receiver anything. Did PMBUS ACK or send NACK?

  • Is UCD9090 master?  Did you receive anything in PMbus slave? Why is your PMBRXBUF empty? Did slave ACK or NACK?

  • Manoj,

    The UCD9090-Q1 is not master but slave, the TMS320F28386D is master.

    The screenshot of the registers values is from before the exchanges as we stated, i.e. initial values.

    We do have ACK.

    Here is a screenshot of the PMBus exchange.

    And here is our C code:

    void APP_exec()
    {
        uint32_t status;
        uint16_t txBuffer[4U] = {0};
        uint16_t rxBuffer[4U] = {0};
        uint32_t computedFrequency;
        uint16_t nbBytesReceived;
    
        /* Initialize PMBUS pins */
        GPIO_setPinConfig(GPIO_24_PMBUSA_SCL);
        GPIO_setPadConfig(24, GPIO_PIN_TYPE_PULLUP);
        GPIO_setQualificationMode(24, GPIO_QUAL_ASYNC);
    
        GPIO_setPinConfig(GPIO_25_PMBUSA_SDA);
        GPIO_setPadConfig(25, GPIO_PIN_TYPE_PULLUP);
        GPIO_setQualificationMode(25, GPIO_QUAL_ASYNC);
    
        // Reset module
        PMBus_disableModule(PMBUSA_BASE);
        PMBus_enableModule(PMBUSA_BASE);
    
        PMBus_initMasterMode(PMBUSA_BASE);
    
        // Set module frequency
        computedFrequency = PMBus_configModuleClock(PMBUSA_BASE, 10000000U, DEVICE_SYSCLK_FREQ);
    
        if (computedFrequency != 10000000U)
        {
            // Error while configuring module clock
            ESTOP0;
        }
    
        /* Select page 1 with command PAGE */
    
        txBuffer[0] = PMBUS_CMD_PAGE;
        txBuffer[1] = 1;
    
        // 1 command byte + 1 data byte
        PMBus_putMasterData(PMBUSA_BASE, txBuffer, 2U);
    
        PMBus_configMaster(PMBUSA_BASE, 0x41U, 1U, PMBUS_MASTER_ENABLE_CMD | PMBUS_MASTER_ENABLE_PEC);
    
        do
        {
            status = PMBus_getStatus(PMBUSA_BASE);
        } while ((status & PMBUS_PMBSTS_EOM) == 0);
    
        DEVICE_DELAY_US(1000000);
    
        /* Read current selected page */
    
        txBuffer[0] = PMBUS_CMD_PAGE;
    
        // 1 command byte
        PMBus_putMasterData(PMBUSA_BASE, txBuffer, 1U);
    
        PMBus_configMaster(PMBUSA_BASE, 0x41U, 1U, PMBUS_MASTER_ENABLE_CMD | PMBUS_MASTER_ENABLE_READ|  PMBUS_MASTER_ENABLE_PEC);
    
        do
        {
            status = PMBus_getStatus(PMBUSA_BASE);
        } while ((status & PMBUS_PMBSTS_EOM) == 0);
    
        if (status & PMBUS_PMBSTS_EOM)
        {
            nbBytesReceived = PMBus_getData(PMBUSA_BASE, rxBuffer, status);
        }
    
        if ((status & PMBUS_PMBSTS_PEC_VALID) == 0)
        {
            ESTOP0; // PEC Invalid
        }
        else
        {
            ESTOP0; // PEC Valid
        }
    }
    

    Our code falls in the ESTOP0; // PEC Invalid which is not what we expect as we have enabled PEC.

    Hope it helps you narrowing down the problem.

    Clément

  • Clement,

    In PMBus Master Write byte configuration, command byte, data byte #0 and PEC is transmitted by master. PEC_VALID is only applicable when PMBus is receive mode. Here you are transmitting. So, PEC_VALID bit will not be set.

    Regards,

    Manoj

  • Manoj,

    If you look closely, we are checking the PEC_VALID when reading, not writing, the first write is aimed at configuring what our read will target.

    Today, we investigated a bit and found out we weren't detecting the PEC bit set because it was most certainly cleared in our while loop where we wait for EOM bit to be set in PMBSTS register as it is clear on read.

    We added a check to log a PEC bit set status and it triggered:

    isPECValid = false;
    
    do
    {
    status = PMBus_getStatus(PMBUSA_BASE);
    
    if (status & PMBUS_PMBSTS_PEC_VALID)
    {
    isPECValid = true;
    }
    
    } while ((status & PMBUS_PMBSTS_EOM) == 0);
    
    if (status & PMBUS_PMBSTS_EOM)
    {
    nbBytesReceived = PMBus_getData(PMBUSA_BASE, rxBuffer, status);
    }
    
    if (isPECValid == false)
    {
    ESTOP0; // PEC Invalid
    }
    else
    {
    ESTOP0; // PEC Valid
    }

    However, this is inconsistent with the TRM which states for the PEC_VALID bit of the PMBSTS register:

    0 = Received PEC not valid (if EOM is asserted)
    1 = Received PEC is valid
    Note: PEC_VALID status is don't care during the message. This will
    have a valid value only after EOM.
    Reset type: SYSRSn

    It would seem like PEC_VALID is not set at the right moment.

    Note that we did check at some point if PEC_VALID was at 1 in the last value of the status variable which makes us leave the wait loop.

    Clément

  • Clement,

    Yes, PEC_VALID bit is Read to Clear bit.

    I believe your point is the PEC_VALID bit should get set only after EOM bit, but it seems to be getting set before EOM. I need to check with design on the timing of this PEC_VALID and EOM bit.It possible that PEC_VALID is getting set before EOM bit.

    However, Have your tried this below changes to your code

    do
    {
    status = PMBus_getStatus(PMBUSA_BASE);

    if (status & PMBUS_PMBSTS_PEC_VALID)
    {
    isPECValid = true;
    }

    } while ((status & PMBUS_PMBSTS_PEC_VALID)) == 0);

    Regards,

    Manoj

  • Manoj,

    Yes it seems PEC_VALID is set before EOM bit which is not as documented in the TRM as we are not supposed to care about the PEC_VALID bit until EOM is set and both are in the same register.

    We did not try that as EOM is the end of message bit so it seems more logical to wait for it before check the validity.

    Clément

  • As I said before, I need to check with design on timing perspective. I don't have immediate answer on this question. Typically, I expect to get a design response in 2 weeks time frame. I shall update you once I get this information.

    My response to the earlier thread was to provide a solution to your problem.

    Regards,

    Manoj

    • Are you doing write byte transaction followed by read byte?
    • When F28386D PMBus send write byte transaction, was PEC_VALID bit set in UCD9090.PMBUS?
    • Do you see the problem in C2000 PMBus when you do read byte transaction? Did you receive the correct PEC byte from UCD9090?
    • It looks like you are using polling method instead of interrupt? Correct?
  • Manoj,

    • Are you doing write byte transaction followed by read byte?
    Yes: we select the UCD9090 current page by doing a write byte transaction with address = 0x41, command = 0x00 and data = 0x01 And then we read back the current selected page by doing a read byte transaction with address = 0x41, command = 0x00. Received data is 0x01 as expected.
    • When F28386D PMBus send write byte transaction, was PEC_VALID bit set in UCD9090.PMBUS?
    What do you mean exactly ? 
    • Do you see the problem in C2000 PMBus when you do read byte transaction? Did you receive the correct PEC byte from UCD9090?
    As I stated above, we do if we poll it before EOM (which is not what we are supposed to do as per the TRM as I said).
    • It looks like you are using polling method instead of interrupt? Correct?
    Yes, we poll the PMBSTS register to handle the transaction, all interrupts propagation are disabled.
     
    Clément
  • As I stated above, we do if we poll it before EOM (which is not what we are supposed to do as per the TRM as I said).

    Just to confirm, following statement are correct:

    1) C2000 PMBus did receive the correct PEC byte from UCD9090

    2) You were able to see PEC_VALID bit set, but it got cleared

    3) Your main concern is, TRM tells that PEC_VALID bit is supposed to get set after EOM. But, here you were observing PEC_VALID bit get set before EOM.

  • Manoj,

    1) Yes

    2) Yes, we didn't see it at first because when EOM got to 1, PEC_VALID had been cleared by our previous read waiting for EOM to set.

    3) The TRM indicates that the state of PEC_VALID is not relevant until EOM gets set so yes.

    Clément

  • Clément,

    I have submitted a JIRA ticket to track this item. I have already pinged design team to look into the timing of PEC_VALID bit and EOM bit. I expect to hear back from design team in 10 business days. I shall keep you posted.

    Regards,

    Manoj

  • Hi Manoj,

    Any news on this matter ?

    Best regards,

    Clément

  • Design team took up this issue and is running simulation.

    I'm expecting an update by next week.

    Regards,

    Manoj

  • Clement,

    Here is the feedback received from design. From a timing perspective, PEC_VALID bit is set one (or) two PMBus CLK cycles before EOM bit get set. When you using polling method on EOM bit, there is a possibility of CPU reading PMBSTS just when PEC_VALID bit is set but EOM bit is still not set. This would clear the PEC_VALID bit just like you reported.

    Here is the workaround suggested:

    Enable EOM interrupt from PMBus at peripheral level. This allows you to poll for PIEIFR9. INTx13 bit (to know whether EOM occured) instead of relying the PMBSTS register.

    Note: Make sure you don't enable PIEIER9.INTx13 (PMBUS interrupt). This will ensure you don't interrupt CPU.

    //PMBus interrupt (EOM) is reported in INT9.13. So, poll this flag

    #define WAIT_FOR_EOM_INTERRUPT_FLAG !((HWREGH(PIECTRL_BASE + PIE_O_IFR9) & 0x1000) == 0x1000)

    PMBus_enableInterrupt(PMBUSA_BASE, PMBUS_INT_EOM);

    while(WAIT_FOR_EOM_INTERRUPT_FLAG );

    //Now, when you read PMBSTS register you should see both PEC_VALID and EOM bit set when you get receive a valid PEC_VALID byte

    status = PMBus_getStatus(PMBUSA_BASE);

    if (status & PMBUS_PMBSTS_PEC_VALID)
    {
    isPECValid = true;
    }

    if (status & PMBUS_PMBSTS_EOM)
    {
    nbBytesReceived = PMBus_getData(PMBUSA_BASE, rxBuffer, status);
    }

    if (isPECValid == false)
    {
    ESTOP0; // PEC Invalid
    }
    else
    {
    ESTOP0; // PEC Valid
    }

    Regards,

    Manoj

  • Manoj,

    Thanks for the response.

    Will the TRM be updated to correct the errorneous indication PEC_VALID is don't care until EOM is set ?

    Best regards,

    Clément

  • Yes, I have filed a ticket. I will be updating the TRM. You should see this update in next TRM release