1 /*
2 * Copyright (c) 2024 Nordic Semiconductor ASA
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <errno.h>
8 #include <string.h>
9
10 #include <zephyr/kernel.h>
11 #include <zephyr/linker/devicetree_regions.h>
12 #include <zephyr/device.h>
13 #include <zephyr/drivers/pinctrl.h>
14
15 #include <zephyr/drivers/i2c.h>
16 #include <nrfx_twis.h>
17
18 #include <zephyr/ztest.h>
19
20 #if CONFIG_NRFX_TWIS1
21 #define I2C_S_INSTANCE 1
22 #elif CONFIG_NRFX_TWIS2
23 #define I2C_S_INSTANCE 2
24 #elif CONFIG_NRFX_TWIS20
25 #define I2C_S_INSTANCE 20
26 #elif CONFIG_NRFX_TWIS21
27 #define I2C_S_INSTANCE 21
28 #elif CONFIG_NRFX_TWIS22
29 #define I2C_S_INSTANCE 22
30 #elif CONFIG_NRFX_TWIS30
31 #define I2C_S_INSTANCE 30
32 #elif CONFIG_NRFX_TWIS131
33 #define I2C_S_INSTANCE 131
34 #else
35 #error "TWIS instance not enabled or not supported"
36 #endif
37
38 #define NODE_SENSOR DT_NODELABEL(sensor)
39 #define NODE_TWIS DT_ALIAS(i2c_slave)
40
41 #define TWIS_MEMORY_SECTION \
42 COND_CODE_1(DT_NODE_HAS_PROP(NODE_TWIS, memory_regions), \
43 (__attribute__((__section__( \
44 LINKER_DT_NODE_REGION_NAME(DT_PHANDLE(NODE_TWIS, memory_regions)))))), \
45 ())
46
47 #define TEST_DATA_SIZE 6
48 static const uint8_t msg[TEST_DATA_SIZE] = "Nordic";
49 static const nrfx_twis_t twis = NRFX_TWIS_INSTANCE(I2C_S_INSTANCE);
50
51 static uint8_t i2c_slave_buffer[TEST_DATA_SIZE] TWIS_MEMORY_SECTION;
52 static uint8_t i2c_master_buffer[TEST_DATA_SIZE];
53 struct i2c_api_twis_fixture {
54 const struct device *dev;
55 uint8_t addr;
56 uint8_t *const master_buffer;
57 uint8_t *const slave_buffer;
58 };
59
i2s_slave_handler(nrfx_twis_evt_t const * p_event)60 void i2s_slave_handler(nrfx_twis_evt_t const *p_event)
61 {
62 switch (p_event->type) {
63 case NRFX_TWIS_EVT_READ_REQ:
64 nrfx_twis_tx_prepare(&twis, i2c_slave_buffer, TEST_DATA_SIZE);
65 TC_PRINT("TWIS event: read request\n");
66 break;
67 case NRFX_TWIS_EVT_READ_DONE:
68 TC_PRINT("TWIS event: read done\n");
69 break;
70 case NRFX_TWIS_EVT_WRITE_REQ:
71 nrfx_twis_rx_prepare(&twis, i2c_slave_buffer, TEST_DATA_SIZE);
72 TC_PRINT("TWIS event: write request\n");
73 break;
74 case NRFX_TWIS_EVT_WRITE_DONE:
75 zassert_mem_equal(i2c_slave_buffer, msg, TEST_DATA_SIZE);
76 TC_PRINT("TWIS event: write done\n");
77 break;
78 default:
79 TC_PRINT("TWIS event: %d\n", p_event->type);
80 break;
81 }
82 }
83
test_setup(void)84 static void *test_setup(void)
85 {
86 static struct i2c_api_twis_fixture fixture = {
87 .dev = DEVICE_DT_GET(DT_BUS(NODE_SENSOR)),
88 .addr = DT_REG_ADDR(NODE_SENSOR),
89 .master_buffer = i2c_master_buffer,
90 .slave_buffer = i2c_slave_buffer,
91 };
92 const nrfx_twis_config_t config = {
93 .addr = {fixture.addr, 0},
94 .skip_gpio_cfg = true,
95 .skip_psel_cfg = true,
96 };
97 int ret;
98
99 zassert_equal(NRFX_SUCCESS, nrfx_twis_init(&twis, &config, i2s_slave_handler),
100 "TWIS initialization failed");
101
102 PINCTRL_DT_DEFINE(NODE_TWIS);
103 ret = pinctrl_apply_state(PINCTRL_DT_DEV_CONFIG_GET(NODE_TWIS), PINCTRL_STATE_DEFAULT);
104 zassert_ok(ret);
105
106 IRQ_CONNECT(DT_IRQN(NODE_TWIS), DT_IRQ(NODE_TWIS, priority),
107 NRFX_TWIS_INST_HANDLER_GET(I2C_S_INSTANCE), NULL, 0);
108
109 nrfx_twis_enable(&twis);
110
111 return &fixture;
112 }
113
cleanup_buffers(void * argc)114 static void cleanup_buffers(void *argc)
115 {
116 struct i2c_api_twis_fixture *fixture = (struct i2c_api_twis_fixture *)argc;
117
118 memset(fixture->slave_buffer, 0, TEST_DATA_SIZE);
119 memset(fixture->master_buffer, 0, TEST_DATA_SIZE);
120 }
121
ZTEST_USER_F(i2c_api_twis,test_i2c_read_write)122 ZTEST_USER_F(i2c_api_twis, test_i2c_read_write)
123 {
124 int ret = i2c_write_read(fixture->dev, fixture->addr, msg, TEST_DATA_SIZE,
125 fixture->master_buffer, TEST_DATA_SIZE);
126
127 zassert_ok(ret);
128 zassert_mem_equal(fixture->master_buffer, msg, TEST_DATA_SIZE);
129 }
130
ZTEST_USER_F(i2c_api_twis,test_i2c_read)131 ZTEST_USER_F(i2c_api_twis, test_i2c_read)
132 {
133 /* Prepare slave data */
134 memcpy(fixture->slave_buffer, msg, TEST_DATA_SIZE);
135 zassert_mem_equal(fixture->slave_buffer, msg, TEST_DATA_SIZE);
136
137 int ret = i2c_read(fixture->dev, fixture->master_buffer, TEST_DATA_SIZE, fixture->addr);
138
139 zassert_ok(ret);
140 zassert_mem_equal(fixture->master_buffer, msg, TEST_DATA_SIZE);
141 }
142
ZTEST_USER_F(i2c_api_twis,test_i2c_write)143 ZTEST_USER_F(i2c_api_twis, test_i2c_write)
144 {
145 int ret = i2c_write(fixture->dev, msg, TEST_DATA_SIZE, fixture->addr);
146
147 zassert_ok(ret);
148 zassert_mem_equal(fixture->slave_buffer, msg, TEST_DATA_SIZE);
149 }
150
151 ZTEST_SUITE(i2c_api_twis, NULL, test_setup, NULL, cleanup_buffers, NULL);
152