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
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.
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 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 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?
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
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))
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
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
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).
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:
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