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.

UCD90320: Need to turn rail on and off on UCD90320 using I2C on Raspberry Pi

Part Number: UCD90320

Hello,

I am trying to turn rail on and off on UCD90320 using I2C on Raspberry Pi. I would like to know if this can be done, if yes what are command format to communicate with UCD using I2C/PMBUS. 

Can anyone point me in the right direction?

Thanks

  • Hi 

    Yes, you can use the PMBus commands to turn on the rail one by one. 

    For each target rail, please follow the below steps

    1.  send out the PAGE_COMMAND(write byte command) with the correct index(0->rail1, 1->rail2. ... and so one) to select the target rail

    2.  send out the ON_OFF_CONIG(write byte c command) with Bit 4 and Bit 3 set. this is to allow that the rail is controlled by OPERATION command. Please refer section 12.2 https://470q2hhkn9g15l4bc2btbal1-wpengine.netdna-ssl.com/wp-content/uploads/2021/05/PMBus-Specification-Rev-1-2-Part-II-20100906.pdf 

    3. send out the OPERATION(write byte command) to turn on or off the rail. please refer section 12.1 of https://470q2hhkn9g15l4bc2btbal1-wpengine.netdna-ssl.com/wp-content/uploads/2021/05/PMBus-Specification-Rev-1-2-Part-II-20100906.pdf 

    Regards

    Yihe

  • Thanks!

    I am assuming handshake protocol and Addressing is same as I2C protocol,

  • Hi

    You can refer section 5.5 of http://smbus.org/specs/smbus20.pdf to understand the SMBus/PMBus protocol, which is based on the I2C protocol. 

    Regards

    Yihe 

  • The PAGE_COMMAND you are referring to in #1, is it the  PAGE_PLUS_WRITE  command described in  section 11.14 of the PMBUS Specification document? 

  • Hi

    It is PAGE command(command code 0x0),section 11.10 of PMBus spec

    Regards

    Yihe

  • Thanks for your response, but I am still confused about the Page Command. Section 11.10 does not say much. I don't see any example or the bits I need to set for PAGE command.Am I supposed to refer to section 11.14 and 11.15. If yes, then how do I know parameters in the example shown for those section (Pg 52) ? What do I use for PAGE_PLUS COMMAND CODE, PAGE NUMBER, COMMAND CODE?

    Do you have any sample code for communicating with UCD through I2C? That would really help.

    All the rails are turned ON by default in my system, I would like to turn it off one at a time for test automation. Any help would be appreciated. Here is my example code to communicate with the UCD90320.

    import smbus
    import sys
    import time
    
    Channel = 1
    I2C = smbus.SMBus(Channel)
    Address = 0x68
    
    ##################################################################################
    def I2C_Write(PAGE_COMMAND, ON_OFF_CONFIG, OPERATION_OFF):
        I2C.write_i2c_block_data(Address, PAGE_COMMAND, ON_OFF_CONFIG, OPERATION_OFF)
    
    
    ##################################################################################
    
    ON_OFF_CONFIG = 0b00001011
    OPERATION_ON = 0b10000000  #ON
    OPERATION_OFF = 0b00000000  #OFF
    PAGE_COMMAND = ??
    
    I2C_Write(PAGE_COMMAND, ON_OFF_CONFIG, OPERATION_OFF)

  • Hello

    You can refer section v6.1 of https://www.ti.com/lit/ug/slvuaw9c/slvuaw9c.pdf.

    Please be noted there is a typo in the Table 3, the max number of rail on UCD90320 is 32 instead of 24. 

    Page command is a write byte command, the command code is 0x00, for example, if you want to select 4th rail. you have to send the following via your i2c software

    0x65(address) + 0x00(command code)+ 0x03(index to select 4th rail).

    Moreover, 

    ON_OFF_CONFIG = 0b00001011 this does not seems right. you have to use OPERATION instead of CONTROL PIN, it need be set to 0b00011000.

    PAGE, ON_OFF_CONFIG, OPERATION are three individual commands, you have to send these three commands one by one separately in the order as described in the original reply.

    Please refer section 5.5 of http://smbus.org/specs/smbus20.pdf to understand the SMBus/PMBus protocol.

    Regards

    Yihe

  • Hi

    You can refer below to use PAGE,ON_OFF_CONFIG and OPERATION to turn on and off for rail#5.

    Address CMD ID CMD_Code Phase Value_Encoded Value_Text
    101         PAGE         0x00     WRITE 0x04          Rail #5 / PAGE 0x04
    101         ON_OFF_CONFIG 0x02     WRITE 0x18          Mode: OPERATION Only
    101         OPERATION     0x01     WRITE 0x80          Unit: On; Margin: None
    101         OPERATION     0x01     WRITE 0x00          Unit: ImmediateOff; Margin: None

    Regards

    Yihe

  • Thanks a lot! now it is working!

    I have one more question, is there a way to read Voltage, Current and Temperature for a rail sensed by UCD's ADC?

  • Hi

    Yes, Please refer section 4 of this application note: https://www.ti.com/lit/pdf/slva385 

    Regards

    Yihe

  • Thanks for your guidance, I was able to read the voltage and current for all the rails.

    As for the temperature reading there are 3 temperature reading commands (0x8D, 0x8E, 0x8F), and I am not sure which one is the correct one for UCD90320. Also I don't see a column for UCD90320 in Table 3 of  the document below. How do I know which command applies to UCD90320? Is there a newer version of this document?

    Also is there any command to see fault status for all the rails?

    https://www.ti.com/lit/ug/slvu352g/slvu352g.pdf?ts=1624403325041&ref_url=https%253A%252F%252Fwww.google.com%252F

    Another question is I am trying to read MFN ID, MFN_MODEL , etc. from UCD using the commands listed in table 3. However I get a big number and I am not sure how to make sense of it. It also seems to change every now and then, for e.g. MFN Location below.

    MFN_ID: 19718
    MFN_MODEL: 19721
    MFN_REVISION: 19724
    MFN_LOCATION: 19724
    MFN_DATE: 22790
    MFN_SERIAL: 22790

    MFN_ID: 19718
    MFN_MODEL: 19721
    MFN_REVISION: 19724
    MFN_LOCATION: 19852
    MFN_DATE: 22790
    MFN_SERIAL: 22790

    MFN_ID: 19718
    MFN_MODEL: 19721
    MFN_REVISION: 19724
    MFN_LOCATION: 19724
    MFN_DATE: 22918
    MFN_SERIAL: 22790

    code using for polling:

    MFN_ID = 0x99
    MFN_MODEL = 0x9A
    MFN_REVISION = 0x9B
    MFN_LOCATION = 0x9C
    MFN_DATE = 0x9D
    MFN_SERIAL = 0x9D
    
    MFN_ID_get = I2C.read_word_data(ADDRESS, MFN_ID)
    print("MFN_ID: {}".format(MFN_ID_get))
    
    MFN_MODEL_get = I2C.read_word_data(ADDRESS, MFN_MODEL)
    print("MFN_MODEL: {}".format(MFN_MODEL_get))
    
    MFN_REVISION_get = I2C.read_word_data(ADDRESS, MFN_REVISION)
    print("MFN_REVISION: {}".format(MFN_REVISION_get))
    
    MFN_LOCATION_get = I2C.read_word_data(ADDRESS, MFN_LOCATION)
    print("MFN_LOCATION: {}".format(MFN_LOCATION_get))
    
    MFN_DATE_get = I2C.read_word_data(ADDRESS, MFN_DATE)
    print("MFN_DATE: {}".format(MFN_DATE_get))
    
    MFN_SERIAL_get = I2C.read_word_data(ADDRESS, MFN_SERIAL)
    print("MFN_SERIAL: {}".format(MFN_SERIAL_get))

  • Hi

    UCD90320 has its own document https://www.ti.com/lit/ug/slvuaw9c/slvuaw9c.pdf 

    Those number are programmed by customers. Have you programmed them?

    Regards

    Yihe 

  • Yes I programmed them as follow: 

    https://drive.google.com/file/d/14g_p3WxabDeY-Unr7OWU0PEArksrvX6o/view?usp=sharing

    Also is there any command to see fault status for all the rails?

  • Hi

    Those MFR_XX is block read command. you have to make sure that your software support these. Please refer SMBus protocol posted in the previous reply to ensure these.

    Please refer the PMBus spec posted in the previous reply to understand STATUS_VOUT and how to  read it.

    Please refer UCD90320 pmbus command reference guide posted previously to understand how to read MFR_STATUS.

    Regards

    Yihe

  • Thanks for pointing me in the right direction. I was able to read the STATUS_VOUT, STATUS_IOUT and STAUS_BYTE

    One last question I have is, when I read  Vout, Iout or Temperature status byte, sometimes I get random fault set even though there is no fault.

    In the example below, you see the left most bit of the STATUS_VOUT and STATUS_IOUT being set on the first pass and then goes away in  second pass. Also it is random, sometime it show fault sometimes it does not. Please advise.

    Output:

    Measuring: VCC5
    Voltage/Current/Temp: 5.135 / 0.002 / 36.812
    *** VOUT_OV_FAULT
    *** IOUT_OC_FAULT
    STATUS_VOUT: 10000000
    STATUS_IOUT: 10000000
    STATUS_TEMP: 0
    Vout_status/Iout_status/Temp_status: NOT OK / NOT OK / OK
    
    Measuring: VCC5
    Voltage/Current/Temp: 5.137 / 0.000 / 36.812
    STATUS_VOUT: 0
    STATUS_IOUT: 0
    STATUS_TEMP: 0
    Vout_status/Iout_status/Temp_status: OK / OK / OK

    Python code:

    STATUS_VOUT = 0x7A
    STATUS_IOUT = 0x7B
    STATUS_TEMPERATURE = 0x7D
    
    def faults():
        STATUS_VOUT_get = I2C.read_byte_data(ADDRESS, STATUS_VOUT)
        if STATUS_VOUT_get != 0:
            Vout_status = "NOT OK"
            if STATUS_VOUT_get >> 7 & 1:
                print("*** VOUT_OV_FAULT")
            if STATUS_VOUT_get >> 6 & 1:
                print("*** VOUT_OV_WARNING")
            if STATUS_VOUT_get >> 5 & 1:
                print("*** VOUT_UV_WARNING")
            if STATUS_VOUT_get >> 4 & 1:
                print("*** VOUT_UV_FAULT")
        else:
            Vout_status = "OK"
            
        print("STATUS_VOUT: {0:b}".format(STATUS_VOUT_get))
        
        ..... and so on for Iout and Temperature
        
        return Vout_status, Iout_status, Temp_status
        
    #Main
    
    Vout_status, Iout_status, Temp_status = faults()   
    print("Vout_status/Iout_status/Temp_status: {} / {} / {}".format(Vout_status, Iout_status, Temp_status))

  • Hi

    Have you sent out PAGE command to select the rail before these status command? Do you have the fusion GUI running at the same time?

    Regards

    Yihe

  • Yes I do have a page command before querying for the statuses. I tried to edit and add Page command in the code above, but looks like it wont accept my edit. But anyway there is a page command before  the code.

    I2C.write_byte_data(ADDRESS, PAGE_COMMAND, rail)
    time.sleep(0.1)

    No TI Fusion GUI is not running at the same time.

  • Hi

    What's the interval between each command? Do you have a waveform to show it?

    Regards

    Yihe 

  • I don't have the waveform, but I tried adding different delay been the commands (10us to 500ms) and it still shows similar behavior.

  • Hi

    Do you have other I2C host access the UCD at the same time? I would recommend to read the PAGE command back to ensure that you were accessing the right rail. Also a waveform could tell whether there is any signal integrity issue. 

    You can also use GUI's low level SMBus& I2C tool test. please follow the below video

    https://training.ti.com/fusion-power-designer-low-level-i2c-smbus-debugger?context=1136655-1139495-1136567 

    Regards

    Yihe

  • No, I don't have any otherI2C host connected to the UCD. I tried reading page back as well, page is set correctly.

    GUI;s low level SMBUS I2C shows no fault. Not sure why raspberry Pi occasionally reads fault on 7th bit.

    I don't have access to an oscilloscope to view waveform at the moment (working from home).

  • Hi

    Have you tried to use the low level SMBUS I2C Tool to run the same test? 

    Regards

    Yihe

  • Yeah I tried using the low level SMBUS I2C Tool, it shows no fault in Status_Vout , STATUS_Iout or STATUS_Temperature.

  • Hi

    It seems there are some signal integrity between your host and UCD. A waveform can definitely help. What's your pull up on SCL/SDA?

    Regards

    Yihe

  • I finally got my hand on an I2C analyzer (Picoscope). I dont see waveform bring distorted or anything, they look good to me. Please see last image below.

    I see no error when reading Voltage, Current or Temperature. I can read the correct data from UCD.

    The problem is when reading Vout_Status Iout_status and Page command. It seems like the MSB is somehow set to 1 every few transactions. I didnt see these MSBs being set on Picoscope waveform.

    For example here is the code I have to read the status:

    def faults(rail):
        print("Page set to:", rail)
        I2C.write_byte_data(ADDRESS, PAGE_COMMAND, rail)
        time.sleep(0.5)
        PAGE = I2C.read_byte_data(ADDRESS, PAGE_COMMAND)
        print("Page read back: ", PAGE)
        time.sleep(0.5)
        
            # Vout Status
        STATUS_VOUT_get = I2C.read_byte_data(ADDRESS, STATUS_VOUT)
        if STATUS_VOUT_get != 0:
            Vout_status = "NOT OK"
            if STATUS_VOUT_get >> 7 & 1:
                print("*** VOUT_OV_FAULT")
            if STATUS_VOUT_get >> 6 & 1:
                print("*** VOUT_OV_WARNING")
            if STATUS_VOUT_get >> 5 & 1:
                print("*** VOUT_UV_WARNING")
            if STATUS_VOUT_get >> 4 & 1:
                print("*** VOUT_UV_FAULT")
        else:
            Vout_status = "OK"
    
        time.sleep(0.5)
    
        # Iout Status
        STATUS_IOUT_get = I2C.read_byte_data(ADDRESS, STATUS_IOUT)
        if STATUS_IOUT_get != 0:
            Iout_status = "NOT OK"
            if STATUS_IOUT_get >> 7 & 1:
                print("*** IOUT_OC_FAULT")
            if STATUS_IOUT_get >> 6 & 1:
                print("*** IOUT_OC_LV_FAULT")
            if STATUS_IOUT_get >> 5 & 1:
                print("*** IOUT_OC_WARNING")
            if STATUS_IOUT_get >> 4 & 1:
                print("*** IOUT_UC_FAULT")
        else:
            Iout_status = "OK"
    
        time.sleep(0.5)
    
        # Iout Status
        STATUS_TEMP_get = I2C.read_byte_data(ADDRESS, STATUS_TEMPERATURE)
        if STATUS_TEMP_get != 0:
            Temp_status = "NOT OK"
            if STATUS_TEMP_get >> 7 & 1:
                print("*** OT_FAULT")
            if STATUS_TEMP_get >> 6 & 1:
                print("*** OT_WARNING")
        else:
            Temp_status = "OK"
    
    
        print("STATUS_VOUT: {0:b} - 0x{0:x}".format(STATUS_VOUT_get, STATUS_VOUT_get))
        print("STATUS_IOUT: {0:b} - 0x{0:x}".format(STATUS_IOUT_get, STATUS_IOUT_get))
        print("STATUS_TEMP: {0:b} - 0x{0:x}".format(STATUS_TEMP_get, STATUS_TEMP_get))
    
        return Vout_status, Iout_status, Temp_status
    
    ########################################################
    Main
    for i in range(0, 6):
        print("\nMeasuring: {}".format(array_rail_name[i]))
    
         Vout_status, Iout_status, Temp_status = faults(array_rail[i])
        print("Vout_status/Iout_status/Temp_status: {} / {} / {}".format(Vout_status, Iout_status, Temp_status))
        time.sleep(1)

    Here is the output from terminal, you can see the MSB of  VCC7 Rail STATUS_TEMP bit set, MSB of VCC5 Rail STATUS_VOUT has MSN set. I am not sure why the MSB is being set to 1 when there is no fault at all?

    Measuring: VCC12
    Page set to: 0
    Page read back:  0
    STATUS_VOUT: 0 - 0x0
    STATUS_IOUT: 0 - 0x0
    STATUS_TEMP: 0 - 0x0
    Vout_status/Iout_status/Temp_status: OK / OK / OK
    
    Measuring: VCC7
    Page set to: 1
    Page read back:  1
    *** OT_FAULT
    STATUS_VOUT: 0 - 0x0
    STATUS_IOUT: 0 - 0x0
    STATUS_TEMP: 10000000 - 0x80
    Vout_status/Iout_status/Temp_status: OK / OK / NOT OK
    
    Measuring: VCC5
    Page set to: 2
    Page read back:  2
    *** VOUT_OV_FAULT
    STATUS_VOUT: 10000000 - 0x80
    STATUS_IOUT: 0 - 0x0
    STATUS_TEMP: 0 - 0x0
    Vout_status/Iout_status/Temp_status: NOT OK / OK / OK
    
    Measuring: VCC_3p3
    Page set to: 3
    Page read back:  3
    STATUS_VOUT: 0 - 0x0
    STATUS_IOUT: 0 - 0x0
    STATUS_TEMP: 0 - 0x0
    Vout_status/Iout_status/Temp_status: OK / OK / OK

    Picoscope image and waveform:

  • Hello

    The waveform show correct data(MSB is 0), but somehow your software or hardware interpret the MSB to 1. You have to debug to see where the problem is.

    Regards

    Yihe

  • The waveform is not for the actual data output listed abive. But I will see what I can do.

  • Hi

    I recalled that you did not see the same issue when using the low level SMBus tool, so the issue is on the host side, either hardware or software.

    in the previous reply, you said there is no MSB set on the waveform. so i assumed that when you read MSB with 1 , the waveform has MSB set to 0.

    Regards

    Yihe

  • I wonder if it is the bus speed issue. UCD90320 runs at I2C speed of 400Khz, correct?

  • Hi

    No. 90320 is a I2C slave and can work with speed under 400Khz.

    Regards

    yihe

  • Solved! Raspberry Pi was running at 100khz. Set it to 400 Khz, working fine now!

    Thanks for all your help.

  • Hi 

    It is good to know that. But it does not sound right. 
    100Khz or 400Khz shall have no impact on 90320.

    regards

    Yihe

  • I think the raspberry  pi was messing it up during reading because of difference in Bus Speed. But why it affects Page and Status command, but does not affect Voltage and current reading is beyond me.

  • Hi 

    Voltage and current reading have different protocol as STATUS and PAGE command

    Regards

    Yihe

  • What do you mean by different protocol?

  • Hi

    One is write/read word the other is write/read byte.

    Regards

    Yihe