- How can I make the device appear disconnected on the host while physically connected? (i.e. It should disappear from Windows Device Manager.) Why doesn't calling
HAL_PCD_DevDisconnect()
cause that to happen?
Calling HAL_PCD_DevDisconnect()
with the proper parameters does indeed disconnect DPPU, thus making the device disappear from Windows Device Manager. The error in the question is that in MX_USB_DEVICE_DeInit()
,
HAL_PCD_DevDisconnect((PCD_HandleTypeDef *)&hUsbDeviceFS.pData);
should be
HAL_PCD_DevDisconnect((PCD_HandleTypeDef *)hUsbDeviceFS.pData);
(without the address operator &
).
Here is a revised version of the USB de-init function:
void MX_USB_DEVICE_DeInit(void)
{
PCD_HandleTypeDef *hpcd = (PCD_HandleTypeDef *)hUsbDeviceFS.pData;
if (hpcd != NULL)
{
HAL_PCD_DevDisconnect(hpcd);
USBD_DeInit(&hUsbDeviceFS);
}
}
- Is the above the right way to go about this? Are the actions all required? Are they in the right order?
Close. There's more to the clock configuration than just turning HSE on or off.
STM32CubeMX generates SystemClock_Config()
. You can use it as a model for the "Configure system clocks" steps in the list below.
- Event - Detect physical USB connection
- Configure system clocks
- Enable HSE
- Turn on PLL
- Set
SYSCLKSOURCE
to PLLCLK
- Set
UsbClockSelection
to PLL
- Configure systick
- Initialize USB and connect Data+ pull-up (
DPPU
) to trigger USB enumeration by host - MX_USB_DEVICE_Init()
does all of this
- Event - Detect physical USB disconnection
- Disconnect
DPPU
(HAL_PCD_DevDisconnect()
)
- De-initialize USB (
USBD_DeInit()
)
- Configure system clocks (note many steps in reverse order from above)
- Turn off USB peripheral
- Switch sysclk back to HSI
- Disable HSE (not sure if driving
PF0-OSC_IN
low is necessary)
- Turn off PLL
- Configure systick
- Do I need to call any functions besides
USBD_DeInit()
to de-init USB?
No, that does it. Dig into the call stacks and you'll find that USBD_DeInit()
calls everything that USBD_Stop()
does and more.
A standard classic USB host must always provide VBUS (+5V +- 10%) to a downstream port, so a device can initiate the connect sequence (pull D+ or D- high). The port must provide at least 500 mA (2.0 version) or 900 mA (3.0 version), regardless of whether there is any communication or attachment or else. These are "at least" requirements for classic USB 2.0 and USB 3.0 "high-power ports" and powered hubs, so they can supply more if they wish. The requirements are listed in Section 7.2 of USB 2.0 Specifications. Small battery-powered might have an exception.
NOTE1: VBUS must be supplied by host even in "sleep" (suspend state) mode.
--
NOTE2: if a host doesn't drive VBUS high, no attachment would/should occur, even if the device has own power. Connect requests (D+ or D-
pull-ups) must occur only if VBUS is present, by USB 2.0
specifications Sec.7.2.1. So it is a spec violation just to "have" the
pull-ups, the pull-up must be conditional with VBUS.
--
NOTE3: So, no VBUS => no communication. Becuse of this rule, no "partial" or "host-signaling" mode is possible without VBUS.
The 500 mA is a requirement for USB HOST. This supply number is frequently confused with a requirement for a USB DEVICE as consumer. A USB device SHOULD NOT draw more than 100 mA upon initial connect stage, and can draw full power only when it gets enumerated and receives "set_configuration ()" command. USB devices report their power requirements in device descriptor, during this inital "100mA" session. If the host has exhausted its power budget, it can stop the enumeration, effectively rejecting the device.
NOTE4: as one can see, there is no "negotiation", it is either "my [host] way", or "freeway".
--
NOTE5: USB hosts have no specified means to police actual power
consumption from its ports. USB host controllers don't have any
registers that can measure/report ports consumption. Therefore a host cannot enforce
the 100mA limit to police out bad devices that might violate the 100
mA specification, unless a drastic event of port overcurrent occurs.
The compliance to 100 mA limit was thought at the level of USB-IF
certification process.
In short, the 500 mA and 100 mA are requirements for different USB entities, one for hosts and hubs, and another for devices, again as described in Section 7.2.1. This is how it works from USB standard point of view.
Now things are a bit different with introduction of Type-C connector. Type-C devices (both hosts and peripherals) are prohibited to output VBUS, initially. So, instead of boldly having VBUS power on a Type-C port, the host must turn on VBUS source only if the port logic detects the presence of cable/device. It does this by sensing voltage level on "CC" (Communication Channel) pin. A Type-C host has a pull-up on both CC pins. A device (or legacy cable assembly) must have 5.1k pull-down. When device/cable is plugged in, the host detects that 5.k drags its pull-up down, and at this point the host has rights to engage VBUS power, and USB communication begins.
Best Answer
Low speed (1.5 Mbps) devices can attach to any USB host (1.0, 1.1, 2.0 or 3.0). The low speed device initiates communication by pulling D- to 3 volts via 1500 ohm resistor. Any version USB host will be immediately able to communicate with the device at 1.5Mbps, e.g. ask for device descriptor, set address etc. Full and high speed devices use D+ for the same purpose.
I'd be surprised if there is a low-speed-only USB host commercially available. But if you are making the USB host yourself, and you only need to support low speed devices, such as an old keyboard or mouse, then you don't need to implement full speed. You don't need anything that is not necessary for your application as you have complete control on how you want to communicate with the device (except the speed). And by making the host yourself, I mean that you are not using a ready-made USB hardware. Perhaps you are using discrete logic or even bit-banging it on a microcontroller (there are known software implementations that bit-bang 1.5 Mbps USB).
With discrete logic, CPLD etc, it's not that complex. At core level, USB is remarkably simple. As an example, here's logic of how to do a USB receiver with just 15 flip-flops. I once did it because I was bored one summer day in 2014. It snoops USB data and converts it to SPI output so it can be snooped with a microcontroller with an SPI input.
Obviously, if a full speed or high speed device is connected to your low-speed-only host, your host will not be able to initiate communication with those devices. But if you're only going to attach low speed devices, then you don't need full speed. You can still detect the DP pull-up of full/high speed device and display a message that the device is not supported.