1 /*
2  * Copyright (c) 2024 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/kernel.h>
8 #include <zephyr/ztest.h>
9 #include <zephyr/drivers/i2s.h>
10 #include "i2s_api_test.h"
11 
12 #define INVALID_TRIGGER_SETTING 7
13 
ZTEST_USER(i2s_errors,test_i2s_improper_configuration)14 ZTEST_USER(i2s_errors, test_i2s_improper_configuration)
15 {
16 	int err;
17 	struct i2s_config invalid_config = { .word_size = 16U,
18 					     .channels = 2U,
19 					     .format = I2S_FMT_DATA_FORMAT_I2S,
20 					     .frame_clk_freq = FRAME_CLK_FREQ,
21 					     .block_size = BLOCK_SIZE,
22 					     .timeout = TIMEOUT,
23 					     .options = I2S_OPT_FRAME_CLK_MASTER |
24 							I2S_OPT_BIT_CLK_MASTER,
25 					     .mem_slab = &tx_mem_slab };
26 
27 
28 	invalid_config.format =
29 		I2S_FMT_DATA_FORMAT_LEFT_JUSTIFIED | I2S_FMT_DATA_FORMAT_RIGHT_JUSTIFIED;
30 
31 	err = i2s_configure(dev_i2s, I2S_DIR_TX, &invalid_config);
32 	zassert_not_equal(
33 		err, 0,
34 		"I2S configuration did not detect improper data format (I2S_FMT_DATA_FORMAT_LEFT_JUSTIFIED | I2S_FMT_DATA_FORMAT_RIGHT_JUSTIFIED)");
35 
36 	invalid_config.format = I2S_FMT_DATA_FORMAT_I2S | I2S_FMT_DATA_ORDER_LSB;
37 
38 	err = i2s_configure(dev_i2s, I2S_DIR_TX, &invalid_config);
39 	zassert_not_equal(
40 		err, 0,
41 		"I2S configuration did not detect improper stream format (I2S_FMT_DATA_ORDER_LSB)");
42 
43 	invalid_config.format = I2S_FMT_DATA_FORMAT_I2S;
44 	invalid_config.channels = 3U;
45 	err = i2s_configure(dev_i2s, I2S_DIR_TX, &invalid_config);
46 	zassert_not_equal(err, 0,
47 			  "I2S configuration did not detect improper channels configuration (3)");
48 }
49 
ZTEST_USER(i2s_errors,test_i2s_config_attempt_in_wrong_state)50 ZTEST_USER(i2s_errors, test_i2s_config_attempt_in_wrong_state)
51 {
52 	int err;
53 	int config_err;
54 	char tx_data[BLOCK_SIZE] = {0};
55 	struct i2s_config inactive_config = { .word_size = 16U,
56 					      .channels = 2U,
57 					      .format = I2S_FMT_DATA_FORMAT_I2S,
58 					      .frame_clk_freq = FRAME_CLK_FREQ,
59 					      .block_size = BLOCK_SIZE,
60 					      .timeout = TIMEOUT,
61 					      .options = I2S_OPT_FRAME_CLK_MASTER |
62 							 I2S_OPT_BIT_CLK_MASTER,
63 					      .mem_slab = &tx_mem_slab };
64 
65 	err = i2s_configure(dev_i2s, I2S_DIR_TX, &inactive_config);
66 	zassert_equal(err, 0, "I2S interface configuration failed, err=%d", err);
67 
68 	err = i2s_buf_write(dev_i2s, tx_data, BLOCK_SIZE);
69 	zassert_equal(err, 0, "I2S buffer write unexpected error: %d", err);
70 
71 	err = i2s_trigger(dev_i2s, I2S_DIR_TX, I2S_TRIGGER_START);
72 	zassert_equal(err, 0, "I2S_TRIGGER_START unexpected error: %d", err);
73 
74 	config_err = i2s_configure(dev_i2s, I2S_DIR_TX, &inactive_config);
75 
76 	err = i2s_trigger(dev_i2s, I2S_DIR_TX, I2S_TRIGGER_STOP);
77 	zassert_equal(err, 0, "I2S_TRIGGER_STOP unexpected error: %d", err);
78 
79 	err = i2s_trigger(dev_i2s, I2S_DIR_TX, I2S_TRIGGER_DROP);
80 	zassert_equal(err, 0, "I2S_TRIGGER_DROP unexpected error: %d", err);
81 
82 	zassert_not_equal(
83 		config_err, 0,
84 		"I2S configuration should not be possible in states other than I2S_STATE_READY");
85 }
86 
ZTEST_USER(i2s_errors,test_i2s_incorrect_trigger)87 ZTEST_USER(i2s_errors, test_i2s_incorrect_trigger)
88 {
89 	int err;
90 	char tx_data[BLOCK_SIZE] = {0};
91 	struct i2s_config test_config = { .word_size = 16U,
92 					  .channels = 2U,
93 					  .format = I2S_FMT_DATA_FORMAT_I2S,
94 					  .frame_clk_freq = FRAME_CLK_FREQ,
95 					  .block_size = BLOCK_SIZE,
96 					  .timeout = TIMEOUT,
97 					  .options =
98 						  I2S_OPT_FRAME_CLK_MASTER | I2S_OPT_BIT_CLK_MASTER,
99 					  .mem_slab = &tx_mem_slab };
100 
101 	err = i2s_configure(dev_i2s, I2S_DIR_TX, &test_config);
102 	zassert_equal(err, 0, "CFG err=%d", err);
103 
104 	err = i2s_buf_write(dev_i2s, tx_data, BLOCK_SIZE);
105 	zassert_equal(err, 0, "I2S buffer write unexpected error: %d", err);
106 
107 	err = i2s_trigger(dev_i2s, I2S_DIR_TX, INVALID_TRIGGER_SETTING);
108 	zassert_equal(err, -EINVAL, "I2S invalid trigger setting not detected: err=%d", err);
109 }
110 
ZTEST_USER(i2s_errors,test_i2s_unconfigured_access)111 ZTEST_USER(i2s_errors, test_i2s_unconfigured_access)
112 {
113 	int err;
114 	char tx_data[BLOCK_SIZE] = {0};
115 	struct i2s_config inactive_config = { .word_size = 16U,
116 					      .channels = 2U,
117 					      .format = I2S_FMT_DATA_FORMAT_I2S,
118 					      .frame_clk_freq = 0,
119 					      .block_size = BLOCK_SIZE,
120 					      .timeout = TIMEOUT,
121 					      .options = I2S_OPT_FRAME_CLK_MASTER |
122 							 I2S_OPT_BIT_CLK_MASTER,
123 					      .mem_slab = &tx_mem_slab };
124 
125 	err = i2s_configure(dev_i2s, I2S_DIR_TX, &inactive_config);
126 	zassert_equal(err, 0, "I2S interface NOT_READY state transition failed. err=%d", err);
127 
128 	err = i2s_buf_write(dev_i2s, tx_data, BLOCK_SIZE);
129 	zassert_equal(
130 		err, -EIO,
131 		"I2S attempting unconfigured interface access did not raise I/O error, err=%d",
132 		err);
133 }
134 
ZTEST_USER(i2s_errors,test_i2s_improper_block_size_write)135 ZTEST_USER(i2s_errors, test_i2s_improper_block_size_write)
136 {
137 	int err;
138 	char tx_data[BLOCK_SIZE] = {0};
139 	struct i2s_config test_config = { .word_size = 16U,
140 					  .channels = 2U,
141 					  .format = I2S_FMT_DATA_FORMAT_I2S,
142 					  .frame_clk_freq = FRAME_CLK_FREQ,
143 					  .block_size = BLOCK_SIZE,
144 					  .timeout = TIMEOUT,
145 					  .options =
146 						  I2S_OPT_FRAME_CLK_MASTER | I2S_OPT_BIT_CLK_MASTER,
147 					  .mem_slab = &tx_mem_slab };
148 
149 	err = i2s_configure(dev_i2s, I2S_DIR_TX, &test_config);
150 	zassert_equal(err, 0, "Unexpected error when configuring I2S interface: %d", err);
151 
152 	err = i2s_buf_write(dev_i2s, tx_data, sizeof(uint16_t) + BLOCK_SIZE);
153 	zassert_not_equal(
154 		err, 0,
155 		"I2S attempting write with incorrect block size did not raise error, err=%d", err);
156 }
157