Skip to content

Commit 0218b36

Browse files
JordanYatesaescolar
authored andcommitted
i2c: i2c_nrfx_twim: extract common code
Extract code useful for an RTIO implementation to a separate file. Signed-off-by: Jordan Yates <[email protected]>
1 parent 6773f33 commit 0218b36

File tree

4 files changed

+225
-163
lines changed

4 files changed

+225
-163
lines changed

drivers/i2c/CMakeLists.txt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,10 @@ else()
4646
)
4747
endif()
4848

49-
zephyr_library_sources_ifdef(CONFIG_I2C_NRFX_TWIM i2c_nrfx_twim.c)
49+
zephyr_library_sources_ifdef(CONFIG_I2C_NRFX_TWIM
50+
i2c_nrfx_twim.c
51+
i2c_nrfx_twim_common.c
52+
)
5053
zephyr_library_sources_ifdef(CONFIG_I2C_SAM_TWI i2c_sam_twi.c)
5154

5255
if(CONFIG_I2C_RTIO)

drivers/i2c/i2c_nrfx_twim.c

Lines changed: 23 additions & 162 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
* SPDX-License-Identifier: Apache-2.0
55
*/
66

7-
87
#include <zephyr/drivers/i2c.h>
98
#include <zephyr/dt-bindings/i2c/i2c.h>
109
#include <zephyr/pm/device.h>
@@ -17,6 +16,9 @@
1716

1817
#include <zephyr/logging/log.h>
1918
#include <zephyr/irq.h>
19+
20+
#include "i2c_nrfx_twim_common.h"
21+
2022
LOG_MODULE_REGISTER(i2c_nrfx_twim, CONFIG_I2C_LOG_LEVEL);
2123

2224
#if CONFIG_I2C_NRFX_TRANSFER_TIMEOUT
@@ -31,31 +33,18 @@ struct i2c_nrfx_twim_data {
3133
volatile nrfx_err_t res;
3234
};
3335

