Author Topic: STM32 USB SOF detection  (Read 2721 times)

0 Members and 1 Guest are viewing this topic.

Offline HalideTopic starter

  • Contributor
  • Posts: 31
  • Country: pl
STM32 USB SOF detection
« on: October 16, 2023, 03:10:29 pm »
Hello everyone,
I'm encountering an issue with USB Start of Frame (SOF) detection on my Nucleo board. My goal is to determine whether the device connected to the Nucleo's USB port is a charger or a PC. I found in the reference manual that I can read the SOF bit for this purpose. It works as expected when I connect the Nucleo to a PC – the SOF bit is set. However, when I connect it to a charger, nothing happens.
The core of my requirement is to establish communication without any action from PC's side (I mean without windows USB plugging voice). My problem is that the host cuts off the VBUS line. I tried setting the SDIS bit (software disconnect bit) before using the HAL deinit function, but it didn't make any difference.
Perhaps some of you have encountered a similar issue and found a solution. I strongly believe that the problem lies on the host side, as when I connect the Nucleo via a USB hub, everything works fine. Using a USB hub is not a viable solution for me; I want to understand why the host is cutting off the VBUS line. Could this be related to some form of device hard reset?

If anything is unclear in my explanation, please let me know, and I will provide more details.
 

Offline ataradov

  • Super Contributor
  • ***
  • Posts: 11277
  • Country: us
    • Personal site
Re: STM32 USB SOF detection
« Reply #1 on: October 16, 2023, 05:08:40 pm »
What do you mean by "establish communication without any action from PC's side"? USB communication requires both sides to participate.

What do you mean by "when I connect it to a charger, nothing happens". Was not this the goal?

Why do you need to know what is connected to the port?
Alex
 

Offline wek

  • Frequent Contributor
  • **
  • Posts: 495
  • Country: sk
Re: STM32 USB SOF detection
« Reply #2 on: October 16, 2023, 05:36:06 pm »
I found in the reference manual that I can read the SOF bit for this purpose. It works as expected when I connect the Nucleo to a PC – the SOF bit is set. However, when I connect it to a charger, nothing happens.
Of course: SOF is sent out by host (usually PC) as part of the communication protocol; charger does perform the USB communication.

The core of my requirement is to establish communication without any action from PC's side (I mean without windows USB plugging voice). My problem is that the host cuts off the VBUS line. I tried setting the SDIS bit (software disconnect bit) before using the HAL deinit function, but it didn't make any difference.
I don't understand how is it related to the first part of your post, with SOF.

There is no such thing as "communication without any action from PC's side". USB is a polled bus, the host (PC) polls the devices, otherwise there's no communication.


If anything is unclear in my explanation, please let me know, and I will provide more details.
Sorry, but to me, almost nothing is clear in your explanation.

JW
 

Offline HalideTopic starter

  • Contributor
  • Posts: 31
  • Country: pl
Re: STM32 USB SOF detection
« Reply #3 on: October 17, 2023, 08:50:41 am »
Hello everyone,
I will try to clarify your questions. 

What do you mean by "establish communication without any action from PC's side"? USB communication requires both sides to participate.
I need to clarify that I aim to pause communication before I hear the "connection" sound on the PC side. I have a rather intricate memory management system in place (I want to enable the MSD class), and in order to gain access to memory, I must reboot the device.

What do you mean by "when I connect it to a charger, nothing happens". Was not this the goal?
When I connect a charger, the SOF bit is not set, and this behavior is as expected.

Why do you need to know what is connected to the port?
As I mentioned, I'm unable to access the memory when the device is in running mode. Information regarding the type of connection (PC or charger) is of significant importance to me. I aim to avoid resetting the device when it's connected to a charger.

I don't understand how is it related to the first part of your post, with SOF.
There is no such thing as "communication without any action from PC's side". USB is a polled bus, the host (PC) polls the devices, otherwise there's no communication.

I understood that some packages need to be pulled between host and device.  In the sentence, "communication without any action from PC's side" I want to say that I aim to pause communication before I hear the "connection" sound on the PC side. And this is reason why I'm trying to say host that i need to software disconnect my device without unplugging cable.  This approach is partially successful because I don't hear the "connection" sound on the PC side. However, after a few seconds, the host disconnects the VBUS line for a brief period and then reconnects it. I have included an oscillogram to illustrate the situation, and it's important to note that I do not physically disconnect the USB cable from the PC.
 

