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-08-20     breo.com     first version
9  */
10 
11 #include <board.h>
12 #include "drv_adc.h"
13 
14 #if defined(BSP_USING_ADC1) || defined(BSP_USING_ADC2) || defined(BSP_USING_ADC3)
15 #define DRV_DEBUG
16 #define LOG_TAG             "drv.adc"
17 #include <drv_log.h>
18 
19 struct n32_adc
20 {
21     struct rt_adc_device n32_adc_device;
22     ADC_Module *ADC_Handler;
23     char *name;
24 };
25 
26 static struct n32_adc n32_adc_obj[] =
27 {
28 #ifdef BSP_USING_ADC1
29     ADC1_CONFIG,
30 #endif
31 
32 #ifdef BSP_USING_ADC2
33     ADC2_CONFIG,
34 #endif
35 
36 #ifdef BSP_USING_ADC3
37     ADC3_CONFIG,
38 #endif
39 };
40 
n32_adc_get_channel(rt_uint32_t channel)41 static rt_uint32_t n32_adc_get_channel(rt_uint32_t channel)
42 {
43     rt_uint32_t n32_channel = 0;
44 
45     switch (channel)
46     {
47     case  0:
48         n32_channel = ADC_CH_0;
49         break;
50     case  1:
51         n32_channel = ADC_CH_1;
52         break;
53     case  2:
54         n32_channel = ADC_CH_2;
55         break;
56     case  3:
57         n32_channel = ADC_CH_3;
58         break;
59     case  4:
60         n32_channel = ADC_CH_4;
61         break;
62     case  5:
63         n32_channel = ADC_CH_5;
64         break;
65     case  6:
66         n32_channel = ADC_CH_6;
67         break;
68     case  7:
69         n32_channel = ADC_CH_7;
70         break;
71     case  8:
72         n32_channel = ADC_CH_8;
73         break;
74     case  9:
75         n32_channel = ADC_CH_9;
76         break;
77     case 10:
78         n32_channel = ADC_CH_10;
79         break;
80     case 11:
81         n32_channel = ADC_CH_11;
82         break;
83     case 12:
84         n32_channel = ADC_CH_12;
85         break;
86     case 13:
87         n32_channel = ADC_CH_13;
88         break;
89     case 14:
90         n32_channel = ADC_CH_14;
91         break;
92     case 15:
93         n32_channel = ADC_CH_15;
94         break;
95     case 16:
96         n32_channel = ADC_CH_16;
97         break;
98     case 17:
99         n32_channel = ADC_CH_17;
100         break;
101     case 18:
102         n32_channel = ADC_CH_18;
103         break;
104     }
105 
106     return n32_channel;
107 }
108 
n32_adc_enabled(struct rt_adc_device * device,rt_uint32_t channel,rt_bool_t enabled)109 static rt_err_t n32_adc_enabled(struct rt_adc_device *device, rt_uint32_t channel, rt_bool_t enabled)
110 {
111     ADC_Module *n32_adc_handler;
112     ADC_InitType ADC_InitStructure;
113     RT_ASSERT(device != RT_NULL);
114     n32_adc_handler = device->parent.user_data;
115 
116     n32_msp_adc_init(n32_adc_handler);
117 
118     ADC_InitStruct(&ADC_InitStructure);
119     ADC_InitStructure.WorkMode              = ADC_WORKMODE_INDEPENDENT;
120     ADC_InitStructure.MultiChEn             = DISABLE;
121     ADC_InitStructure.ContinueConvEn        = DISABLE;
122     ADC_InitStructure.ExtTrigSelect         = ADC_EXT_TRIGCONV_NONE;
123     ADC_InitStructure.DatAlign              = ADC_DAT_ALIGN_R;
124     ADC_InitStructure.ChsNumber             = 1;
125     ADC_Init(n32_adc_handler, &ADC_InitStructure);
126 
127     if (((n32_adc_handler == ADC1) || (n32_adc_handler == ADC2))
128         && ((n32_adc_get_channel(channel) == ADC_CH_16)
129             || (n32_adc_get_channel(channel) == ADC_CH_18)))
130     {
131         ADC_EnableTempSensorVrefint(ENABLE);
132     }
133 
134     if (enabled)
135     {
136         /* Enable ADC1 */
137         ADC_Enable(n32_adc_handler, ENABLE);
138         /*Check ADC Ready*/
139         while (ADC_GetFlagStatusNew(n32_adc_handler, ADC_FLAG_RDY) == RESET);
140         /* Start ADCx calibration */
141         ADC_StartCalibration(n32_adc_handler);
142         /* Check the end of ADCx calibration */
143         while (ADC_GetCalibrationStatus(n32_adc_handler));
144     }
145     else
146     {
147         /* Enable ADCx */
148         ADC_Enable(n32_adc_handler, DISABLE);
149     }
150 
151     return RT_EOK;
152 }
153 
n32_get_adc_value(struct rt_adc_device * device,rt_uint32_t channel,rt_uint32_t * value)154 static rt_err_t n32_get_adc_value(struct rt_adc_device *device, rt_uint32_t channel, rt_uint32_t *value)
155 {
156     ADC_Module *n32_adc_handler;
157 
158     RT_ASSERT(device != RT_NULL);
159     RT_ASSERT(value != RT_NULL);
160 
161     n32_adc_handler = device->parent.user_data;
162 
163     /* ADCx regular channels configuration */
164     ADC_ConfigRegularChannel(n32_adc_handler, n32_adc_get_channel(channel), 1, ADC_SAMP_TIME_28CYCLES5);
165 
166     /* Start ADCx Software Conversion */
167     ADC_EnableSoftwareStartConv(n32_adc_handler, ENABLE);
168 
169     /* Wait for the ADC to convert */
170     while (ADC_GetFlagStatus(n32_adc_handler, ADC_FLAG_ENDC) == RESET);
171 
172     ADC_ClearFlag(n32_adc_handler, ADC_FLAG_ENDC);
173 
174     /* get ADC value */
175     *value = ADC_GetDat(n32_adc_handler);
176 
177     return RT_EOK;
178 }
179 
180 static const struct rt_adc_ops at_adc_ops =
181 {
182     .enabled = n32_adc_enabled,
183     .convert = n32_get_adc_value,
184 };
185 
rt_hw_adc_init(void)186 static int rt_hw_adc_init(void)
187 {
188     int result = RT_EOK;
189     int i = 0;
190 
191     for (i = 0; i < sizeof(n32_adc_obj) / sizeof(n32_adc_obj[0]); i++)
192     {
193         /* register ADC device */
194         if (rt_hw_adc_register(&n32_adc_obj[i].n32_adc_device,
195                                n32_adc_obj[i].name, &at_adc_ops,
196                                n32_adc_obj[i].ADC_Handler) == RT_EOK)
197         {
198             LOG_D("%s register success", n32_adc_obj[i].name);
199         }
200         else
201         {
202             LOG_E("%s register failed", n32_adc_obj[i].name);
203             result = -RT_ERROR;
204         }
205     }
206 
207     return result;
208 }
209 INIT_BOARD_EXPORT(rt_hw_adc_init);
210 
211 #endif /* BSP_USING_ADC */
212 
213