1 /*
2  * Copyright (c) 2020-2021, Bluetrum Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author            Notes
8  * 2021-02-01     greedyhao         first version
9  */
10 
11 #include "drv_gpio.h"
12 
13 #ifdef BSP_USING_ADC0
14 
15 #include "adc_config.h"
16 
17 // #define DRV_DEBUG
18 #define LOG_TAG             "drv.adc"
19 #include <drv_log.h>
20 
21 struct ab32_adc
22 {
23     struct rt_adc_device ab32_adc_device;
24     hal_sfr_t adc_dat_handle;
25     char *name;
26 };
27 
28 enum
29 {
30 #ifdef BSP_USING_ADC0
31     ADC0_INDEX,
32 #endif
33 
34     ADC_INDEX_END
35 };
36 
37 static struct ab32_adc ab32_adc_obj[] =
38 {
39 #ifdef BSP_USING_ADC0
40     ADC0_CONFIG,
41 #endif
42 };
43 
ab32_adc_enabled(struct rt_adc_device * device,rt_uint32_t channel,rt_bool_t enabled)44 static rt_err_t ab32_adc_enabled(struct rt_adc_device *device, rt_uint32_t channel, rt_bool_t enabled)
45 {
46     RT_ASSERT(device != RT_NULL);
47 
48     hal_adc_enable(enabled);
49 
50     return RT_EOK;
51 }
52 
ab32_adc_get_channel(rt_uint32_t channel)53 static rt_uint32_t ab32_adc_get_channel(rt_uint32_t channel)
54 {
55     rt_uint32_t ab32_channel = 0;
56 
57     switch (channel)
58     {
59     case  0:
60         ab32_channel = ADC_CHANNEL_0;
61         break;
62     case  1:
63         ab32_channel = ADC_CHANNEL_1;
64         break;
65     case  2:
66         ab32_channel = ADC_CHANNEL_2;
67         break;
68     case  3:
69         ab32_channel = ADC_CHANNEL_3;
70         break;
71     case  4:
72         ab32_channel = ADC_CHANNEL_4;
73         break;
74     case  5:
75         ab32_channel = ADC_CHANNEL_5;
76         break;
77     case  6:
78         ab32_channel = ADC_CHANNEL_6;
79         break;
80     case  7:
81         ab32_channel = ADC_CHANNEL_7;
82         break;
83     case  8:
84         ab32_channel = ADC_CHANNEL_8;
85         break;
86     case  9:
87         ab32_channel = ADC_CHANNEL_9;
88         break;
89     case 10:
90         ab32_channel = ADC_CHANNEL_10;
91         break;
92     case 11:
93         ab32_channel = ADC_CHANNEL_11;
94         break;
95     case 12:
96         ab32_channel = ADC_CHANNEL_12;
97         break;
98     case 13:
99         ab32_channel = ADC_CHANNEL_13;
100         break;
101     case 14:
102         ab32_channel = ADC_CHANNEL_14;
103         break;
104     case 15:
105         ab32_channel = ADC_CHANNEL_15;
106         break;
107     }
108 
109     return ab32_channel;
110 }
111 
ab32_get_adc_value(struct rt_adc_device * device,rt_uint32_t channel,rt_uint32_t * value)112 static rt_err_t ab32_get_adc_value(struct rt_adc_device *device, rt_uint32_t channel, rt_uint32_t *value)
113 {
114     hal_sfr_t ab32_adc_handler;
115 
116     RT_ASSERT(device != RT_NULL);
117     RT_ASSERT(value != RT_NULL);
118 
119     ab32_adc_handler = device->parent.user_data;
120 
121     hal_adc_start(ab32_adc_get_channel(channel));
122     hal_adc_poll_for_conversion(1000);
123 
124     *value = ab32_adc_handler[channel];
125 
126     return RT_EOK;
127 }
128 
129 static const struct rt_adc_ops _adc_ops =
130 {
131     .enabled = ab32_adc_enabled,
132     .convert = ab32_get_adc_value,
133 };
134 
ab32_adc_init(void)135 static int ab32_adc_init(void)
136 {
137     int result = RT_EOK;
138     int i = 0;
139 
140     if (ADC_INDEX_END == 0) {
141         return result;
142     }
143 
144     CLKCON0 |= BIT(28); // enable adc clock
145 
146     for (i = 0; i < sizeof(ab32_adc_obj) / sizeof(ab32_adc_obj[0]); i++) {
147         if (rt_hw_adc_register(&ab32_adc_obj[i].ab32_adc_device, ab32_adc_obj[i].name, &_adc_ops, (const void *)ab32_adc_obj[i].adc_dat_handle) == RT_EOK)
148         {
149             LOG_D("%s init success", ab32_adc_obj[i].name);
150         }
151         else
152         {
153             LOG_E("%s register failed", ab32_adc_obj[i].name);
154             result = -RT_ERROR;
155         }
156     }
157 
158     return result;
159 }
160 INIT_BOARD_EXPORT(ab32_adc_init);
161 
162 #endif
163 
164