STUSB4500 setCurrent() not working

Hi everyone,

I am able to program the STUSB4500 using the RedBoard and the SetParameters example from Arduino.

I can easily change the voltage using SetVoltage(). I have a small USBC voltmeter from which I can read Voltage and Current.

However, the setCurrent() doesn’t seem to work.

#include <Wire.h>
#include <SparkFun_STUSB4500.h>

STUSB4500 usb;

void setup() 
{
  Serial.begin(115200);
  Wire.begin(); //Join I2C bus
  
  delay(500);
  

  if(!usb.begin())
  {
    Serial.println("Cannot connect to STUSB4500.");
    Serial.println("Is the board connected? Is the device ID correct?");
    while(1);
  }
  
  Serial.println("Connected to STUSB4500!");
  delay(100);

  usb.setPdoNumber(3);

  /* PDO1
   - Voltage fixed at 5V
   - Current value for PDO1 0-5A, if 0 used, FLEX_I value is used
   - Under Voltage Lock Out (setUnderVoltageLimit) fixed at 3.3V
   - Over Voltage Lock Out (setUpperVoltageLimit) 5-20%
  */
  usb.setCurrent(1,2);
  usb.setUpperVoltageLimit(1,20);
  usb.setReqSrcCurrent(5);

  /* PDO2
   - Voltage 5-20V
   - Current value for PDO2 0-5A, if 0 used, FLEX_I value is used
   - Under Voltage Lock Out (setUnderVoltageLimit) 5-20%
   - Over Voltage Lock Out (setUpperVoltageLimit) 5-20%
  */
  usb.setVoltage(2,15.0);
  usb.setCurrent(2,1);
  usb.setLowerVoltageLimit(2,5);
  usb.setUpperVoltageLimit(2,20);

  /* PDO3
   - Voltage 5-20V
   - Current value for PDO3 0-5A, if 0 used, FLEX_I value is used
   - Under Voltage Lock Out (setUnderVoltageLimit) 5-20%
   - Over Voltage Lock Out (setUpperVoltageLimit) 5-20%
  */
  usb.setVoltage(3,9.0);
  usb.setCurrent(3,0.5);
  usb.setLowerVoltageLimit(3,5);
  usb.setUpperVoltageLimit(3,20);

  /* Flexible current value common to all PDOs */
  usb.setFlexCurrent(1.0);

  /* Unconstrained Power bit setting in capabilities message sent by the sink */
  usb.setExternalPower(false);

  /* USB 2.0 or 3.x data communication capability by sink system */
  usb.setUsbCommCapable(false);

  /* Selects POWER_OK pins configuration
     0 - Configuration 1
     1 - No applicable
     2 - Configuration 2 (default)
     3 - Configuration 3
  */
  usb.setConfigOkGpio(2);

  /* Selects GPIO pin configuration
     0 - SW_CTRL_GPIO
     1 - ERROR_RECOVERY
     2 - DEBUG
     3 - SINK_POWER
  */
  usb.setGpioCtrl(3);

  usb.setPowerAbove5vOnly(false);

  usb.setReqSrcCurrent(false);

  usb.write();
  
  usb.read();

  Serial.println("New Parameters:\n");

  /* Read the Power Data Objects (PDO) highest priority */
  Serial.print("PDO Number: ");
  Serial.println(usb.getPdoNumber());

  /* Read settings for PDO1 */
  Serial.println();
  Serial.print("Voltage1 (V): ");
  Serial.println(usb.getVoltage(1));
  Serial.print("Current1 (A): ");
  Serial.println(usb.getCurrent(1));
  Serial.print("Lower Voltage Tolerance1 (%): ");
  Serial.println(usb.getLowerVoltageLimit(1));
  Serial.print("Upper Voltage Tolerance1 (%): ");
  Serial.println(usb.getUpperVoltageLimit(1));
  Serial.println();

  /* Read settings for PDO2 */
  Serial.print("Voltage2 (V): ");
  Serial.println(usb.getVoltage(2));
  Serial.print("Current2 (A): ");
  Serial.println(usb.getCurrent(2));
  Serial.print("Lower Voltage Tolerance2 (%): ");
  Serial.println(usb.getLowerVoltageLimit(2));
  Serial.print("Upper Voltage Tolerance2 (%): ");
  Serial.println(usb.getUpperVoltageLimit(2));
  Serial.println();

  /* Read settings for PDO3 */
  Serial.print("Voltage3 (V): ");
  Serial.println(usb.getVoltage(3));
  Serial.print("Current3 (A): ");
  Serial.println(usb.getCurrent(3));
  Serial.print("Lower Voltage Tolerance3 (%): ");
  Serial.println(usb.getLowerVoltageLimit(3));
  Serial.print("Upper Voltage Tolerance3 (%): ");
  Serial.println(usb.getUpperVoltageLimit(3));
  Serial.println();

  /* Read the flex current value */
  Serial.print("Flex Current: ");
  Serial.println(usb.getFlexCurrent());

  /* Read the External Power capable bit */
  Serial.print("External Power: ");
  Serial.println(usb.getExternalPower());

  /* Read the USB Communication capable bit */
  Serial.print("USB Communication Capable: ");
  Serial.println(usb.getUsbCommCapable());

  /* Read the POWER_OK pins configuration */
  Serial.print("Configuration OK GPIO: ");
  Serial.println(usb.getConfigOkGpio());

  /* Read the GPIO pin configuration */
  Serial.print("GPIO Control: ");
  Serial.println(usb.getGpioCtrl());

  /* Read the bit that enables VBUS_EN_SNK pin only when power is greater than 5V */
  Serial.print("Enable Power Only Above 5V: ");
  Serial.println(usb.getPowerAbove5vOnly());
  
  /* Read bit that controls if the Source or Sink device's 
     operating current is used in the RDO message */
  Serial.print("Request Source Current: ");
  Serial.println(usb.getReqSrcCurrent());
}

