1 /*
2  * Copyright (c) 2020 Libre Solar Technologies GmbH
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/kernel.h>
8 #include <zephyr/sys/printk.h>
9 #include <zephyr/drivers/dac.h>
10 
11 #define ZEPHYR_USER_NODE DT_PATH(zephyr_user)
12 
13 #if (DT_NODE_HAS_PROP(ZEPHYR_USER_NODE, dac) && \
14 	DT_NODE_HAS_PROP(ZEPHYR_USER_NODE, dac_channel_id) && \
15 	DT_NODE_HAS_PROP(ZEPHYR_USER_NODE, dac_resolution))
16 #define DAC_NODE DT_PHANDLE(ZEPHYR_USER_NODE, dac)
17 #define DAC_CHANNEL_ID DT_PROP(ZEPHYR_USER_NODE, dac_channel_id)
18 #define DAC_RESOLUTION DT_PROP(ZEPHYR_USER_NODE, dac_resolution)
19 #else
20 #error "Unsupported board: see README and check /zephyr,user node"
21 #define DAC_NODE DT_INVALID_NODE
22 #define DAC_CHANNEL_ID 0
23 #define DAC_RESOLUTION 0
24 #endif
25 
26 static const struct device *const dac_dev = DEVICE_DT_GET(DAC_NODE);
27 
28 static const struct dac_channel_cfg dac_ch_cfg = {
29 	.channel_id  = DAC_CHANNEL_ID,
30 	.resolution  = DAC_RESOLUTION,
31 #if defined(CONFIG_DAC_BUFFER_NOT_SUPPORT)
32 	.buffered = false,
33 #else
34 	.buffered = true,
35 #endif /* CONFIG_DAC_BUFFER_NOT_SUPPORT */
36 };
37 
main(void)38 int main(void)
39 {
40 	if (!device_is_ready(dac_dev)) {
41 		printk("DAC device %s is not ready\n", dac_dev->name);
42 		return 0;
43 	}
44 
45 	int ret = dac_channel_setup(dac_dev, &dac_ch_cfg);
46 
47 	if (ret != 0) {
48 		printk("Setting up of DAC channel failed with code %d\n", ret);
49 		return 0;
50 	}
51 
52 	printk("Generating sawtooth signal at DAC channel %d.\n",
53 		DAC_CHANNEL_ID);
54 	while (1) {
55 		/* Number of valid DAC values, e.g. 4096 for 12-bit DAC */
56 		const int dac_values = 1U << DAC_RESOLUTION;
57 
58 		/*
59 		 * 1 msec sleep leads to about 4 sec signal period for 12-bit
60 		 * DACs. For DACs with lower resolution, sleep time needs to
61 		 * be increased.
62 		 * Make sure to sleep at least 1 msec even for future 16-bit
63 		 * DACs (lowering signal frequency).
64 		 */
65 		const int sleep_time = 4096 / dac_values > 0 ?
66 			4096 / dac_values : 1;
67 
68 		for (int i = 0; i < dac_values; i++) {
69 			ret = dac_write_value(dac_dev, DAC_CHANNEL_ID, i);
70 			if (ret != 0) {
71 				printk("dac_write_value() failed with code %d\n", ret);
72 				return 0;
73 			}
74 			k_sleep(K_MSEC(sleep_time));
75 		}
76 	}
77 	return 0;
78 }
79