marshall9
marshall9

Reputation: 63

STM32f107 usb re-enumerate

I have a board that is connected to USB on a STM32F107 with the following pins

USB_OTG_VBUS : PA9 USBDM : PA11 USBDP : PA12

I have a project that needs to use both Virtual Com Port and USB Mass Storage. It needs to re-enumerate the USB then do a software reset to enable the different USB class.

I have tried various different things to get it to re-enumerate but so far have been unable to, the only way to re-enumerate is to unplug usb cable.

These are some of the functions i have tried with no success

USB_OTG_DisableGlobalInt(&USB_OTG_dev);
USB_OTG_WRITE_REG32(&USB_OTG_dev.regs.GREGS->GINTSTS, 0xBFFFFFFF);
USB_OTG_CoreReset(&USB_OTG_dev);
USBD_DeInit(&USB_OTG_dev);
DCD_DevDisconnect(&USB_OTG_dev);
NVIC_SystemReset();

Would anyone have any ideas on how to get the USB to re-enumerate when it is configured with only these 3 pins for the STM32F107?

Upvotes: 4

Views: 5159

Answers (4)

phil_rawlings
phil_rawlings

Reputation: 1263

I used the answer from @viteo and tweaked it a little as I had some compile errors. This code works on the Blue Pill development board (STM32F103C8), which includes a 1.5k pullup resistor on the PA12 (USB_DP) line. Therefore, this code forces the USB_DP line low for a short time, which is like the USB cable has been unplugged and reconnected, thereby forcing the host to re-enumerate the bus when the USB is subsequently configured.

Edit USB_DEVICE/App/usb_device.c and add the code inside the USB_DEVICE_Init_PreTreatment block

void MX_USB_DEVICE_Init(void)
{
  /* 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(100);
  /* USER CODE END USB_DEVICE_Init_PreTreatment */

Upvotes: 2

viteo
viteo

Reputation: 309

Before initializing USB peripheral, configure D+ pin (USBP) as GPIO output push-pull and set low (0V) for 5ms. Then initiate standard USB configuration including GPIO. After this procedure USB host recognizes new device and starts enumeration.

GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_ResetBits(GPIOA, GPIO_Pin_12);
delay_ms(5);

//call your USB Init here

Worked for me.

source

Upvotes: 2

dryggs
dryggs

Reputation: 33

Had a similar problem. Try this:

USB_OTG_dev.regs.GREGS->GCCFG = 0;

Wait a bit and then init the USB again.

Upvotes: 1

Fiddling Bits
Fiddling Bits

Reputation: 8861

If you're using a demo board, it has the functionality to disconnect the USB through a microcontroller pin. If you're not using a demo board, you need to come up with that ability yourself, by disconnecting the pull-up resistor on the USB_DM/USB_DP line...

Upvotes: 2

Related Questions