title: STM32Cube USB VCP becomes inoperative after microcontroller reset
body: <p>I'm trying to figure out how to make the USB VCP functionality on my STM32F103-based Blue Pill board operate after a microcontroller reset, e.g. after uploading new code.</p>
  <p>As I have it right now, the VCP operates normally at first, but then PuTTY ceases to report any new lines from the VCP after a hardware reset. The FTDI adapter connected to <code>UART1</code> continues to work, though. Here is a <em>minified</em> version of <code>main.c</code>:</p>
  <pre class="lang-c prettyprint-override"><code>#include &quot;main.h&quot;
  #include &quot;usb_device.h&quot;
  #include &lt;string.h&gt;
  #include &lt;usbd_cdc_if.h&gt; // Necessary to avoid &quot;warning: implicit declaration of function&quot; for CDC_Transmit_FS()
  
  int main(void) {
    HAL_Init();
    SystemClock_Config();
    MX_GPIO_Init();
    MX_USART1_UART_Init();
    MX_USB_DEVICE_Init();
  
    char msg[50];
    HAL_StatusTypeDef ret_status = HAL_OK;
    sprintf(msg, &quot;Reset!\n&quot;);
    ret_status = HAL_UART_Transmit(&amp;huart1, (uint8_t*)msg, strlen(msg), HAL_MAX_DELAY);
    uint8_t state = 0;
  
    while (1) {
        HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, state ? GPIO_PIN_RESET : GPIO_PIN_SET);
        sprintf(msg, &quot;Hello World! LED State: %d\n&quot;, state);
        ret_status = HAL_UART_Transmit(&amp;huart1, (uint8_t*)msg, strlen(msg), HAL_MAX_DELAY);
        ret_status = CDC_Transmit_FS((uint8_t*)msg, strlen(msg));
  
        HAL_Delay(500);
        state = state == 1 ? 0 : 1;
    }
  }
  </code></pre>
  <p>In reading <a href="https://stackoverflow.com/q/54939948/3339274">this SO Q/A</a>, I learned that the issue is likely due to the host not recognizing that the client device was reset (<em>and thus needs to be reinitialized</em>) because the <code>D+</code> line was never pulled down. However, I don't understand where/how to apply a fix for this. I tried inserting a pair of <code>HAL_GPIO_WritePin</code> and <code>HAL_Delay</code> instructions into the <code>MX_USB_DEVICE_Init()</code> function like so:</p>
  <pre class="lang-c prettyprint-override"><code>void MX_USB_DEVICE_Init(void)
  {
    /* USER CODE BEGIN USB_DEVICE_Init_PreTreatment */
    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_12, GPIO_PIN_SET);
    HAL_Delay(100);
    /* USER CODE END USB_DEVICE_Init_PreTreatment */
  
    /* Init Device Library, add supported class and start the library. */
    if (USBD_Init(&amp;hUsbDeviceFS, &amp;FS_Desc, DEVICE_FS) != USBD_OK)
    {
      Error_Handler();
    }
    if (USBD_RegisterClass(&amp;hUsbDeviceFS, &amp;USBD_CDC) != USBD_OK)
    {
      Error_Handler();
    }
    if (USBD_CDC_RegisterInterface(&amp;hUsbDeviceFS, &amp;USBD_Interface_fops_FS) != USBD_OK)
    {
      Error_Handler();
    }
    if (USBD_Start(&amp;hUsbDeviceFS) != USBD_OK)
    {
      Error_Handler();
    }
  
    /* USER CODE BEGIN USB_DEVICE_Init_PostTreatment */
  
    /* USER CODE END USB_DEVICE_Init_PostTreatment */
  }
  </code></pre>
  <p>but there was no effect. I also tried changing the instruction to pull the pin to <code>GPIO_PIN_RESET</code> in case I'd misunderstood which constant corresponded to a logic low, but it also didn't have any effect. As far as I can reason, this should have the effect of applying the fix described in <a href="https://stackoverflow.com/a/54950568/3339274">0___________'s answer</a>, but I must have misunderstood the problem. Does anyone know how to address this?</p>
  <h1>Solution (<em>Oct. 22, 2021</em>)</h1>
  <p>In accordance with <a href="https://stackoverflow.com/a/69661896/3339274">@Flexz's answer below</a>, I added code to my modification of the <code>MX_USB_DEVICE_Init()</code> function to be the following:</p>
  <pre class="lang-c prettyprint-override"><code>void MX_USB_DEVICE_Init(void)
  {
    /* USER CODE BEGIN USB_DEVICE_Init_PreTreatment */
    GPIO_InitTypeDef GPIO_InitStruct = {0};
  
    /*Configure GPIO pin Output Level */
    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_12, GPIO_PIN_RESET);
  
    /*Configure GPIO pin : PA12 */
    GPIO_InitStruct.Pin = GPIO_PIN_12;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    HAL_GPIO_Init(GPIOA, &amp;GPIO_InitStruct);
  
  
    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_12, GPIO_PIN_RESET);
    HAL_Delay(100); // Actually unnecessary (from my testing) and can be removed without consequence.
    /* USER CODE END USB_DEVICE_Init_PreTreatment */
  
    /* Init Device Library, add supported class and start the library. */
    if (USBD_Init(&amp;hUsbDeviceFS, &amp;FS_Desc, DEVICE_FS) != USBD_OK)
    {
      Error_Handler();
    }
    if (USBD_RegisterClass(&amp;hUsbDeviceFS, &amp;USBD_CDC) != USBD_OK)
    {
      Error_Handler();
    }
    if (USBD_CDC_RegisterInterface(&amp;hUsbDeviceFS, &amp;USBD_Interface_fops_FS) != USBD_OK)
    {
      Error_Handler();
    }
    if (USBD_Start(&amp;hUsbDeviceFS) != USBD_OK)
    {
      Error_Handler();
    }
  
    /* USER CODE BEGIN USB_DEVICE_Init_PostTreatment */
  
    /* USER CODE END USB_DEVICE_Init_PostTreatment */
  }
  </code></pre>
  <p>I adapted this from code generated by STM32CubeMX to configure the Blue Pill's green SMD LED (<em>PC13</em>). At least for me, this makes the VCP function again after an MCU reset, although PuTTY still complains and I have to reinit it manually. :)</p>