1 /*
2 * Copyright (c) 2017 comsuisse AG
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7
8 #include <zephyr/kernel.h>
9 #include <zephyr/ztest.h>
10 #include <zephyr/drivers/i2s.h>
11 #include "i2s_api_test.h"
12
13 /** @brief Short I2S transfer.
14 *
15 * - TX stream START trigger starts transmission.
16 * - RX stream START trigger starts reception.
17 * - sending / receiving a short sequence of data returns success.
18 * - TX stream DRAIN trigger empties the transmit queue.
19 * - RX stream STOP trigger stops reception.
20 */
ZTEST_USER(i2s_loopback,test_i2s_transfer_short)21 ZTEST_USER(i2s_loopback, test_i2s_transfer_short)
22 {
23 if (IS_ENABLED(CONFIG_I2S_TEST_USE_I2S_DIR_BOTH)) {
24 TC_PRINT("RX/TX transfer requires use of I2S_DIR_BOTH.\n");
25 ztest_test_skip();
26 return;
27 }
28
29 int ret;
30
31 /* Prefill TX queue */
32 ret = tx_block_write(dev_i2s_tx, 0, 0);
33 zassert_equal(ret, TC_PASS);
34 TC_PRINT("%d->OK\n", 1);
35
36 ret = tx_block_write(dev_i2s_tx, 1, 0);
37 zassert_equal(ret, TC_PASS);
38 TC_PRINT("%d->OK\n", 2);
39
40 /* Start reception */
41 ret = i2s_trigger(dev_i2s_rx, I2S_DIR_RX, I2S_TRIGGER_START);
42 zassert_equal(ret, 0, "RX START trigger failed");
43
44 /* Start transmission */
45 ret = i2s_trigger(dev_i2s_tx, I2S_DIR_TX, I2S_TRIGGER_START);
46 zassert_equal(ret, 0, "TX START trigger failed");
47
48 ret = rx_block_read(dev_i2s_rx, 0);
49 zassert_equal(ret, TC_PASS);
50 TC_PRINT("%d<-OK\n", 1);
51
52 ret = tx_block_write(dev_i2s_tx, 2, 0);
53 zassert_equal(ret, TC_PASS);
54 TC_PRINT("%d->OK\n", 3);
55
56 /* All data written, drain TX queue and stop the transmission */
57 ret = i2s_trigger(dev_i2s_tx, I2S_DIR_TX, I2S_TRIGGER_DRAIN);
58 zassert_equal(ret, 0, "TX DRAIN trigger failed");
59
60 ret = rx_block_read(dev_i2s_rx, 1);
61 zassert_equal(ret, TC_PASS);
62 TC_PRINT("%d<-OK\n", 2);
63
64 /* All but one data block read, stop reception */
65 ret = i2s_trigger(dev_i2s_rx, I2S_DIR_RX, I2S_TRIGGER_STOP);
66 zassert_equal(ret, 0, "RX STOP trigger failed");
67
68 ret = rx_block_read(dev_i2s_rx, 2);
69 zassert_equal(ret, TC_PASS);
70 TC_PRINT("%d<-OK\n", 3);
71
72 /* TODO: Verify the interface is in READY state when i2s_state_get
73 * function is available.
74 */
75 }
76
77 #define TEST_I2S_TRANSFER_LONG_REPEAT_COUNT 100
78
79 /** @brief Long I2S transfer.
80 *
81 * - TX stream START trigger starts transmission.
82 * - RX stream START trigger starts reception.
83 * - sending / receiving a long sequence of data returns success.
84 * - TX stream DRAIN trigger empties the transmit queue.
85 * - RX stream STOP trigger stops reception.
86 */
ZTEST_USER(i2s_loopback,test_i2s_transfer_long)87 ZTEST_USER(i2s_loopback, test_i2s_transfer_long)
88 {
89 if (IS_ENABLED(CONFIG_I2S_TEST_USE_I2S_DIR_BOTH)) {
90 TC_PRINT("RX/TX transfer requires use of I2S_DIR_BOTH.\n");
91 ztest_test_skip();
92 return;
93 }
94
95 int ret;
96
97 /* Prefill TX queue */
98 ret = tx_block_write(dev_i2s_tx, 0, 0);
99 zassert_equal(ret, TC_PASS);
100
101 /* Start reception */
102 ret = i2s_trigger(dev_i2s_rx, I2S_DIR_RX, I2S_TRIGGER_START);
103 zassert_equal(ret, 0, "RX START trigger failed");
104
105 /* Start transmission */
106 ret = i2s_trigger(dev_i2s_tx, I2S_DIR_TX, I2S_TRIGGER_START);
107 zassert_equal(ret, 0, "TX START trigger failed");
108
109 for (int i = 0; i < TEST_I2S_TRANSFER_LONG_REPEAT_COUNT; i++) {
110 ret = tx_block_write(dev_i2s_tx, 0, 0);
111 zassert_equal(ret, TC_PASS);
112
113 ret = rx_block_read(dev_i2s_rx, 0);
114 zassert_equal(ret, TC_PASS);
115 }
116
117 /* All data written, flush TX queue and stop the transmission */
118 ret = i2s_trigger(dev_i2s_tx, I2S_DIR_TX, I2S_TRIGGER_DRAIN);
119 zassert_equal(ret, 0, "TX DRAIN trigger failed");
120
121 /* All but one data block read, stop reception */
122 ret = i2s_trigger(dev_i2s_rx, I2S_DIR_RX, I2S_TRIGGER_STOP);
123 zassert_equal(ret, 0, "RX STOP trigger failed");
124
125 ret = rx_block_read(dev_i2s_rx, 0);
126 zassert_equal(ret, TC_PASS);
127
128 /* TODO: Verify the interface is in READY state when i2s_state_get
129 * function is available.
130 */
131 }
132
133 /** @brief RX sync start.
134 *
135 * - TX stream START trigger starts transmission.
136 * - sending RX stream START trigger after a delay starts reception on the next
137 * word select sync event at the start of the frame.
138 * - TX stream DROP trigger stops transmission and clears the transmit queue.
139 * - RX stream DROP trigger stops reception and clears the receive queue.
140 */
ZTEST_USER(i2s_loopback,test_i2s_rx_sync_start)141 ZTEST_USER(i2s_loopback, test_i2s_rx_sync_start)
142 {
143 if (IS_ENABLED(CONFIG_I2S_TEST_USE_I2S_DIR_BOTH)) {
144 TC_PRINT("RX/TX transfer requires use of I2S_DIR_BOTH.\n");
145 ztest_test_skip();
146 return;
147 }
148
149 size_t rx_size;
150 int ret;
151 char buf[BLOCK_SIZE];
152
153 /* Prefill TX queue */
154 for (int n = 0; n < NUM_TX_BLOCKS; n++) {
155 fill_buf_const((uint16_t *)buf, 1, 2);
156 ret = i2s_buf_write(dev_i2s_tx, buf, BLOCK_SIZE);
157 zassert_equal(ret, TC_PASS);
158 TC_PRINT("%d->OK\n", n);
159 }
160
161 /* Start transmission */
162 ret = i2s_trigger(dev_i2s_tx, I2S_DIR_TX, I2S_TRIGGER_START);
163 zassert_equal(ret, 0, "TX START trigger failed");
164
165 k_busy_wait(75);
166
167 /* Start reception */
168 ret = i2s_trigger(dev_i2s_rx, I2S_DIR_RX, I2S_TRIGGER_START);
169 zassert_equal(ret, 0, "RX START trigger failed");
170 ret = i2s_buf_read(dev_i2s_rx, buf, &rx_size);
171 zassert_equal(ret, TC_PASS);
172 ret = verify_buf_const((uint16_t *)buf, 1, 2);
173
174 zassert_equal(ret, TC_PASS);
175 TC_PRINT("%d<-OK\n", 1);
176
177 /* All data written, drop TX, RX queue and stop the transmission */
178 ret = i2s_trigger(dev_i2s_tx, I2S_DIR_TX, I2S_TRIGGER_DROP);
179 zassert_equal(ret, 0, "TX DROP trigger failed");
180
181 ret = i2s_trigger(dev_i2s_rx, I2S_DIR_RX, I2S_TRIGGER_DROP);
182 zassert_equal(ret, 0, "RX DROP trigger failed");
183
184 /* TODO: Verify the interface is in READY state when i2s_state_get
185 * function is available.
186 */
187 }
188
189 /** @brief Timeout on RX queue empty.
190 *
191 * - Reading empty RX queue in READY state returns time out error.
192 */
ZTEST_USER(i2s_loopback,test_i2s_rx_empty_timeout)193 ZTEST_USER(i2s_loopback, test_i2s_rx_empty_timeout)
194 {
195 size_t rx_size;
196 int ret;
197 char buf[BLOCK_SIZE];
198
199 ret = i2s_buf_read(dev_i2s_rx, buf, &rx_size);
200 zassert_equal(ret, -EAGAIN, "i2s_read did not timed out");
201 }
202
203 /** @brief Re-start I2S transfer.
204 *
205 * - STOP trigger stops transfer / reception at the end of the current block,
206 * consecutive START trigger restarts transfer / reception with the next data
207 * block.
208 */
ZTEST_USER(i2s_loopback,test_i2s_transfer_restart)209 ZTEST_USER(i2s_loopback, test_i2s_transfer_restart)
210 {
211 if (IS_ENABLED(CONFIG_I2S_TEST_USE_I2S_DIR_BOTH)) {
212 TC_PRINT("RX/TX transfer requires use of I2S_DIR_BOTH.\n");
213 ztest_test_skip();
214 return;
215 }
216
217 int ret;
218
219 /* Prefill TX queue */
220 ret = tx_block_write(dev_i2s_tx, 0, 0);
221 zassert_equal(ret, TC_PASS);
222 TC_PRINT("%d->OK\n", 1);
223
224 ret = tx_block_write(dev_i2s_tx, 1, 0);
225 zassert_equal(ret, TC_PASS);
226 TC_PRINT("%d->OK\n", 2);
227
228 /* Start reception */
229 ret = i2s_trigger(dev_i2s_rx, I2S_DIR_RX, I2S_TRIGGER_START);
230 zassert_equal(ret, 0, "RX START trigger failed");
231
232 /* Start transmission */
233 ret = i2s_trigger(dev_i2s_tx, I2S_DIR_TX, I2S_TRIGGER_START);
234 zassert_equal(ret, 0, "TX START trigger failed");
235
236 /* Stop transmission */
237 ret = i2s_trigger(dev_i2s_tx, I2S_DIR_TX, I2S_TRIGGER_STOP);
238 zassert_equal(ret, 0, "TX STOP trigger failed");
239
240 /* Stop reception */
241 ret = i2s_trigger(dev_i2s_rx, I2S_DIR_RX, I2S_TRIGGER_STOP);
242 zassert_equal(ret, 0, "RX STOP trigger failed");
243
244 ret = rx_block_read(dev_i2s_rx, 0);
245 zassert_equal(ret, TC_PASS);
246 TC_PRINT("%d<-OK\n", 1);
247
248 TC_PRINT("Stop transmission\n");
249
250 /* Keep interface inactive */
251 k_sleep(K_MSEC(1000));
252
253 TC_PRINT("Start transmission\n");
254
255 /* Prefill TX queue */
256 ret = tx_block_write(dev_i2s_tx, 2, 0);
257 zassert_equal(ret, TC_PASS);
258 TC_PRINT("%d->OK\n", 3);
259
260 /* Start reception */
261 ret = i2s_trigger(dev_i2s_rx, I2S_DIR_RX, I2S_TRIGGER_START);
262 zassert_equal(ret, 0, "RX START trigger failed");
263
264 /* Start transmission */
265 ret = i2s_trigger(dev_i2s_tx, I2S_DIR_TX, I2S_TRIGGER_START);
266 zassert_equal(ret, 0, "TX START trigger failed");
267
268 /* All data written, drain TX queue and stop the transmission */
269 ret = i2s_trigger(dev_i2s_tx, I2S_DIR_TX, I2S_TRIGGER_DRAIN);
270 zassert_equal(ret, 0, "TX DRAIN trigger failed");
271
272 ret = rx_block_read(dev_i2s_rx, 1);
273 zassert_equal(ret, TC_PASS);
274 TC_PRINT("%d<-OK\n", 2);
275
276 /* All but one data block read, stop reception */
277 ret = i2s_trigger(dev_i2s_rx, I2S_DIR_RX, I2S_TRIGGER_STOP);
278 zassert_equal(ret, 0, "RX STOP trigger failed");
279
280 ret = rx_block_read(dev_i2s_rx, 2);
281 zassert_equal(ret, TC_PASS);
282 TC_PRINT("%d<-OK\n", 3);
283 }
284
285 /** @brief RX buffer overrun.
286 *
287 * - In case of RX buffer overrun it is possible to read out RX data blocks
288 * that are stored in the RX queue.
289 * - Reading from an empty RX queue when the RX buffer overrun occurred results
290 * in an error.
291 * - Sending PREPARE trigger after the RX buffer overrun occurred changes
292 * the interface state to READY.
293 */
ZTEST_USER(i2s_loopback,test_i2s_transfer_rx_overrun)294 ZTEST_USER(i2s_loopback, test_i2s_transfer_rx_overrun)
295 {
296 if (IS_ENABLED(CONFIG_I2S_TEST_USE_I2S_DIR_BOTH)) {
297 TC_PRINT("RX/TX transfer requires use of I2S_DIR_BOTH.\n");
298 ztest_test_skip();
299 return;
300 }
301
302 size_t rx_size;
303 int ret;
304 char rx_buf[BLOCK_SIZE];
305
306 /* Prefill TX queue */
307 ret = tx_block_write(dev_i2s_tx, 0, 0);
308 zassert_equal(ret, TC_PASS);
309
310 /* Start reception */
311 ret = i2s_trigger(dev_i2s_rx, I2S_DIR_RX, I2S_TRIGGER_START);
312 zassert_equal(ret, 0, "RX START trigger failed");
313
314 /* Start transmission */
315 ret = i2s_trigger(dev_i2s_tx, I2S_DIR_TX, I2S_TRIGGER_START);
316 zassert_equal(ret, 0, "TX START trigger failed");
317
318 for (int i = 0; i < NUM_RX_BLOCKS; i++) {
319 ret = tx_block_write(dev_i2s_tx, 0, 0);
320 zassert_equal(ret, TC_PASS);
321 }
322
323 /* All data written, flush TX queue and stop the transmission */
324 ret = i2s_trigger(dev_i2s_tx, I2S_DIR_TX, I2S_TRIGGER_DRAIN);
325 zassert_equal(ret, 0, "TX DRAIN trigger failed");
326
327 /* Wait for transmission to finish */
328 k_sleep(K_MSEC(200));
329
330 /* Read one data block, expect success even if RX queue is already in
331 * the error state.
332 */
333 ret = rx_block_read(dev_i2s_rx, 0);
334 zassert_equal(ret, TC_PASS);
335
336 /* Attempt to read more data blocks than are available in the RX queue */
337 for (int i = 0; i < NUM_RX_BLOCKS; i++) {
338 ret = i2s_buf_read(dev_i2s_rx, rx_buf, &rx_size);
339 if (ret != 0) {
340 break;
341 }
342 }
343 zassert_equal(ret, -EIO, "RX overrun error not detected");
344
345 ret = i2s_trigger(dev_i2s_rx, I2S_DIR_RX, I2S_TRIGGER_PREPARE);
346 zassert_equal(ret, 0, "RX PREPARE trigger failed");
347
348 /* Transmit and receive one more data block */
349 ret = tx_block_write(dev_i2s_tx, 0, 0);
350 zassert_equal(ret, TC_PASS);
351 ret = i2s_trigger(dev_i2s_rx, I2S_DIR_RX, I2S_TRIGGER_START);
352 zassert_equal(ret, 0, "RX START trigger failed");
353 ret = i2s_trigger(dev_i2s_tx, I2S_DIR_TX, I2S_TRIGGER_START);
354 zassert_equal(ret, 0, "TX START trigger failed");
355 ret = i2s_trigger(dev_i2s_tx, I2S_DIR_TX, I2S_TRIGGER_DRAIN);
356 zassert_equal(ret, 0, "TX DRAIN trigger failed");
357 ret = i2s_trigger(dev_i2s_rx, I2S_DIR_RX, I2S_TRIGGER_STOP);
358 zassert_equal(ret, 0, "RX STOP trigger failed");
359 ret = rx_block_read(dev_i2s_rx, 0);
360 zassert_equal(ret, TC_PASS);
361
362 k_sleep(K_MSEC(200));
363 }
364
365 /** @brief TX buffer underrun.
366 *
367 * - An attempt to write to the TX queue when TX buffer underrun has occurred
368 * results in an error.
369 * - Sending PREPARE trigger after the TX buffer underrun occurred changes
370 * the interface state to READY.
371 */
ZTEST_USER(i2s_loopback,test_i2s_transfer_tx_underrun)372 ZTEST_USER(i2s_loopback, test_i2s_transfer_tx_underrun)
373 {
374 if (IS_ENABLED(CONFIG_I2S_TEST_USE_I2S_DIR_BOTH)) {
375 TC_PRINT("RX/TX transfer requires use of I2S_DIR_BOTH.\n");
376 ztest_test_skip();
377 return;
378 }
379
380 int ret;
381
382 /* Prefill TX queue */
383 ret = tx_block_write(dev_i2s_tx, 0, 0);
384 zassert_equal(ret, TC_PASS);
385
386 /* Start reception */
387 ret = i2s_trigger(dev_i2s_rx, I2S_DIR_RX, I2S_TRIGGER_START);
388 zassert_equal(ret, 0, "RX START trigger failed");
389
390 /* Start transmission */
391 ret = i2s_trigger(dev_i2s_tx, I2S_DIR_TX, I2S_TRIGGER_START);
392 zassert_equal(ret, 0, "TX START trigger failed");
393
394 /* Stop reception */
395 ret = i2s_trigger(dev_i2s_rx, I2S_DIR_RX, I2S_TRIGGER_STOP);
396 zassert_equal(ret, 0, "RX STOP trigger failed");
397
398 ret = rx_block_read(dev_i2s_rx, 0);
399 zassert_equal(ret, TC_PASS);
400
401 k_sleep(K_MSEC(200));
402
403 /* Write one more TX data block, expect an error */
404 ret = tx_block_write(dev_i2s_tx, 2, -EIO);
405 zassert_equal(ret, TC_PASS);
406
407 ret = i2s_trigger(dev_i2s_tx, I2S_DIR_TX, I2S_TRIGGER_PREPARE);
408 zassert_equal(ret, 0, "TX PREPARE trigger failed");
409
410 k_sleep(K_MSEC(200));
411
412 /* Transmit and receive two more data blocks */
413 ret = tx_block_write(dev_i2s_tx, 1, 0);
414 zassert_equal(ret, TC_PASS);
415 ret = tx_block_write(dev_i2s_tx, 1, 0);
416 zassert_equal(ret, TC_PASS);
417 ret = i2s_trigger(dev_i2s_rx, I2S_DIR_RX, I2S_TRIGGER_START);
418 zassert_equal(ret, 0, "RX START trigger failed");
419 ret = i2s_trigger(dev_i2s_tx, I2S_DIR_TX, I2S_TRIGGER_START);
420 zassert_equal(ret, 0, "TX START trigger failed");
421 ret = rx_block_read(dev_i2s_rx, 1);
422 zassert_equal(ret, TC_PASS);
423 ret = i2s_trigger(dev_i2s_tx, I2S_DIR_TX, I2S_TRIGGER_DRAIN);
424 zassert_equal(ret, 0, "TX DRAIN trigger failed");
425 ret = i2s_trigger(dev_i2s_rx, I2S_DIR_RX, I2S_TRIGGER_STOP);
426 zassert_equal(ret, 0, "RX STOP trigger failed");
427 ret = rx_block_read(dev_i2s_rx, 1);
428 zassert_equal(ret, TC_PASS);
429
430 k_sleep(K_MSEC(200));
431 }
432