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.

TPSM846C23EVM-806: i2c interface

Part Number: TPSM846C23EVM-806
Other Parts Discussed in Thread: TPSM846C23,

Tool/software:

Good day.

We will be using TPSM846C23 for our new evaluation board design. 

As part of validation, I've ordered TPSM846C23EVM-806 module to verify its i2c functionality but I couldn't get it working. I've been using Raspberry pi as a i2c interface and control the voltage but I couldn't get the communication working between the 2 devices.

Q1: TPSM846C23EVM-806 says its a PMbus compatible.. I believe it should work with I2c as well as they have both the same protocols?

Q2: Would raspberry pi works as a master i2c to verify this module? if not.. any other devices/interface i can use to verify it? 

Or am i just missing any important technical details of the module to get it working?

Thanks,

Jay

  • Hi Jay,

    The TPSM846C23 is a PMBus device so you got to make sure to communicate using PMBus 1.3 protocol. The way this device is typically sampled is by ordering the EVM which you already have done but additionally you can order USB2GPIO2 to connect device to computer and download our GUI to have access to all the digital features.

    This is how USB2GPIO2 dongle get connected in out EVM:

    https://www.ti.com/lit/ug/slvub26d/slvub26d.pdf#page=7 

    That way you don't have to do any coding or worry about doing write it a specific way, as that setup up along with our GUI automatically will recognize the TPSM846C23 device and display all the commands, along with the read values. It has a lot of functionality like monitor tab to keep up with IOUT/VOUT/TEMP etc., STATUS tab to keep track of specific error/s, and all commands page:

    I have not tried it with raspberry pi but the above should work. 

    Regards,

    Eileen

  • Hi Eileen,

    Thanks for the response.

    I am aware of the the USB2GPIO2  and software GUI. However, we already have our board design finalized and we cant and don't plan to use the gui/usb2gpio.

    My current set up is connecting both SDA, SCL and Gnd of TPSM846C23  and Raspberry Pi (or any i2c interface). 

    Have you tried or is it going to work with other i2c interface module? I would like to verify it and control the voltage output without using your gui/usb2gpio.

    Thanks,

    Jay

  • Hi Jay,

    If you can replicate the setup of USB2GPIO and are doing what the GUI does thru raspberry pi I think it should work. PMBus is a communication protocol built upon I2C interface so technically it should support it with some changes.

    Make sure to have the PMBUS related pins connected to your Raspberry PI in order to function, that would be ALERT, DATA, CLK, CNTL (this last one you may not need if you have it setup externally). 

    We don't have a setup/steps on using your method as we only support the setup previously mentioned, however few things I can tell you to look out for is: make sure when you are doing reads/writes that it's following SMBus format, this tends to be different than I2C, also make sure to follow data rate speeds allowed by device/pmbus protocol, this device particularly goes up to 400 kHz.

    DS doesn't go into PMBus details on individual bits that need to be written outside the main data but you can look up protocol here: https://pmbus.org/  

  • Hi Eileen,

    Since we were not using the  USB2GPIO, do i need to power up the USB interface/header (P1) to get the SCL and SDA up?

  • Hi Jay,

    SDA should equate to DATA pin and SCL to CLK pin. Not familiarized with changes for direct capability but if you can follow as below it should work:

    Another thing I forgot to mention is I2C communication has certain addresses reserved for special functions (don't know which ones), so be careful when selecting the device address thru ADDR0 and ADDR1 resistors.

  • Hi Eileen,

    Yes, I am aware of these and the SDA SCL pin.. Its just whenever i measure SDA and SCL pins I don't see any voltages which it typically 3-5V. 

    does it need to be powered up somewhere? 

    I only applying 12V into the TB1 Vin to power up the module.

    Thanks,

    Jay

  • Hi Jay,

    Earlier I added image of the voltages for those pins. Typically we have pull up resistors to ensure voltage stays low/high, but that is with our setup. I believe SDA and SCL raspberry pi lines should have internal pull up resistors, in which case you probably don't need to add it. If you aren't sure you can try an add some externally. If lines don't have pull ups, they will float and you wont read voltage. 

  • Hi Eileen,

    Sorry I overlooked first image you shared. On the pin#7 of the USB interface which is the CNTRL pin you added a 3.3V supply which is also tied up with PGOOD. Is the 3.3V coming from external supply?

    If I look at the original schematics.. there is already a 3.3V  coming from the BP3 pin of the chip going to CNTRL and PGOOD.

    Thanks,

    Jay

  • Hi Jay,

    The image I had attached earlier was from the 2PH EVM schematic, they named 3V3 for BP3, it should be the same thing. No external source.

    Another thing, you mentioned SDA and SCL pins are typically 3-5V. Make sure it doesn't go above abs max as its close:

  • Hi Eileen,

    Thats point taken.

    Raspberry pi I2c is also 3.3V - 5V range so it should be fine. My existing problem is I couldn't get any output voltage from the SDA and SCL pin of the TPSM module :( .. while SDA of SCL pin of Raspberry Pi are verified with 3.3V output.

  • Jay,

    Got it! Where you able to get SDA and SCL working successfully with DATA and CLK? If not, you may need pull up resistors but I believe Raspberry pi should have some internally. 

  • No luck so far. Im still measuring no voltage from the TP of Data and CLK of the TPSM. Thats probably the reason why it couldnt communicate.

  • Hi Jay,

    I looked a bit deeper into this and our typical setup. There is some connection in the USB2PIO userguide for reference. Based on that, it looks like SDA/SCL = DATA/CLK lines have pull up resistors to enable those communication lines.

    Our GUI and USB2GPIO setup has multiple options of pull up resistors 668 Ω, 1.1 kΩ, 2.2 kΩ, or open drain but 2.2k (is typical for 400kHz "fast mode" speed) to a 3.3V source. I'm guessing your SDA/SCL lines are open drain and therefore pulling low. 

    You can check your raspberry pi UG to see if this is already included internally and if you just have to do something to enable it.

    Let me know if that ends up working. 

  • Raspberry pi has its built i internal pull up resistors already for I2C. I've also tried adding extra externally but still couldnt get it working.

    My concern is that the module TPSM i2c function can work without using your USB2PIO interface?

    Thanks,

    Jay

  • Because TPSM is PMBus, the device itself should be able to support i2c.

    If you are having issues getting the lines up (default state), that probably has something to do with the connections itself either the pull up resistor value or the voltage. Some raspberry pi need internal pullup/down resistors to be enabled/disabled through libraries, with that been said double check that raspberry pi isn't pull down by default. Also, there's probably a mismatch with the voltage of the DATA+CLK pins vs SCL/SDA pins, to where you may need a bidirectional logic level converter to ensure both devices read the correct V for high level.  

    TPSM values are given on DS:

  • Hi Eileen,

    As mentioned earlier, pull up resistors already enabled in Rasp-pi both external and internal.

    And Fyi. Other i2c module that i tried with Raspberry working without problems except for this module. Thanks for the help anyway.

  • Hi Jay,

    Did you try adding bidirectional logic level converter for proper V read? raspberry and module probably have a difference in V. 

  • Hi Eileen,

    Sorry for the late reply. I was able to detect and read the TPSM module. It was a wrong pin connections. Realized that the pin config (P1) on both user guide schematic and actual hardware is not correct Disappointed.

    However, ive been trying to write and change the output voltage through vout_command 0x21 address referencing the datasheet.. but I always getting the defaults measurement value of 0.5V. Any idea where should i look for or anything I'm missing out? 

    Any chance i could reference on the software side from your end?
    Here's my code.

    import smbus
    import time

    # --- Configuration ---
    I2C_BUS = 1
    PMBUS_ADDRESS = 0x1B
    # --- PMBus Commands ---
    VOUT_COMMAND = 0x21
    READ_VOUT = 0x8B
    OPERATION_CMD = 0x01
    ON_OFF_CONFIG = 0x80  # Default ON/OFF config
    # --- PMBus Fixed Exponent ---
    FIXED_EXPONENT = -9
    # --- Conversion Functions ---
    def voltage_to_mantissa(voltage, exponent):
        """
        Converts a desired voltage into the PMBus mantissa value.
        Value = Mantissa * 2^Exponent  ->  Mantissa = Value / 2^Exponent
        """
        mantissa = int(voltage / (2**exponent))
        # Check for 16-bit mantissa range
        if not -32768 <= mantissa <= 32767:
            raise ValueError("Voltage {}V is out of range for exponent {}".format(voltage, exponent))
        return mantissa

    def mantissa_to_voltage(mantissa, exponent):
        """
        Converts a PMBus mantissa value into a real-world voltage.
        Value = Mantissa * 2^Exponent
        """
        return mantissa * (2**exponent)

    # --- SMBus Interaction Functions ---
    def get_current_voltage(bus, address, exponent):
        """
        Reads the output voltage using the fixed exponent.
        """
        try:
            # read_word_data returns a 16-bit little-endian integer.
            voltage_raw_word = bus.read_word_data(address, READ_VOUT)

            # The received word is the 16-bit mantissa in this fixed-exponent mode.
            # Need to handle two's complement for the 16-bit mantissa.
            mantissa = voltage_raw_word
            if mantissa > 32767:  # 0x7FFF
                mantissa -= 65536  # 0x10000

            return mantissa_to_voltage(mantissa, exponent)
        except IOError as e:
            print("Error reading from device at address {}: {}".format(hex(address), e))
            return None

    def set_output_voltage(bus, address, voltage, exponent):
        """
        Sets the output voltage using the VOUT_COMMAND with the fixed exponent.
        """
        try:
            mantissa = voltage_to_mantissa(voltage, exponent)
            bus.write_word_data(address, VOUT_COMMAND, mantissa)
            print("Wrote mantissa {} to command {}".format(mantissa, hex(VOUT_COMMAND)))
        except ValueError as e:
            print("Failed to set voltage: {}".format(e))
        except IOError as e:
            print("Error writing to device at address {}: {}".format(hex(address), e))

    def main():
        try:
            # Initialize SMBus
            bus = smbus.SMBus(I2C_BUS)
            print("Connected to I2C bus {}".format(I2C_BUS))

            # 1. Turn the converter ON (Optional, check datasheet)
            print("Turning converter ON...")
            bus.write_word_data(PMBUS_ADDRESS, OPERATION_CMD, ON_OFF_CONFIG)
            time.sleep(1)  # Wait for converter to stabilize

            # 2. Read the initial output voltage
            print("\nReading initial voltage...")
            initial_voltage = get_current_voltage(bus, PMBUS_ADDRESS, FIXED_EXPONENT)
            if initial_voltage is not None:
                print("Initial output voltage: {:.3f} V".format(initial_voltage))

            # 3. Set a new output voltage
            new_voltage = 1.2  # Example: 1.8V
            print("\nSetting output voltage to {} V...".format(new_voltage))
            set_output_voltage(bus, PMBUS_ADDRESS, new_voltage, FIXED_EXPONENT)
            time.sleep(1)  # Wait for voltage to change

            # 4. Read the updated voltage to confirm
            print("\nReading updated voltage...")
            updated_voltage = get_current_voltage(bus, PMBUS_ADDRESS, FIXED_EXPONENT)
            if updated_voltage is not None:
                print("Updated output voltage: {:.3f} V".format(updated_voltage))

        except FileNotFoundError:
            print("Error: I2C bus {} not found. Ensure I2C is enabled and modules are loaded.".format(I2C_BUS))
        except Exception as e:
            print("An unexpected error occurred: {}".format(e))
        finally:
            if "bus" in locals():
                try:
                    bus.close()
                except AttributeError:
                    pass  # smbus library may not have a close method

    if __name__ == "__main__":
        main()
    Appreciate your support,
    Jay
  • Hi Jay,

    No worries! When you say P1 are you referring to NC pin 1? What were you doing before vs now that its working?

    As far as the VOUT_COMMAND mantissa, 641 decimal should be correct for 1.199Vout.

    Got 2 questions:

    1) Have you tried writing to other commands to see if the write goes thru outside VOUT_COMMAND? 

    2) Can you check if device is reading as master or slave?

    You can check this thru:

      

      

  • On the EVM schematic and actual EVM board, P1 is marked below pin9 which is telling us the orientation making pin9 = CLK. However, the correct pin config is upside down. so, i have to flip it.

    regarding the 2 questions:
    1. I did try writing VOUT_MIN and VOUT_MAX, but im getting the same. no errors but seems not being received or ack by the module.
    2. I tried reading the STATUS_CML but im getting 0xFF which indicates all bits are 1.

    On the side note, the first issue i had before is the raspberry was unable to detect the module. But now it can read the pmbus address = 0x1b which i thought the communications were established. However, the issue now is reading and writing output voltage. :(

    Thanks,

    Jay

  • Hi Eileen,

    I managed to write into VOUT_COMMAND and change/control the output voltage now. Turns out that the write protect feature of the module was enabled by default and had to disable it. 

    The issue now is that whenever I try reading the raw output value straight from READ_OUT 0x8B, I'm always getting a raw output of 65535 (0xffff). 

    Any idea what could have cause this false reading?

    Thanks,

    Jay

  • Hi Jay,

    Are you having same issue with the other READ_.. commands?

  • Yes. Seems like I couldn't get any read on all the registers. I tried reading DEVICE_ID, READ_IOT and read STATUS CML.

  • Closing this thread since new one was opened.