STM32F070 - conexión USB controlada por firmware y activación HSE

3

Estoy desarrollando un firmware para un dispositivo USB 2.0 de alta velocidad de baja potencia (12 Mbps) que utiliza un STM32F070CB microcontrolador. La fuente del reloj para el módulo USB será el oscilador externo de alta velocidad (HSE). Estoy usando STM32CubeMX con la versión 1.7.0 de STM32CubeF0 para generar la base de código .

Para conservar nuestro presupuesto de energía, debemos apagar el HSE cuando el USB no está conectado. Estoy pensando que deberíamos hacer que el host demore la detección de USB por el host hasta que el dispositivo esté listo, para que los eventos en el firmware sean así:

  • Evento - Detectar la conexión USB física
    • Habilitar HSE
    • Inicializar USB
    • Conecte Data + pull-up ( DPPU ) para activar la enumeración USB por el host
  • Evento - Detecta la conexión física USB dis
    • Desconecte DPPU (simular la desconexión física al host)
    • Desinicializar USB
    • Deshabilitar HSE (unidad PF0-OSC_IN bajo)

Preguntas

  1. ¿Lo anterior es la forma correcta de hacerlo? ¿Se requieren todas las acciones? ¿Están en el orden correcto?

  2. ¿Debo llamar a alguna función además de USBD_DeInit() para de-init USB?

  3. ¿Cómo puedo hacer que el dispositivo aparezca desconectado en el host mientras está conectado físicamente? (es decir, debería desaparecer del Administrador de dispositivos de Windows). ¿Por qué las llamadas a HAL_PCD_DevDisconnect() hacen que eso suceda?

Detalles

En los párrafos siguientes, "conectar físicamente" significa conectar el cable USB al dispositivo y al PC host.

Espero que todas las llamadas a MX_USB_DEVICE_Init() y MX_USB_DEVICE_DeInit() surtan efecto de inmediato, es decir, vería que el dispositivo aparece / desaparece en el Administrador de dispositivos de Windows si se llama a la función mientras el dispositivo está físicamente conectado. Sin embargo, he observado esto solo en la primera llamada a MX_USB_DEVICE_Init() . Todas las llamadas a MX_USB_DEVICE_DeInit() y las llamadas subsiguientes a MX_USB_DEVICE_Init() no hacen que el dispositivo aparezca / desaparezca del Administrador de dispositivos de Windows hasta después de la reconexión física. (es decir, si está conectado, cuando se llama a la función, no hay cambios en el Administrador de dispositivos hasta después de la desconexión / reconexión).

Código

Según lo generado por STM32CubeMX:

/* USB Device Core handle declaration */
USBD_HandleTypeDef hUsbDeviceFS;

/* init function */                     
void MX_USB_DEVICE_Init(void)
{
  /* Init Device Library,Add Supported Class and Start the library*/
  USBD_Init(&hUsbDeviceFS, &FS_Desc, DEVICE_FS);

  USBD_RegisterClass(&hUsbDeviceFS, &USBD_CDC);

  USBD_CDC_RegisterInterface(&hUsbDeviceFS, &USBD_Interface_fops_FS);

  USBD_Start(&hUsbDeviceFS);
}

He creado:

void MX_USB_DEVICE_DeInit(void)
{
   HAL_PCD_DevDisconnect((PCD_HandleTypeDef *)&hUsbDeviceFS.pData);
   USBD_Stop  (&hUsbDeviceFS);
   USBD_DeInit(&hUsbDeviceFS);
}

No hace ninguna diferencia si o cuando llamo a HAL_PCD_DevDisconnect() . Nunca he observado que el dispositivo desaparezca del Administrador de dispositivos de Windows mientras esté conectado físicamente.

    
pregunta cp.engr

1 respuesta

0
  
  1. ¿Cómo puedo hacer que el dispositivo aparezca desconectado en el host mientras está conectado físicamente? (es decir, debería desaparecer del Administrador de dispositivos de Windows). ¿Por qué las llamadas a HAL_PCD_DevDisconnect() hacen que eso suceda?
  2.   

Llamar a HAL_PCD_DevDisconnect() con los parámetros adecuados de hecho desconecta DPPU, por lo que el dispositivo desaparece del Administrador de dispositivos de Windows. El error en la pregunta es que en MX_USB_DEVICE_DeInit() ,

HAL_PCD_DevDisconnect((PCD_HandleTypeDef *)&hUsbDeviceFS.pData);

debería ser

HAL_PCD_DevDisconnect((PCD_HandleTypeDef *)hUsbDeviceFS.pData);

(sin el operador de dirección & ).

Aquí hay una versión revisada de la función de inicio de USB:

void MX_USB_DEVICE_DeInit(void)
{
   PCD_HandleTypeDef *hpcd = (PCD_HandleTypeDef *)hUsbDeviceFS.pData;

   if (hpcd != NULL)
   {
      HAL_PCD_DevDisconnect(hpcd);
      USBD_DeInit(&hUsbDeviceFS);
   }
}
  
  1. ¿Lo anterior es la forma correcta de hacerlo? ¿Se requieren todas las acciones? ¿Están en el orden correcto?
  2.   

Cerrar. La configuración del reloj es más que solo encender o apagar HSE.

STM32CubeMX genera SystemClock_Config() . Puede usarlo como modelo para los pasos de "Configurar relojes del sistema" en la lista a continuación.

  • Evento - Detectar la conexión USB física
    • configurar relojes del sistema
      • Habilitar HSE
      • Activar PLL
      • Establezca SYSCLKSOURCE en PLLCLK
      • Establezca UsbClockSelection en PLL
      • Configurar systick
    • Inicialice USB y conecte Data + pull-up ( DPPU ) para activar la enumeración USB por el host: MX_USB_DEVICE_Init() hace todo esto
  • Evento - Detectar la desconexión física del USB
    • Desconectar DPPU ( HAL_PCD_DevDisconnect() )
    • Desinicializar USB ( USBD_DeInit() )
    • Configure los relojes del sistema (observe muchos pasos en orden inverso desde arriba)
      • Apague el periférico USB
      • Cambie sysclk de nuevo a HSI
      • Deshabilitar HSE (no estoy seguro si es necesario conducir PF0-OSC_IN low)
      • Desactivar PLL
      • Configurar systick
  
  1. ¿Debo llamar a alguna función además de USBD_DeInit() para desiniciar el USB?
  2.   

No, eso lo hace. Profundice en las pilas de llamadas y encontrará que USBD_DeInit() llama a todo lo que hace USBD_Stop() y más.

    
respondido por el cp.engr

Lea otras preguntas en las etiquetas