34-
struct i2c_nrfx_twim_config {
35-
nrfx_twim_t twim;
36-
nrfx_twim_config_t twim_config;
37-
uint16_t msg_buf_size;
38-
void (*irq_connect)(void);
39-
const struct pinctrl_dev_config *pcfg;
40-
uint8_t *msg_buf;
41-
uint16_t max_transfer_size;
42-
};
43-
44-
static int i2c_nrfx_twim_recover_bus(const struct device *dev);
45-
4636
static int i2c_nrfx_twim_transfer(const struct device *dev,
4737
struct i2c_msg *msgs,
4838
uint8_t num_msgs, uint16_t addr)
4939
{
5040
struct i2c_nrfx_twim_data *dev_data = dev->data;
51-
const struct i2c_nrfx_twim_config *dev_config = dev->config;
41+
const struct i2c_nrfx_twim_common_config *dev_config = dev->config;
5242
int ret = 0;
5343
uint8_t *msg_buf = dev_config->msg_buf;
5444
uint16_t msg_buf_used = 0;
5545
uint16_t msg_buf_size = dev_config->msg_buf_size;
56-
nrfx_twim_xfer_desc_t cur_xfer = {
57-
.address = addr
58-
};
46+
uint8_t *buf;
47+
uint16_t buf_len;
5948

6049
k_sem_take(&dev_data->transfer_sync, K_FOREVER);
6150

@@ -116,35 +105,15 @@ static int i2c_nrfx_twim_transfer(const struct device *dev,
116105
}
117106

118107
if (msg_buf_used == 0) {
119-
cur_xfer.p_primary_buf = msgs[i].buf;
120-
cur_xfer.primary_length = msgs[i].len;
108+
buf = msgs[i].buf;
109+
buf_len = msgs[i].len;
121110
} else {
122-
cur_xfer.p_primary_buf = msg_buf;
123-
cur_xfer.primary_length = msg_buf_used;
124-
}
125-
cur_xfer.type = (msgs[i].flags & I2C_MSG_READ) ?
126-
NRFX_TWIM_XFER_RX : NRFX_TWIM_XFER_TX;
127-
128-
if (cur_xfer.primary_length > dev_config->max_transfer_size) {
129-
LOG_ERR("Trying to transfer more than the maximum size "
130-
"for this device: %d > %d",
131-
cur_xfer.primary_length,
132-
dev_config->max_transfer_size);
133-
return -ENOSPC;
111+
buf = msg_buf;
112+
buf_len = msg_buf_used;
134113
}
135-
136-
nrfx_err_t res = nrfx_twim_xfer(&dev_config->twim,
137-
&cur_xfer,
138-
(msgs[i].flags & I2C_MSG_STOP) ?
139-
0 : NRFX_TWIM_FLAG_TX_NO_STOP);
140-
if (res != NRFX_SUCCESS) {
141-
if (res == NRFX_ERROR_BUSY) {
142-
ret = -EBUSY;
143-
break;
144-
} else {
145-
ret = -EIO;
146-
break;
147-
}
114+
ret = i2c_nrfx_twim_msg_transfer(dev, msgs[i].flags, buf, buf_len, addr);
115+
if (ret < 0) {
116+
break;
148117
}
149118

150119
ret = k_sem_take(&dev_data->completion_sync,
@@ -171,18 +140,15 @@ static int i2c_nrfx_twim_transfer(const struct device *dev,
171140
break;
172141
}
173142

174-
res = dev_data->res;
175-
176-
if (res != NRFX_SUCCESS) {
143+
if (dev_data->res != NRFX_SUCCESS) {
177144
ret = -EIO;
178145
break;
179146
}
180147

181148
/* If concatenated messages were I2C_MSG_READ type, then
182149
* content of concatenation buffer has to be copied back into
183150
* buffers provided by user. */
184-
if ((msgs[i].flags & I2C_MSG_READ)
185-
&& cur_xfer.p_primary_buf == msg_buf) {
151+
if ((msgs[i].flags & I2C_MSG_READ) && (buf == msg_buf)) {
186152
int j = i;
187153

188154
while (msg_buf_used >= msgs[j].len) {
@@ -227,65 +193,14 @@ static void event_handler(nrfx_twim_evt_t const *p_event, void *p_context)
227193
k_sem_give(&dev_data->completion_sync);
228194
}
229195

230-
static int i2c_nrfx_twim_configure(const struct device *dev,
231-
uint32_t i2c_config)
232-
{
233-
const struct i2c_nrfx_twim_config *dev_config = dev->config;
234-
235-
if (I2C_ADDR_10_BITS & i2c_config) {
236-
return -EINVAL;
237-
}
238-
239-
switch (I2C_SPEED_GET(i2c_config)) {
240-
case I2C_SPEED_STANDARD:
241-
nrf_twim_frequency_set(dev_config->twim.p_twim,
242-
NRF_TWIM_FREQ_100K);
243-
break;
244-
case I2C_SPEED_FAST:
245-
nrf_twim_frequency_set(dev_config->twim.p_twim,
246-
NRF_TWIM_FREQ_400K);
247-
break;
248-
#if NRF_TWIM_HAS_1000_KHZ_FREQ
249-
case I2C_SPEED_FAST_PLUS:
250-
nrf_twim_frequency_set(dev_config->twim.p_twim,
251-
NRF_TWIM_FREQ_1000K);
252-
break;
253-
#endif
254-
default:
255-
LOG_ERR("unsupported speed");
256-
return -EINVAL;
257-
}
258-
259-
return 0;
260-
}
261-
262-
static int i2c_nrfx_twim_recover_bus(const struct device *dev)
196+
static int i2c_nrfx_twim_init(const struct device *dev)
263197
{
264-
const struct i2c_nrfx_twim_config *dev_config = dev->config;
265-
enum pm_device_state state;
266-
uint32_t scl_pin;
267-
uint32_t sda_pin;
268-
nrfx_err_t err;
269-
270-
scl_pin = nrf_twim_scl_pin_get(dev_config->twim.p_twim);
271-
sda_pin = nrf_twim_sda_pin_get(dev_config->twim.p_twim);
272-
273-
/* disable peripheral if active (required to release SCL/SDA lines) */
274-
(void)pm_device_state_get(dev, &state);
275-
if (state == PM_DEVICE_STATE_ACTIVE) {
276-
nrfx_twim_disable(&dev_config->twim);
277-
}
198+
struct i2c_nrfx_twim_data *data = dev->data;
278199

279-
err = nrfx_twim_bus_recover(scl_pin, sda_pin);
280-
281-
/* restore peripheral if it was active before */
282-
if (state == PM_DEVICE_STATE_ACTIVE) {
283-
(void)pinctrl_apply_state(dev_config->pcfg,
284-
PINCTRL_STATE_DEFAULT);
285-
nrfx_twim_enable(&dev_config->twim);
286-
}
200+
k_sem_init(&data->transfer_sync, 1, 1);
201+
k_sem_init(&data->completion_sync, 0, 1);
287202

288-
return (err == NRFX_SUCCESS ? 0 : -EBUSY);
203+
return i2c_nrfx_twim_common_init(dev);
289204
}
290205

291206
static const struct i2c_driver_api i2c_nrfx_twim_driver_api = {
@@ -297,62 +212,6 @@ static const struct i2c_driver_api i2c_nrfx_twim_driver_api = {
297212
.recover_bus = i2c_nrfx_twim_recover_bus,
298213
};
299214

300-
static int twim_nrfx_pm_action(const struct device *dev,
301-
enum pm_device_action action)
302-
{
303-
const struct i2c_nrfx_twim_config *dev_config = dev->config;
304-
305-
switch (action) {
306-
case PM_DEVICE_ACTION_RESUME:
307-
(void)pinctrl_apply_state(dev_config->pcfg, PINCTRL_STATE_DEFAULT);
308-
nrfx_twim_enable(&dev_config->twim);
309-
break;
310-
case PM_DEVICE_ACTION_SUSPEND:
311-
nrfx_twim_disable(&dev_config->twim);
312-
(void)pinctrl_apply_state(dev_config->pcfg, PINCTRL_STATE_SLEEP);
313-
break;
314-
default:
315-
return -ENOTSUP;
316-
}
317-
318-
return 0;
319-
}
320-
321-
static int i2c_nrfx_twim_init(const struct device *dev)
322-
{
323-
const struct i2c_nrfx_twim_config *dev_config = dev->config;
324-
struct i2c_nrfx_twim_data *dev_data = dev->data;
325-
326-
dev_config->irq_connect();
327-
328-
k_sem_init(&dev_data->transfer_sync, 1, 1);
329-
k_sem_init(&dev_data->completion_sync, 0, 1);
330-
331-
(void)pinctrl_apply_state(dev_config->pcfg, PINCTRL_STATE_SLEEP);
332-
333-
if (nrfx_twim_init(&dev_config->twim, &dev_config->twim_config,
334-
event_handler, dev_data) != NRFX_SUCCESS) {
335-
LOG_ERR("Failed to initialize device: %s", dev->name);
336-
return -EIO;
337-
}
338-
339-
return pm_device_driver_init(dev, twim_nrfx_pm_action);
340-
}
341-
342-
#define I2C_NRFX_TWIM_INVALID_FREQUENCY ((nrf_twim_frequency_t)-1)
343-
#define I2C_NRFX_TWIM_FREQUENCY(bitrate) \
344-
(bitrate == I2C_BITRATE_STANDARD ? NRF_TWIM_FREQ_100K : \
345-
bitrate == 250000 ? NRF_TWIM_FREQ_250K : \
346-
bitrate == I2C_BITRATE_FAST ? NRF_TWIM_FREQ_400K : \
347-
IF_ENABLED(NRF_TWIM_HAS_1000_KHZ_FREQ, \
348-
(bitrate == I2C_BITRATE_FAST_PLUS ? NRF_TWIM_FREQ_1000K :)) \
349-
I2C_NRFX_TWIM_INVALID_FREQUENCY)
350-
351-
#define I2C(idx) DT_NODELABEL(i2c##idx)
352-
#define I2C_HAS_PROP(idx, prop) DT_NODE_HAS_PROP(I2C(idx), prop)
353-
#define I2C_FREQUENCY(idx) \
354-
I2C_NRFX_TWIM_FREQUENCY(DT_PROP(I2C(idx), clock_frequency))
355-
356215
#define CONCAT_BUF_SIZE(idx) \
357216
COND_CODE_1(DT_NODE_HAS_PROP(I2C(idx), zephyr_concat_buf_size), \
358217
(DT_PROP(I2C(idx), zephyr_concat_buf_size)), (0))
@@ -381,13 +240,15 @@ static int i2c_nrfx_twim_init(const struct device *dev)
381240
I2C_MEMORY_SECTION(idx);)) \
382241
static struct i2c_nrfx_twim_data twim_##idx##_data; \
383242
PINCTRL_DT_DEFINE(I2C(idx)); \
384-
static const struct i2c_nrfx_twim_config twim_##idx##z_config = { \
243+
static const \
244+
struct i2c_nrfx_twim_common_config twim_##idx##z_config = { \
385245
.twim = NRFX_TWIM_INSTANCE(idx), \
386246
.twim_config = { \
387247
.skip_gpio_cfg = true, \
388248
.skip_psel_cfg = true, \
389249
.frequency = I2C_FREQUENCY(idx), \
390250
}, \
251+
.event_handler = event_handler, \
391252
.msg_buf_size = MSG_BUF_SIZE(idx), \
392253
.irq_connect = irq_connect##idx, \
393254
.pcfg = PINCTRL_DT_DEV_CONFIG_GET(I2C(idx)), \

0 commit comments

Comments
 (0)