Skip to content

Commit db413b6

Browse files
ankunsrlubos
authored andcommitted
[nrf fromtree] drivers: i2c_nrfx_twim: add exclusive access API
This commit provides an extension to the i2c_nrfx_twim driver. It introduces possibility to acquire/release exclusive access to the i2c bus. While the exclusive access to the i2c bus is acquired you can access the underlying nrfx_twim driver directly. Signed-off-by: Andrzej Kuros <andrzej.kuros@nordicsemi.no> (cherry picked from commit d15c9fe9a613e2f9f6741f25209ef1a5fb9d4326)
1 parent 1a2d42b commit db413b6

9 files changed

+451
-6
lines changed

drivers/i2c/i2c_nrfx_twim.c

+26-6
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
*/
66

77
#include <zephyr/drivers/i2c.h>
8+
#include <zephyr/drivers/i2c/i2c_nrfx_twim.h>
89
#include <zephyr/dt-bindings/i2c/i2c.h>
910
#include <zephyr/pm/device.h>
1011
#include <zephyr/pm/device_runtime.h>
@@ -33,6 +34,29 @@ struct i2c_nrfx_twim_data {
3334
volatile nrfx_err_t res;
3435
};
3536

37+
int i2c_nrfx_twim_exclusive_access_acquire(const struct device *dev, k_timeout_t timeout)
38+
{
39+
struct i2c_nrfx_twim_data *dev_data = dev->data;
40+
int ret;
41+
42+
ret = k_sem_take(&dev_data->transfer_sync, timeout);
43+
44+
if (ret == 0) {
45+
(void)pm_device_runtime_get(dev);
46+
}
47+
48+
return ret;
49+
}
50+
51+
void i2c_nrfx_twim_exclusive_access_release(const struct device *dev)
52+
{
53+
struct i2c_nrfx_twim_data *dev_data = dev->data;
54+
55+
(void)pm_device_runtime_put(dev);
56+
57+
k_sem_give(&dev_data->transfer_sync);
58+
}
59+
3660
static int i2c_nrfx_twim_transfer(const struct device *dev,
3761
struct i2c_msg *msgs,
3862
uint8_t num_msgs, uint16_t addr)
@@ -46,13 +70,11 @@ static int i2c_nrfx_twim_transfer(const struct device *dev,
4670
uint8_t *buf;
4771
uint16_t buf_len;
4872

49-
k_sem_take(&dev_data->transfer_sync, K_FOREVER);
73+
(void)i2c_nrfx_twim_exclusive_access_acquire(dev, K_FOREVER);
5074

5175
/* Dummy take on completion_sync sem to be sure that it is empty */
5276
k_sem_take(&dev_data->completion_sync, K_NO_WAIT);
5377

54-
(void)pm_device_runtime_get(dev);
55-
5678
for (size_t i = 0; i < num_msgs; i++) {
5779
if (I2C_MSG_ADDR_10_BITS & msgs[i].flags) {
5880
ret = -ENOTSUP;
@@ -164,9 +186,7 @@ static int i2c_nrfx_twim_transfer(const struct device *dev,
164186
msg_buf_used = 0;
165187
}
166188

167-
(void)pm_device_runtime_put(dev);
168-
169-
k_sem_give(&dev_data->transfer_sync);
189+
i2c_nrfx_twim_exclusive_access_release(dev);
170190

171191
return ret;
172192
}
+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/*
2+
* Copyright (c) 2025 Nordic Semiconductor ASA
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#ifndef ZEPHYR_INCLUDE_DRIVERS_I2C_NRFX_TWIM_H
8+
#define ZEPHYR_INCLUDE_DRIVERS_I2C_NRFX_TWIM_H
9+
10+
#include <zephyr/kernel.h>
11+
#include <zephyr/drivers/i2c.h>
12+
13+
/** @brief Acquires exclusive access to the i2c bus controller.
14+
*
15+
* @param dev Pointer to the device structure for an I2C controller
16+
* driver configured in controller mode.
17+
* @param timeout Timeout for waiting to acquire exclusive access.
18+
*
19+
* @retval 0 If successful.
20+
* @retval -EBUSY Returned without waiting.
21+
* @retval -EAGAIN Waiting period timed out,
22+
* or the underlying semaphore was reset during the waiting period.
23+
*/
24+
int i2c_nrfx_twim_exclusive_access_acquire(const struct device *dev, k_timeout_t timeout);
25+
26+
/** @brief Releases exclusive access to the i2c bus controller.
27+
*
28+
* @param dev Pointer to the device structure for an I2C controller
29+
* driver on which @ref i2c_nrfx_twim_exclusive_access_acquire
30+
* has been successfully called.
31+
*/
32+
void i2c_nrfx_twim_exclusive_access_release(const struct device *dev);
33+
34+
#endif /* ZEPHYR_INCLUDE_DRIVERS_I2C_NRFX_TWIM_H */
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# SPDX-License-Identifier: Apache-2.0
2+
3+
cmake_minimum_required(VERSION 3.20.0)
4+
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
5+
project(i2c_api)
6+
7+
FILE(GLOB app_sources src/*.c)
8+
target_sources(app PRIVATE ${app_sources})
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/*
2+
* Copyright (c) 2025 Nordic Semiconductor ASA
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
/*
8+
* SDA = P0.26 and P1.2
9+
* SCL = P0.25 and P1.3
10+
*/
11+
12+
/ {
13+
aliases {
14+
i2c-controller = &i2c1;
15+
i2c-controller-target = &i2c2;
16+
};
17+
};
18+
19+
&pinctrl {
20+
i2c2_default: i2c2_default {
21+
group1 {
22+
psels = <NRF_PSEL(TWIS_SDA, 0, 26)>,
23+
<NRF_PSEL(TWIS_SCL, 0, 25)>;
24+
bias-pull-up;
25+
};
26+
};
27+
28+
i2c2_sleep: i2c2_sleep {
29+
group1 {
30+
psels = <NRF_PSEL(TWIS_SDA, 0, 26)>,
31+
<NRF_PSEL(TWIS_SCL, 0, 25)>;
32+
low-power-enable;
33+
};
34+
};
35+
};
36+
37+
&i2c2 {
38+
compatible = "nordic,nrf-twis";
39+
pinctrl-0 = <&i2c2_default>;
40+
pinctrl-1 = <&i2c2_sleep>;
41+
pinctrl-names = "default", "sleep";
42+
status = "okay";
43+
};
44+
45+
&i2c1 {
46+
compatible = "nordic,nrf-twim";
47+
zephyr,concat-buf-size = <256>;
48+
status = "okay";
49+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/*
2+
* Copyright (c) 2025 Nordic Semiconductor ASA
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
/*
8+
* SDA = P2.8 and P2.9
9+
* SCL = P1.2 and P1.3
10+
*/
11+
12+
/ {
13+
aliases {
14+
i2c-controller = &i2c130;
15+
i2c-controller-target = &i2c131;
16+
};
17+
};
18+
19+
&pinctrl {
20+
i2c130_default: i2c130_default {
21+
group1 {
22+
psels = <NRF_PSEL(TWIM_SDA, 2, 8)>,
23+
<NRF_PSEL(TWIM_SCL, 1, 2)>;
24+
bias-pull-up;
25+
};
26+
};
27+
28+
i2c130_sleep: i2c130_sleep {
29+
group1 {
30+
psels = <NRF_PSEL(TWIM_SDA, 2, 8)>,
31+
<NRF_PSEL(TWIM_SCL, 1, 2)>;
32+
low-power-enable;
33+
};
34+
};
35+
36+
i2c131_default: i2c131_default {
37+
group1 {
38+
psels = <NRF_PSEL(TWIM_SDA, 2, 9)>,
39+
<NRF_PSEL(TWIM_SCL, 1, 3)>;
40+
bias-pull-up;
41+
};
42+
};
43+
44+
i2c131_sleep: i2c131_sleep {
45+
group1 {
46+
psels = <NRF_PSEL(TWIM_SDA, 2, 9)>,
47+
<NRF_PSEL(TWIM_SCL, 1, 3)>;
48+
low-power-enable;
49+
};
50+
};
51+
};
52+
53+
&i2c130 {
54+
compatible = "nordic,nrf-twim";
55+
clock-frequency = <I2C_BITRATE_STANDARD>;
56+
pinctrl-0 = <&i2c130_default>;
57+
pinctrl-1 = <&i2c130_sleep>;
58+
pinctrl-names = "default", "sleep";
59+
zephyr,concat-buf-size = <256>;
60+
memory-regions = <&cpuapp_dma_region>;
61+
status = "okay";
62+
};
63+
64+
&i2c131 {
65+
compatible = "nordic,nrf-twis";
66+
clock-frequency = <I2C_BITRATE_STANDARD>;
67+
pinctrl-0 = <&i2c131_default>;
68+
pinctrl-1 = <&i2c131_sleep>;
69+
pinctrl-names = "default", "sleep";
70+
memory-regions = <&cpuapp_dma_region>;
71+
status = "okay";
72+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/*
2+
* Copyright (c) 2024 Nordic Semiconductor ASA
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
/*
8+
* SDA = P1.8 and P1.9
9+
* SCL = P1.10 and P1.11
10+
*/
11+
12+
/ {
13+
aliases {
14+
i2c-controller = &i2c21;
15+
i2c-controller-target = &i2c22;
16+
};
17+
};
18+
19+
&pinctrl {
20+
i2c21_default: i2c21_default {
21+
group1 {
22+
psels = <NRF_PSEL(TWIS_SDA, 1, 8)>,
23+
<NRF_PSEL(TWIS_SCL, 1, 10)>;
24+
bias-pull-up;
25+
};
26+
};
27+
28+
i2c21_sleep: i2c21_sleep {
29+
group1 {
30+
psels = <NRF_PSEL(TWIS_SDA, 1, 8)>,
31+
<NRF_PSEL(TWIS_SCL, 1, 10)>;
32+
low-power-enable;
33+
};
34+
};
35+
36+
i2c22_default: i2c22_default {
37+
group1 {
38+
psels = <NRF_PSEL(TWIS_SDA, 1, 9)>,
39+
<NRF_PSEL(TWIS_SCL, 1, 11)>;
40+
bias-pull-up;
41+
};
42+
};
43+
44+
i2c22_sleep: i2c22_sleep {
45+
group1 {
46+
psels = <NRF_PSEL(TWIS_SDA, 1, 9)>,
47+
<NRF_PSEL(TWIS_SCL, 1, 11)>;
48+
low-power-enable;
49+
};
50+
};
51+
};
52+
53+
&i2c21 {
54+
compatible = "nordic,nrf-twim";
55+
pinctrl-0 = <&i2c21_default>;
56+
pinctrl-1 = <&i2c21_sleep>;
57+
pinctrl-names = "default", "sleep";
58+
zephyr,concat-buf-size = <256>;
59+
status = "okay";
60+
};
61+
62+
&i2c22 {
63+
compatible = "nordic,nrf-twis";
64+
pinctrl-0 = <&i2c22_default>;
65+
pinctrl-1 = <&i2c22_sleep>;
66+
pinctrl-names = "default", "sleep";
67+
status = "okay";
68+
};
+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
CONFIG_ZTEST=y
2+
CONFIG_BOOT_BANNER=n
3+
4+
CONFIG_LOG=y
5+
CONFIG_I2C_LOG_LEVEL_INF=y
6+
CONFIG_I2C=y
7+
CONFIG_I2C_TARGET=y
8+
CONFIG_I2C_TARGET_BUFFER_MODE=y
9+
CONFIG_I2C_NRFX_TWIS_BUF_SIZE=256
10+
11+
CONFIG_ZERO_LATENCY_IRQS=y

0 commit comments

Comments
 (0)