1 /*
2  * Copyright 2023 NXP
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 /*
8  * Based on DMIC driver sample, which is:
9  * Copyright (c) 2021 Nordic Semiconductor ASA
10  */
11 
12 #include <zephyr/kernel.h>
13 #include <zephyr/audio/dmic.h>
14 #include <zephyr/ztest.h>
15 
16 static const struct device *dmic_dev = DEVICE_DT_GET(DT_ALIAS(dmic_dev));
17 
18 #if DT_HAS_COMPAT_STATUS_OKAY(nxp_dmic)
19 #define PDM_CHANNELS 4 /* Two L/R pairs of channels */
20 #define SAMPLE_BIT_WIDTH 16
21 #define BYTES_PER_SAMPLE sizeof(int16_t)
22 #define SLAB_ALIGN 4
23 #define MAX_SAMPLE_RATE  48000
24 /* Milliseconds to wait for a block to be read. */
25 #define READ_TIMEOUT 1000
26 /* Size of a block for 100 ms of audio data. */
27 #define BLOCK_SIZE(_sample_rate, _number_of_channels) \
28 	(BYTES_PER_SAMPLE * (_sample_rate / 10) * _number_of_channels)
29 #else
30 #error "Unsupported DMIC device"
31 #endif
32 
33 /* Driver will allocate blocks from this slab to receive audio data into them.
34  * Application, after getting a given block from the driver and processing its
35  * data, needs to free that block.
36  */
37 #define MAX_BLOCK_SIZE   BLOCK_SIZE(MAX_SAMPLE_RATE, PDM_CHANNELS)
38 #define BLOCK_COUNT      8
39 K_MEM_SLAB_DEFINE_STATIC(mem_slab, MAX_BLOCK_SIZE, BLOCK_COUNT, SLAB_ALIGN);
40 
41 static struct pcm_stream_cfg pcm_stream = {
42 	.pcm_width = SAMPLE_BIT_WIDTH,
43 	.mem_slab = &mem_slab,
44 };
45 static struct dmic_cfg dmic_cfg = {
46 	.io = {
47 		/* These fields can be used to limit the PDM clock
48 		 * configurations that the driver is allowed to use
49 		 * to those supported by the microphone.
50 		 */
51 		.min_pdm_clk_freq = 1000000,
52 		.max_pdm_clk_freq = 3500000,
53 		.min_pdm_clk_dc   = 40,
54 		.max_pdm_clk_dc   = 60,
55 	},
56 	.streams = &pcm_stream,
57 	.channel = {
58 		.req_num_streams = 1,
59 	},
60 };
61 
62 /* Verify that dmic_trigger fails when DMIC is not configured
63  * this test must run first, before DMIC has been configured
64  */
ZTEST(dmic,test_0_start_fail)65 ZTEST(dmic, test_0_start_fail)
66 {
67 	int ret;
68 
69 	zassert_true(device_is_ready(dmic_dev), "DMIC device is not ready");
70 	ret = dmic_trigger(dmic_dev, DMIC_TRIGGER_START);
71 	zassert_not_equal(ret, 0, "DMIC trigger should fail when DMIC is not configured");
72 }
73 
do_pdm_transfer(const struct device * dmic,struct dmic_cfg * cfg)74 static int do_pdm_transfer(const struct device *dmic,
75 			    struct dmic_cfg *cfg)
76 {
77 	int ret;
78 	void *buffer;
79 	uint32_t size;
80 
81 	TC_PRINT("PCM output rate: %u, channels: %u\n",
82 		 cfg->streams[0].pcm_rate, cfg->channel.req_num_chan);
83 
84 	ret = dmic_configure(dmic, cfg);
85 	if (ret < 0) {
86 		TC_PRINT("DMIC configuration failed: %d\n", ret);
87 		return ret;
88 	}
89 
90 	/* Check that the driver is properly populating the "act*" fields */
91 	zassert_equal(cfg->channel.act_num_chan,
92 		      cfg->channel.req_num_chan,
93 		      "DMIC configure should populate act_num_chan field");
94 	zassert_equal(cfg->channel.act_chan_map_lo,
95 		      cfg->channel.req_chan_map_lo,
96 		      "DMIC configure should populate act_chan_map_lo field");
97 	zassert_equal(cfg->channel.act_chan_map_hi,
98 		      cfg->channel.req_chan_map_hi,
99 		      "DMIC configure should populate act_chan_map_hi field");
100 	ret = dmic_trigger(dmic, DMIC_TRIGGER_START);
101 	if (ret < 0) {
102 		TC_PRINT("DMIC start trigger failed: %d\n", ret);
103 		return ret;
104 	}
105 
106 	/* We read more than the total BLOCK_COUNT to insure the DMIC
107 	 * driver correctly reallocates memory slabs as it exhausts existing
108 	 * ones.
109 	 */
110 	for (int i = 0; i < (2 * BLOCK_COUNT); i++) {
111 		ret = dmic_read(dmic, 0, &buffer, &size, READ_TIMEOUT);
112 		if (ret < 0) {
113 			TC_PRINT("DMIC read failed: %d\n", ret);
114 			return ret;
115 		}
116 
117 		TC_PRINT("%d - got buffer %p of %u bytes\n", i, buffer, size);
118 		k_mem_slab_free(&mem_slab, buffer);
119 	}
120 
121 	ret = dmic_trigger(dmic, DMIC_TRIGGER_STOP);
122 	if (ret < 0) {
123 		TC_PRINT("DMIC stop trigger failed: %d\n", ret);
124 		return ret;
125 	}
126 	return 0;
127 }
128 
129 
130 /* Verify that the DMIC can transfer from a single channel */
ZTEST(dmic,test_single_channel)131 ZTEST(dmic, test_single_channel)
132 {
133 	dmic_cfg.channel.req_num_chan = 1;
134 	dmic_cfg.channel.req_chan_map_lo =
135 		dmic_build_channel_map(0, 0, PDM_CHAN_LEFT);
136 	dmic_cfg.streams[0].pcm_rate = MAX_SAMPLE_RATE;
137 	dmic_cfg.streams[0].block_size =
138 		BLOCK_SIZE(dmic_cfg.streams[0].pcm_rate,
139 			   dmic_cfg.channel.req_num_chan);
140 	zassert_equal(do_pdm_transfer(dmic_dev, &dmic_cfg), 0,
141 		      "Single channel transfer failed");
142 }
143 
144 /* Verify that the DMIC can transfer from a L/R channel pair */
ZTEST(dmic,test_stereo_channel)145 ZTEST(dmic, test_stereo_channel)
146 {
147 	dmic_cfg.channel.req_num_chan = 2;
148 	dmic_cfg.channel.req_chan_map_lo =
149 		dmic_build_channel_map(0, 0, PDM_CHAN_LEFT) |
150 		dmic_build_channel_map(1, 0, PDM_CHAN_RIGHT);
151 	dmic_cfg.streams[0].pcm_rate = MAX_SAMPLE_RATE;
152 	dmic_cfg.streams[0].block_size =
153 		BLOCK_SIZE(dmic_cfg.streams[0].pcm_rate,
154 			   dmic_cfg.channel.req_num_chan);
155 	zassert_equal(do_pdm_transfer(dmic_dev, &dmic_cfg), 0,
156 		      "L/R channel transfer failed");
157 	dmic_cfg.channel.req_chan_map_lo =
158 		dmic_build_channel_map(0, 0, PDM_CHAN_RIGHT) |
159 		dmic_build_channel_map(1, 0, PDM_CHAN_LEFT);
160 	zassert_equal(do_pdm_transfer(dmic_dev, &dmic_cfg), 0,
161 		      "R/L channel transfer failed");
162 }
163 
164 /* Test DMIC with maximum number of channels */
ZTEST(dmic,test_max_channel)165 ZTEST(dmic, test_max_channel)
166 {
167 	enum pdm_lr lr;
168 	uint8_t pdm_hw_chan;
169 
170 	dmic_cfg.channel.req_num_chan = PDM_CHANNELS;
171 	dmic_cfg.channel.req_chan_map_lo = 0;
172 	dmic_cfg.channel.req_chan_map_hi = 0;
173 	for (uint8_t i = 0; i < PDM_CHANNELS; i++) {
174 		lr = ((i % 2) == 0) ? PDM_CHAN_LEFT : PDM_CHAN_RIGHT;
175 		pdm_hw_chan = i >> 1;
176 		if (i < 4) {
177 			dmic_cfg.channel.req_chan_map_lo |=
178 				dmic_build_channel_map(i, pdm_hw_chan, lr);
179 		} else {
180 			dmic_cfg.channel.req_chan_map_hi |=
181 				dmic_build_channel_map(i, pdm_hw_chan, lr);
182 		}
183 	}
184 
185 	dmic_cfg.streams[0].pcm_rate = MAX_SAMPLE_RATE;
186 	dmic_cfg.streams[0].block_size =
187 		BLOCK_SIZE(dmic_cfg.streams[0].pcm_rate,
188 			   dmic_cfg.channel.req_num_chan);
189 	zassert_equal(do_pdm_transfer(dmic_dev, &dmic_cfg), 0,
190 		      "Maximum channel transfer failed");
191 }
192 
193 /* Test pausing and restarting a channel */
ZTEST(dmic,test_pause_restart)194 ZTEST(dmic, test_pause_restart)
195 {
196 	int ret, i;
197 	void *buffer;
198 	uint32_t size;
199 
200 	dmic_cfg.channel.req_num_chan = 1;
201 	dmic_cfg.channel.req_chan_map_lo =
202 		dmic_build_channel_map(0, 0, PDM_CHAN_LEFT);
203 	dmic_cfg.streams[0].pcm_rate = MAX_SAMPLE_RATE;
204 	dmic_cfg.streams[0].block_size =
205 		BLOCK_SIZE(dmic_cfg.streams[0].pcm_rate,
206 			   dmic_cfg.channel.req_num_chan);
207 	ret = dmic_configure(dmic_dev, &dmic_cfg);
208 	zassert_equal(ret, 0, "DMIC configure failed");
209 
210 	/* Start the DMIC, and pause it immediately */
211 	ret = dmic_trigger(dmic_dev, DMIC_TRIGGER_START);
212 	zassert_equal(ret, 0, "DMIC start failed");
213 	ret = dmic_trigger(dmic_dev, DMIC_TRIGGER_PAUSE);
214 	zassert_equal(ret, 0, "DMIC pause failed");
215 	/* There may be some buffers in the DMIC queue, but a read
216 	 * should eventually time out while it is paused
217 	 */
218 	for (i = 0; i < (2 * BLOCK_COUNT); i++) {
219 		ret = dmic_read(dmic_dev, 0, &buffer, &size, READ_TIMEOUT);
220 		if (ret < 0) {
221 			break;
222 		}
223 		k_mem_slab_free(&mem_slab, buffer);
224 	}
225 	zassert_not_equal(ret, 0, "DMIC is paused, reads should timeout");
226 	TC_PRINT("Queue drained after %d reads\n", i);
227 	/* Unpause the DMIC */
228 	ret = dmic_trigger(dmic_dev, DMIC_TRIGGER_RELEASE);
229 	zassert_equal(ret, 0, "DMIC release failed");
230 	/* Reads should not timeout now */
231 	for (i = 0; i < (2 * BLOCK_COUNT); i++) {
232 		ret = dmic_read(dmic_dev, 0, &buffer, &size, READ_TIMEOUT);
233 		if (ret < 0) {
234 			break;
235 		}
236 		k_mem_slab_free(&mem_slab, buffer);
237 	}
238 	zassert_equal(ret, 0, "DMIC is active, reads should succeed");
239 	TC_PRINT("%d reads completed\n", (2 * BLOCK_COUNT));
240 	/* Stop the DMIC, and repeat the same tests */
241 	ret = dmic_trigger(dmic_dev, DMIC_TRIGGER_STOP);
242 	zassert_equal(ret, 0, "DMIC stop failed");
243 	/* Versus a pause, DMIC reads should immediately stop once DMIC times
244 	 * out
245 	 */
246 	ret = dmic_read(dmic_dev, 0, &buffer, &size, READ_TIMEOUT);
247 	zassert_not_equal(ret, 0, "DMIC read should timeout when DMIC is stopped");
248 	ret = dmic_trigger(dmic_dev, DMIC_TRIGGER_START);
249 	zassert_equal(ret, 0, "DMIC restart failed");
250 	/* Reads should not timeout now */
251 	for (i = 0; i < (2 * BLOCK_COUNT); i++) {
252 		ret = dmic_read(dmic_dev, 0, &buffer, &size, READ_TIMEOUT);
253 		if (ret < 0) {
254 			break;
255 		}
256 		k_mem_slab_free(&mem_slab, buffer);
257 	}
258 	zassert_equal(ret, 0, "DMIC is active, reads should succeed");
259 	TC_PRINT("%d reads completed\n", (2 * BLOCK_COUNT));
260 	/* Test is over. Stop the DMIC */
261 	ret = dmic_trigger(dmic_dev, DMIC_TRIGGER_STOP);
262 	zassert_equal(ret, 0, "DMIC stop failed");
263 }
264 
265 /* Verify that channel map without adjacent L/R pairs fails */
ZTEST(dmic,test_bad_pair)266 ZTEST(dmic, test_bad_pair)
267 {
268 	int ret;
269 
270 	dmic_cfg.channel.req_num_chan = 2;
271 	dmic_cfg.channel.req_chan_map_lo =
272 		dmic_build_channel_map(0, 0, PDM_CHAN_RIGHT) |
273 		dmic_build_channel_map(1, 0, PDM_CHAN_RIGHT);
274 	dmic_cfg.streams[0].pcm_rate = MAX_SAMPLE_RATE;
275 	dmic_cfg.streams[0].block_size =
276 		BLOCK_SIZE(dmic_cfg.streams[0].pcm_rate,
277 			   dmic_cfg.channel.req_num_chan);
278 	ret = dmic_configure(dmic_dev, &dmic_cfg);
279 	zassert_not_equal(ret, 0, "DMIC configure should fail with "
280 			  "two of same channel in map");
281 
282 	dmic_cfg.channel.req_num_chan = 2;
283 	dmic_cfg.channel.req_chan_map_lo =
284 		dmic_build_channel_map(0, 0, PDM_CHAN_RIGHT) |
285 		dmic_build_channel_map(1, 1, PDM_CHAN_LEFT);
286 	ret = dmic_configure(dmic_dev, &dmic_cfg);
287 	zassert_not_equal(ret, 0, "DMIC configure should fail with "
288 			  "non adjacent channels in map");
289 }
290 
291 ZTEST_SUITE(dmic, NULL, NULL, NULL, NULL, NULL);
292