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