USB en STM32F107RCT y Stm32CubeMX

Tengo un MCU STM32f107 soldado en una placa personalizada. Me gustaría usar un periférico USB en modo CDC. Conecté los pines PA11 (D-), PA12 (D+) y GND directamente a un cable USB CDC que conduce a la computadora. El dispositivo es autoalimentado, por lo que no uso el pin VDD.

En STM32Cube creé un nuevo proyecto, configuré solo el dispositivo USB_OTG_FS y USB_DEVICE en la sección de middleware. También configuré el reloj de alta velocidad en la sección RCC para que el periférico USB tenga un reloj de 48 MHz.

Luego generé el esqueleto del programa y lo subí a la MCU. Desafortunadamente no funciona. Creo que el principal problema es que no hay voltaje en el pin D +, por lo que la computadora no puede reconocer un nuevo dispositivo. Cuando ejecuto la CDC_Transmit_FSfunción, el procesador cae en falla Hard.

Lo más extraño es que cuando configuro la MCU STM32F429 en el kit Discovery de manera similar, el USB funciona de manera inmediata. Traté de diferenciar el código fuente, pero no encontré ninguna diferencia crucial (excepto que la MCU STMF4 usa USB OTG de alta velocidad en modo de velocidad máxima).

¿Alguien tiene alguna experiencia en el uso de USB con el esqueleto del programa STM32F107 y STM32CubeMX?

EDITAR: cuando ejecuto la MCU en el modo de cargador de arranque, la línea D + se tira a 3V3; por lo tanto, creo que la MCU realmente no necesita ningún pull-up externo (también la hoja de datos dice esto).

EDIT2: ¿Alguien sabe qué hace exactamente la opción Activar VBUS en CubeMX? Puedo entenderlo en el modo Host, pero ¿qué hace en el modo Solo dispositivo?

Con las partes ST, normalmente necesita la resistencia pullup en una línea de datos USB que indica que la velocidad del dispositivo es externa ; por lo general, no la incluyen dentro del chip.
@ChrisStratton Otras partes de ST pueden requerir esto, pero no este microcontrolador específico. Tengo un proyecto de trabajo con este IC y no hay pullups de datos.

Respuestas (5)

Aunque el dispositivo es autoalimentado, aún necesita conectar el Vbus del USB (pin 1) al OTG_FS_VBUS del microcontrolador (pin PA9).

Esto no es para proporcionar energía, sino para permitir que el microcontrolador sepa cuándo iniciar el subsistema USB.

¿Está seguro? Probé la conexión de 3 hilos en el kit Discovery STMF429I (pasé por alto el conector microUSB oficial y conecté el cable USB directamente a los pines MCU apropiados) y funcionó sin problemas. Creo que lo más importante es que la línea de datos D+ se lleva a 3V3 y esta es la señal para que la computadora inicie la comunicación USB.
@klasyc Veo por su respuesta que se requiere la detección de Vbus en el modo Dispositivo, pero se puede desactivar en el modo Host. ¡Gracias por volver y avisarnos!

Gracias por ambas respuestas, tienes razón. Para resumir, haré otra respuesta. Espero que alguien encuentre esto útil.

  • La conexión USB requiere líneas GND, D+ y D-. VBUS se usa solo para la detección de cable USB.
  • La detección de VBUS se puede desactivar al menos en algunas MCU. En este caso, el cable VUSB no es necesario.
  • Cuando habilita el periférico USB OTG en CubeMX, no enciende el pin VBUS incluso si es necesario (a menos que marque la casilla de verificación Activar VBUS ).
  • No puedo decir qué hace la opción Activar VBUS en el modo Dispositivo. Traté de generar fuentes con y sin esta opción y ambos proyectos requerían una línea VBUS para que el USB funcionara.
  • Cuando genera código desde CubeMX (estoy usando HAL versión 1.31) con USB CDC en modo Dispositivo, el código generado realmente funciona en los núcleos stm32f1 y stm32f4 listos para usar. Incluso si no implementa controladores de envío/recepción, la MCU aún se reconoce como VCP.
  • Quería deshabilitar la detección de VBUS en STM32F107 escribiendo cero en el bit VBUSBSEN en el registro GCCFG, pero no tuve éxito o
    la biblioteca usb sobrescribió el valor (la biblioteca es bastante complicada, por lo tanto, no sé dónde poner exactamente la asignación de registro). También es interesante que el manual de referencia en la página 926, sección 28.17.3 dice que en el modo Dispositivo, la detección VBUS debe estar activada.
  • La MCU STM32F107 no requiere ninguna resistencia pull-up para que el USB funcione.

