STM32 USB: detección de conexión y desconexión

Usando el ejemplo del controlador de almacenamiento masivo USB STM32F4 en modo dispositivo, ¿cómo detecta las conexiones y desconexiones con un controlador host?

Intenté sondear el estado del pin VBUS, pero podría ser alto desde un adaptador de pared o alto sin ninguna comunicación con el host.

¿Hay un registro para comprobar? Noté DSTS (¿estado, supongo?) en las estructuras de la biblioteca USB, pero no pude encontrar su documentación ni ningún comentario útil en el código.

lleve esta pregunta al foro STM, envíe un correo electrónico a su soporte técnico. ¿Es esta una PCB personalizada con STM32 o una placa de descubrimiento/otro desarrollo?
Ver la actividad del bus USB sería una buena pista.

Respuestas (7)

Podría detectar la conexión y desconexión de este archivo:

usbd_core.c

y la API para ello es esta

USBD_StatusTypeDef USBD_LL_DevConnected(USBD_HandleTypeDef  *pdev)
USBD_StatusTypeDef USBD_LL_DevDisconnected(USBD_HandleTypeDef  *pdev)

No estoy seguro acerca de la clase de almacenamiento masivo USB, pero en la clase CDC, las 2 API anteriores detectan la conexión y desconexión USB, tal vez esto ayude

Cosas a tener en cuenta:

  • Conexión > cuando el cable USB físico está conectado al puerto USB
  • Desconexión > cuando el cable USB físico se desconecta del puerto USB

Usé STMCubeMX para generar la clase USB CDC.

usbd_core.ctiene USBD_StatusTypeDef USBD_LL_DevConnected(USBD_HandleTypeDef *pdev) { return USBD_OK; }... ¿Cómo funciona esto?
OP pregunta cómo detectar la conexión, no qué hacer después de detectarla.
Esta parece la respuesta correcta, pero AFAICS ese código solo está activo si USB es OTG.
Pero estas devoluciones de llamada ya están implementadas en usbd_core.c y no puede agregar código de usuario allí. Entonces, ¿cómo puede el usuario manejar el evento?
Quiero decir, si está usando CubeMx, sobrescribirá su código cada vez que presione el botón generar.
Para resolver el problema que mencioné, puede editar el archivo C:\Program Files\STMicroelectronics\STM32Cube\STM32CubeMX\db\templates\usbdconf_f7_c.ftl(según el nombre de su tablero) y simplemente eliminar la implementación de las devoluciones de llamada en este archivo. Ahora puede agregar su propia implementación en sus archivos y CubeMx no sobrescribirá su código.
void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd)
{
  /* Inform USB library that core enters in suspend Mode. */
  USBD_LL_Suspend((USBD_HandleTypeDef*)hpcd->pData);
......

en usbd_conf.c

Llamadas de función en la desconexión del cable usb

(probado en dispositivo de almacenamiento masivo, CubeMX)

Para las personas que desean usar las partes del "Código de usuario" hechas por CubeMX, esta devolución de llamada se llama cuando el USB está conectado al sistema.

void HAL_PCD_ResumeCallback(PCD_HandleTypeDef *hpcd)

Y este se llama cuando el USB se desconecta del sistema.

void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd)

Ambas funciones están dentro de usbd_conf.c

La mejor manera de encajar con la pila de software de ST es implementar estas funciones:

void HAL_PCD_ConnectCallback(PCD_HandleTypeDef *hpcd);
void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd);

Estos se declaran con vínculos débiles en la pila HAL, por lo que sus implementaciones anularán los stubs HAL que no hacen nada.

Sin embargo, si está utilizando Cube, encontrará que ya están implementadas usbd_conf.cy, por razones desconocidas, no hay /* USER CODE BEGIN */secciones en estas funciones, por lo que Cube sobrescribirá su código la próxima vez que lo guarde. Hasta que ST arregle esto, no debe usar Cube (lo uso para iniciar un proyecto, luego dejo de usarlo y tomo el control) o puede modificar la plantilla de Cube para este archivo.

En el [CUBE-INSTALL-DIR]/db/templatesdirectorio, busque el usbdconf_XX.ftlarchivo para su MCU. por ejemplo, para el f4 será usbdconf_f4_c.ftl. Ahora edite ese archivo para incluir bloques únicos USER CODE BEGINy de comentarios. USER CODE ENDLa próxima vez que genere código fuente, tendrá una sección donde podrá colocar su código.

Estoy usando STM32F767ZI y me enfrentaba al mismo problema de no detectar USB como puerto de comunicación virtual, así que agregué la pila mínima de almacenamiento dinámico 2000 y el tamaño máximo de almacenamiento dinámico de 4000 y ¡boom! Empezó a funcionar.

En mi proyecto, estoy usando las devoluciones de llamada que se inicializan/registran en la siguiente estructura:

typedef struct _USBD_CDC_Itf
{
  int8_t (* Init)(void);   // <- triggered on connection
  int8_t (* DeInit)(void); // <- triggered on disconnection

  int8_t (* Control)(uint8_t cmd, uint8_t *pbuf, uint16_t length);
  int8_t (* Receive)(uint8_t *Buf, uint32_t *Len);
  int8_t (* TransmitCplt)(uint8_t *Buf, uint32_t *Len, uint8_t epnum);
} USBD_CDC_ItfTypeDef;

La respuesta es muy simple. ¡Al igual que probó VBUS, pruebe DSTS y vea qué sucede! Buena suerte.

Esto es apenas una respuesta. La pregunta establece que DSTS no está claramente documentado. ¿Tienes alguna idea para agregar? ¿O está sugiriendo simplemente registrar el valor para ver qué sucede, sin molestarse en entender lo que representa?
Presumiblemente, @Guill está hablando de esto: "Bit0 SUSPSTS: Suspendstatus En el modo de dispositivo, este bit se establece siempre que se detecte una condición de Suspensión en el USB. El núcleo ingresa al estado Suspendido cuando no hay actividad en las líneas de datos USB para un período de 3 ms. El núcleo sale de la suspensión: – Cuando hay una actividad en las líneas de datos USB"
Sin embargo, estoy de acuerdo, como un profesional que lucha con este horrible núcleo USB y la documentación asociada, esto es innecesariamente burlón.