1 /*
2  * Copyright (c) 2006-2024 RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author                 Notes
8  * 2022-07-28     rtthread qiu       first version
9  */
10 #include "drv_dac.h"
11 #include "drv_common.h"
12 #include <rtthread.h>
13 
14 #if defined(BSP_USING_DAC1) || defined(BSP_USING_DAC2)
15 
16 #define LOG_TAG "drv.dac"
17 #include <drv_log.h>
18 
19 struct cyp_dac
20 {
21     cy_stc_csdidac_config_t cyhal_dac_device;
22     struct rt_dac_device cyp_dac_device;
23     char *name;
24 };
25 
26 static struct cyp_dac dac_config[] =
27     {
28 #ifdef BSP_USING_DAC1
29         DAC1_CONFIG,
30 #endif
31 #ifdef BSP_USING_DAC2
32         DAC2_CONFIG,
33 #endif
34 
35 };
36 
37 /*get dac channel*/
cyp_dac_get_channel(rt_uint32_t channel)38 static rt_uint32_t cyp_dac_get_channel(rt_uint32_t channel)
39 {
40     rt_uint32_t cyp_dac_channel = 0;
41 
42     switch (channel)
43     {
44     case 1:
45         cyp_dac_channel = CY_CSDIDAC_A;
46         break;
47     case 2:
48         cyp_dac_channel = CY_CSDIDAC_B;
49         break;
50     default:
51         RT_ASSERT(0);
52         break;
53     }
54 
55     return cyp_dac_channel;
56 }
57 
58 struct cyp_dac cyp_adc_obj[sizeof(dac_config) / sizeof(dac_config[0])];
59 
60 cy_stc_csdidac_context_t csdidac_context;
61 
62 /*dac device enable*/
cyp_dac_enabled(struct rt_dac_device * device,rt_uint32_t channel)63 static rt_err_t cyp_dac_enabled(struct rt_dac_device *device, rt_uint32_t channel)
64 {
65     cy_rslt_t result;
66 
67     rt_uint32_t cyp_channel;
68 
69     RT_ASSERT(device != RT_NULL);
70 
71     cyhal_dac_t *dac_device;
72 
73     dac_device = device->parent.user_data;
74 
75     /* get current dac channel*/
76     cyp_channel = cyp_dac_get_channel(channel);
77 
78     /*DAC device init*/
79     result = Cy_CSDIDAC_Init(&CSDIDAC_csdidac_config, &csdidac_context);
80 
81     if (result != RT_EOK)
82     {
83         LOG_E("Cy_CSDIDAC_Init fail = %d\n", result);
84         return -RT_ENOSYS;
85     }
86 
87     return RT_EOK;
88 }
89 
90 /*dac device disable*/
cyp_dac_disable(struct rt_dac_device * device,rt_uint32_t channel)91 static rt_err_t cyp_dac_disable(struct rt_dac_device *device, rt_uint32_t channel)
92 {
93     rt_uint32_t cyp_channel;
94 
95     cy_rslt_t result;
96 
97     RT_ASSERT(device != RT_NULL);
98 
99     cyhal_dac_t *dac_device;
100 
101     dac_device = device->parent.user_data;
102 
103     cyp_channel = cyp_dac_get_channel(channel);
104 
105     /*DAC free device*/
106     result = Cy_CSDIDAC_OutputDisable(cyp_channel, &csdidac_context);
107     if (result != RT_EOK)
108     {
109         LOG_E("DAC Outputdisable failed. Error: %d\n", result);
110         return -RT_ENOSYS;
111     }
112     return RT_EOK;
113 }
114 
115 /*set dac output value*/
cyp_adc_convert(struct rt_dac_device * device,rt_uint32_t channel,rt_uint32_t * value)116 static rt_err_t cyp_adc_convert(struct rt_dac_device *device, rt_uint32_t channel, rt_uint32_t *value)
117 {
118     RT_ASSERT(device != RT_NULL);
119 
120     cy_rslt_t result;
121 
122     rt_uint32_t cyp_channel;
123 
124     cyp_channel = cyp_dac_get_channel(channel);
125 
126     result = Cy_CSDIDAC_OutputEnable(cyp_channel, *value, &csdidac_context);
127     if (result != RT_EOK)
128     {
129         LOG_E("DAC  channel initialization failed. Error: %d\n", result);
130         return -RT_ENOSYS;
131     }
132 
133     return RT_EOK;
134 }
135 
136 static const struct rt_dac_ops cyp_dac_ops =
137 {
138     .disabled = cyp_dac_disable,
139     .enabled = cyp_dac_enabled,
140     .convert = cyp_adc_convert,
141 };
142 
143 /*dac device init*/
rt_hw_dac_init(void)144 static int rt_hw_dac_init(void)
145 {
146     int result = RT_EOK;
147 
148     /* save dac name */
149     char name_buf[5] = {'d', 'a', 'c', '0', 0};
150 
151     int i = 0;
152 
153     i = sizeof(dac_config) / sizeof(dac_config[0]);
154 
155     for (i = 0; i < sizeof(dac_config) / sizeof(dac_config[0]); i++)
156     {
157 
158 #ifdef BSP_USING_DAC1
159         name_buf[3] = '1';
160 #endif
161 
162 #ifdef BSP_USING_DAC2
163         name_buf[3] = '2';
164 #endif
165         /* register DAC device */
166         if (rt_hw_dac_register(&cyp_adc_obj[i].cyp_dac_device, name_buf, &cyp_dac_ops, RT_NULL) == RT_EOK)
167         {
168             LOG_E("dac device register success\n");
169         }
170         else
171         {
172             LOG_E("dac device register fail\n");
173             result = -RT_ERROR;
174         }
175     }
176     return result;
177 }
178 
179 INIT_BOARD_EXPORT(rt_hw_dac_init);
180 
181 #endif /* BSP_USING_DAC1 /BSP_USING_DAC2 */
182