Si he dicho algo incorrecto, corrígeme en los comentarios.

Klasyc

Ese pull-up R en D+ (o D-) se usa para indicar la velocidad USB del dispositivo. Si bien el host puede detectar el dispositivo conectado mediante este pull-up, en su caso tiene un dispositivo USB (esclavo). Y dado que es autoalimentado, como respondió @bitsmack, detectará la conexión al monitorear VBUS e iniciará la operación USB.

Si configuró el periférico USB como función dual/OTG, también debe conectar el pin USB_OTG_xx_ID al pin ID/OTG en su conector micro-USB.

Para CDC, en CubeMX puedes configurar tu dispositivo como Device_Only, conecta VBUS (conector <-> MCU). Si utiliza un conector micro USB, conecte también los conectores ID/OTG <-> GND.

Todavía no puedo entender por qué STM32F429 funciona sin cable VBUS y STM32F107 no. ¿Crees que es una diferencia de hardware de ambos MCU?
No mencionaste el tipo de conector USB. Si el suyo es un micro USB, entonces debe conectar a tierra el pin ID/OTG. La placa STMF4 seguramente maneja el pin ID/OTG correctamente por software. Con respecto a VBUS, en STMF4 ya está conectado, de alguna manera 'piensa' que el dispositivo está conectado, incluso si usa otros 3 pines. Tal vez pueda desactivar la detección de VBUS en el software.
Yo uso el conector USB A conectado a la computadora y en el otro lado conecto el cable blanco, verde y negro directamente a los pines del kit de descubrimiento (el mismo circuito que para stm32f107). Por lo tanto, creo que el pin VBUS no es necesario.
Como no tenía VBUS conectado, debe deshabilitar la detección de VBUS: electronics.stackexchange.com/questions/124063/…
No he logrado deshabilitar la detección de VBUS, pero la conexión del pin VBUS realmente ayudó. Como tengo muchas observaciones, las escribí en una respuesta separada. Gracias por su asistencia.

Una forma de registrar un nivel alto en el pin VBUS (PA9) en el software (o sin una conexión física), es desmarcar la casilla de verificación "Activar_VBUS" en CubeMx y hacer que PA9 sea una salida GPIO, con el nivel predeterminado alto. Esto funcionó para mí con un STM32F105 que tiene la misma pila USB_OTG_FS que el F107. CubeMx resaltará una advertencia, pero esto puede ignorarse. El dispositivo enumera como debería.

La detección VBUS es obligatoria para los dispositivos autoalimentados (esclavos). La especificación USB exige que un dispositivo no pueda suministrar energía a las líneas D en ausencia de VBUS. Un dispositivo autoalimentado debe desconectar la resistencia pull-up tan pronto como desaparezca VBUS.

Por ejemplo, un dispositivo autoalimentado puede estar conectado físicamente a una PC que está apagada. Como el dispositivo todavía tiene energía, envía energía a la línea D a menos que pueda detectar la ausencia de VBUS.

No estoy seguro de qué sucede si no cumple con este requisito. Supongo que su dispositivo puede funcionar bien con algunos hosts pero no con otros. O funciona la mayor parte del tiempo, pero a veces puede causar un comportamiento extraño del host. Lo mejor es seguir la especificación USB y no correr riesgos.

La detección de VBUS no es necesaria para los dispositivos alimentados por bus, ya que no hay riesgo de conducir líneas D cuando el VBUS no está. Cuando VBUS se haya ido, el dispositivo también estará apagado, obviamente.

El hardware OTG_FS de STM32 administra su resistencia pull-up interna automáticamente, si la detección VBUS está activada. El otro hardware USB_Device, que está presente en algunos otros microcontroladores STM32, no tiene esta función y necesita software adicional y pull-up externo.