1 /*
2 * Copyright (c) 2006-2024 RT-Thread Development Team
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date Author Notes
8 * 2022-07-04 Rbb666 first version
9 */
10 #include "drv_config.h"
11
12 #if defined(BSP_USING_ADC1) || defined(BSP_USING_ADC2)
13
14 /*#define DRV_DEBUG*/
15 #define LOG_TAG "drv.adc"
16 #include <drv_log.h>
17
18 static struct ifx_adc ifx_adc_obj[] =
19 {
20 #ifdef BSP_USING_ADC1
21 ADC1_CONFIG,
22 #endif
23 };
24
ifx_adc_enabled(struct rt_adc_device * device,rt_uint32_t channel,rt_bool_t enabled)25 static rt_err_t ifx_adc_enabled(struct rt_adc_device *device, rt_uint32_t channel, rt_bool_t enabled)
26 {
27 cyhal_adc_channel_t *adc_ch;
28 cy_rslt_t result;
29
30 RT_ASSERT(device != RT_NULL);
31 adc_ch = device->parent.user_data;
32
33 const cyhal_adc_channel_config_t channel_config =
34 {
35 .enable_averaging = false, /* Disable averaging for channel*/
36 .min_acquisition_ns = 1000, /* Minimum acquisition time set to 1us*/
37 .enabled = enabled /* Sample this channel when ADC performs a scan*/
38 };
39
40 if (enabled)
41 {
42 result = cyhal_adc_init(&adc_obj, adc_gpio[channel], NULL);
43
44 if (result != RT_EOK)
45 {
46 LOG_E("ADC initialization failed. Error: %u\n", result);
47 return -RT_ENOSYS;
48 }
49
50 result = cyhal_adc_channel_init_diff(adc_ch, &adc_obj, adc_gpio[channel],
51 CYHAL_ADC_VNEG, &channel_config);
52
53 if (result != RT_EOK)
54 {
55 LOG_E("ADC single ended channel initialization failed. Error: %u\n", result);
56 return -RT_ENOSYS;
57 }
58
59 /* Update ADC configuration */
60 result = cyhal_adc_configure(&adc_obj, &adc_config);
61
62 if (result != RT_EOK)
63 {
64 rt_kprintf("ADC configuration update failed. Error: %u\n", result);
65 return -RT_ENOSYS;
66 }
67 }
68 else
69 {
70 cyhal_adc_channel_free(adc_ch);
71 cyhal_adc_free(&adc_obj);
72 }
73
74 return RT_EOK;
75 }
76
ifx_get_adc_value(struct rt_adc_device * device,rt_uint32_t channel,rt_uint32_t * value)77 static rt_err_t ifx_get_adc_value(struct rt_adc_device *device, rt_uint32_t channel, rt_uint32_t *value)
78 {
79 cyhal_adc_channel_t *adc_ch;
80
81 RT_ASSERT(device != RT_NULL);
82 adc_ch = device->parent.user_data;
83
84 channel = adc_ch->channel_idx;
85
86 *value = cyhal_adc_read(adc_ch);
87
88 return RT_EOK;
89 }
90
91 static const struct rt_adc_ops at_adc_ops =
92 {
93 .enabled = ifx_adc_enabled,
94 .convert = ifx_get_adc_value,
95 };
96
rt_hw_adc_init(void)97 static int rt_hw_adc_init(void)
98 {
99 int result = RT_EOK;
100 int i = 0;
101
102 for (i = 0; i < sizeof(ifx_adc_obj) / sizeof(ifx_adc_obj[0]); i++)
103 {
104 /* register ADC device */
105 if (rt_hw_adc_register(&ifx_adc_obj[i].ifx_adc_device, ifx_adc_obj[i].name, &at_adc_ops, ifx_adc_obj[i].adc_ch) == RT_EOK)
106 {
107 LOG_D("%s register success", ifx_adc_obj[i].name);
108 }
109 else
110 {
111 LOG_E("%s register failed", ifx_adc_obj[i].name);
112 result = -RT_ERROR;
113 }
114 }
115
116 return result;
117 }
118 INIT_BOARD_EXPORT(rt_hw_adc_init);
119
120 #endif /* BSP_USING_ADC */
121