¿Cómo _disable_ USB en STM32F1xx?

4

Tengo un dispositivo alimentado por batería que utiliza un STM32F107 . El dispositivo funciona y actualmente estoy trabajando para minimizar su consumo de energía.

Uno de los mayores consumos de corriente es el subsistema USB, que utiliza aproximadamente 8 mA cuando está inactivo. El USB solo se utiliza para fines de configuración; casi siempre es innecesario tenerlo habilitado.

Estoy usando ST de la biblioteca USB v2.1.0 . Se comunica como un puerto COM virtual de clase CDC ("VCP"). Estoy usando la velocidad completa incrustada PHY.

Al encenderlo, quiero que el USB se inicie y esté activo durante, por ejemplo, 30 segundos. Después de esto, asumiendo que no hay conexión a un host, quiero simplemente cerrar la funcionalidad USB. Como si nunca lo hubiera habilitado en primer lugar.

No veo nada expuesto en la API que haría esto posible. Hay algunas funciones notables, pero no parecen ser lo que necesito:

  • de la plantilla de la API: usbDeInit()

    Esto es para código de usuario personalizado. Sin embargo, es llamado por la función de controlador de dispositivo usbd_cdc_DeInit() , que en realidad nunca se llama, por lo que puedo ver.

  • en la biblioteca cdc_core: usbd_cdc_DeInit()

    Este es el archivo al que nunca se llama en la fuente del controlador. Cierra los puntos finales, luego llama a la función usbDeInit() (mencionada anteriormente). Parece prometedor; sin embargo, se declara como static en la fuente del controlador. Dudo en cambiar el código de la biblioteca del controlador directamente, ya que esto se sobrescribirá cuando se actualice el controlador de ST en el futuro.

  • de la biblioteca device_core: USBD_DeInit()

    El controlador lo llama en algunos lugares, pero está vacío. Es decir, la función no contiene ningún código. De nuevo, prefiero no cambiar la fuente del controlador de ST.

Mi enrutamiento de inicialización se ve así:

// Configure USB Clock Source
RCC_OTGFSCLKConfig(RCC_OTGFSCLKSource_PLLVCO_Div3);

// Enable USB Clock
RCC_AHBPeriphClockCmd(USB_AHB_CLK, ENABLE);

// Initialize USB
USBD_Init(&USB_OTG_dev, USB_OTG_FS_CORE_ID, &USR_desc, &USBD_CDC_cb, &USR_cb);

Por supuesto, si simplemente deshabilito la fuente del reloj USB, entonces el microcontrolador se bloquea.

Me he asegurado de que el interruptor USB_OTG_FS_LOW_PWR_MGMT_SUPPORT esté habilitado en el archivo usb_conf.h, pero el sorteo actual permanece. Supongo que no entra en modo de suspensión (que, como dice Ali Chen, sería la solución adecuada).

  1. ¿Alguien sabe cómo lograr lo que estoy buscando?
  2. ¿Debo hacer algo especial en el lado del Host para decirle al dispositivo que suspenda?
pregunta bitsmack

2 respuestas

4

Deshabilitar bloques funcionales como USB en un SoC moderno no es algo que se deba hacer en el nivel de registro por parte del usuario. El bloque IP USB contiene varios sub-bloques e interfaces entre ellos: tejido de acceso, controlador central, FIFOs / SIPOs, PHY. Todas las interfaces generalmente funcionan con algunos protocolos de intercambio que, por lo general, requieren cierta presencia de relojes en ambos lados de la interfaz, por lo que la simulación arbitraria con los registros de control de reloj puede ocasionar interbloqueos. Por lo tanto, se recomienda encarecidamente utilizar funciones prediseñadas (como SUSPENDER) del software IP para administrar el bloqueo de USB. El documentación dice, en parte:

  

La interfaz OTG_HS tiene las siguientes características:   ...   - Las funciones de ahorro de energía, como la parada del reloj del sistema durante la suspensión del USB, la desactivación de los dominios del reloj interno del núcleo digital, PHY y   Gestión de energía DFIFO   ...

y

  

Suspensión del dispositivo Cuando el dispositivo detecta una condición de suspensión en el USB,   La biblioteca detiene todas las operaciones y pone el sistema a suspender.   estado (si el modo de bajo consumo está habilitado en el archivo usb_conf.h).

Por lo tanto, para llevar a cabo la tarea de ahorro de energía, recomendaría encarecidamente utilizar las funciones ya desarrolladas de la biblioteca USB de STM.

ADICIÓN: El paquete STM parece tener una limitación de que los modos de suspensión o desconexión no pueden ser forzados por el firmware del usuario. Aquí tiene una idea: una vez que finalice la función del dispositivo, cambie el controlador OTG al modo HOST. Pero luego no continúe con la inicialización de la función HOST, ni apague la función HOST. Podría resultar en un bloqueo USB completamente deshabilitado.

    
respondido por el Ale..chenski
1

Probablemente necesites deshabilitar todo en orden inverso. Prueba:

USBD_DeInit();
RCC_AHBPeriphClockCmd(USB_AHB_CLK, ENABLE);

O tal vez lo inverso.

    
respondido por el Ronan Paixão

Lea otras preguntas en las etiquetas