Offline janoc

  • Super Contributor
  • ***
  • Posts: 3785
  • Country: de
Re: STM32 USB SOF detection
« Reply #4 on: October 17, 2023, 12:06:05 pm »
I don't understand how is it related to the first part of your post, with SOF.
There is no such thing as "communication without any action from PC's side". USB is a polled bus, the host (PC) polls the devices, otherwise there's no communication.

I understood that some packages need to be pulled between host and device.  In the sentence, "communication without any action from PC's side" I want to say that I aim to pause communication before I hear the "connection" sound on the PC side. And this is reason why I'm trying to say host that i need to software disconnect my device without unplugging cable.  This approach is partially successful because I don't hear the "connection" sound on the PC side. However, after a few seconds, the host disconnects the VBUS line for a brief period and then reconnects it. I have included an oscillogram to illustrate the situation, and it's important to note that I do not physically disconnect the USB cable from the PC.

I suspect this is an XY problem.

If you don't want the PC to detect your device (and try to restart it when the enumeration fails), why don't you simply disable the USB pull-up resistor? Most STM32s have it built-in and controlled by software. When that resistor is disabled, the host will not be able to detect that anything has been connected and no communication (and neither port reset by the host) will happen. That's the canonical way to implement USB device connection/disconnection without power cycling.

If you mess with the SOF packet that means you are effectively telling the host - "Hello, I am here and I am ready to enumerate!" by pulling the D+ or D- line up - and then you fail to do so within the timeout window. So now  the host assumes there is a problem and will try to force a bus reset (by pulling D+ & D- down), even going as far as cycling the Vbus in some cases attempting to recover communication.

If  you really need to detect a charger for whatever reason then the way to do so is to check whether the D+/D- pins are shorted together. If they are you have a charger (but possibly not every charger shorts them).

Checking SOF is not going to be reliable because if you don't get it, you can't know whether that's because the upstream is a charger, the host is slow to react or there is whatever other software problem. You may still be connected to a computer that will ask you to enumerate later, after you have checked your SOF bit. And then what?
« Last Edit: October 17, 2023, 12:13:28 pm by janoc »
 

Offline ataradov

  • Super Contributor
  • ***
  • Posts: 11277
  • Country: us
    • Personal site
Re: STM32 USB SOF detection
« Reply #5 on: October 17, 2023, 05:43:58 pm »
I don't think there is an easy way to do what you want to do. No idea when Windows connection sound happens, but it is likely that attempting to start and interrupt the enumeration process will result in a host attempting to power cycle the port.

One way of doing this would be to configure the D+/D- pins as GPIO inputs with internal pull-up resistor. Then sample the value of the pins. A USB host would have 15 kOhm pull-down resistors, and embedded pull-up would be ~40 kOhm. With this voltage on the pin when a host is connected would be ~0.9 V. This is on the edge of V_IL, so GPIO detection will not be reliable and you may need to use ADC for this.

Or use external switchable pull-up resistor of a much higher value (100 kOhm).
Alex
 
The following users thanked this post: Halide

Online langwadt

  • Super Contributor
  • ***
  • Posts: 4444
  • Country: dk
Re: STM32 USB SOF detection
« Reply #6 on: October 17, 2023, 07:54:40 pm »
how does devices like cypress FX2 do it?

it plugs, gets firmware over USB, boots that firmware and reenumerate as that device
 

Offline ataradov

  • Super Contributor
  • ***
  • Posts: 11277
  • Country: us
    • Personal site
Re: STM32 USB SOF detection
« Reply #7 on: October 17, 2023, 08:13:58 pm »
It still fully enumerates as a blank FX2LP device. This would cause OS notification if they are enabled.
Alex
 

Offline HalideTopic starter

  • Contributor
  • Posts: 31
  • Country: pl
