Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

System: make sure that the power source being USB host is well detected #2310

Open
wants to merge 2 commits into
base: develop
Choose a base branch
from

Conversation

XuGuohui
Copy link
Member

Problem

This issue can be easily replicated on Tracker.

  1. Attached both battery and connect device to computer via USB cable
  2. Unplug the USB cable and plug back again
  3. The power source is detected as VIN, instead of USB Host

If there is a power source attached to the DC jack, pluging back USB cable won't update the power source either.

Solution

When it detects the power source is VIN and the USB peripheral is powered, try to run DPDM in the system power management loop to make sure the USB host is correctly reported by PMIC

Steps to Test

As steps to replicate the issue.

Example App

#include "Particle.h"

SYSTEM_THREAD(ENABLED);
SYSTEM_MODE(SEMI_AUTOMATIC);

Serial1LogHandler logHandler(115200, LOG_LEVEL_ALL);

constexpr char const* batteryStates[] = {
  "unknown", "not charging", "charging",
  "charged", "discharging", "fault", "disconnected"
};
constexpr char const* powerSources[] = {
  "unknown", "vin", "usb host", "usb adapter",
  "usb otg", "battery"
};

void setup() {
#if PLATFORM_ID == PLATFORM_TRACKER
  // We need to enable the CAN_5V to connect the Serial1 to M8.
  pinMode(CAN_PWR, OUTPUT);
  digitalWrite(CAN_PWR, HIGH);
#endif

  Serial1.begin(115200);
  Serial1.printlnf("Application started.");

  System.on(battery_state, [](system_event_t event, int data) -> void {
    Serial1.printlnf("battery_state: %s", batteryStates[std::max(0, data)]);
  });

  System.on(power_source, [](system_event_t event, int data) -> void {
    Serial1.printlnf("power_source: %s", powerSources[std::max(0, data)]);
  });
}

void loop() {
}

References

  • ch77765

Completeness

  • User is totes amazing for contributing!
  • Contributor has signed CLA (Info here)
  • Problem and Solution clearly stated
  • Run unit/integration/application tests on device
  • Added documentation
  • Added to CHANGELOG.md after merging (add links to docs and issues)

} else {
src = POWER_SOURCE_UNKNOWN;
// Do not update power source if power is good and in DPDM
if (!pwr_good || !power.isInDPDM()) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be this be !power.isInDPDM() && !pwr_good?

// FIXME: maybe introduce a new flag?
#if HAL_PLATFORM_POWER_WORKAROUND_USB_HOST_VIN_SOURCE
static system_tick_t lastRun = 0;
static uint8_t dpdmRetry = 0;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move these into the class member variables.

if (power.isInDPDM()) {
return;
}
power.enableDPDM();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is going to cause dips to 100mA current temporarily and may cause for example the modem to brownout if there is no battery attached.

See #2215 for some additional info.

We should probably opt to just reporting USB_HOST and configuring the PMIC manually as needed (i.e. lowering the input current limit to 500mA) and avoiding re-running DPDM as much as possible.


if (millis() - lastRun >= DPDM_PERIOD) {
lastRun = millis();
if (g_powerSource == POWER_SOURCE_VIN && HAL_USB_Get_State(nullptr) >= HAL_USB_STATE_POWERED) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what other states are caught by HAL_USB_Get_State(nullptr) >= HAL_USB_STATE_POWERED? Can you make this more explicit such as a switch/case statement?

@eberseth
Copy link
Contributor

There are cases where the status register is showing 0x24 and the device is being powered through USB. Is there something not configured completely for USB detection?

@technobly technobly removed this from the 3.1.0 milestone May 18, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
4 participants