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_LPADC
14 
15 #if !defined(BSP_USING_LPADC1) && !defined(BSP_USING_LPADC2)
16 #error "Please define at least one BSP_USING_LPADCx"
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.lpadc"
24 #include <drv_log.h>
25 #include "drv_lpadc.h"
26 #include "fsl_lpadc.h"
27 #include <rtdevice.h>
28 
29 lpadc_config_t mLpadcConfigStruct;
30 
31 #if defined(BSP_USING_LPADC1)
32 static struct rt_adc_device lpadc1_device;
33 #endif
34 
35 #if defined(BSP_USING_LPADC2)
36 static struct rt_adc_device lpadc2_device;
37 #endif
38 
39 #if (defined(DEMO_LPADC_USE_HIGH_RESOLUTION) && DEMO_LPADC_USE_HIGH_RESOLUTION)
40 uint32_t g_LpadcResultShift = 0U;
41 #else
42 uint32_t g_LpadcResultShift = 3U;
43 #endif /* DEMO_LPADC_USE_HIGH_RESOLUTION */
44 
imxrt_hp_adc_enabled(struct rt_adc_device * device,rt_uint32_t channel,rt_bool_t enabled)45 static rt_err_t imxrt_hp_adc_enabled(struct rt_adc_device *device, rt_uint32_t channel, rt_bool_t enabled)
46 {
47     return RT_EOK;
48 }
49 
imxrt_hp_adc_convert(struct rt_adc_device * device,rt_uint32_t channel,rt_uint32_t * value)50 static rt_err_t imxrt_hp_adc_convert(struct rt_adc_device *device, rt_uint32_t channel, rt_uint32_t *value)
51 {
52     LPADC1_BASE *base;
53     lpadc_conv_command_config_t mLpadcCommandConfigStruct;
54     lpadc_conv_trigger_config_t mLpadcTriggerConfigStruct;
55     lpadc_conv_result_t mLpadcResultConfigStruct;
56     base = (LPADC1_BASE *)(device->parent.user_data);
57 
58     //ADC_SetChannelConfig(base, 0, &adc_channel);
59     LPADC_GetDefaultConvCommandConfig(&mLpadcCommandConfigStruct);
60     mLpadcCommandConfigStruct.channelNumber = channel;
61 #if defined(DEMO_LPADC_USE_HIGH_RESOLUTION) && DEMO_LPADC_USE_HIGH_RESOLUTION
62     mLpadcCommandConfigStruct.conversionResolutionMode = kLPADC_ConversionResolutionHigh;
63 #endif /* DEMO_LPADC_USE_HIGH_RESOLUTION */
64     LPADC_SetConvCommandConfig(base, 1U, &mLpadcCommandConfigStruct);
65 
66     /* Set trigger configuration. */
67     LPADC_GetDefaultConvTriggerConfig(&mLpadcTriggerConfigStruct);
68     mLpadcTriggerConfigStruct.targetCommandId       = 1U;
69     mLpadcTriggerConfigStruct.enableHardwareTrigger = false;
70     LPADC_SetConvTriggerConfig(base, 0U, &mLpadcTriggerConfigStruct); /* Configurate the trigger0. */
71 
72     LPADC_DoSoftwareTrigger(base, 1U);
73 
74 #if (defined(FSL_FEATURE_LPADC_FIFO_COUNT) && (FSL_FEATURE_LPADC_FIFO_COUNT == 2U))
75     while (!LPADC_GetConvResult(base, &mLpadcResultConfigStruct, 0U))
76 #else
77     while (!LPADC_GetConvResult(base, &mLpadcResultConfigStruct))
78 #endif /* FSL_FEATURE_LPADC_FIFO_COUNT */
79     {
80     }
81     *value = (mLpadcResultConfigStruct.convValue) >> g_LpadcResultShift;
82 
83     return RT_EOK;
84 }
85 
86 static struct rt_adc_ops imxrt_lpadc_ops =
87 {
88     .enabled = imxrt_hp_adc_enabled,
89     .convert = imxrt_hp_adc_convert,
90 };
91 
rt_hw_adc_init(void)92 int rt_hw_adc_init(void)
93 {
94     int result = RT_EOK;
95 
96     LPADC_GetDefaultConfig(&mLpadcConfigStruct);
97     mLpadcConfigStruct.enableAnalogPreliminary = true;
98 #if defined(kLPADC_ReferenceVoltageAlt1)
99     mLpadcConfigStruct.referenceVoltageSource = kLPADC_ReferenceVoltageAlt1;
100 #endif /* DEMO_LPADC_VREF_SOURCE */
101 #if defined(BSP_USING_LPADC1)
102     LPADC_Init(LPADC1, &mLpadcConfigStruct);
103     result = rt_hw_adc_register(&lpadc1_device, "lpadc1", &imxrt_lpadc_ops, LPADC1);
104     if (result != RT_EOK)
105     {
106         LOG_E("register lpadc1 device failed error code = %d\n", result);
107     }
108 #endif
109 #if defined(BSP_USING_LPADC2)
110     LPADC_Init(LPADC1, &mLpadcConfigStruct);
111     result = rt_hw_adc_register(&lpadc2_device, "lpadc2", &imxrt_lpadc_ops, LPADC2);
112     if (result != RT_EOK)
113     {
114         LOG_E("register lpadc2 device failed error code = %d\n", result);
115     }
116 #endif
117     return result;
118 }
119 
120 INIT_DEVICE_EXPORT(rt_hw_adc_init);
121 
122 #endif /* BSP_USING_LPADC */
123 
124