Re: STM32 USB SOF detection
« Reply #8 on: October 17, 2023, 08:52:49 pm »
If you don't want the PC to detect your device (and try to restart it when the enumeration fails), why don't you simply disable the USB pull-up resistor? Most STM32s have it built-in and controlled by software. When that resistor is disabled, the host will not be able to detect that anything has been connected and no communication (and neither port reset by the host) will happen. That's the canonical way to implement USB device connection/disconnection without power cycling.

But if I understood that part correctly I can't detect that is the host from device side too?


If  you really need to detect a charger for whatever reason then the way to do so is to check whether the D+/D- pins are shorted together. If they are you have a charger (but possibly not every charger shorts them).

This is the reason why I want to attempt initiating some communication. Any charger does not initiate communication on the data lines (I hope so)

Checking SOF is not going to be reliable because if you don't get it, you can't know whether that's because the upstream is a charger, the host is slow to react or there is whatever other software problem. You may still be connected to a computer that will ask you to enumerate later, after you have checked your SOF bit. And then what?
I'm utilizing an RTOS, which allows me to employ a dedicated thread for monitoring the SOF status. This means that until the PC initiates communication, the device can behave as if it were connected to a charger.

No idea when Windows connection sound happens, but it is likely that attempting to start and interrupt the enumeration process will result in a host attempting to power cycle the port.
I have an idea: I'll try using the ENUMDNE bit. This bit is set after the enumeration process, so I can end transmission after that point. If this doesn't resolve my issue, I might have to rethink my approach.

However, do any of you have an idea as to why some ports allow me to halt communication? I mean, I'm using the same PC with two different USB ports. On one of them, everything works perfectly, but when I attempt to use the other, I observe a VBUS reset.

Thank you all for your help so far. :)
 

Offline ataradov

  • Super Contributor
  • ***
  • Posts: 11277
  • Country: us
    • Personal site
Re: STM32 USB SOF detection
« Reply #9 on: October 17, 2023, 09:06:08 pm »
It is possible that some of the port are connected to the root hub and others to some internal secondary hub. Or they connected to different host controllers and drivers for those controllers behave differently. It is impossible to say for sure.

The whole thing is very strange.

Improving on the idea I described earlier, an easy way to detect host would be to connect 100-200 kOhm resistor to D+ and any other GPIO. When detecting the host, set D+ as input and the other GPIO as output high. If there is no host, then D+ would be pulled high. If there is a host, D+ would be low, so you can reset into the USB mode.
Alex
 

Offline abyrvalg

  • Frequent Contributor
  • **
  • Posts: 825
  • Country: es
Re: STM32 USB SOF detection
« Reply #10 on: October 17, 2023, 11:27:59 pm »
There are chargers (i.e. Apple’s Type A ones, some other brands) with various resistive dividers on D+/D- indicating charger type. Those could sabotage GPIO+pullup approach.

Just for curiosity, why connection sound is a problem in the first place?
 

Offline janoc

  • Super Contributor
  • ***
  • Posts: 3785
  • Country: de
Re: STM32 USB SOF detection
« Reply #11 on: October 18, 2023, 07:41:36 pm »
If you don't want the PC to detect your device (and try to restart it when the enumeration fails), why don't you simply disable the USB pull-up resistor? Most STM32s have it built-in and controlled by software. When that resistor is disabled, the host will not be able to detect that anything has been connected and no communication (and neither port reset by the host) will happen. That's the canonical way to implement USB device connection/disconnection without power cycling.

But if I understood that part correctly I can't detect that is the host from device side too?

You might be able to detect that you are connected to a real, talking, host and not a charger - but by the time you do so it is too late because the host has already started the enumeration process. And if your device doesn't enumerate properly at that stage by sending proper descriptors, etc., it will make the host to try to reset the port, power cycle your device and ultimately report an error to the user.

You can't do anything about that from the device side. Full stop.

It is as simple as that. The moment you have put that pull-up resistor on the bus you are committed because USB is entirely host-driven. The only way to stop the communication is by disconnecting from the bus, which will likely cause an error message to be shown to the user.

So if your goal is to prevent the host from power cycling your device at an inopportune moment because you weren't ready to communicate yet, you can't do it by trying to detect when the enumeration starts - at that point the clock is ticking already and it is too late.

I'm utilizing an RTOS, which allows me to employ a dedicated thread for monitoring the SOF status. This means that until the PC initiates communication, the device can behave as if it were connected to a charger.

That's completely irrelevant because if your device does not enumerate within few hundred ms or so of putting that resistor on the bus (and receiving SOF means the host has detected that already), it will get a bus reset and possibly power cycle, no matter what you do on the device side with your RTOS and threads.

If you don't want to talk to the host, don't put those pull-up resistors on the bus.

The proper way to achieve what you want would be to leave the USB interface off, try to check whether the two data pins are shorted, e.g. checking whether driving one with a small voltage (do not put 3.3V on the pin/drive it high - that will start the enumeration, the same as connecting a pull-up!) drives the other pin up too. If it does, they are likely shorted and you have a charger. If it does not, assume a host, do whatever you need to do and only when you are ready to communicate initialize the USB peripheral and connect the pull-up resistor to the bus.

The host side has 15k pull-down resistors on the D+/D- lines, so they are normally idling low when there is nothing connected. Chargers short the data lines together and leave them floating.

The other way to solve this is to always enumerate as some dummy device when you are connected. When that happens, you know you are talking to a host, so you do your housekeeping, disconnect from the bus by disconnecting the pull-up to force re-enumeration, then reconnect the resistor to the bus to signal new device connected. Finally reply to the new enumeration request as the real device you want to be seen as. This is very common with devices that have bootloaders for firmware update, for example like that Cypress FX2. The disadvantage of this is that you will often get two "device connected" sounds from the computer and it may confuse some users if they see some weird device connecting, then disconnecting and a new device connecting.

Those two ways are the only methods to achieve what you want reliably. Messing with the SOF and trying to beat the USB host by reconfiguring your code while it is waiting for your enumeration response is bound to be fragile and unreliable.

However, do any of you have an idea as to why some ports allow me to halt communication? I mean, I'm using the same PC with two different USB ports. On one of them, everything works perfectly, but when I attempt to use the other, I observe a VBUS reset.

That completely depends on the host, the capabilities of the hubs you are connected to, etc. Some are capable of power cycling the ports, some are not. Also the driver may be more or less "aggresive" at trying to recover the communication - some drivers/hosts could be content with just forcing a bus reset (driving both data lines low) to force a re-enumeration. Some others may also try to power cycle the port as a last resort. Either way, that's not a behavior you can rely on.
« Last Edit: October 18, 2023, 08:01:42 pm by janoc »
 
The following users thanked this post: Halide

Offline janoc

  • Super Contributor
  • ***
  • Posts: 3785
  • Country: de
Re: STM32 USB SOF detection
« Reply #12 on: October 18, 2023, 07:52:58 pm »
I don't think there is an easy way to do what you want to do. No idea when Windows connection sound happens

AFAIK once the device is enumerated the OS will at some point (possibly even many seconds later) send the notification to the user. I don't recall whether it does it only for devices it knows (and has driver for) or for any device, I haven't used Windows in a while.
 

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 14510
  • Country: fr
Re: STM32 USB SOF detection
« Reply #13 on: October 18, 2023, 08:41:41 pm »
how does devices like cypress FX2 do it?

it plugs, gets firmware over USB, boots that firmware and reenumerate as that device

It first enumerates with a given VID/PID (Cypress defaults, or read from an attached EEPROM), which will trigger the host to load the corresponding driver - this first driver will upload the firmware to the FX2 RAM.
Then the firmware is responsible for triggering a re-enumeration (internally the FX2 just disconnects the USB data lines for a short while and re-connects them). After that, the firmware handles USB communication, usually exposing another PID.
 
The following users thanked this post: Halide

Offline HalideTopic starter

  • Contributor
  • Posts: 31
  • Country: pl
Re: STM32 USB SOF detection
« Reply #14 on: November 15, 2023, 11:26:59 am »
Hello everyone!
As you said there is no possibility to keep my solution.
I enable CDC class to check that there is some communication and leave it enable all the time.

Thank you!

Best regards
Bartosz
 

Online peter-h

  • Super Contributor
  • ***
  • Posts: 3711
  • Country: gb
  • Doing electronics since the 1960s...
Re: STM32 USB SOF detection
« Reply #15 on: November 16, 2023, 12:06:31 pm »
Quote
check whether the D+/D- pins are shorted together. If they are you have a charger

Is that really so? There is a protocol for charging from USB - check the DS for a TPS2511 for one chip which implements this. Definitely not a simple short.

Quote
There are chargers (i.e. Apple’s Type A ones, some other brands) with various resistive dividers on D+/D- indicating charger type. Those could sabotage GPIO+pullup approach.

Exactly, and not just Apple. The whole industry uses this. I spent a lot of time in this area a few years ago. Also consider current drawn; if >90mA (IIRC) then you cannot just draw it from the +5V pin; you have to "negotiate" like the TPS2511 does. With that you can go up to 500mA (900mA on USB3, IIRC). Above that it gets more involved.

I was digging around this recently
https://www.eevblog.com/forum/microcontrollers/defective-usb-host-hanging-up-your-target/msg4679803/#msg4679803
to see if a USB client can detect whether there is a VCP application running on the host capable of "consuming" data sent to the host, and it appears this is not possible.
Z80 Z180 Z280 Z8 S8 8031 8051 H8/300 H8/500 80x86 90S1200 32F417
 

Offline Siwastaja

  • Super Contributor
  • ***
  • Posts: 8183
  • Country: fi
Re: STM32 USB SOF detection
« Reply #16 on: November 16, 2023, 01:20:31 pm »
Quote
check whether the D+/D- pins are shorted together. If they are you have a charger

Is that really so? There is a protocol for charging from USB - check the DS for a TPS2511 for one chip which implements this. Definitely not a simple short.

Literally the first thing mentioned on TPS2511 datasheet:
Quote
Supports a USB DCP Shorting D+ Line to D– Line
 

Online peter-h

  • Super Contributor
  • ***
  • Posts: 3711
  • Country: gb
  • Doing electronics since the 1960s...
Re: STM32 USB SOF detection
« Reply #17 on: November 16, 2023, 03:04:33 pm »
And the rest of it?

I don't understand.
Z80 Z180 Z280 Z8 S8 8031 8051 H8/300 H8/500 80x86 90S1200 32F417
 

Offline Siwastaja

  • Super Contributor
  • ***
  • Posts: 8183
  • Country: fi
Re: STM32 USB SOF detection
« Reply #18 on: November 16, 2023, 03:09:37 pm »
In other words, there are a few different ways of indicating "this is a charger, you can pull more than 100mA and you don't have to enumerate" - one of which, a really popular one, is shorting the data lines together. The chip you referred to implements, among others, that one.
 
The following users thanked this post: peter-h

Online nctnico

  • Super Contributor
  • ***
  • Posts: 26964
  • Country: nl
    • NCT Developments
Re: STM32 USB SOF detection
« Reply #19 on: November 16, 2023, 10:49:04 pm »
Quote
check whether the D+/D- pins are shorted together. If they are you have a charger

Is that really so? There is a protocol for charging from USB - check the DS for a TPS2511 for one chip which implements this. Definitely not a simple short.
It is. Chargers must be made cheap. The maximum resistance of that 'short' is 500 Ohm BTW. So you can implement this with crappy CMOS switches and still get away with it.
There are small lies, big lies and then there is what is on the screen of your oscilloscope.
 

Online nctnico

  • Super Contributor
  • ***
  • Posts: 26964
  • Country: nl
    • NCT Developments
Re: STM32 USB SOF detection
« Reply #20 on: November 16, 2023, 10:52:36 pm »
I don't think there is an easy way to do what you want to do. No idea when Windows connection sound happens, but it is likely that attempting to start and interrupt the enumeration process will result in a host attempting to power cycle the port.
In my experience this doesn't happen as power cycling the port only adds complexity to the driver and hardware making the solution less reliable. One of the standard things I have in my USB devices is to cycle the pull-up resistor on the D+ (IIRC otherwise it is D-; just check the specs) to restart the USB negotiation. This helps to make sure the device always ends up in a state where it can communicate with the host.
« Last Edit: November 16, 2023, 10:55:06 pm by nctnico »
There are small lies, big lies and then there is what is on the screen of your oscilloscope.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf