Expertos, ¿alguien ha hecho comunicación PMBus con la librería HAL de STM32? Un STM32 como maestro y otro como esclavo.

Configuré SMBus con CubeMX y agregué el paquete X_CUBE_SMBUS. Veo que en la carpeta Middlewares están stm32_PMBUS_stack y stm32_SMBUS_stack, pero no sé qué hacer a continuación, no sé cómo usarlo.

No te rompas la cabeza leyendo el código fuente de bajo nivel del Middleware, que te vas a marear. ST siempre sigue el mismo patrón, así que, como ya te has descargado el paquete X_CUBE_SMBUS, ve directamente al directorio de instalación de este paquete (normalmente en STM32Cube\Repository) y busca la carpeta Projects. Ahí seguro que hay ejemplos listos para usar para algunas placas de desarrollo (como NUCLEO o EVAL). Encuentra el proyecto relacionado con PMBus y ábrelo directamente para mirar su main.c y stm32_xx_it.c. Fíjate sobre todo en dos cosas: primero, la función de procesamiento Stack Process que se llama en el bucle principal; y segundo, cómo está escrito el Callback después de que el esclavo recibe un Command. Copia su código de la capa de aplicación, modifícalo un poco y ya funcionará.

Tránquilo, hermano, es verdad que la documentación de este paquete está un poco dispersa, la primera vez que lo usé yo también estuve un buen rato perdido.

Tu estado actual es: la capa de hardware (CubeMX) ya está configurada, pero no sabes cómo conectar la capa de protocolo (stack) con el código de tu aplicación.

Déjame aclararte la idea principal según mi entendimiento, sigue estos pasos:

Paso 1: Confirma que generaste la estructura de proyecto correcta Al añadir X-CUBE-SMBUS en los Software Packs de CubeMX, la ventana Mode tiene dos checkboxes: SMBus stack y PMBus extension, tienes que marcar ambos. Después de generar el código, tu proyecto debería tener:

  • Middlewares/ST/STM32_SMBus_Stack/ —— este es el stack de protocolo principal
  • Drivers/BSP/ —— soporte a nivel de placa (si lo seleccionaste)

Paso 2: Entiende cómo funciona el stack Este stack no es para que llames a HAL_I2C_xxx, encapsula una máquina de estados. Tu código interactúa principalmente con tres funciones:

  • STACK_SMBUS_Init() —— inicialización, vincula el handle del I2C
  • STACK_SMBUS_HostCommand() —— para el host, inicia una comunicación
  • STACK_SMBUS_ExecuteCommand() —— para el esclavo, callback al recibir un comando

Paso 3: Cómo programar el esclavo Lo más importante en el esclavo es CMD_Table, que es un array que le dice al stack: «cuando reciba el código de comando 0x01, qué registro leo; cuando reciba 0x02, qué registro escribo».

const tSMBUS_CMD_Table MyCmdTable[] = {
    {0x01, MyReadHandler, MyWriteHandler, 1},  // código de comando, callback de lectura, callback de escritura, longitud de datos
    {0x02, MyReadHandler2, NULL, 2},
};

Luego, en STACK_SMBUS_ExecuteCommand(), haces el dispatch basándote en stackhandle.CurrentCommand.

Paso 4: Cómo programar el host El host es mucho más simple, solo construye la estructura del comando y llama a STACK_SMBUS_HostCommand(&stackhandle, &cmd). Ten en cuenta que esta función es no bloqueante, el resultado lo ves en stackhandle.State dentro del callback de interrupción.

Recordatorios importantes:

  • Los ejemplos oficiales están en el directorio Projects, busca el que más se acerque a tu placa, como el NUCLEO-G431RB o el Discovery F072.
  • Definitivamente lee el AN4502, es la nota de aplicación oficial; aunque es larga, el capítulo 8 «Configuration» y el capítulo 9 «Project example» son salvavidas.
  • Al conectar dos STM32 entre sí, tanto SDA como SCL necesitan resistencias pull-up; incluso si la placa tiene pull-ups internas, agregar unas externas de 4.7k lo hace más estable, ya que PMBus es más sensible a la integridad de la señal que I2C.

Si tienes problemas, pega el error específico y la gente te echará una mano.

Probablemente estés mirando las carpetas desde una perspectiva equivocada. stm32_SMBUS_stack es la capa de comunicación inferior, mientras que stm32_PMBUS_stack se encuentra por encima para la gestión de comandos PMBus.
Lo que necesitas hacer a continuación, por lo general, es: habilitar el periférico HAL SMBus, incluir los archivos fuente del middleware en el proyecto, inicializar la pila en main() e implementar las funciones de callback que requiere la librería. Sin los callbacks, la pila no tiene dónde enviar las tramas recibidas.

Gracias a los cracks por las respuestas, voy a probarlo primero.

¿Cómo resultó el intento?

Le dejé esta parte a mi compañero de equipo, me falta energía :sweat_smile: