From dfb240f37ced92b5f487179dba6c93bc8f6c04e6 Mon Sep 17 00:00:00 2001 From: Francois Ramu Date: Thu, 26 Oct 2023 11:13:35 +0200 Subject: [PATCH] samples: boards: stm32 I2C config and gives V2 timing calculation This sample reports the I2C configuration of the selected I2C node from the board DTS : bitrate property of the I2C node In case of I2C V2, it also gives the TIMINGS which has to be written in the DTS property of the I2C V2 node. Uses the i2c_get_config function with CONFIG_I2C_STM32_V2_TIMING. Signed-off-by: Francois Ramu --- .../boards/stm32/i2c_timing/CMakeLists.txt | 8 ++ samples/boards/stm32/i2c_timing/README.rst | 81 +++++++++++++++++++ .../i2c_timing/boards/nucleo_l476rg.overlay | 10 +++ .../i2c_timing/boards/nucleo_wb55rg.overlay | 10 +++ samples/boards/stm32/i2c_timing/prj.conf | 4 + samples/boards/stm32/i2c_timing/sample.yaml | 15 ++++ samples/boards/stm32/i2c_timing/src/main.c | 52 ++++++++++++ 7 files changed, 180 insertions(+) create mode 100644 samples/boards/stm32/i2c_timing/CMakeLists.txt create mode 100644 samples/boards/stm32/i2c_timing/README.rst create mode 100644 samples/boards/stm32/i2c_timing/boards/nucleo_l476rg.overlay create mode 100644 samples/boards/stm32/i2c_timing/boards/nucleo_wb55rg.overlay create mode 100644 samples/boards/stm32/i2c_timing/prj.conf create mode 100644 samples/boards/stm32/i2c_timing/sample.yaml create mode 100644 samples/boards/stm32/i2c_timing/src/main.c diff --git a/samples/boards/stm32/i2c_timing/CMakeLists.txt b/samples/boards/stm32/i2c_timing/CMakeLists.txt new file mode 100644 index 00000000000000..e9f2b44191722a --- /dev/null +++ b/samples/boards/stm32/i2c_timing/CMakeLists.txt @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(i2c_timing) + +FILE(GLOB app_sources src/*.c) +target_sources(app PRIVATE ${app_sources}) diff --git a/samples/boards/stm32/i2c_timing/README.rst b/samples/boards/stm32/i2c_timing/README.rst new file mode 100644 index 00000000000000..a951a0872e22aa --- /dev/null +++ b/samples/boards/stm32/i2c_timing/README.rst @@ -0,0 +1,81 @@ +.. _i2c_config: + +STM32 I2C V2 timings +#################### + +Overview +******** +This sample simply demonstrate the **get_config** API of the stm32 I2C driver. +The I2C peripheral configuration is checked regarding the I2C bitrate which can be: + + - + - + - + + +In case of the I2C V2, the I2C peripheral of the STM32 microcontrollers have +a TIMING register to write in order to generate the correct I2C clock signal. +This value depends on the peripheral clock input and the I2C speed. +The calculation of that TIMING value can be given by the `STM32CubeMX`_ application +**or** by the present sample. + +Because the code sequence to calculate the I2C V2 TIMING value is heavy, +it is not advised to enable it in production binary. +By enabling CONFIG_I2C_STM32_V2_TIMING flag, this sample allows to +retrieve timing register configuration for the defined ``clock-frequency``. +User can then configure timing in his application by adapting the following dts +snippet with the output of this sample: + + + .. code-block:: c + + &i2c { + timings = <160000000 I2C_BITRATE_STANDARD 0xB0C03E40>, + <160000000 I2C_BITRATE_FAST 0xC041090F>, + <160000000 I2C_BITRATE_FAST_PLUS 0x6021050A>; + } + + +Building and Running +******************** + +In order to run this sample, make sure to + +- enable ``i2c`` node in your board DT file. +- enable the CONFIG_I2C_STM32_V2_TIMING=y in the board **conf** file +- alias the **i2c-0** to your ``i2c`` node of the board **overlay** file + + .. zephyr-app-commands:: + :zephyr-app: samples/boards/stm32/i2c_config + :board: b_u585i_iot02a + :goals: build + :compact: + +Sample Output +============= +When setting the b_u585i_iot02a.overlay to + + .. code-block:: c + + / { + aliases { + i2c-0 = &i2c2; + }; + }; + &i2c2 { + /delete-property/ clock-frequency; + clock-frequency = ; + }; + +The sample gives the corresponding TIMING value to report to the Device Tree: + +.. code-block:: console + + I2C timing value, report to the DTS : + timings = <160000000 I2C_BITRATE_FAST 0xC041090F>; + + I2C config : I2C_BITRATE_FAST + + +.. _STM32CubeMX: + https://www.st.com/en/development-tools/stm32cubemx.html diff --git a/samples/boards/stm32/i2c_timing/boards/nucleo_l476rg.overlay b/samples/boards/stm32/i2c_timing/boards/nucleo_l476rg.overlay new file mode 100644 index 00000000000000..a5e6a1ff1cf156 --- /dev/null +++ b/samples/boards/stm32/i2c_timing/boards/nucleo_l476rg.overlay @@ -0,0 +1,10 @@ +/ { + aliases { + i2c-0 = &i2c1; + }; +}; + +&i2c1 { + /delete-property/ clock-frequency; + clock-frequency = ; +}; diff --git a/samples/boards/stm32/i2c_timing/boards/nucleo_wb55rg.overlay b/samples/boards/stm32/i2c_timing/boards/nucleo_wb55rg.overlay new file mode 100644 index 00000000000000..a5e6a1ff1cf156 --- /dev/null +++ b/samples/boards/stm32/i2c_timing/boards/nucleo_wb55rg.overlay @@ -0,0 +1,10 @@ +/ { + aliases { + i2c-0 = &i2c1; + }; +}; + +&i2c1 { + /delete-property/ clock-frequency; + clock-frequency = ; +}; diff --git a/samples/boards/stm32/i2c_timing/prj.conf b/samples/boards/stm32/i2c_timing/prj.conf new file mode 100644 index 00000000000000..f5c70dc8a20476 --- /dev/null +++ b/samples/boards/stm32/i2c_timing/prj.conf @@ -0,0 +1,4 @@ +CONFIG_I2C=y +CONFIG_I2C_STM32_V2_TIMING=y +CONFIG_LOG=y +CONFIG_I2C_LOG_LEVEL_INF=y diff --git a/samples/boards/stm32/i2c_timing/sample.yaml b/samples/boards/stm32/i2c_timing/sample.yaml new file mode 100644 index 00000000000000..aacd13ef98d448 --- /dev/null +++ b/samples/boards/stm32/i2c_timing/sample.yaml @@ -0,0 +1,15 @@ +sample: + name: STM32 I2C V2 timing +tests: + sample.boards.stm32.i2c_timing: + depends_on: i2c + tags: + - drivers + - i2c + filter: dt_compat_enabled("st,stm32-i2c-v2") + platform_allow: nucleo_l476rg nucleo_wb55rg + harness: console + harness_config: + type: one_line + regex: + - "I2C freq. I2C_BITRATE_*" diff --git a/samples/boards/stm32/i2c_timing/src/main.c b/samples/boards/stm32/i2c_timing/src/main.c new file mode 100644 index 00000000000000..41b8dfa2dee25d --- /dev/null +++ b/samples/boards/stm32/i2c_timing/src/main.c @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2023 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + + + +#include +#include + + +#if DT_NODE_HAS_STATUS(DT_ALIAS(i2c_0), okay) +#define I2C_DEV_NODE DT_ALIAS(i2c_0) +#else +#error "Please set the correct I2C device" +#endif + +int main(void) +{ + const struct device *const i2c_dev = DEVICE_DT_GET(I2C_DEV_NODE); + uint32_t i2c_cfg; + + if (!device_is_ready(i2c_dev)) { + printk("I2C device is not ready\n"); + return -1; + } + + /* Verify i2c_get_config() */ + if (i2c_get_config(i2c_dev, (uint32_t *)&i2c_cfg)) { + printk("I2C get_config failed\n"); + return -1; + } + + /* I2C BIT RATE */ + printk("\nI2C freq."); + + if ((I2C_SPEED_GET(i2c_cfg) == 1) && + (DT_PROP(I2C_DEV_NODE, clock_frequency) == 100000)) { + printk(" I2C_BITRATE_STANDARD\n"); + } else if ((I2C_SPEED_GET(i2c_cfg) == 2) && + (DT_PROP(I2C_DEV_NODE, clock_frequency) == 400000)) { + printk(" I2C_BITRATE_FAST\n"); + } else if ((I2C_SPEED_GET(i2c_cfg) == 3) && + (DT_PROP(I2C_DEV_NODE, clock_frequency) == 1000000)) { + printk(" I2C_SPEED_FAST_PLUS\n"); + } else { + printk(" I2C speed mismatch (%d)\n", I2C_SPEED_GET(i2c_cfg)); + } + + return 0; +}