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