Skip to content

Commit

Permalink
logging: add driver for i2c log backend
Browse files Browse the repository at this point in the history
It's usually used to output FW log to i2c FDTI device connected on ISH boards.

Signed-off-by: Dong Wang <[email protected]>
  • Loading branch information
kwd-doodling committed Jun 3, 2024
1 parent 4d8cb3d commit ce1a74b
Show file tree
Hide file tree
Showing 6 changed files with 162 additions and 0 deletions.
1 change: 1 addition & 0 deletions zephyr/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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()
12 changes: 12 additions & 0 deletions zephyr/Kconfig
Original file line number Diff line number Diff line change
@@ -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
1 change: 1 addition & 0 deletions zephyr/module.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
name: hal_intel
build:
cmake: zephyr
kconfig: zephyr/Kconfig
8 changes: 8 additions & 0 deletions zephyr/subsys/logging/backends/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -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()
40 changes: 40 additions & 0 deletions zephyr/subsys/logging/backends/Kconfig.i2c
Original file line number Diff line number Diff line change
@@ -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
100 changes: 100 additions & 0 deletions zephyr/subsys/logging/backends/log_backend_i2c.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
/*
* Copyright (c) 2024 Intel Corporation.
*
* SPDX-License-Identifier: Apache-2.0
*/

#include <zephyr/device.h>
#include <zephyr/drivers/i2c.h>
#include <zephyr/logging/log_backend.h>
#include <zephyr/logging/log_core.h>
#include <zephyr/logging/log_ctrl.h>
#include <zephyr/logging/log_msg.h>
#include <zephyr/logging/log_output.h>
#include <zephyr/logging/log_backend_std.h>
#include <zephyr/sys/__assert.h>
#include <sedi_driver_i2c.h>

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));

0 comments on commit ce1a74b

Please sign in to comment.