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  * 2021-09-09     WCH          the first version
9  * 2022-09-17     hg0720       add some operation function
10  */
11 
12 #include <board.h>
13 #include <rtthread.h>
14 #include <rtdevice.h>
15 #include "drv_dac.h"
16 
17 #if defined BSP_USING_DAC
18 
19 //#define DRV_DEBUG
20 #define LOG_TAG              "drv.dac"
21 #include <drv_log.h>
22 
23 static DAC_HandleTypeDef dac_config[] =
24 {
25 #ifdef BSP_USING_DAC_CHANNEL1
26     {                                                                         \
27         .Instance                               = DAC,                        \
28         .Init.DAC_Trigger                       = DAC_Trigger_None,           \
29         .Init.DAC_WaveGeneration                = DAC_WaveGeneration_None,    \
30         .Init.DAC_LFSRUnmask_TriangleAmplitude  = DAC_TriangleAmplitude_4095, \
31         .Init.DAC_OutputBuffer                  = DAC_OutputBuffer_Enable,    \
32         .Channel                                = DAC_Channel_1,
33     },
34 #endif
35 
36 #ifdef BSP_USING_DAC_CHANNEL2
37     {
38         .Instance                               = DAC,                        \
39         .Init.DAC_Trigger                       = DAC_Trigger_None,           \
40         .Init.DAC_WaveGeneration                = DAC_WaveGeneration_None,    \
41         .Init.DAC_LFSRUnmask_TriangleAmplitude  = DAC_TriangleAmplitude_4095, \
42         .Init.DAC_OutputBuffer                  = DAC_OutputBuffer_Enable,    \
43         .Channel                                = DAC_Channel_2,
44     }
45 #endif
46 };
47 
48 struct ch32_dac
49 {
50     DAC_HandleTypeDef      DAC_Handler;
51     struct rt_dac_device   ch32_dac_device;
52 };
53 
54 static struct ch32_dac ch32_dac_obj[sizeof(dac_config) / sizeof(dac_config[0])];
55 
ch32_dac_enabled(struct rt_dac_device * device,rt_uint32_t channel)56 static rt_err_t ch32_dac_enabled(struct rt_dac_device *device, rt_uint32_t channel)
57 {
58     DAC_HandleTypeDef *ch32_dac_handler;
59     RT_ASSERT(device != RT_NULL);
60     ch32_dac_handler = device->parent.user_data;
61     DAC_Cmd(ch32_dac_handler->Channel, ENABLE);
62     return RT_EOK;
63 }
64 
ch32_dac_disabled(struct rt_dac_device * device,rt_uint32_t channel)65 static rt_err_t ch32_dac_disabled(struct rt_dac_device *device, rt_uint32_t channel)
66 {
67     DAC_HandleTypeDef *ch32_dac_handler;
68     RT_ASSERT(device != RT_NULL);
69     ch32_dac_handler = device->parent.user_data;
70     DAC_Cmd(ch32_dac_handler->Channel, DISABLE);
71     return RT_EOK;
72 }
73 
ch32_dac_get_resolution(struct rt_dac_device * device)74 static rt_uint8_t ch32_dac_get_resolution(struct rt_dac_device *device)
75 {
76     DAC_HandleTypeDef *ch32_dac_handler;
77 
78     RT_ASSERT(device != RT_NULL);
79 
80     ch32_dac_handler = device->parent.user_data;
81     (void)ch32_dac_handler;
82 
83     /* Only has supported DAC_ALIGN_12B_R, so it will return 12 bits */
84     return 12;
85 }
86 
ch32_dac_get_channel(rt_uint32_t channel)87 static rt_uint32_t ch32_dac_get_channel(rt_uint32_t channel)
88 {
89     rt_uint32_t ch32_channel = 0;
90 
91     switch (channel)
92     {
93     case  1:
94         ch32_channel = DAC_Channel_1;
95         break;
96     case  2:
97         ch32_channel = DAC_Channel_2;
98         break;
99     default:
100         RT_ASSERT(0);
101         break;
102     }
103 
104     return ch32_channel;
105 }
106 
ch32_set_dac_value(struct rt_dac_device * device,rt_uint32_t channel,rt_uint32_t * value)107 static rt_err_t ch32_set_dac_value(struct rt_dac_device *device, rt_uint32_t channel, rt_uint32_t *value)
108 {
109     rt_uint32_t dac_channel;
110     DAC_HandleTypeDef *ch32_dac_handler;
111 
112     RT_ASSERT(device != RT_NULL);
113     RT_ASSERT(value != RT_NULL);
114 
115     ch32_dac_handler = device->parent.user_data;
116 
117 
118     if ((channel <= 2) && (channel > 0))
119     {
120         /* set ch32 dac channel */
121         dac_channel =  ch32_dac_get_channel(channel);
122     }
123     else
124     {
125         LOG_E("dac channel must be 1 or 2.");
126         return -RT_ERROR;
127     }
128 
129     if (channel==1)
130     {
131         DAC_SetChannel1Data(DAC_Align_12b_R, *value);
132     }
133     else if (channel==2)
134     {
135         DAC_SetChannel2Data(DAC_Align_12b_R, *value);
136     }
137 
138     return RT_EOK;
139 }
140 
141 static const struct rt_dac_ops ch_dac_ops =
142 {
143     .disabled = ch32_dac_disabled,
144     .enabled  = ch32_dac_enabled,
145     .convert  = ch32_set_dac_value,
146     .get_resolution = ch32_dac_get_resolution,
147 };
148 
ch32_dac_init(void)149 static int ch32_dac_init(void)
150 {
151     int result = RT_EOK;
152     /* save dac name */
153     char name_buf[6] = {'d', 'a', 'c', 'c','0', 0};
154     int i = 0;
155     GPIO_InitTypeDef GPIO_InitStructure={0};
156 
157     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE );
158     RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE );
159     for (i = 0; i < sizeof(dac_config) / sizeof(dac_config[0]); i++)
160     {
161         /* dac channel init */
162         name_buf[4] = '0';
163         ch32_dac_obj[i].DAC_Handler = dac_config[i];
164 
165         if (ch32_dac_obj[i].DAC_Handler.Channel==DAC_Channel_1)
166         {
167             name_buf[4] = '1';
168             GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
169             GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
170             GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
171             GPIO_Init(GPIOA, &GPIO_InitStructure);
172         }
173         if (ch32_dac_obj[i].DAC_Handler.Channel==DAC_Channel_2)
174         {
175             name_buf[4] = '2';
176             GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
177             GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
178             GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
179             GPIO_Init(GPIOA, &GPIO_InitStructure);
180         }
181         /* init dac channelx */
182         DAC_Init(ch32_dac_obj[i].DAC_Handler.Channel,&ch32_dac_obj[i].DAC_Handler.Init);
183 
184         /* register dac device */
185         if (rt_hw_dac_register(&ch32_dac_obj[i].ch32_dac_device, name_buf, &ch_dac_ops, &ch32_dac_obj[i].DAC_Handler) == RT_EOK)
186         {
187             LOG_D("%s init success", name_buf);
188         }
189         else
190         {
191             LOG_E("%s register failed", name_buf);
192             result = -RT_ERROR;
193         }
194     }
195 
196     return result;
197 }
198 
199 INIT_DEVICE_EXPORT(ch32_dac_init);
200 
201 #endif /* BSP_USING_DAC */
202