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; +}