Гуру, кто-нибудь делал обмен по PMBus на HAL библиотеке STM32? Один STM32 — мастер, другой — слейв.

Я настраиваю SMBus в CubeMX, добавил пакет X_CUBE_SMBUS, в папке Middlewares вижу stm32_PMBUS_stack и stm32_SMBUS_stack, но не знаю, что делать дальше, не умею этим пользоваться.

Не стоит упорно вгрызаться в низкоуровневый исходный код в Middleware, можно легко запутаться. У ST всё по одной схеме: раз уж ты скачал пакет X_CUBE_SMBUS, сразу иди в каталог его установки (обычно STM32Cube\Repository) и ищи папку Projects. Там точно будут готовые примеры (Example) для некоторых отладочных плат (например, NUCLEO или EVAL). Найди проект, связанный с PMBus, и просто открой его main.c и stm32_xx_it.c. Обрати внимание на две вещи: во-первых, на функцию обработки Stack Process, которая вызывается в главном цикле; во-вторых, как написан Callback при получении Command ведомым. Скопируй его код прикладного уровня, немного подправь — и всё заработает.

Брат, не парься, дока у этого пакета действительно написана немного разбросанно, я сам, когда впервые с ним столкнулся, долго въезжал.

Сейчас твоя ситуация такая: аппаратный уровень (CubeMX) настроен, но непонятно, как подружить уровень протокола (стек) с прикладным кодом.

Я вкратце распишу тебе основной алгоритм, как я его понял, просто действуй по нему:

Шаг 1: Убедись, что сгенерировал правильную структуру проекта При добавлении X-CUBE-SMBUS в Software Packs в CubeMX, в окне Mode есть два чекбокса: SMBus stack и PMBus extension, нужно отметить оба. После генерации кода в твоем проекте должны быть:

  • Middlewares/ST/STM32_SMBus_Stack/ — это основной стек протокола
  • Drivers/BSP/ — board support package (если ты его выбрал)

Шаг 2: Пойми, как работает стек Этот стек нужен не для того, чтобы ты дергал HAL_I2C_xxx, он оборачивает конечный автомат. Твой код будет в основном взаимодействовать с тремя функциями:

  • STACK_SMBUS_Init() — инициализация, привязка I2C-хэндла
  • STACK_SMBUS_HostCommand()для хоста (мастера), инициирует обмен данными
  • STACK_SMBUS_ExecuteCommand()для слейва, коллбэк при получении команды

Шаг 3: Как писать код для слейва Самое главное для слейва — это CMD_Table, массив, который говорит стеку: «Когда я получу код команды 0x01, из какого регистра мне читать; когда получу 0x02, в какой регистр писать».

const tSMBUS_CMD_Table MyCmdTable[] = {
    {0x01, MyReadHandler, MyWriteHandler, 1},  // код команды, коллбэк чтения, коллбэк записи, длина данных
    {0x02, MyReadHandler2, NULL, 2},
};

А затем внутри STACK_SMBUS_ExecuteCommand() делать диспетчеризацию на основе stackhandle.CurrentCommand.

Шаг 4: Как писать код для хоста С хостом всё намного проще: формируешь структуру команды и вызываешь STACK_SMBUS_HostCommand(&stackhandle, &cmd). Имей в виду, что эта функция неблокирующая, результат нужно смотреть в прерывании коллбэка через stackhandle.State.

Важные моменты:

  • Официальные примеры лежат в директории Projects, ищи тот, что ближе к твоей плате, например, для NUCLEO-G431RB или Discovery F072.
  • Обязательно прочитай AN4502, это официальный аппноут. Пусть он и объемный, но 8-я глава «Configuration» и 9-я глава «Project example» — просто спасательный круг.
  • При соединении двух STM32 линии SDA и SCL нужно подтягивать. Даже если на плате есть внутренние подтяжки, добавь внешние на 4.7 кОм — так надежнее. PMBus более чувствителен к целостности сигнала, чем I2C.

Если будут проблемы, кидай конкретные ошибки, подсобим.

Скорее всего, вы смотрите на эти папки не под тем углом. stm32_SMBUS_stack — это нижний коммуникационный уровень, а stm32_PMBUS_stack находится поверх него для обработки команд PMBus.
Что обычно нужно сделать дальше: включить периферию HAL SMBus, добавить в проект исходные файлы промежуточного ПО, инициализировать стек в main() и реализовать необходимые библиотеке функции обратного вызова. Без функций обратного вызова стеку некуда отправлять принятые кадры.

Спасибо всем гуру за ответы, пойду попробую.

Каков результат попытки?

Я скинул эту часть ребятам из команды, не хватает сил :sweat_smile: