1 /*
2  * Copyright (c) 2018 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/drivers/gpio.h>
12 #include <zephyr/drivers/led.h>
13 
14 #include <zephyr/audio/dmic.h>
15 
16 /* uncomment if you want PCM output in ascii */
17 /*#define PCM_OUTPUT_IN_ASCII		1  */
18 
19 #define AUDIO_FREQ		16000
20 #define CHAN_SIZE		16
21 #define PCM_BLK_SIZE_MS		((AUDIO_FREQ/1000) * sizeof(int16_t))
22 
23 #define NUM_MS		5000
24 
25 K_MEM_SLAB_DEFINE(rx_mem_slab, PCM_BLK_SIZE_MS, NUM_MS, 1);
26 
27 struct pcm_stream_cfg mic_streams = {
28 	.pcm_rate = AUDIO_FREQ,
29 	.pcm_width = CHAN_SIZE,
30 	.block_size = PCM_BLK_SIZE_MS,
31 	.mem_slab = &rx_mem_slab,
32 };
33 
34 struct dmic_cfg cfg = {
35 	.io = {
36 		/* requesting a pdm freq around 2MHz */
37 		.min_pdm_clk_freq = 1800000,
38 		.max_pdm_clk_freq = 2500000,
39 	},
40 	.streams = &mic_streams,
41 	.channel = {
42 		.req_num_chan = 1,
43 	},
44 };
45 
46 #define NUM_LEDS 12
47 #define DELAY_TIME K_MSEC(25)
48 
49 static const struct gpio_dt_spec led0 = GPIO_DT_SPEC_GET(DT_ALIAS(led0), gpios);
50 static const struct gpio_dt_spec led1 = GPIO_DT_SPEC_GET(DT_ALIAS(led1), gpios);
51 
signal_sampling_started(void)52 void signal_sampling_started(void)
53 {
54 	gpio_pin_configure_dt(&led0, GPIO_OUTPUT_ACTIVE);
55 	gpio_pin_configure_dt(&led1, GPIO_OUTPUT_INACTIVE);
56 }
57 
signal_sampling_stopped(void)58 void signal_sampling_stopped(void)
59 {
60 	gpio_pin_configure_dt(&led0, GPIO_OUTPUT_ACTIVE);
61 	gpio_pin_configure_dt(&led1, GPIO_OUTPUT_ACTIVE);
62 }
63 
signal_print_stopped(void)64 void signal_print_stopped(void)
65 {
66 	gpio_pin_configure_dt(&led0, GPIO_OUTPUT_INACTIVE);
67 	gpio_pin_configure_dt(&led1, GPIO_OUTPUT_ACTIVE);
68 }
69 
70 void *rx_block[NUM_MS];
71 size_t rx_size = PCM_BLK_SIZE_MS;
72 
main(void)73 int main(void)
74 {
75 	int i;
76 	uint32_t ms;
77 
78 	if (!gpio_is_ready_dt(&led0)) {
79 		printk("LED0 GPIO controller device is not ready\n");
80 		return 0;
81 	}
82 
83 	if (!gpio_is_ready_dt(&led1)) {
84 		printk("LED1 GPIO controller device is not ready\n");
85 		return 0;
86 	}
87 
88 #ifdef CONFIG_LP3943
89 	static const struct device *const ledc = DEVICE_DT_GET_ONE(ti_lp3943);
90 
91 	if (!device_is_ready(ledc)) {
92 		printk("Device %s is not ready\n", ledc->name);
93 		return 0;
94 	}
95 
96 	/* turn all leds on */
97 	for (i = 0; i < NUM_LEDS; i++) {
98 		led_on(ledc, i);
99 		k_sleep(DELAY_TIME);
100 	}
101 
102 	/* turn all leds off */
103 	for (i = 0; i < NUM_LEDS; i++) {
104 		led_off(ledc, i);
105 		k_sleep(DELAY_TIME);
106 	}
107 
108 #endif
109 
110 	printk("ArgonKey test!!\n");
111 
112 	int ret;
113 
114 	const struct device *const mic_dev = DEVICE_DT_GET_ONE(st_mpxxdtyy);
115 
116 	if (!device_is_ready(mic_dev)) {
117 		printk("Device %s is not ready\n", mic_dev->name);
118 		return 0;
119 	}
120 
121 	ret = dmic_configure(mic_dev, &cfg);
122 	if (ret < 0) {
123 		printk("microphone configuration error\n");
124 		return 0;
125 	}
126 
127 	ret = dmic_trigger(mic_dev, DMIC_TRIGGER_START);
128 	if (ret < 0) {
129 		printk("microphone start trigger error\n");
130 		return 0;
131 	}
132 
133 	signal_sampling_started();
134 
135 	/* Acquire microphone audio */
136 	for (ms = 0U; ms < NUM_MS; ms++) {
137 		ret = dmic_read(mic_dev, 0, &rx_block[ms], &rx_size, 2000);
138 		if (ret < 0) {
139 			printk("microphone audio read error\n");
140 			return 0;
141 		}
142 	}
143 
144 	signal_sampling_stopped();
145 
146 	ret = dmic_trigger(mic_dev, DMIC_TRIGGER_STOP);
147 	if (ret < 0) {
148 		printk("microphone stop trigger error\n");
149 		return 0;
150 	}
151 
152 	/* print PCM stream */
153 #ifdef PCM_OUTPUT_IN_ASCII
154 	printk("-- start\n");
155 	int j;
156 
157 	for (i = 0; i < NUM_MS; i++) {
158 		uint16_t *pcm_out = rx_block[i];
159 
160 		for (j = 0; j < rx_size/2; j++) {
161 			printk("0x%04x,\n", pcm_out[j]);
162 		}
163 	}
164 	printk("-- end\n");
165 #else
166 	unsigned char pcm_l, pcm_h;
167 	int j;
168 
169 	for (i = 0; i < NUM_MS; i++) {
170 		uint16_t *pcm_out = rx_block[i];
171 
172 		for (j = 0; j < rx_size/2; j++) {
173 			pcm_l = (char)(pcm_out[j] & 0xFF);
174 			pcm_h = (char)((pcm_out[j] >> 8) & 0xFF);
175 
176 			z_impl_k_str_out(&pcm_l, 1);
177 			z_impl_k_str_out(&pcm_h, 1);
178 		}
179 	}
180 #endif
181 
182 	signal_print_stopped();
183 	return 0;
184 }
185