1 /*
2 * Copyright (c) 2006-2022, RT-Thread Development Team
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date Author Notes
8 * 2022-10-19 Nations first version
9 */
10 #include "drv_adc.h"
11
12 #ifdef RT_USING_ADC
13
14 #if defined(BSP_USING_ADC) || defined(BSP_USING_ADC1) || \
15 defined(BSP_USING_ADC2) || defined(BSP_USING_ADC3) || \
16 defined(BSP_USING_ADC4)
17
18 static struct n32_adc_config adc_config[] =
19 {
20 #if defined(SOC_N32L43X) || defined(SOC_N32L40X) || defined(SOC_N32G43X)
21 #ifdef BSP_USING_ADC
22 {
23 "adc",
24 ADC,
25 },
26 #endif
27 #endif
28
29 #ifdef BSP_USING_ADC1
30 {
31 "adc1",
32 ADC1,
33 },
34 #endif
35
36 #ifdef BSP_USING_ADC2
37 {
38 "adc2",
39 ADC2,
40 },
41 #endif
42
43 #ifdef BSP_USING_ADC3
44 {
45 "adc3",
46 ADC3,
47 },
48 #endif
49
50 #ifdef BSP_USING_ADC4
51 {
52 "adc4",
53 ADC4,
54 },
55 #endif
56 };
57
58 static struct n32_adc adc_obj[sizeof(adc_config) / sizeof(adc_config[0])] = {0};
59
n32_adc_init(struct n32_adc_config * config)60 static void n32_adc_init(struct n32_adc_config *config)
61 {
62 ADC_InitType ADC_InitStructure;
63
64 ADC_DeInit((ADC_Module*)config->adc_periph);
65
66 /* ADC configuration */
67 #if defined(SOC_N32G45X) || defined(SOC_N32WB452) || defined(SOC_N32G4FR)
68 ADC_InitStructure.WorkMode = ADC_WORKMODE_INDEPENDENT;
69 #endif
70
71 ADC_InitStructure.MultiChEn = DISABLE;
72 ADC_InitStructure.ContinueConvEn = DISABLE;
73 ADC_InitStructure.ExtTrigSelect = ADC_EXT_TRIGCONV_NONE;
74 ADC_InitStructure.DatAlign = ADC_DAT_ALIGN_R;
75 ADC_InitStructure.ChsNumber = 1;
76 ADC_Init((ADC_Module*)config->adc_periph, &ADC_InitStructure);
77
78 /* Enable ADC */
79 ADC_Enable((ADC_Module*)config->adc_periph, ENABLE);
80
81 /* Check ADC Ready */
82 while (ADC_GetFlagStatusNew((ADC_Module*)config->adc_periph, ADC_FLAG_RDY) == RESET);
83
84 /* Start ADC calibration */
85 ADC_StartCalibration((ADC_Module*)config->adc_periph);
86
87 /* Check the end of ADC calibration */
88 while (ADC_GetCalibrationStatus((ADC_Module*)config->adc_periph));
89 }
90
n32_adc_enabled(struct rt_adc_device * device,rt_uint32_t channel,rt_bool_t enabled)91 static rt_err_t n32_adc_enabled(struct rt_adc_device *device, rt_uint32_t channel, rt_bool_t enabled)
92 {
93 if (channel > ADC_CH_18)
94 {
95 return -RT_EINVAL;
96 }
97 return RT_EOK;
98 }
99
n32_adc_convert(struct rt_adc_device * device,rt_uint32_t channel,rt_uint32_t * value)100 static rt_err_t n32_adc_convert(struct rt_adc_device *device, rt_uint32_t channel, rt_uint32_t *value)
101 {
102 struct n32_adc_config *config;
103 RT_ASSERT(device != RT_NULL);
104
105 if (channel > ADC_CH_18)
106 {
107 return -RT_EINVAL;
108 }
109 config = (struct n32_adc_config *)(device->parent.user_data);
110
111 ADC_ConfigRegularChannel((ADC_Module*)config->adc_periph, channel, 1, ADC_SAMP_TIME_239CYCLES5);
112
113 /* Start ADC Software Conversion */
114 ADC_EnableSoftwareStartConv((ADC_Module*)config->adc_periph, ENABLE);
115
116 while (ADC_GetFlagStatus((ADC_Module*)config->adc_periph, ADC_FLAG_ENDC)==0)
117 {
118 }
119
120 ADC_ClearFlag((ADC_Module*)config->adc_periph, ADC_FLAG_ENDC);
121 ADC_ClearFlag((ADC_Module*)config->adc_periph, ADC_FLAG_STR);
122 *value = ADC_GetDat((ADC_Module*)config->adc_periph);
123
124 return RT_EOK;
125 }
126
127 static struct rt_adc_ops n32_adc_ops =
128 {
129 .enabled = n32_adc_enabled,
130 .convert = n32_adc_convert,
131 };
132
rt_hw_adc_init(void)133 int rt_hw_adc_init(void)
134 {
135 GPIO_InitType GPIO_InitStructure;
136
137 int i = 0;
138 int result = RT_EOK;
139
140 #if defined(SOC_N32L43X) || defined(SOC_N32L40X) || defined(SOC_N32G43X) || defined(SOC_N32G4FR)
141 #ifdef BSP_USING_ADC
142 RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOA, ENABLE);
143 RCC_EnableAHBPeriphClk(RCC_AHB_PERIPH_ADC, ENABLE);
144
145 GPIO_InitStruct(&GPIO_InitStructure);
146 /* Configure PA.01 PA.02 as analog input */
147 GPIO_InitStructure.Pin = GPIO_PIN_1 | GPIO_PIN_2;
148 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Analog;
149 GPIO_InitPeripheral(GPIOA, &GPIO_InitStructure);
150 #endif
151 #endif
152
153 #ifdef BSP_USING_ADC1
154 RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOA, ENABLE);
155 RCC_EnableAHBPeriphClk(RCC_AHB_PERIPH_ADC1, ENABLE);
156
157 GPIO_InitStruct(&GPIO_InitStructure);
158 /* Configure PA.01 PA.03 as analog input */
159 GPIO_InitStructure.Pin = GPIO_PIN_1 | GPIO_PIN_3;
160 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
161 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
162 GPIO_InitPeripheral(GPIOA, &GPIO_InitStructure);
163 #endif /* BSP_USING_ADC1 */
164
165 #ifdef BSP_USING_ADC2
166 RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOA, ENABLE);
167 RCC_EnableAHBPeriphClk(RCC_AHB_PERIPH_ADC2, ENABLE);
168
169 GPIO_InitStruct(&GPIO_InitStructure);
170 /* Configure PA.04 PA.05 as analog input */
171 GPIO_InitStructure.Pin = GPIO_PIN_4 | GPIO_PIN_5;
172 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
173 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
174 GPIO_InitPeripheral(GPIOA, &GPIO_InitStructure);
175 #endif /* BSP_USING_ADC2 */
176
177 #ifdef BSP_USING_ADC3
178 RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOB, ENABLE);
179 RCC_EnableAHBPeriphClk(RCC_AHB_PERIPH_ADC3, ENABLE);
180
181 GPIO_InitStruct(&GPIO_InitStructure);
182 /* Configure PB.11 PB.13 as analog input */
183 GPIO_InitStructure.Pin = GPIO_PIN_11 | GPIO_PIN_13;
184 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
185 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
186 GPIO_InitPeripheral(GPIOB, &GPIO_InitStructure);
187 #endif /* BSP_USING_ADC3 */
188
189 #ifdef BSP_USING_ADC4
190 RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOB, ENABLE);
191 RCC_EnableAHBPeriphClk(RCC_AHB_PERIPH_ADC4, ENABLE);
192
193 GPIO_InitStruct(&GPIO_InitStructure);
194 /* Configure PB.14 PB.15 as analog input */
195 GPIO_InitStructure.Pin = GPIO_PIN_14 | GPIO_PIN_15;
196 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
197 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
198 GPIO_InitPeripheral(GPIOB, &GPIO_InitStructure);
199 #endif /* BSP_USING_ADC4 */
200
201 /* RCC_ADCHCLK_DIV16*/
202 ADC_ConfigClk(ADC_CTRL3_CKMOD_AHB, RCC_ADCHCLK_DIV16);
203 /* Selsect HSE as RCC ADC1M CLK Source */
204 RCC_ConfigAdc1mClk(RCC_ADC1MCLK_SRC_HSE, RCC_ADC1MCLK_DIV8);
205
206 for (i = 0; i < sizeof(adc_obj) / sizeof(adc_obj[0]); i++)
207 {
208 adc_obj[i].config = &adc_config[i];
209 n32_adc_init(&adc_config[i]);
210 rt_hw_adc_register(&adc_obj[i].adc_device, \
211 adc_obj[i].config->name, &n32_adc_ops, adc_obj[i].config);
212 }
213 return result;
214 }
215 INIT_DEVICE_EXPORT(rt_hw_adc_init);
216
217 #endif /* defined(BSP_USING_ADC1) || defined(BSP_USING_ADC2) || defined(BSP_USING_ADC3) || defined(BSP_USING_ADC4) */
218 #endif /* RT_USING_ADC */
219
220