tests: drivers: smbus: add packet error correction (pec) testsuite
Add tests for SMBus packet error correction (PEC). The two primary
utilities tested are
* smbus_pec(): compute the PEC byte for a Block Write
* smbus_read_check_pec(): verify a PEC after
* Read Byte
* Read Word
* Block Read
Signed-off-by: Chris Friedt <cfriedt@tenstorrent.com>
diff --git a/tests/drivers/smbus/smbus_pec/CMakeLists.txt b/tests/drivers/smbus/smbus_pec/CMakeLists.txt
new file mode 100644
index 0000000..c23f2b6
--- /dev/null
+++ b/tests/drivers/smbus/smbus_pec/CMakeLists.txt
@@ -0,0 +1,10 @@
+# Copyright (c) 2025 Tenstorrent AI ULC
+# SPDX-License-Identifier: Apache-2.0
+
+cmake_minimum_required(VERSION 3.20.0)
+find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
+project(smbus_pec)
+
+target_include_directories(app PRIVATE ${ZEPHYR_BASE}/drivers/smbus)
+
+target_sources(app PRIVATE src/main.c)
diff --git a/tests/drivers/smbus/smbus_pec/prj.conf b/tests/drivers/smbus/smbus_pec/prj.conf
new file mode 100644
index 0000000..4aba7d8
--- /dev/null
+++ b/tests/drivers/smbus/smbus_pec/prj.conf
@@ -0,0 +1,4 @@
+CONFIG_ZTEST=y
+
+CONFIG_SMBUS=y
+CONFIG_SMBUS_SOFT_PEC=y
diff --git a/tests/drivers/smbus/smbus_pec/src/main.c b/tests/drivers/smbus/smbus_pec/src/main.c
new file mode 100644
index 0000000..e55908e
--- /dev/null
+++ b/tests/drivers/smbus/smbus_pec/src/main.c
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2025 Tenstorrent AI ULC
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#include <zephyr/ztest.h>
+#include <zephyr/sys/util.h>
+
+#include <smbus_utils.h>
+
+ZTEST(smbus_pec, test_smbus_pec)
+{
+ uint8_t addr = 0x42;
+ /* Write Block with PEC (SMBus spec v3.1, Section 6.5.7) */
+ uint8_t write_data[] = {
+ 0x73, /* command */
+ 4, /* len */
+ 0xde, 0xad, 0xbe, 0xef, /* data */
+ };
+ struct i2c_msg msgs[] = {
+ {
+ .buf = write_data,
+ .len = sizeof(write_data),
+ .flags = I2C_MSG_WRITE | I2C_MSG_STOP,
+ },
+ /* driver would add a PEC message here */
+ };
+
+ uint8_t actual_pec = smbus_pec(addr, msgs, ARRAY_SIZE(msgs));
+ uint8_t expected_pec = 0x12;
+
+ zexpect_equal(expected_pec, actual_pec, "expected: %02x actual: %02x",
+ expected_pec, actual_pec);
+}
+
+ZTEST(smbus_pec, test_smbus_read_check_pec)
+{
+ uint8_t addr = 0xa;
+
+ {
+ /* Read Byte with PEC (SMBus spec v3.1, Section 6.5.5) */
+ uint8_t data[] = {
+ 0x10, /* command */
+ 0x05, /* data */
+ 0x90, /* PEC */
+ };
+ struct i2c_msg msgs[] = {
+ {
+ .buf = &data[0], /* command */
+ .len = 1,
+ .flags = I2C_MSG_WRITE,
+ },
+ {
+ .buf = &data[1], /* data */
+ .len = 1,
+ .flags = I2C_MSG_READ,
+ },
+ {
+ .buf = &data[2], /* PEC */
+ .len = 1,
+ .flags = I2C_MSG_READ,
+ },
+ };
+
+ zexpect_ok(smbus_read_check_pec(SMBUS_MODE_PEC, addr, msgs, ARRAY_SIZE(msgs)));
+ }
+
+ {
+ /* Read Word with PEC (SMBus spec v3.1, Section 6.5.5) */
+ uint8_t data[] = {
+ 0x10, /* command */
+ 0x05, /* data byte (low) */
+ 0x0a, /* data byte (high) */
+ 0xcf, /* PEC */
+ };
+ struct i2c_msg msgs[] = {
+ {
+ .buf = &data[0], /* command */
+ .len = 1,
+ .flags = I2C_MSG_WRITE,
+ },
+ {
+ .buf = &data[1], /* data */
+ .len = 2,
+ .flags = I2C_MSG_READ,
+ },
+ {
+ .buf = &data[3], /* PEC */
+ .len = 1,
+ .flags = I2C_MSG_READ,
+ },
+ };
+
+ zexpect_ok(smbus_read_check_pec(SMBUS_MODE_PEC, addr, msgs, ARRAY_SIZE(msgs)));
+ }
+
+ {
+ /* Block read (SMBus spec v3.1, Section 6.5.7) */
+ uint8_t data[] = {
+ 0x10, /* command */
+ 0x06, /* block count */
+ 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, /* data */
+ 0x99, /* PEC */
+ };
+ struct i2c_msg msgs[] = {
+ {
+ .buf = &data[0], /* command */
+ .len = 1,
+ .flags = I2C_MSG_WRITE,
+ },
+ {
+ .buf = &data[1], /* block count */
+ .len = 1,
+ .flags = I2C_MSG_READ | I2C_MSG_RESTART,
+ },
+ {
+ .buf = &data[2], /* data */
+ .len = data[1],
+ .flags = I2C_MSG_READ,
+ },
+ {
+ .buf = &data[2] + data[1], /* PEC */
+ .len = 1,
+ .flags = I2C_MSG_READ,
+ },
+ };
+
+ zexpect_ok(smbus_read_check_pec(SMBUS_MODE_PEC, addr, msgs, ARRAY_SIZE(msgs)));
+ }
+}
+
+ZTEST_SUITE(smbus_pec, NULL, NULL, NULL, NULL, NULL);
diff --git a/tests/drivers/smbus/smbus_pec/testcase.yaml b/tests/drivers/smbus/smbus_pec/testcase.yaml
new file mode 100644
index 0000000..81c1fcd
--- /dev/null
+++ b/tests/drivers/smbus/smbus_pec/testcase.yaml
@@ -0,0 +1,4 @@
+common:
+ tags: smbus
+tests:
+ drivers.smbus.pec: {}