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  * 2019-04-20     tyustli      the first version.
9  *
10  */
11 #include <rtthread.h>
12 
13 #ifdef BSP_USING_ADC
14 
15 #if !defined(BSP_USING_ADC1) && !defined(BSP_USING_ADC2)
16 #error "Please define at least one BSP_USING_ADCx"
17 #endif
18 
19 #if (defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
20 #error "Please don't define 'FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL'!"
21 #endif
22 
23 #define LOG_TAG             "drv.adc"
24 #include <drv_log.h>
25 #include "drv_adc.h"
26 #include "fsl_adc.h"
27 #include <rtdevice.h>
28 
imxrt_hp_adc_enabled(struct rt_adc_device * device,rt_uint32_t channel,rt_bool_t enabled)29 static rt_err_t imxrt_hp_adc_enabled(struct rt_adc_device *device, rt_uint32_t channel, rt_bool_t enabled)
30 {
31     return RT_EOK;
32 }
33 
imxrt_hp_adc_convert(struct rt_adc_device * device,rt_uint32_t channel,rt_uint32_t * value)34 static rt_err_t imxrt_hp_adc_convert(struct rt_adc_device *device, rt_uint32_t channel, rt_uint32_t *value)
35 {
36     adc_channel_config_t adc_channel;
37     ADC_Type *base;
38     base = (ADC_Type *)(device->parent.user_data);
39 
40     adc_channel.channelNumber = channel;
41     adc_channel.enableInterruptOnConversionCompleted = false;
42 
43     ADC_SetChannelConfig(base, 0, &adc_channel);
44 
45     while (0U == ADC_GetChannelStatusFlags(base, 0))
46     {
47         continue;
48     }
49 
50     *value = ADC_GetChannelConversionValue(base, 0);
51 
52     return RT_EOK;
53 }
54 
55 static struct rt_adc_ops imxrt_adc_ops =
56 {
57     .enabled = imxrt_hp_adc_enabled,
58     .convert = imxrt_hp_adc_convert,
59 };
60 
61 #if defined(BSP_USING_ADC1)
62 
63 static adc_config_t ADC1_config_value;
64 static struct rt_adc_device adc1_device;
65 
66 #endif  /* BSP_USING_ADC1 */
67 
68 #if defined(BSP_USING_ADC2)
69 
70 static adc_config_t ADC2_config_value;
71 static struct rt_adc_device adc2_device;
72 
73 #endif  /* BSP_USING_ADC2 */
74 
rt_hw_adc_init(void)75 int rt_hw_adc_init(void)
76 {
77     int result = RT_EOK;
78 
79 #if defined(BSP_USING_ADC1)
80 
81     ADC_GetDefaultConfig(&ADC1_config_value);
82     ADC_Init(ADC1, &ADC1_config_value);
83 
84 #if !(defined(FSL_FEATURE_ADC_SUPPORT_HARDWARE_TRIGGER_REMOVE) && FSL_FEATURE_ADC_SUPPORT_HARDWARE_TRIGGER_REMOVE)
85     ADC_EnableHardwareTrigger(ADC1, false);
86 #endif
87     ADC_DoAutoCalibration(ADC1);
88 
89     result = rt_hw_adc_register(&adc1_device, "adc1", &imxrt_adc_ops, ADC1);
90 
91     if (result != RT_EOK)
92     {
93         LOG_E("register adc1 device failed error code = %d\n", result);
94     }
95 
96 #endif /* BSP_USING_ADC1 */
97 
98 #if defined(BSP_USING_ADC2)
99 
100     ADC_GetDefaultConfig(&ADC2_config_value);
101     ADC_Init(ADC2, &ADC2_config_value);
102 
103 #if !(defined(FSL_FEATURE_ADC_SUPPORT_HARDWARE_TRIGGER_REMOVE) && FSL_FEATURE_ADC_SUPPORT_HARDWARE_TRIGGER_REMOVE)
104     ADC_EnableHardwareTrigger(ADC2, false);
105 #endif
106     ADC_DoAutoCalibration(ADC2);
107 
108     result = rt_hw_adc_register(&adc2_device, "adc2", &imxrt_adc_ops, ADC2);
109 
110     if (result != RT_EOK)
111     {
112         LOG_E("register adc2 device failed error code = %d\n", result);
113     }
114 
115 #endif /* BSP_USING_ADC2 */
116 
117     return result;
118 }
119 
120 INIT_DEVICE_EXPORT(rt_hw_adc_init);
121 
122 #endif /* BSP_USING_ADC */
123 
124