USB Connection Detection

Is there a strategy for detecting USB state on NRF based devices? We have a hardware watchdog that we would like to disable if a USB host is connected. The Boron and Argon.

Only mention I could find was pretty old:

I wrote a function that can quickly and efficiently poll whether there is power on the USB port on an nRF52 device:

#include "Particle.h"

SYSTEM_THREAD(ENABLED);

bool vusbDetect() {
    // 0x40000000 POWER register
    // USBREGSTATUS Address offset: 0x438 USB supply status
    const uint32_t *usbRegStatus = (const uint32_t *)(0x40000438);

    return (*usbRegStatus & 1) != 0;
}

void setup() {
    pinMode(D7, OUTPUT);
}

void loop() {
    digitalWrite(D7, vusbDetect());
}

The blue D7 LED will on when there’s power on VUSB, which will be true for both host and charger mode, unlike Serial.isConnected() which is only true when connected to a USB host.

In theory there’s an nRF52 event that would allow a callback to be called when it changes, but getting events across the Device OS - User boundary is a pain, and presumably you’d just poll when servicing your watchdog.

On the Boron and Argon this only detects the Micro USB connector power. There’s a Schottky diode between the Feather pin marked VUSB and the USB block of the nRF52, so the function will return false when powered by the Feather VUSB pin.

2 Likes

Many thanks, I’ll give this a shot. -AP

Unfortunately, while that register clearly works, it can not differentiate between 5V bus voltage and USB power. In the end they are the same of course. Hmm…

Perhaps a way to trap an impending DFU mode? I see that particle does a disconnect before entering DFU, but there is no system event.

USB Trigger DFU Mode:

0000037502 [system] INFO: Cloud: disconnecting
0000037503 [system] INFO: Cloud: disconnected

OK, here’s a version that detects only USB host and not USB charger:

#include "Particle.h"

SYSTEM_THREAD(ENABLED);

// This returns true only for USB host, not a USB charger. It returns false for the VUSB pin on the Feather.
bool usbHostDetect() {
    // 0x40027000 USBD register
    // USBADDR Address offset: 0x470 Device USB address
    const uint32_t *usbRegStatus = (const uint32_t *)(0x40027470);

    return (*usbRegStatus != 0);
}


void setup() {
    pinMode(D7, OUTPUT);
}

void loop() {
    digitalWrite(D7, usbHostDetect());
}

Thanks, I need to get more familiar with the NRF device. I took a stab looking for that register and did not find it.

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.