0
\$\begingroup\$

Here is a problem to which the obvious answer is "use a switch," but that is not permitted in the design. ;)

I am writing software for a USB audio application that is supposed to be able to play audio from iP{od,ad,hone}s, Android devices, and also Samsung Audio from Samsung devices.

(quick note: USB Device with capital D = USB Peripheral = device with B-Connector)

I wouldn't have to ask this question if all these devices played nice and were just USB Devices. iPxx and Android devices are USB Devcies, but Samsung devices playing Samsung Audio act as USB Hosts (but they can also be USB Devices not playing Samsung Audio but as regular Android devices).

All devices have to connect to a single Type Standard-A connector on our embedded system running on a PIC32. Yeah, I know that's not USB-legal, but that's what the requirements are.

Since both USB Hosts and Devices have to connect to our embedded device, I need a way to detect when a device is plugged-in if it is a USB Host or a USB Device, so that my USB system shuts/brings itself up with the correct role depending on the attached device.

I have read the On-The-Go and Embedded Host Supplement to the USB Revision 2.0 Spec. The closest thing I got was Attach Detection Protocol. That helps with the general detection of attached devices but doesn't help detect the role of the device (Host or Device). Our hardware design is not final yet, so I am able to consider any hardware solutions that help that aren't... well... a switch. ;)

Look forward to the community's insight.

\$\endgroup\$
  • \$\begingroup\$ This is not directly workable. Android phones switch host/device mode based on the ID pin of the 5-pin micro (or in a few cases, mini) USB connector. Since you don't have that pin on your USB "A" connection you'll have to either change your requirement or create a "smart cable" with internal software-controlled logic which can drive that pin low or leave it floating. \$\endgroup\$ – Chris Stratton Feb 20 '14 at 20:11
  • \$\begingroup\$ Such a cable would be tricky to build from off-the-shelf ICs as it will have to work in either direction of host-device relationship - you might end up with back-to-back OTG MCUs proxying traffic or perhaps something that can "spy" on USB operations to detect a special "change mode" signal and drive the ID pin in response. \$\endgroup\$ – Chris Stratton Feb 20 '14 at 20:15
  • \$\begingroup\$ Thanks for the comments Chris. I know the fundamental limitation of the A-Connector requirement is the absence of the ID pin required for host/device differentiation, and there's no changing that requirement. I had considered the "smart cable" idea as well - not easily accomplished with off-the-shelf ICs as you said. Correct me if I am wrong, but I don't think a Samsung device running an Android OS that is capable of playing USB Host needs the ID pin on the other side in order to switch from USB Host to USB Device. \$\endgroup\$ – Skateboarder Feb 20 '14 at 20:48
  • \$\begingroup\$ That would be kind of surprising, as the power switching may be a little risky otherwise. But maybe you can try it - get a Samsung compatible audio "device" and try it with a cable with a verified unconnected mode pin. \$\endgroup\$ – Chris Stratton Feb 20 '14 at 20:54
  • \$\begingroup\$ Given that only a USB Host is allowed to source current, would an implementation where my system's USB stack is shut down by default, and given a VBUS sensing I/O pin and a current sensing circuit, I could use the fact that only USB Hosts are allowed to source current to play USB Device on my part when a Host is sensed to be plugged-in? If no current is sourced, and the VBUS sense is picked up on a GPIO pin, that means a USB Device was plugged in. Does that make sense? \$\endgroup\$ – Skateboarder Feb 20 '14 at 20:55
2
\$\begingroup\$

I think you should be able to detect it quite reliably by knowing the electrical properties of the pins. USB hosts pull the DP and DN data lines low with 15kOhm resistance. USB devices pull the DP line (DN line if it's a slow speed device) to 3 volts with a 1.5K resistance. If the device at the other end pulls up and also you pull up, nothing would happen because the device doesn't react to the extra pull-up. So you could use this to check if the other end starts to send packets to the bus.

I suggest a procedure something like this:

You could start by pulling the DN line weakly high (with something like 200K to 1M resistor). You could detect a pull-down on the DN line to give a first hint that there's a host at the other side.

Then measure the VBUS, if it's high, it's a further indication that there is a host at the other side. If so, activate a 1.5k pull-up (to 3 volts) on the DP line and listen for incoming packets. If there actually is a host on the other side, it will issue a bus reset and send a GET_DESCRIPTOR packet to the bus. If this happens, you know that the other chip is a host. I suggest to do it in this order as if there's a device at the other side, it will not react to the DP pull-up.

If nothing happens, there may be a device at the other side. Release your DP pull-up and see if it's still pulled up at the other side. If that is so, then there is probably a self-powered device at the other side. If not, then start driving the VBUS line to 5 volts. At this time at the latest you should see the device's 1.5k pull-up tp 3 volts on the DP line. If you see instead 3 volts in the DN line, then there's a slow speed device such as a keyboard or a mouse at the other side.

Now act as a host and issue a BUS RESET and GET DESCRIPTOR : DEVICE DESCRIPTOR to address 0, endpoint 0. The device should now answer and finally at this point you know for sure that there is a usb device at the other end. If you haven't enabled your 5V drive to VBUS so far, I suggest that you enable it now. Test with all the devices you intend to support.

Ok, this is a hack, and the official bus doesn't work this way because if both ends would work like this then it would be a matter of luck (timing) if it detects correctly or not. But if the other end is a well-behaving USB entity, then I think that it should work. I've done a fair bit of work on the USB, but not this exact thing.

\$\endgroup\$
  • \$\begingroup\$ Would a device ever put +5v on the VBUS line? Even if it is self-powered, why would it be supplying power to the cable (which could conflict with the +5 from the host?) So then a test for host/device is simply whether there is +5 on VBUS, prior to the near end configuring itself as a host or device. \$\endgroup\$ – tcrosley Oct 30 '14 at 22:17
  • \$\begingroup\$ This will not work for the OP. Software cannot provide what the hardware simply doesn't support: An OTG phone will not go into host mode and supply VBUS unless you ground the ID pin (or hack its kernel or whatever, which is obviously out). But the OP's requirement seems to preclude a cable with that connection. \$\endgroup\$ – Chris Stratton Oct 30 '14 at 23:27
  • \$\begingroup\$ Chris, I think that he is writing code for the PIC32 and that he should be able to make the PIC32 became a host or a device as he likes. You are of course correct about the phone and that he cannot control whether the phone is a host or a device. \$\endgroup\$ – PkP Oct 31 '14 at 3:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.