void loop()
{
}

Hi Shmaltz.

Can you describe how setCurrent isn’t working? Do you get some sort of error? What’s your setup?

Using a USBC multimeter, I can see that the board will pull 3A at 5V, or 1.4A at 9V, … Basically, setCurrent seem to have no effect as the result is always the same: as much as the USBC source can provide. In the image below, we can see the board pulling 1.36A despite having set the current limit to 0.5A.

https://i.ibb.co/jvTGtB3/IMG-20210122-121623-1.jpg

Basically, setCurrent seem to have no effect as the result is always the same: as much as the USBC source can provide.

Unfortunately that is how the controller is designed to work as described in the Arduino Library section of the hookup guide (https://learn.sparkfun.com/tutorials/po … no-library). With regards to setCurrent():

The current value should be the amount that the source should be expected to output. If the current is higher than the source is able to provide, the contract will be rejected and the next PDO contract will be negotiated. The Power Delivery board will sink more current than negotiated if the source is able deliver it, but it’s recommended to provide the maximum amount of current the project is expected to draw.

In other words, that means that if your source is able to deliver 1.4A at 9V, when the Power Delivery Board is connected to the source, the source advertises its capabilities and the Power Delivery Board compares them the the saved PDO configurations. With a 9V/0.5A PDO contract, it’s assuming you only plan to draw up to 500mA at 9V, which the source is able to do since it has a maximum output of up to 1.4A. If however you said you wanted a power delivery option at 9V and up to 2A of current, it wouldn’t be able to find a match and the source would remain at 5V.

The controller IC doesn’t have a current sense capability, only VBUS measuring unfortunately. It’s possible that based on the PD contract, that a high end power source would enforce the negotiated current side of the contract, but all of the sources I tested with during development had the same behavior of allowing the maximum current that the source has available.