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