1 /*
2 * Copyright (C) 2021 Alibaba Group Holding Limited
3 */
4
5 #include <errno.h>
6 #include <stdbool.h>
7 #include <aos/adc_core.h>
8 #include <aos/adc_csi.h>
9
adc_csi_unregister(aos_adc_t * adc)10 static void adc_csi_unregister(aos_adc_t *adc)
11 {
12 aos_adc_csi_t *aos_csi_adc = aos_container_of(adc, aos_adc_csi_t, aos_adc);
13
14 csi_adc_uninit(&(aos_csi_adc->csi_adc));
15 }
16
adc_csi_startup(aos_adc_t * adc)17 static aos_status_t adc_csi_startup(aos_adc_t *adc)
18 {
19 aos_adc_csi_t *aos_csi_adc = aos_container_of(adc, aos_adc_csi_t, aos_adc);
20
21 return csi_adc_start(&(aos_csi_adc->csi_adc));
22 }
23
adc_csi_shutdown(aos_adc_t * adc)24 static void adc_csi_shutdown(aos_adc_t *adc)
25 {
26 aos_adc_csi_t *aos_csi_adc = aos_container_of(adc, aos_adc_csi_t, aos_adc);
27
28 (void)csi_adc_stop(&(aos_csi_adc->csi_adc));
29 }
30
adc_csi_read(aos_adc_t * adc,int32_t channel,int32_t * data)31 static aos_status_t adc_csi_read(aos_adc_t *adc, int32_t channel, int32_t *data)
32 {
33 aos_status_t ret;
34 aos_adc_csi_t *aos_csi_adc = aos_container_of(adc, aos_adc_csi_t, aos_adc);
35
36 ret = csi_adc_channel_enable(&(aos_csi_adc->csi_adc), (uint8_t)channel, true);
37 if (ret < 0)
38 return -EIO;
39
40 ret = csi_adc_start(&(aos_csi_adc->csi_adc));
41 if (ret != CSI_OK)
42 return -EIO;
43 *data = csi_adc_read(&(aos_csi_adc->csi_adc));
44 (void)csi_adc_stop(&(aos_csi_adc->csi_adc));
45
46 return 0;
47 }
48
adc_csi_read_voltage(aos_adc_t * adc,int32_t channel,int32_t * data)49 static aos_status_t adc_csi_read_voltage(aos_adc_t *adc, int32_t channel, int32_t *data)
50 {
51 aos_status_t ret;
52 aos_adc_csi_t *aos_csi_adc = aos_container_of(adc, aos_adc_csi_t, aos_adc);
53
54 ret = csi_adc_channel_enable(&(aos_csi_adc->csi_adc), (uint8_t)channel, true);
55 if (ret < 0)
56 return -EIO;
57
58 ret = csi_adc_start(&(aos_csi_adc->csi_adc));
59 if (ret != CSI_OK)
60 return -EIO;
61 *data = csi_adc_read_voltage(&(aos_csi_adc->csi_adc));
62 (void)csi_adc_stop(&(aos_csi_adc->csi_adc));
63
64 return 0;
65 }
66
adc_csi_set_channel(aos_adc_t * adc,int32_t channel,bool enable)67 static aos_status_t adc_csi_set_channel(aos_adc_t *adc, int32_t channel, bool enable)
68 {
69 aos_adc_csi_t *aos_csi_adc = aos_container_of(adc, aos_adc_csi_t, aos_adc);
70
71 return csi_adc_channel_enable(&(aos_csi_adc->csi_adc), (uint8_t)channel, enable);
72 }
73
adc_csi_set_sample_time(aos_adc_t * adc,int32_t channel,uint32_t clock)74 static aos_status_t adc_csi_set_sample_time(aos_adc_t *adc, int32_t channel, uint32_t clock)
75 {
76 aos_adc_csi_t *aos_csi_adc = aos_container_of(adc, aos_adc_csi_t, aos_adc);
77
78 return csi_adc_channel_sampling_time(&(aos_csi_adc->csi_adc), (uint8_t)channel, (uint16_t)clock);
79 }
80
adc_csi_set_mode(aos_adc_t * adc,aos_adc_mode_t mode)81 static aos_status_t adc_csi_set_mode(aos_adc_t *adc, aos_adc_mode_t mode)
82 {
83 bool enable = (mode == AOS_ADC_MODE_CONTINUE);
84 aos_adc_csi_t *aos_csi_adc = aos_container_of(adc, aos_adc_csi_t, aos_adc);
85
86 return csi_adc_continue_mode(&(aos_csi_adc->csi_adc), enable);
87 }
88
adc_csi_get_range(aos_adc_t * adc,int32_t channel,uint32_t * range)89 static aos_status_t adc_csi_get_range(aos_adc_t *adc, int32_t channel, uint32_t *range)
90 {
91 aos_adc_csi_t *aos_csi_adc = aos_container_of(adc, aos_adc_csi_t, aos_adc);
92
93 return csi_adc_get_range(&(aos_csi_adc->csi_adc), (uint8_t)channel, range);
94 }
95
96 static const aos_adc_ops_t adc_csi_ops = {
97 .unregister = adc_csi_unregister,
98 .startup = adc_csi_startup,
99 .shutdown = adc_csi_shutdown,
100 .read = adc_csi_read,
101 .read_voltage = adc_csi_read_voltage,
102 .set_channel = adc_csi_set_channel,
103 .set_sample_time = adc_csi_set_sample_time,
104 .set_mode = adc_csi_set_mode,
105 .get_range = adc_csi_get_range,
106 };
107
aos_adc_csi_register(aos_adc_csi_t * adc_csi)108 aos_status_t aos_adc_csi_register(aos_adc_csi_t *adc_csi)
109 {
110 if (!adc_csi)
111 return -EINVAL;
112
113 adc_csi->aos_adc.ops = &adc_csi_ops;
114
115 return aos_adc_register(&adc_csi->aos_adc);
116 }
117
aos_adc_csi_unregister(uint32_t id)118 aos_status_t aos_adc_csi_unregister(uint32_t id)
119 {
120 return aos_adc_unregister(id);
121 }
122