1 /*
2  * Copyright (c) 2006-2021, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  * 2022-05-16     shelton      first version
9  * 2023-01-31     shelton      add support f421/f425
10  * 2023-04-08     shelton      add support f423
11  * 2023-10-18     shelton      add support f402/f405
12  * 2024-04-12     shelton      add support a403a and a423
13  * 2024-08-30     shelton      add support m412 and m416
14  * 2024-12-18     shelton      add support f455/f456 and f457
15  */
16 
17 #include "drv_common.h"
18 #include "drv_adc.h"
19 
20 #if defined(BSP_USING_ADC1) || defined(BSP_USING_ADC2) || \
21     defined(BSP_USING_ADC3)
22 
23 //#define DRV_DEBUG
24 #define LOG_TAG             "drv.adc"
25 #include <drv_log.h>
26 
27 struct at32_adc
28 {
29     struct rt_adc_device at32_adc_device;
30     adc_type *adc_x;
31     char *name;
32 };
33 
34 static struct at32_adc at32_adc_obj[] =
35 {
36 #ifdef BSP_USING_ADC1
37     ADC1_CONFIG,
38 #endif
39 
40 #ifdef BSP_USING_ADC2
41     ADC2_CONFIG,
42 #endif
43 
44 #ifdef BSP_USING_ADC3
45     ADC3_CONFIG,
46 #endif
47 };
48 
at32_adc_enabled(struct rt_adc_device * device,rt_int8_t channel,rt_bool_t enabled)49 static rt_err_t at32_adc_enabled(struct rt_adc_device *device, rt_int8_t channel, rt_bool_t enabled)
50 {
51     adc_type *adc_x;
52     adc_base_config_type adc_config_struct;
53 #if defined (SOC_SERIES_AT32F435) || defined (SOC_SERIES_AT32F437) || \
54     defined (SOC_SERIES_AT32F423) || defined (SOC_SERIES_AT32A423) || \
55     defined (SOC_SERIES_AT32M412) || defined (SOC_SERIES_AT32M416) || \
56     defined (SOC_SERIES_AT32F455) || defined (SOC_SERIES_AT32F456) || \
57     defined (SOC_SERIES_AT32F457)
58     adc_common_config_type adc_common_struct;
59     adc_common_default_para_init(&adc_common_struct);
60 #endif
61 
62     RT_ASSERT(device != RT_NULL);
63     adc_x = device->parent.user_data;
64 
65     at32_msp_adc_init(adc_x);
66 
67 #if defined (SOC_SERIES_AT32F435) || defined (SOC_SERIES_AT32F437) || \
68     defined (SOC_SERIES_AT32M412) || defined (SOC_SERIES_AT32M416) || \
69     defined (SOC_SERIES_AT32F455) || defined (SOC_SERIES_AT32F456) || \
70     defined (SOC_SERIES_AT32F457)
71     /* config combine mode */
72     adc_common_struct.combine_mode = ADC_INDEPENDENT_MODE;
73     /* config division, adcclk is division by hclk */
74     adc_common_struct.div = ADC_HCLK_DIV_4;
75     /* config common dma mode,it's not useful in independent mode */
76     adc_common_struct.common_dma_mode = ADC_COMMON_DMAMODE_DISABLE;
77     /* config common dma request repeat */
78     adc_common_struct.common_dma_request_repeat_state = FALSE;
79     /* config adjacent adc sampling interval,it's useful for ordinary shifting mode */
80     adc_common_struct.sampling_interval = ADC_SAMPLING_INTERVAL_5CYCLES;
81     /* config inner temperature sensor and vintrv */
82     adc_common_struct.tempervintrv_state = FALSE;
83     /* config voltage battery */
84 #if defined (SOC_SERIES_AT32F435) || defined (SOC_SERIES_AT32F437) || \
85     defined (SOC_SERIES_AT32F455) || defined (SOC_SERIES_AT32F456) || \
86     defined (SOC_SERIES_AT32F457)
87     adc_common_struct.vbat_state = FALSE;
88 #endif
89     adc_common_config(&adc_common_struct);
90 #elif defined (SOC_SERIES_AT32F423) || defined (SOC_SERIES_AT32A423)
91     /* config division, adcclk is division by hclk */
92     adc_common_struct.div = ADC_HCLK_DIV_4;
93     /* config inner temperature sensor and vintrv */
94     adc_common_struct.tempervintrv_state = FALSE;
95     adc_common_config(&adc_common_struct);
96 #else
97 #if !defined (SOC_SERIES_AT32F415) && !defined (SOC_SERIES_AT32F421) && \
98     !defined (SOC_SERIES_AT32F425) && !defined (SOC_SERIES_AT32F402) && \
99     !defined (SOC_SERIES_AT32F405)
100     adc_combine_mode_select(ADC_INDEPENDENT_MODE);
101 #endif
102     adc_ordinary_conversion_trigger_set(adc_x, ADC12_ORDINARY_TRIG_SOFTWARE, TRUE);
103 #endif
104 
105     /* adc_x configuration */
106     adc_base_default_para_init(&adc_config_struct);
107     adc_config_struct.data_align = ADC_RIGHT_ALIGNMENT;
108     adc_config_struct.ordinary_channel_length = 1;
109     adc_config_struct.repeat_mode = FALSE;
110     adc_config_struct.sequence_mode = FALSE;
111     adc_base_config(adc_x, &adc_config_struct);
112 
113     if (!enabled)
114     {
115         /* disable adc_x */
116         adc_enable(adc_x, FALSE);
117     }
118     else
119     {
120         /* enable adc_x */
121         adc_enable(adc_x, TRUE);
122 
123         /* enable adc_x calibration */
124         adc_calibration_init(adc_x);
125         /* check the end of adc_x reset calibration register */
126         while(adc_calibration_init_status_get(adc_x) == SET)
127         {
128         }
129         /* start adc_x calibration */
130          adc_calibration_start(adc_x);
131         /* check the end of adc_x calibration */
132         while(adc_calibration_status_get(adc_x) == SET)
133         {
134         }
135     }
136 
137     return RT_EOK;
138 }
139 
at32_get_adc_value(struct rt_adc_device * device,rt_int8_t channel,rt_uint32_t * value)140 static rt_err_t at32_get_adc_value(struct rt_adc_device *device, rt_int8_t channel, rt_uint32_t *value)
141 {
142     adc_type *adc_x;
143     rt_uint32_t timeout = 0;
144 
145     RT_ASSERT(device != RT_NULL);
146     adc_x = device->parent.user_data;
147 
148     /* adc_x regular channels configuration */
149 #if defined (SOC_SERIES_AT32F435) || defined (SOC_SERIES_AT32F437) || \
150     defined (SOC_SERIES_AT32F423) || defined (SOC_SERIES_AT32A423) || \
151     defined (SOC_SERIES_AT32F455) || defined (SOC_SERIES_AT32F456) || \
152     defined (SOC_SERIES_AT32F457)
153     adc_flag_clear(adc_x, ADC_OCCE_FLAG);
154     adc_ordinary_channel_set(adc_x, (adc_channel_select_type)channel, 1, ADC_SAMPLETIME_247_5);
155 #else
156 #if defined (SOC_SERIES_AT32M412) || defined (SOC_SERIES_AT32M416)
157     adc_flag_clear(adc_x, ADC_OCCE_FLAG);
158 #else
159     adc_flag_clear(adc_x, ADC_CCE_FLAG);
160 #endif
161     adc_ordinary_channel_set(adc_x, (adc_channel_select_type)channel, 1, ADC_SAMPLETIME_239_5);
162 #endif
163 
164     /* start adc_x software conversion */
165     adc_ordinary_software_trigger_enable(adc_x, TRUE);
166 
167     /* wait for the adc to convert */
168 #if defined (SOC_SERIES_AT32F435) || defined (SOC_SERIES_AT32F437) || \
169     defined (SOC_SERIES_AT32F423) || defined (SOC_SERIES_AT32A423) || \
170     defined (SOC_SERIES_AT32M412) || defined (SOC_SERIES_AT32M416) || \
171     defined (SOC_SERIES_AT32F455) || defined (SOC_SERIES_AT32F456) || \
172     defined (SOC_SERIES_AT32F457)
173     while((adc_flag_get(adc_x, ADC_OCCE_FLAG) == RESET) && timeout < 0xFFFF)
174 #else
175     while((adc_flag_get(adc_x, ADC_CCE_FLAG) == RESET) && timeout < 0xFFFF)
176 #endif
177     {
178         timeout ++;
179     }
180 
181     if(timeout >= 0xFFFF)
182     {
183         LOG_D("channel%d converts timeout, please confirm adc_x enabled or not", channel);
184     }
185 
186     /* get adc value */
187     *value = adc_ordinary_conversion_data_get(adc_x);
188 
189     return RT_EOK;
190 }
191 
192 static const struct rt_adc_ops at_adc_ops =
193 {
194     .enabled = at32_adc_enabled,
195     .convert = at32_get_adc_value,
196 };
197 
rt_hw_adc_init(void)198 static int rt_hw_adc_init(void)
199 {
200     int result = RT_EOK;
201     int i = 0;
202 
203     for (i = 0; i < sizeof(at32_adc_obj) / sizeof(at32_adc_obj[0]); i++)
204     {
205         /* register ADC device */
206         if (rt_hw_adc_register(&at32_adc_obj[i].at32_adc_device, at32_adc_obj[i].name, &at_adc_ops, at32_adc_obj[i].adc_x) == RT_EOK)
207         {
208             LOG_D("%s register success", at32_adc_obj[i].name);
209         }
210         else
211         {
212             LOG_E("%s register failed", at32_adc_obj[i].name);
213             result = -RT_ERROR;
214         }
215 
216     }
217 
218     return result;
219 }
220 INIT_BOARD_EXPORT(rt_hw_adc_init);
221 
222 #endif /* BSP_USING_ADC */
223