1 /*
2  * Copyright (c) 2020 STMicroelectronics
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <string.h>
8 #include <zephyr/kernel.h>
9 #include <zephyr/sys/printk.h>
10 
11 #include <zephyr/audio/dmic.h>
12 
13 /* uncomment if you want PCM output in ascii */
14 /*#define PCM_OUTPUT_IN_ASCII		1  */
15 
16 #define AUDIO_FREQ		16000
17 #define CHAN_SIZE		16
18 #define PCM_BLK_SIZE_MS		((AUDIO_FREQ/1000) * sizeof(int16_t))
19 
20 #define NUM_MS		1000
21 
22 K_MEM_SLAB_DEFINE(rx_mem_slab, PCM_BLK_SIZE_MS, NUM_MS, 1);
23 
24 struct pcm_stream_cfg mic_streams = {
25 	.pcm_rate = AUDIO_FREQ,
26 	.pcm_width = CHAN_SIZE,
27 	.block_size = PCM_BLK_SIZE_MS,
28 	.mem_slab = &rx_mem_slab,
29 };
30 
31 struct dmic_cfg cfg = {
32 	.io = {
33 		/* requesting a pdm freq around 2MHz */
34 		.min_pdm_clk_freq = 1800000,
35 		.max_pdm_clk_freq = 2500000,
36 	},
37 	.streams = &mic_streams,
38 	.channel = {
39 		.req_num_chan = 1,
40 	},
41 };
42 
43 void *rx_block[NUM_MS];
44 size_t rx_size = PCM_BLK_SIZE_MS;
45 
main(void)46 int main(void)
47 {
48 	int i;
49 	uint32_t ms;
50 	int ret;
51 
52 	const struct device *const mic_dev = DEVICE_DT_GET_ONE(st_mpxxdtyy);
53 
54 	if (!device_is_ready(mic_dev)) {
55 		printk("%s: device not ready.\n", mic_dev->name);
56 		return 0;
57 	}
58 
59 	ret = dmic_configure(mic_dev, &cfg);
60 	if (ret < 0) {
61 		printk("microphone configuration error\n");
62 		return 0;
63 	}
64 
65 	ret = dmic_trigger(mic_dev, DMIC_TRIGGER_START);
66 	if (ret < 0) {
67 		printk("microphone start trigger error\n");
68 		return 0;
69 	}
70 
71 	/* Acquire microphone audio */
72 	for (ms = 0; ms < NUM_MS; ms++) {
73 		ret = dmic_read(mic_dev, 0, &rx_block[ms], &rx_size, 2000);
74 		if (ret < 0) {
75 			printk("microphone audio read error\n");
76 			return 0;
77 		}
78 	}
79 
80 	ret = dmic_trigger(mic_dev, DMIC_TRIGGER_STOP);
81 	if (ret < 0) {
82 		printk("microphone stop trigger error\n");
83 		return 0;
84 	}
85 
86 	/* print PCM stream */
87 #ifdef PCM_OUTPUT_IN_ASCII
88 	printk("-- start\n");
89 	int j;
90 
91 	for (i = 0; i < NUM_MS; i++) {
92 		uint16_t *pcm_out = rx_block[i];
93 
94 		for (j = 0; j < rx_size/2; j++) {
95 			printk("0x%04x,\n", pcm_out[j]);
96 		}
97 	}
98 	printk("-- end\n");
99 #else
100 	unsigned char pcm_l, pcm_h;
101 	int j;
102 
103 	for (i = 0; i < NUM_MS; i++) {
104 		uint16_t *pcm_out = rx_block[i];
105 
106 		for (j = 0; j < rx_size/2; j++) {
107 			pcm_l = (char)(pcm_out[j] & 0xFF);
108 			pcm_h = (char)((pcm_out[j] >> 8) & 0xFF);
109 
110 			z_impl_k_str_out(&pcm_l, 1);
111 			z_impl_k_str_out(&pcm_h, 1);
112 		}
113 	}
114 #endif
115 	return 0;
116 }
117