1 /*
2 * Copyright (c) 2023 Intel Corporation.
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include "iut.h"
8 #include "sedi_driver_i2c.h"
9 #include "sedi_driver_rtc.h"
10 #include <zephyr/drivers/i2c.h>
11
12 #define DT_DRV_COMPAT intel_sedi_i2c
13
14 #define LOG_I2C_BUS (0)
15 #define LOG_I2C_DEV_ADDR (0x5e)
16 #define LOG_I2C_RETRY_CNT (3)
17 #define LOG_I2C_DATA_SIZE (128)
18
19 #define POLLING (1 << 0)
20 #define IRQ (1 << 1)
21 #define ASYNC (1 << 2)
22
get_sec(void)23 static uint32_t get_sec(void)
24 {
25 uint64_t start = sedi_rtc_get_us();
26
27 return (uint32_t)(start / 1000 / 1000);
28 }
29
30 #if defined(CONFIG_I2C_ASYNC)
31 static int async_req;
32 static int async_rpl;
33 static int async_err;
async_cb(int result,void * userdata)34 static void async_cb(int result, void *userdata)
35 {
36 async_rpl++;
37 }
38 #endif
39
impl_test_log_i2c(uint32_t sec_run,int mode,uint32_t * err_cnt)40 static int impl_test_log_i2c(uint32_t sec_run, int mode, uint32_t *err_cnt)
41 {
42 int ret;
43 uint8_t data[LOG_I2C_DATA_SIZE];
44 const struct device *i2c_dev = DEVICE_DT_GET(DT_DRV_INST(0));
45
46 uint32_t sec_start = get_sec();
47 int loop = 0;
48 int retry = 0;
49 uint32_t error = 0;
50
51 uint32_t i2c_cfg = I2C_SPEED_SET(I2C_SPEED_FAST) | I2C_MODE_CONTROLLER;
52
53 if (!i2c_dev) {
54 return -ENODEV;
55 }
56
57 ret = i2c_configure(i2c_dev, i2c_cfg);
58 if (ret) {
59 return -EINVAL;
60 }
61
62 while (1) {
63 for (int i = 0; i < sizeof(data) - 2; i++) {
64 data[i] = ((loop + i) % 10) + 0x30;
65 }
66 data[sizeof(data) - 2] = '\n';
67 data[sizeof(data) - 1] = '\r';
68
69 if (mode & POLLING) {
70 ret = sedi_i2c_master_poll_write(LOG_I2C_BUS, LOG_I2C_DEV_ADDR, data,
71 sizeof(data), false);
72 #if defined(CONFIG_I2C_ASYNC)
73 } else if (mode & ASYNC) {
74 struct i2c_msg msg;
75
76 msg.buf = (uint8_t *)data;
77 msg.len = sizeof(data);
78 msg.flags = I2C_MSG_WRITE | I2C_MSG_STOP;
79 ret = i2c_transfer_async(i2c_dev, &msg, 1, LOG_I2C_DEV_ADDR, async_cb,
80 (void *)loop);
81 async_req++;
82 if (ret == -EWOULDBLOCK) {
83 k_sleep(K_MSEC(5));
84 async_err++;
85 ret = 0; /* recover async busy */
86 }
87 #endif
88 } else {
89 ret = i2c_write(i2c_dev, data, sizeof(data), LOG_I2C_DEV_ADDR);
90 }
91
92 if (ret) {
93 if (retry >= LOG_I2C_RETRY_CNT) {
94 break;
95 }
96
97 retry++;
98 error++;
99 continue;
100 }
101
102 loop++;
103 if (!(loop % 100)) {
104 iut_print("\ttransfer %d-%d: error=%d\n", loop - 100, loop, error);
105 retry = 0;
106 *err_cnt += error;
107 error = 0;
108 k_msleep(100);
109
110 if ((get_sec() - sec_start) >= sec_run) {
111 break;
112 }
113 }
114 }
115
116 return ret;
117 }
118
test_log_i2c_polling(int argc,char ** argv)119 static int test_log_i2c_polling(int argc, char **argv)
120 {
121 uint32_t sec_run = 10;
122 int ret;
123 uint32_t err_cnt = 0;
124
125 if (argc) {
126 sec_run = (uint32_t)strtoul(argv[0], NULL, 0);
127 }
128
129 iut_case_print("starting to run %d seconds ...\n", sec_run);
130
131 ret = impl_test_log_i2c(sec_run, POLLING, &err_cnt);
132
133 iut_case_print("done, ret=%d, err_cnt=%u\n", ret, err_cnt);
134 TEST_ASSERT_EQUAL(0, ret);
135
136 return IUT_ERR_OK;
137 }
138 DEFINE_IUT_CASE(log_i2c_polling, logging, IUT_ATTRI_NONE);
139
test_log_i2c_irq(int argc,char ** argv)140 static int test_log_i2c_irq(int argc, char **argv)
141 {
142 uint32_t sec_run = 10;
143 int ret;
144 uint32_t err_cnt = 0;
145
146 if (argc) {
147 sec_run = (uint32_t)strtoul(argv[0], NULL, 0);
148 }
149
150 iut_case_print("starting to run %d seconds ...\n", sec_run);
151
152 ret = impl_test_log_i2c(sec_run, IRQ, &err_cnt);
153
154 iut_case_print("done, ret=%d, err_cnt=%u\n", ret, err_cnt);
155 TEST_ASSERT_EQUAL(0, ret);
156
157 return IUT_ERR_OK;
158 }
159 DEFINE_IUT_CASE(log_i2c_irq, logging, IUT_ATTRI_NONE);
160
161 #if defined(CONFIG_I2C_ASYNC)
test_log_i2c_async(int argc,char ** argv)162 static int test_log_i2c_async(int argc, char **argv)
163 {
164 uint32_t sec_run = 10;
165 int ret;
166 uint32_t err_cnt = 0;
167
168 if (argc) {
169 sec_run = (uint32_t)strtoul(argv[0], NULL, 0);
170 }
171
172 async_err = 0;
173 async_req = 0;
174 async_rpl = 0;
175
176 iut_case_print("starting to run %d seconds ...\n", sec_run);
177
178 ret = impl_test_log_i2c(sec_run, ASYNC, &err_cnt);
179
180 iut_case_print("done, ret=%d, err_cnt=%u\n", ret, err_cnt);
181 iut_case_print("finish: async_req:%d, async_rpl:%d, async_err:%d\n", async_req, async_rpl,
182 async_err);
183
184 TEST_ASSERT_EQUAL(0, ret);
185
186 return IUT_ERR_OK;
187 }
188 DEFINE_IUT_CASE(log_i2c_async, logging, IUT_ATTRI_NONE);
189 #endif
190