i2c_emul: Add support for CONFIG_I2C_TARGET_BUFFER_MODE
Add emulation and test to support the buffered target mode. Signed-off-by: Yuval Peress <peress@google.com>
This commit is contained in:
parent
81f163e6fb
commit
690134356c
11 changed files with 334 additions and 38 deletions
|
@ -150,7 +150,7 @@ I2C Emulation features
|
|||
In the binding of the I2C emulated bus, there's a custom property for address
|
||||
based forwarding. Given the following devicetree node:
|
||||
|
||||
.. code-block::
|
||||
.. code-block:: devicetree
|
||||
|
||||
i2c0: i2c@100 {
|
||||
status = "okay";
|
||||
|
@ -170,7 +170,7 @@ same image.
|
|||
|
||||
.. note::
|
||||
The ``#forward-cells`` attribute should always be 1. Each entry in the
|
||||
``fowards`` attribute consists of the phandle followed by the address. In
|
||||
``forwards`` attribute consists of the phandle followed by the address. In
|
||||
the example above, ``<&i2c1 0x20>`` will forward all read/write operations
|
||||
made to ``i2c0`` at port ``0x20`` to ``i2c1`` on the same port. Since no
|
||||
additional cells are used by the emulated controller, the number of cells
|
||||
|
|
|
@ -36,6 +36,7 @@ struct i2c_emul_data {
|
|||
|
||||
struct i2c_emul_config {
|
||||
struct emul_list_for_bus emul_list;
|
||||
bool target_buffered_mode;
|
||||
const struct i2c_dt_spec *forward_list;
|
||||
uint16_t forward_list_size;
|
||||
};
|
||||
|
@ -89,6 +90,41 @@ static int i2c_emul_send_to_target(const struct device *dev, struct i2c_msg *msg
|
|||
struct i2c_emul_data *data = dev->data;
|
||||
const struct i2c_target_callbacks *callbacks = data->target_cfg->callbacks;
|
||||
|
||||
#ifdef CONFIG_I2C_TARGET_BUFFER_MODE
|
||||
const struct i2c_emul_config *config = dev->config;
|
||||
|
||||
if (config->target_buffered_mode) {
|
||||
for (uint8_t i = 0; i < num_msgs; ++i) {
|
||||
if (i2c_is_read_op(&msgs[i])) {
|
||||
uint8_t *ptr = NULL;
|
||||
uint32_t len;
|
||||
int rc =
|
||||
callbacks->buf_read_requested(data->target_cfg, &ptr, &len);
|
||||
|
||||
if (rc != 0) {
|
||||
return rc;
|
||||
}
|
||||
if (len > msgs[i].len) {
|
||||
LOG_ERR("buf_read_requested returned too many bytes");
|
||||
return -ENOMEM;
|
||||
}
|
||||
memcpy(msgs[i].buf, ptr, len);
|
||||
} else {
|
||||
callbacks->buf_write_received(data->target_cfg, msgs[i].buf,
|
||||
msgs[i].len);
|
||||
}
|
||||
if (i2c_is_stop_op(&msgs[i])) {
|
||||
int rc = callbacks->stop(data->target_cfg);
|
||||
|
||||
if (rc != 0) {
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_I2C_TARGET_BUFFER_MODE */
|
||||
|
||||
for (uint8_t i = 0; i < num_msgs; ++i) {
|
||||
LOG_DBG(" msgs[%u].flags? 0x%02x", i, msgs[i].flags);
|
||||
if (i2c_is_read_op(&msgs[i])) {
|
||||
|
@ -289,6 +325,7 @@ static const struct i2c_driver_api i2c_emul_api = {
|
|||
.children = emuls_##n, \
|
||||
.num_children = ARRAY_SIZE(emuls_##n), \
|
||||
}, \
|
||||
.target_buffered_mode = DT_INST_PROP(n, target_buffered_mode), \
|
||||
.forward_list = emul_forward_list_##n, \
|
||||
.forward_list_size = ARRAY_SIZE(emul_forward_list_##n), \
|
||||
}; \
|
||||
|
|
|
@ -10,6 +10,12 @@ include: i2c-controller.yaml
|
|||
properties:
|
||||
reg:
|
||||
required: true
|
||||
target-buffered-mode:
|
||||
type: boolean
|
||||
description: |
|
||||
This option is used when the I2C target is enabled and it can support
|
||||
buffered mode for I2C target transfer. When 'false', the target will use
|
||||
PIO (Programmed I/O) mode.
|
||||
forwards:
|
||||
type: phandle-array
|
||||
description: |
|
||||
|
|
|
@ -7,6 +7,11 @@ project(i2c_emul)
|
|||
|
||||
target_sources(app PRIVATE
|
||||
src/emulated_target.cpp
|
||||
src/test_forwarding.cpp
|
||||
src/test_fowarding_common.cpp
|
||||
)
|
||||
if(CONFIG_I2C_TARGET_BUFFER_MODE)
|
||||
target_sources(app PRIVATE src/test_forwarding_buf.cpp)
|
||||
else()
|
||||
target_sources(app PRIVATE src/test_forwarding_pio.cpp)
|
||||
endif()
|
||||
target_include_directories(app PRIVATE include)
|
||||
|
|
8
tests/drivers/i2c/i2c_emul/boards/native_sim.buf.overlay
Normal file
8
tests/drivers/i2c/i2c_emul/boards/native_sim.buf.overlay
Normal file
|
@ -0,0 +1,8 @@
|
|||
/*
|
||||
* Copyright 2024 Google LLC
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
&i2c1 {
|
||||
target-buffered-mode;
|
||||
};
|
|
@ -31,7 +31,11 @@ extern struct i2c_target_config emulated_target_config[FORWARD_COUNT];
|
|||
DECLARE_FAKE_VALUE_FUNC(int, target_write_requested_##n, struct i2c_target_config *); \
|
||||
DECLARE_FAKE_VALUE_FUNC(int, target_write_received_##n, struct i2c_target_config *, \
|
||||
uint8_t); \
|
||||
DECLARE_FAKE_VALUE_FUNC(int, target_stop_##n, struct i2c_target_config *);
|
||||
DECLARE_FAKE_VALUE_FUNC(int, target_stop_##n, struct i2c_target_config *); \
|
||||
DECLARE_FAKE_VALUE_FUNC(int, target_buf_read_requested_##n, struct i2c_target_config *, \
|
||||
uint8_t **, uint32_t *) \
|
||||
DECLARE_FAKE_VOID_FUNC(target_buf_write_received_##n, struct i2c_target_config *, \
|
||||
uint8_t *, uint32_t)
|
||||
|
||||
DT_FOREACH_PROP_ELEM(CONTROLLER_LABEL, forwards, DECLARE_FAKE_TARGET_FUNCTIONS)
|
||||
|
||||
|
@ -42,6 +46,8 @@ DT_FOREACH_PROP_ELEM(CONTROLLER_LABEL, forwards, DECLARE_FAKE_TARGET_FUNCTIONS)
|
|||
fn(target_write_requested_##n); \
|
||||
fn(target_write_received_##n); \
|
||||
fn(target_stop_##n); \
|
||||
fn(target_buf_read_requested_##n); \
|
||||
fn(target_buf_write_received_##n); \
|
||||
} while (0);
|
||||
|
||||
#define FFF_FAKES_LIST_FOREACH(fn) \
|
||||
|
|
|
@ -15,18 +15,28 @@ DEFINE_FFF_GLOBALS;
|
|||
DEFINE_FAKE_VALUE_FUNC(int, target_write_requested_##n, struct i2c_target_config *); \
|
||||
DEFINE_FAKE_VALUE_FUNC(int, target_write_received_##n, struct i2c_target_config *, \
|
||||
uint8_t); \
|
||||
DEFINE_FAKE_VALUE_FUNC(int, target_stop_##n, struct i2c_target_config *);
|
||||
DEFINE_FAKE_VALUE_FUNC(int, target_stop_##n, struct i2c_target_config *); \
|
||||
DEFINE_FAKE_VALUE_FUNC(int, target_buf_read_requested_##n, struct i2c_target_config *, \
|
||||
uint8_t **, uint32_t *) \
|
||||
DEFINE_FAKE_VOID_FUNC(target_buf_write_received_##n, struct i2c_target_config *, \
|
||||
uint8_t *, uint32_t)
|
||||
|
||||
DT_FOREACH_PROP_ELEM(CONTROLLER_LABEL, forwards, DEFINE_FAKE_TARGET_FUNCTION);
|
||||
|
||||
/* clang-format off */
|
||||
#define DEFINE_EMULATED_CALLBACK(node_id, prop, n) \
|
||||
[n] = { \
|
||||
.write_requested = target_write_requested_##n, \
|
||||
.read_requested = target_read_requested_##n, \
|
||||
.write_received = target_write_received_##n, \
|
||||
.read_processed = target_read_processed_##n, \
|
||||
COND_CODE_1(CONFIG_I2C_TARGET_BUFFER_MODE, \
|
||||
(.buf_write_received = target_buf_write_received_##n, ), ()) \
|
||||
COND_CODE_1(CONFIG_I2C_TARGET_BUFFER_MODE, \
|
||||
(.buf_read_requested = target_buf_read_requested_##n, ), ()) \
|
||||
.stop = target_stop_##n, \
|
||||
},
|
||||
/* clang-format on */
|
||||
|
||||
struct i2c_target_callbacks emulated_callbacks[FORWARD_COUNT] = {
|
||||
DT_FOREACH_PROP_ELEM(CONTROLLER_LABEL, forwards, DEFINE_EMULATED_CALLBACK)};
|
||||
|
|
155
tests/drivers/i2c/i2c_emul/src/test_forwarding_buf.cpp
Normal file
155
tests/drivers/i2c/i2c_emul/src/test_forwarding_buf.cpp
Normal file
|
@ -0,0 +1,155 @@
|
|||
/*
|
||||
* Copyright 2024 Google LLC
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include "emulated_target.hpp"
|
||||
#include <cstdint>
|
||||
|
||||
#include <zephyr/devicetree.h>
|
||||
#include <zephyr/drivers/i2c.h>
|
||||
#include <zephyr/fff.h>
|
||||
#include <zephyr/ztest.h>
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
#define GET_TARGET_DEVICE(node_id, prop, n) DEVICE_DT_GET(DT_PHANDLE_BY_IDX(node_id, prop, n)),
|
||||
|
||||
/* Get the devicetree constants */
|
||||
constexpr const struct device *controller = DEVICE_DT_GET(CONTROLLER_LABEL);
|
||||
constexpr const struct device *targets[FORWARD_COUNT] = {
|
||||
DT_FOREACH_PROP_ELEM(CONTROLLER_LABEL, forwards, GET_TARGET_DEVICE)};
|
||||
|
||||
ZTEST(i2c_emul_forwarding, test_write_is_forwarded)
|
||||
{
|
||||
uint8_t data[] = {0x00, 0x01, 0x02};
|
||||
|
||||
target_buf_write_received_0_fake.custom_fake = [&data](struct i2c_target_config *,
|
||||
uint8_t *buf, uint32_t len) {
|
||||
zassert_equal(ARRAY_SIZE(data), len);
|
||||
zexpect_mem_equal(data, buf, len);
|
||||
};
|
||||
|
||||
zassert_ok(
|
||||
i2c_write(controller, data, ARRAY_SIZE(data), emulated_target_config[0].address));
|
||||
|
||||
// Expect 0 reads and 1 write/stop to be made
|
||||
zexpect_equal(0, target_buf_read_requested_0_fake.call_count);
|
||||
zexpect_equal(1, target_buf_write_received_0_fake.call_count);
|
||||
zexpect_equal(1, target_stop_0_fake.call_count);
|
||||
}
|
||||
|
||||
ZTEST(i2c_emul_forwarding, test_read_is_forwarded)
|
||||
{
|
||||
uint8_t expected[] = {0x01, 0x02, 0x03};
|
||||
uint8_t data[ARRAY_SIZE(expected)] = {};
|
||||
|
||||
/* Set the custom fake function to a lambda which captures the expected value as a reference.
|
||||
* This means that when the function is executed, we can access 'expected' as though it were
|
||||
* within the lambda's scope.
|
||||
*/
|
||||
target_buf_read_requested_0_fake.custom_fake = [&expected](struct i2c_target_config *,
|
||||
uint8_t **ptr, uint32_t *len) {
|
||||
*ptr = expected;
|
||||
*len = ARRAY_SIZE(expected);
|
||||
return 0;
|
||||
};
|
||||
|
||||
zassert_ok(i2c_read(controller, data, ARRAY_SIZE(expected),
|
||||
emulated_target_config[0].address));
|
||||
|
||||
// Expect 1 read/stop and 0 write to be made
|
||||
zexpect_equal(1, target_buf_read_requested_0_fake.call_count);
|
||||
zexpect_equal(0, target_buf_write_received_0_fake.call_count);
|
||||
zexpect_equal(1, target_stop_0_fake.call_count);
|
||||
zexpect_mem_equal(expected, data, ARRAY_SIZE(expected));
|
||||
}
|
||||
|
||||
ZTEST(i2c_emul_forwarding, test_failed_read_request)
|
||||
{
|
||||
uint8_t data;
|
||||
target_buf_read_requested_0_fake.return_val = -EINTR;
|
||||
|
||||
zassert_equal(-EINTR, i2c_read(controller, &data, 1, emulated_target_config[0].address));
|
||||
zexpect_equal(1, target_buf_read_requested_0_fake.call_count);
|
||||
zexpect_equal(0, target_buf_write_received_0_fake.call_count);
|
||||
zexpect_equal(0, target_stop_0_fake.call_count);
|
||||
}
|
||||
|
||||
ZTEST(i2c_emul_forwarding, test_read_request_overflow)
|
||||
{
|
||||
uint8_t data;
|
||||
|
||||
/* Set the custom_fake to a local lambda with no capture values. */
|
||||
target_buf_read_requested_0_fake.custom_fake = [](struct i2c_target_config *, uint8_t **_,
|
||||
uint32_t *len) {
|
||||
*len = UINT32_MAX;
|
||||
return 0;
|
||||
};
|
||||
|
||||
zassert_equal(-ENOMEM, i2c_read(controller, &data, 1, emulated_target_config[0].address));
|
||||
zexpect_equal(1, target_buf_read_requested_0_fake.call_count);
|
||||
zexpect_equal(0, target_buf_write_received_0_fake.call_count);
|
||||
zexpect_equal(0, target_stop_0_fake.call_count);
|
||||
}
|
||||
|
||||
ZTEST(i2c_emul_forwarding, test_transfer_is_forwarded)
|
||||
{
|
||||
uint8_t write_data[1] = {};
|
||||
uint8_t read_data[2] = {};
|
||||
|
||||
struct i2c_msg msgs[] = {
|
||||
{
|
||||
.buf = write_data,
|
||||
.len = sizeof(write_data),
|
||||
.flags = I2C_MSG_WRITE,
|
||||
},
|
||||
{
|
||||
.buf = read_data,
|
||||
.len = sizeof(read_data),
|
||||
.flags = I2C_MSG_READ | I2C_MSG_STOP,
|
||||
},
|
||||
};
|
||||
|
||||
int phase = 0;
|
||||
target_buf_write_received_0_fake.custom_fake = [&phase](struct i2c_target_config *,
|
||||
uint8_t *, uint32_t) {
|
||||
zassert_equal(0, phase,
|
||||
"Expected a call to buf_write_received before anything else");
|
||||
phase++;
|
||||
};
|
||||
target_buf_read_requested_0_fake.custom_fake = [&phase](struct i2c_target_config *,
|
||||
uint8_t **ptr, uint32_t *len) {
|
||||
zassert_equal(1, phase, "Expected a call to buf_Read_requested as the second step");
|
||||
phase++;
|
||||
|
||||
// Write a random byte. It doesn't make a difference.
|
||||
*ptr = (uint8_t *)&phase;
|
||||
*len = 1;
|
||||
return 0;
|
||||
};
|
||||
target_stop_0_fake.custom_fake = [&phase](struct i2c_target_config *) -> int {
|
||||
zassert_equal(2, phase, "Expected a call to stop as the 3rd step");
|
||||
phase++;
|
||||
return 0;
|
||||
};
|
||||
|
||||
zassert_ok(i2c_transfer(controller, msgs, ARRAY_SIZE(msgs),
|
||||
emulated_target_config[0].address));
|
||||
zexpect_equal(1, target_buf_write_received_0_fake.call_count);
|
||||
zexpect_equal(1, target_buf_read_requested_0_fake.call_count);
|
||||
zexpect_equal(1, target_stop_0_fake.call_count);
|
||||
zexpect_equal(3, phase, "Expected a total of 3 phases, but got %d", phase);
|
||||
}
|
||||
|
||||
ZTEST(i2c_emul_forwarding, test_call_pio_forwarded_bus_when_buffering_enabled)
|
||||
{
|
||||
uint8_t data[2];
|
||||
|
||||
zassert_ok(i2c_read(controller, data, ARRAY_SIZE(data), emulated_target_config[1].address));
|
||||
zexpect_equal(1, target_read_requested_1_fake.call_count);
|
||||
zexpect_equal(1, target_read_processed_1_fake.call_count);
|
||||
zexpect_equal(1, target_stop_1_fake.call_count);
|
||||
}
|
||||
|
||||
} // namespace
|
|
@ -19,38 +19,6 @@ constexpr const struct device *controller = DEVICE_DT_GET(CONTROLLER_LABEL);
|
|||
constexpr const struct device *targets[FORWARD_COUNT] = {
|
||||
DT_FOREACH_PROP_ELEM(CONTROLLER_LABEL, forwards, GET_TARGET_DEVICE)};
|
||||
|
||||
static void *i2c_emul_forwarding_setup(void)
|
||||
{
|
||||
// Register the target
|
||||
for (int i = 0; i < FORWARD_COUNT; ++i) {
|
||||
zassert_ok(i2c_target_register(targets[i], &emulated_target_config[i]));
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void i2c_emul_forwarding_before(void *fixture)
|
||||
{
|
||||
ARG_UNUSED(fixture);
|
||||
|
||||
// Reset all fakes
|
||||
FFF_FAKES_LIST_FOREACH(RESET_FAKE);
|
||||
FFF_RESET_HISTORY();
|
||||
}
|
||||
|
||||
static void i2c_emul_forwarding_teardown(void *fixture)
|
||||
{
|
||||
ARG_UNUSED(fixture);
|
||||
|
||||
// Unregister the I2C target callbacks
|
||||
for (int i = 0; i < FORWARD_COUNT; ++i) {
|
||||
zassert_ok(i2c_target_unregister(targets[i], &emulated_target_config[i]));
|
||||
}
|
||||
}
|
||||
|
||||
ZTEST_SUITE(i2c_emul_forwarding, NULL, i2c_emul_forwarding_setup, i2c_emul_forwarding_before, NULL,
|
||||
i2c_emul_forwarding_teardown);
|
||||
|
||||
ZTEST(i2c_emul_forwarding, test_write_is_forwarded)
|
||||
{
|
||||
// Try writing some values
|
||||
|
@ -271,4 +239,16 @@ ZTEST(i2c_emul_forwarding, test_forward_two_targets)
|
|||
"Expected to be called 0 times, got %d",
|
||||
target_read_processed_0_fake.call_count);
|
||||
}
|
||||
|
||||
ZTEST(i2c_emul_forwarding, test_error_in_write_received)
|
||||
{
|
||||
uint8_t data;
|
||||
|
||||
target_write_received_0_fake.return_val = -EINTR;
|
||||
zassert_equal(-EINTR, i2c_write(controller, &data, 1, emulated_target_config[0].address));
|
||||
zexpect_equal(1, target_write_requested_0_fake.call_count);
|
||||
zexpect_equal(1, target_write_received_0_fake.call_count);
|
||||
zexpect_equal(0, target_stop_0_fake.call_count);
|
||||
}
|
||||
|
||||
} // namespace
|
79
tests/drivers/i2c/i2c_emul/src/test_fowarding_common.cpp
Normal file
79
tests/drivers/i2c/i2c_emul/src/test_fowarding_common.cpp
Normal file
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* Copyright 2024 Google LLC
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include "emulated_target.hpp"
|
||||
|
||||
#include <zephyr/devicetree.h>
|
||||
#include <zephyr/drivers/i2c.h>
|
||||
#include <zephyr/fff.h>
|
||||
#include <zephyr/ztest.h>
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
#define GET_TARGET_DEVICE(node_id, prop, n) DEVICE_DT_GET(DT_PHANDLE_BY_IDX(node_id, prop, n)),
|
||||
|
||||
/* Get the devicetree constants */
|
||||
constexpr const struct device *controller = DEVICE_DT_GET(CONTROLLER_LABEL);
|
||||
constexpr const struct device *targets[FORWARD_COUNT] = {
|
||||
DT_FOREACH_PROP_ELEM(CONTROLLER_LABEL, forwards, GET_TARGET_DEVICE)};
|
||||
|
||||
static void *i2c_emul_forwarding_setup(void)
|
||||
{
|
||||
// Register the target
|
||||
for (int i = 0; i < FORWARD_COUNT; ++i) {
|
||||
zassert_ok(i2c_target_register(targets[i], &emulated_target_config[i]));
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void i2c_emul_forwarding_before(void *fixture)
|
||||
{
|
||||
ARG_UNUSED(fixture);
|
||||
|
||||
// Reset all fakes
|
||||
FFF_FAKES_LIST_FOREACH(RESET_FAKE);
|
||||
FFF_RESET_HISTORY();
|
||||
}
|
||||
|
||||
static void i2c_emul_forwarding_teardown(void *fixture)
|
||||
{
|
||||
ARG_UNUSED(fixture);
|
||||
|
||||
// Unregister the I2C target callbacks
|
||||
for (int i = 0; i < FORWARD_COUNT; ++i) {
|
||||
zassert_ok(i2c_target_unregister(targets[i], &emulated_target_config[i]));
|
||||
}
|
||||
}
|
||||
|
||||
ZTEST_SUITE(i2c_emul_forwarding, NULL, i2c_emul_forwarding_setup, i2c_emul_forwarding_before, NULL,
|
||||
i2c_emul_forwarding_teardown);
|
||||
|
||||
/* Common tests */
|
||||
|
||||
ZTEST(i2c_emul_forwarding, test_invalid_address_for_target)
|
||||
{
|
||||
uint8_t data;
|
||||
int rc = i2c_write(targets[0], &data, 1, emulated_target_config[0].address + 1);
|
||||
zassert_equal(-EINVAL, rc, "Expected %d (-EINVAL), but got %d", -EINVAL, rc);
|
||||
zexpect_equal(0, target_read_requested_0_fake.call_count);
|
||||
zexpect_equal(0, target_read_processed_0_fake.call_count);
|
||||
zexpect_equal(0, target_write_requested_0_fake.call_count);
|
||||
zexpect_equal(0, target_write_received_0_fake.call_count);
|
||||
zexpect_equal(0, target_buf_write_received_0_fake.call_count);
|
||||
zexpect_equal(0, target_buf_read_requested_0_fake.call_count);
|
||||
zexpect_equal(0, target_stop_0_fake.call_count);
|
||||
}
|
||||
|
||||
ZTEST(i2c_emul_forwarding, test_error_in_stop)
|
||||
{
|
||||
uint8_t data;
|
||||
|
||||
target_stop_0_fake.return_val = -EINTR;
|
||||
zassert_equal(-EINTR, i2c_write(controller, &data, 1, emulated_target_config[0].address));
|
||||
zexpect_equal(1, target_stop_0_fake.call_count);
|
||||
}
|
||||
|
||||
} // namespace
|
|
@ -2,6 +2,16 @@
|
|||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
tests:
|
||||
drivers.i2c.emul:
|
||||
drivers.i2c.emul.target_pio:
|
||||
platform_allow:
|
||||
- native_sim
|
||||
extra_configs:
|
||||
- CONFIG_I2C_TARGET_BUFFER_MODE=n
|
||||
drivers.i2c.emul.target_buf:
|
||||
platform_allow:
|
||||
- native_sim
|
||||
extra_configs:
|
||||
- CONFIG_I2C_TARGET_BUFFER_MODE=y
|
||||
extra_dtc_overlay_files:
|
||||
- "boards/native_sim.overlay"
|
||||
- "boards/native_sim.buf.overlay"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue