From ce1a74b3642dd3ba571a7ee7523175d3eb3a722d Mon Sep 17 00:00:00 2001 From: Dong Wang Date: Tue, 14 May 2024 15:27:55 +0800 Subject: [PATCH] logging: add driver for i2c log backend It's usually used to output FW log to i2c FDTI device connected on ISH boards. Signed-off-by: Dong Wang --- zephyr/CMakeLists.txt | 1 + zephyr/Kconfig | 12 +++ zephyr/module.yml | 1 + zephyr/subsys/logging/backends/CMakeLists.txt | 8 ++ zephyr/subsys/logging/backends/Kconfig.i2c | 40 +++++++ .../subsys/logging/backends/log_backend_i2c.c | 100 ++++++++++++++++++ 6 files changed, 162 insertions(+) create mode 100644 zephyr/Kconfig create mode 100644 zephyr/subsys/logging/backends/CMakeLists.txt create mode 100644 zephyr/subsys/logging/backends/Kconfig.i2c create mode 100644 zephyr/subsys/logging/backends/log_backend_i2c.c diff --git a/zephyr/CMakeLists.txt b/zephyr/CMakeLists.txt index 30dcf6d..a315d47 100644 --- a/zephyr/CMakeLists.txt +++ b/zephyr/CMakeLists.txt @@ -39,4 +39,5 @@ if(CONFIG_INTEL_HAL) zephyr_library_sources(${BSP_SEDI_SOC_DIR}/sedi_soc.c) endif() + add_subdirectory(subsys/logging/backends) endif() diff --git a/zephyr/Kconfig b/zephyr/Kconfig new file mode 100644 index 0000000..9b4425b --- /dev/null +++ b/zephyr/Kconfig @@ -0,0 +1,12 @@ +# Kconfig - Intel HAL Zephyr configuration options +# +# Copyright (c) 2024 Intel Corporation. +# +# SPDX-License-Identifier: Apache-2.0 +# + +menu "Intel HAL Zephyr Configuration" + +rsource "subsys/logging/backends/Kconfig.i2c" + +endmenu diff --git a/zephyr/module.yml b/zephyr/module.yml index d0baee8..afa3cef 100644 --- a/zephyr/module.yml +++ b/zephyr/module.yml @@ -1,3 +1,4 @@ name: hal_intel build: cmake: zephyr + kconfig: zephyr/Kconfig diff --git a/zephyr/subsys/logging/backends/CMakeLists.txt b/zephyr/subsys/logging/backends/CMakeLists.txt new file mode 100644 index 0000000..f331f1e --- /dev/null +++ b/zephyr/subsys/logging/backends/CMakeLists.txt @@ -0,0 +1,8 @@ +# Copyright (c) 2024 Intel Corporation Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# + +if (CONFIG_LOG) + zephyr_sources_ifdef(CONFIG_LOG_BACKEND_I2C log_backend_i2c.c) +endif() diff --git a/zephyr/subsys/logging/backends/Kconfig.i2c b/zephyr/subsys/logging/backends/Kconfig.i2c new file mode 100644 index 0000000..b9206b1 --- /dev/null +++ b/zephyr/subsys/logging/backends/Kconfig.i2c @@ -0,0 +1,40 @@ +# +# Copyright (c) 2024 Intel Corporation +# +# SPDX-License-Identifier: Apache-2.0 +# + +if LOG + +config LOG_BACKEND_I2C + bool "Enable I2C log backend" + depends on I2C_SEDI + select LOG_OUTPUT + help + When enabled, backend will use I2C for logging. + +if LOG_BACKEND_I2C + +config LOG_BACKEND_I2C_AUTOSTART + bool "Automatically start I2C backend" + default y + help + When enabled automatically start the I2C logging backend on + application start. When disabled, the application needs to start + the backend manually using log_backend_enable(). + +backend = I2C +backend-str = i2c +source "subsys/logging/Kconfig.template.log_format_config" + +config LOG_I2C_MAX_MSG_LEN + int "Maximum message length" + default 256 + +config LOG_I2C_DEV_ADDR + hex "I2C address of I2C log device" + default 0x5E + +endif # LOG_BACKEND_I2C + +endif # LOG diff --git a/zephyr/subsys/logging/backends/log_backend_i2c.c b/zephyr/subsys/logging/backends/log_backend_i2c.c new file mode 100644 index 0000000..0162544 --- /dev/null +++ b/zephyr/subsys/logging/backends/log_backend_i2c.c @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2024 Intel Corporation. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static uint32_t log_format_current = CONFIG_LOG_BACKEND_I2C_OUTPUT_DEFAULT; +static uint8_t log_i2c_buf[CONFIG_LOG_I2C_MAX_MSG_LEN]; +static bool panic_mode; +static uint8_t i2c_bus; + +static int log_i2c_char_out(uint8_t *data, size_t length, void *ctx) +{ + ARG_UNUSED(ctx); + + __ASSERT_NO_MSG(length > 0 && length <= CONFIG_LOG_I2C_MAX_MSG_LEN); + + sedi_i2c_master_poll_write(i2c_bus, CONFIG_LOG_I2C_DEV_ADDR, + data, length, false); + + return length; +} + +LOG_OUTPUT_DEFINE(log_output_i2c, log_i2c_char_out, + log_i2c_buf, CONFIG_LOG_I2C_MAX_MSG_LEN); + +static void log_i2c_panic(struct log_backend const *const backend) +{ + ARG_UNUSED(backend); + + panic_mode = true; + sedi_i2c_control(i2c_bus, SEDI_I2C_ABORT_TRANSFER, 0); + log_backend_std_panic(&log_output_i2c); +} + +static void log_i2c_dropped(const struct log_backend *const backend, + uint32_t cnt) +{ + ARG_UNUSED(backend); + + log_backend_std_dropped(&log_output_i2c, cnt); +} + +static void process(const struct log_backend *const backend, + union log_msg_generic *msg) +{ + uint32_t flags = log_backend_std_get_flags(); + log_format_func_t log_output_func = log_format_func_t_get(log_format_current); + + log_output_func(&log_output_i2c, &msg->log, flags); +} + +static int format_set(const struct log_backend *const backend, uint32_t log_type) +{ + log_format_current = log_type; + return 0; +} + +static void log_backend_i2c_init(const struct log_backend *const backend) +{ +#if DT_HAS_CHOSEN(zephyr_log_i2c) + uint32_t cfg = I2C_SPEED_SET(I2C_SPEED_FAST) | I2C_MODE_CONTROLLER; + int ret = i2c_configure(DEVICE_DT_GET(DT_CHOSEN(zephyr_log_i2c)), cfg); + + if (ret) { + goto disable; + } + + i2c_bus = DT_PROP(DT_CHOSEN(zephyr_log_i2c), peripheral_id); + panic_mode = false; + + return; + +disable: +#endif + /* No specified log i2c device or device not ready */ + log_backend_disable(backend); +} + +static const struct log_backend_api log_backend_i2c_api = { + .process = process, + .panic = log_i2c_panic, + .init = log_backend_i2c_init, + .dropped = IS_ENABLED(CONFIG_LOG_MODE_IMMEDIATE) ? NULL : log_i2c_dropped, + .format_set = format_set, +}; + +LOG_BACKEND_DEFINE(log_backend_i2c, log_backend_i2c_api, + IS_ENABLED(CONFIG_LOG_BACKEND_I2C_AUTOSTART));