1 /*
2 * Copyright (c) 2006-2023, RT-Thread Development Team
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date Author Notes
8 * 2023-04-18 shelton first version
9 * 2024-08-30 shelton add support m412/416
10 */
11
12 #include "drv_common.h"
13
14 #if defined(BSP_USING_DAC1)
15 #include "drv_config.h"
16
17 //#define DRV_DEBUG
18 #define LOG_TAG "drv.dac"
19 #include <drv_log.h>
20
21 struct at32_dac {
22 char *name;
23 dac_type *dac_x;
24 struct rt_dac_device dac_device;
25 };
26
27 enum {
28 #ifdef BSP_USING_DAC1
29 DAC1_INDEX,
30 #endif
31 };
32
33 static struct at32_dac dac_config[] =
34 {
35 #ifdef BSP_USING_DAC1
36 DAC1_CONFIG,
37 #endif
38 };
39
at32_dac_get_channel(rt_uint32_t channel)40 static dac_select_type at32_dac_get_channel(rt_uint32_t channel)
41 {
42 dac_select_type at32_channel = DAC1_SELECT;
43
44 switch (channel)
45 {
46 case 1:
47 at32_channel = DAC1_SELECT;
48 break;
49 case 2:
50 at32_channel = DAC2_SELECT;
51 break;
52 default:
53 RT_ASSERT(0);
54 break;
55 }
56
57 return at32_channel;
58 }
59
at32_dac_enabled(struct rt_dac_device * device,rt_uint32_t channel)60 static rt_err_t at32_dac_enabled(struct rt_dac_device *device, rt_uint32_t channel)
61 {
62 dac_select_type dac_channel;
63 dac_type *instance;
64
65 RT_ASSERT(device != RT_NULL);
66 instance = device->parent.user_data;
67 /* prepare for mult dac instance */
68 (void)instance;
69
70 if ((channel <= 2) && (channel > 0))
71 {
72 /* set at32 dac channel */
73 dac_channel = at32_dac_get_channel(channel);
74 }
75 else
76 {
77 LOG_E("dac channel must be 1 or 2.");
78 return -RT_ERROR;
79 }
80 #if defined (SOC_SERIES_AT32M412) || defined (SOC_SERIES_AT32M416)
81 dac_output_enable(dac_channel, TRUE);
82 #endif
83 dac_enable(dac_channel, TRUE);
84
85 return RT_EOK;
86 }
87
at32_dac_disabled(struct rt_dac_device * device,rt_uint32_t channel)88 static rt_err_t at32_dac_disabled(struct rt_dac_device *device, rt_uint32_t channel)
89 {
90 dac_select_type dac_channel;
91 dac_type *instance;
92
93 RT_ASSERT(device != RT_NULL);
94 instance = device->parent.user_data;
95 /* prepare for mult dac instance */
96 (void)instance;
97
98 if ((channel <= 2) && (channel > 0))
99 {
100 /* set at32 dac channel */
101 dac_channel = at32_dac_get_channel(channel);
102 }
103 else
104 {
105 LOG_E("dac channel must be 1 or 2.");
106 return -RT_ERROR;
107 }
108 #if defined (SOC_SERIES_AT32M412) || defined (SOC_SERIES_AT32M416)
109 dac_output_enable(dac_channel, FALSE);
110 #endif
111 dac_enable(dac_channel, FALSE);
112
113 return RT_EOK;
114 }
115
at32_dac_get_resolution(struct rt_dac_device * device)116 static rt_uint8_t at32_dac_get_resolution(struct rt_dac_device *device)
117 {
118 dac_type *instance;
119
120 RT_ASSERT(device != RT_NULL);
121 instance = device->parent.user_data;
122 /* prepare for mult dac instance */
123 (void)instance;
124
125 /* Only has supported DAC_ALIGN_12B_R, so it will return 12 bits */
126 return 12;
127 }
128
at32_set_dac_value(struct rt_dac_device * device,rt_uint32_t channel,rt_uint32_t * value)129 static rt_err_t at32_set_dac_value(struct rt_dac_device *device, rt_uint32_t channel, rt_uint32_t *value)
130 {
131 dac_select_type dac_channel;
132 dac_type *instance;
133
134 RT_ASSERT(device != RT_NULL);
135 RT_ASSERT(value != RT_NULL);
136
137 instance = device->parent.user_data;
138 /* prepare for mult dac instance */
139 (void)instance;
140
141 if ((channel <= 2) && (channel > 0))
142 {
143 /* set at32 dac channel */
144 dac_channel = at32_dac_get_channel(channel);
145 }
146 else
147 {
148 LOG_E("dac channel must be 1 or 2.");
149 return -RT_ERROR;
150 }
151 #if !defined (SOC_SERIES_AT32M412) && !defined (SOC_SERIES_AT32M416)
152 dac_output_buffer_enable(dac_channel, FALSE);
153 #endif
154 dac_trigger_enable(dac_channel, FALSE);
155
156 /* set dac channel out value*/
157 if(dac_channel == DAC1_SELECT)
158 {
159 #if !defined (SOC_SERIES_AT32M412) && !defined (SOC_SERIES_AT32M416)
160 dac_1_data_set(DAC1_12BIT_RIGHT, *value);
161 #else
162 /* 6-bit */
163 *value = *value >> 6;
164 dac_1_data_set(*value);
165 #endif
166 }
167 else
168 {
169 #if !defined (SOC_SERIES_AT32M412) && !defined (SOC_SERIES_AT32M416)
170 dac_2_data_set(DAC2_12BIT_RIGHT, *value);
171 #else
172 /* 6-bit */
173 *value = *value >> 6;
174 dac_2_data_set(*value);
175 #endif
176 }
177
178 /* start dac */
179 dac_enable(dac_channel, TRUE);
180
181 return RT_EOK;
182 }
183
184 static const struct rt_dac_ops at32_dac_ops =
185 {
186 .disabled = at32_dac_disabled,
187 .enabled = at32_dac_enabled,
188 .convert = at32_set_dac_value,
189 .get_resolution = at32_dac_get_resolution,
190 };
191
at32_dac_init(void)192 static int at32_dac_init(void)
193 {
194 rt_size_t obj_num;
195 int index;
196
197 obj_num = sizeof(dac_config) / sizeof(struct at32_dac);
198 rt_err_t result = 0;
199
200 for (index = 0; index < obj_num; index++) {
201 at32_msp_dac_init((void *)(dac_config[index].dac_x));
202 /* reset dac */
203 dac_reset();
204
205 /* register dac device */
206 if (rt_hw_dac_register(&dac_config[index].dac_device, dac_config[index].name, &at32_dac_ops, \
207 &dac_config[index].dac_x) == RT_EOK)
208 {
209 LOG_D("%s init success", dac_config[index].name);
210 }
211 else
212 {
213 LOG_E("%s register failed", dac_config[index].name);
214 result = -RT_ERROR;
215 }
216 }
217
218 return result;
219 }
220
221 INIT_DEVICE_EXPORT(at32_dac_init);
222
223 #endif /* BSP_USING_DAC */
224