Commit 84583ee6 authored by Tom Burdick's avatar Tom Burdick Committed by Alberto Escolar
Browse files

samples: pmci: mctp: Add I2C+GPIO bus owner sample



Adds a sample application that can act as the bus owner using
i2c+gpio mctp binding.

Provides an overlay for the frdm-mcxn947 using JP8 pins for i2c and
gpio.

It attempts to send a "ping" message to all endpoints while accepting
string messages from endpoints to print out.

Signed-off-by: default avatarTom Burdick <thomas.burdick@intel.com>
parent cbfe7813
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
cmake_minimum_required(VERSION 3.20.0)

find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(mctp_host)

target_sources(app PRIVATE src/main.c)
+32 −0
Original line number Diff line number Diff line
.. zephyr:code-sample:: mctp_i2c_bus_owner
   :name: MCTP I2C GPIO Top Node Sample

   Create an MCTP top node controlling I2C with GPIO signaling.

Overview
********
Sets up an MCTP top node that may talk to any number of connected endpoints over I2C.

Requirements
************
Board with an I2C and number of GPIOs used for triggering by each bus connected endpoint.

Wiring
******
A common I2C bus SDA/SCL pair connected to any number of boards (setup in devicetree)
along with a GPIO per board for signaling endpoint write requests.

Building and Running
********************

.. zephyr-app-commands::
   :zephyr-app: samples/modules/pmci/mctp/i2c_gpio_bus_owner
   :host-os: unix
   :board: frdm_mcxn947_mcxn947_cpu0
   :goals: run
   :compact:

References
**********

`MCTP Base Specification 2019 <https://www.dmtf.org/sites/default/files/standards/documents/DSP0236_1.3.1.pdf>`_
+30 −0
Original line number Diff line number Diff line
#include <zephyr/dt-bindings/gpio/gpio.h>

/* Sets up I2C and a GPIO on JP8 to use as our i2c bus for MCTP */

&gpio0 {
	status = "okay";
};

&gpio4 {
	status = "okay";
};

&flexcomm2 {
	status = "okay";
};

&flexcomm2_lpi2c2 {
	status = "okay";
	clock-frequency = <I2C_BITRATE_STANDARD>;
};

/ {
	mctp_i2c: mctp_i2c {
		compatible = "zephyr,mctp-i2c-gpio-controller";
		i2c = <&flexcomm2_lpi2c2>;
		endpoint-ids = <11>, <12>;
		endpoint-addrs = <70>, <71>;
		endpoint-gpios = <&gpio4 6 GPIO_ACTIVE_HIGH>, <&gpio4 7 GPIO_ACTIVE_HIGH>;
	};
};
+9 −0
Original line number Diff line number Diff line
# nothing here
CONFIG_I2C=y
CONFIG_I2C_MCUX_LPI2C_BUS_RECOVERY=y
CONFIG_I2C_RTIO=y
CONFIG_MCTP=y
CONFIG_MCTP_I2C_GPIO_CONTROLLER=y
CONFIG_MCTP_LOG_LEVEL_DBG=y
CONFIG_LOG=y
CONFIG_LOG_BUFFER_SIZE=4096
+59 −0
Original line number Diff line number Diff line
/*
 * Copyright (c) 2025 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <unistd.h>
#include <zephyr/types.h>
#include <zephyr/kernel.h>
#include <libmctp.h>
#include <zephyr/pmci/mctp/mctp_i2c_gpio_controller.h>

#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(mctp_i2c_gpio_bus_owner);

#define LOCAL_EID 20

MCTP_I2C_GPIO_CONTROLLER_DT_DEFINE(mctp_i2c_ctrl, DT_NODELABEL(mctp_i2c));

static void rx_message(uint8_t eid, bool tag_owner, uint8_t msg_tag, void *data, void *msg,
		       size_t len)
{
	LOG_INF("received message %s from endpoint %d to %d, msg_tag %d, len %zu", (char *)msg, eid,
		LOCAL_EID, msg_tag, len);
}

int main(void)
{
	int rc;
	struct mctp *mctp_ctx;

	LOG_INF("MCTP Host EID:%d on %s\n", LOCAL_EID, CONFIG_BOARD_TARGET);

	mctp_ctx = mctp_init();
	__ASSERT_NO_MSG(mctp_ctx != NULL);
	mctp_register_bus(mctp_ctx, &mctp_i2c_ctrl.binding, LOCAL_EID);
	mctp_set_rx_all(mctp_ctx, rx_message, NULL);

	while (true) {
		for (int i = 0; i < mctp_i2c_ctrl.num_endpoints; i++) {

			LOG_INF("sending message \"ping\" to endpoint %d",
				mctp_i2c_ctrl.endpoint_ids[i]);
			rc = mctp_message_tx(mctp_ctx, mctp_i2c_ctrl.endpoint_ids[i], false,
					0, "ping", sizeof("ping"));
			if (rc != 0) {
				LOG_WRN("Failed to send message \"ping\" to endpoint %d,"
					" errno %d\n", mctp_i2c_ctrl.endpoint_ids[i], rc);
			}

			k_msleep(500);
		}
	}

	return 0;
}