STM32 USB Device Renumeration
USB devices need a 1.5 kOhm pull-up resistor on the D+ line in order for them to identify as devices (rather than hosts). On many STM32 MCUs this pull-up resistor is built-in. Unfortunately on the "device only" STM32's - like the STM32F103 this is not the case, so in modules using those processors one often see something like this in the schematics:
This generally works just fine with one noticeable exception - since the D+ line is permanently pulled high, the device will not re-enumerate when it is soft restarted (for example when flashing new firmware). This is of course a major PITA when doing USB related development.
Fortunately there is a rather elegant work-around. In "usb_device.c" add the following at the top of the MX_USB_DEVICE_Init function:
/* USER CODE BEGIN USB_DEVICE_Init_PreTreatment */ GPIO_InitTypeDef GPIO_InitStruct = { 0 }; GPIO_InitStruct.Pin = GPIO_PIN_12; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_PULLDOWN; GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); HAL_GPIO_WritePin(GPIOA, GPIO_PIN_12, GPIO_PIN_RESET); HAL_Delay(50); HAL_GPIO_WritePin(GPIOA, GPIO_PIN_12, GPIO_PIN_SET); /* USER CODE END USB_DEVICE_Init_PreTreatment */
What this does is essentially to configure the PA12 pin (USB D+) as a GPIO output pin and pull that to GND for 50 ms, before letting the USB initialisation continue as normal. The result is that the host notice the device has been disconnected and thus tries to re-enumerate immediately.