1 /******************************************************************************
2  *
3  * Copyright (C) 2022-2023 Maxim Integrated Products, Inc. (now owned by
4  * Analog Devices, Inc.),
5  * Copyright (C) 2023-2024 Analog Devices, Inc.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *     http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  ******************************************************************************/
20 #include <stdio.h>
21 #include "adc.h"
22 #include "adc_regs.h"
23 #include "adc_reva.h"
24 #include "mxc_device.h"
25 #include "mxc_errors.h"
26 #include "mxc_assert.h"
27 #include "mxc_sys.h"
28 #include "mcr_regs.h"
29 #include "mxc_lock.h"
30 #include "mxc_pins.h"
31 
initGPIOForChannel(mxc_adc_chsel_t channel)32 static void initGPIOForChannel(mxc_adc_chsel_t channel)
33 {
34     switch (channel) {
35     case MXC_ADC_CH_0:
36         MXC_GPIO_Config(&gpio_cfg_adc_ain0);
37         break;
38 
39     case MXC_ADC_CH_1:
40         MXC_GPIO_Config(&gpio_cfg_adc_ain1);
41         break;
42 
43     case MXC_ADC_CH_2:
44         MXC_GPIO_Config(&gpio_cfg_adc_ain2);
45         break;
46 
47     case MXC_ADC_CH_3:
48         MXC_GPIO_Config(&gpio_cfg_adc_ain3);
49         break;
50 
51     case MXC_ADC_CH_4:
52         MXC_GPIO_Config(&gpio_cfg_adc_ain4);
53         break;
54 
55     case MXC_ADC_CH_5:
56         MXC_GPIO_Config(&gpio_cfg_adc_ain5);
57         break;
58 
59     case MXC_ADC_CH_6:
60         MXC_GPIO_Config(&gpio_cfg_adc_ain6);
61         break;
62 
63     case MXC_ADC_CH_7:
64         MXC_GPIO_Config(&gpio_cfg_adc_ain7);
65         break;
66 
67     default:
68         break;
69     }
70 }
71 
MXC_ADC_Init(void)72 int MXC_ADC_Init(void)
73 {
74 #ifndef MSDK_NO_GPIO_CLK_INIT
75     MXC_SYS_Reset_Periph(MXC_SYS_RESET0_ADC);
76 
77     MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_ADC);
78 #endif
79 
80     return MXC_ADC_RevA_Init((mxc_adc_reva_regs_t *)MXC_ADC);
81 }
82 
MXC_ADC_Shutdown(void)83 int MXC_ADC_Shutdown(void)
84 {
85     MXC_ADC_RevA_Shutdown((mxc_adc_reva_regs_t *)MXC_ADC);
86 
87     MXC_SYS_ClockDisable(MXC_SYS_PERIPH_CLOCK_ADC);
88 
89     return E_NO_ERROR;
90 }
91 
MXC_ADC_Busy(void)92 int MXC_ADC_Busy(void)
93 {
94     return MXC_ADC_RevA_Busy((mxc_adc_reva_regs_t *)MXC_ADC);
95 }
96 
MXC_ADC_EnableInt(uint32_t flags)97 void MXC_ADC_EnableInt(uint32_t flags)
98 {
99     MXC_ADC_RevA_EnableInt((mxc_adc_reva_regs_t *)MXC_ADC, flags);
100 }
101 
MXC_ADC_DisableInt(uint32_t flags)102 void MXC_ADC_DisableInt(uint32_t flags)
103 {
104     MXC_ADC_RevA_DisableInt((mxc_adc_reva_regs_t *)MXC_ADC, flags);
105 }
106 
MXC_ADC_GetFlags(void)107 int MXC_ADC_GetFlags(void)
108 {
109     return MXC_ADC_RevA_GetFlags((mxc_adc_reva_regs_t *)MXC_ADC);
110 }
111 
MXC_ADC_ClearFlags(uint32_t flags)112 void MXC_ADC_ClearFlags(uint32_t flags)
113 {
114     MXC_ADC_RevA_ClearFlags((mxc_adc_reva_regs_t *)MXC_ADC, flags);
115 }
116 
MXC_ADC_SetConversionSpeed(uint32_t hz)117 int MXC_ADC_SetConversionSpeed(uint32_t hz)
118 {
119     //check for overflow
120     MXC_ASSERT(hz < ((uint32_t)((1U << 31) - 1) / 1024));
121     uint32_t adc_clock_freq = 1024 * hz;
122 
123     if (adc_clock_freq > MXC_ADC_MAX_CLOCK) {
124         return E_BAD_PARAM;
125     }
126 
127     uint8_t divider = PeripheralClock / adc_clock_freq;
128 
129     if (divider > 0xf || divider < 2) {
130         return E_BAD_PARAM;
131     }
132 
133     //disable clock
134     MXC_ADC->ctrl &= ~MXC_F_ADC_CTRL_CLK_EN;
135     //clear clock divisor
136     MXC_GCR->pclkdiv &= (~MXC_F_GCR_PCLKDIV_ADCFRQ);
137     //load in new clock divisor
138     MXC_GCR->pclkdiv |= (divider << MXC_F_GCR_PCLKDIV_ADCFRQ_POS);
139 
140     //enable clock
141     MXC_ADC_RevA_SetConversionSpeed((mxc_adc_reva_regs_t *)MXC_ADC, hz);
142 
143     return MXC_ADC_GetConversionSpeed();
144 }
145 
MXC_ADC_GetConversionSpeed(void)146 int MXC_ADC_GetConversionSpeed(void)
147 {
148     uint8_t divider = (MXC_GCR->pclkdiv & MXC_F_GCR_PCLKDIV_ADCFRQ) >> MXC_F_GCR_PCLKDIV_ADCFRQ_POS;
149     return MXC_ADC_RevA_GetConversionSpeed(divider);
150 }
151 
MXC_ADC_SetDataAlignment(int msbJustify)152 void MXC_ADC_SetDataAlignment(int msbJustify)
153 {
154     MXC_ADC_RevA_SetDataAlignment((mxc_adc_reva_regs_t *)MXC_ADC, msbJustify);
155 }
156 
MXC_ADC_SetExtScale(mxc_adc_scale_t scale)157 void MXC_ADC_SetExtScale(mxc_adc_scale_t scale)
158 {
159     MXC_ADC_RevA_SetExtScale((mxc_adc_reva_regs_t *)MXC_ADC, scale);
160 }
161 
MXC_ADC_EnableMonitor(mxc_adc_monitor_t monitor)162 void MXC_ADC_EnableMonitor(mxc_adc_monitor_t monitor)
163 {
164     MXC_ADC_RevA_EnableMonitor((mxc_adc_reva_regs_t *)MXC_ADC, monitor);
165 }
166 
MXC_ADC_DisableMonitor(mxc_adc_monitor_t monitor)167 void MXC_ADC_DisableMonitor(mxc_adc_monitor_t monitor)
168 {
169     MXC_ADC_RevA_DisableMonitor((mxc_adc_reva_regs_t *)MXC_ADC, monitor);
170 }
171 
MXC_ADC_SetMonitorHighThreshold(mxc_adc_monitor_t monitor,uint32_t threshold)172 void MXC_ADC_SetMonitorHighThreshold(mxc_adc_monitor_t monitor, uint32_t threshold)
173 {
174     MXC_ADC_RevA_SetMonitorHighThreshold((mxc_adc_reva_regs_t *)MXC_ADC, monitor, threshold);
175 }
176 
MXC_ADC_GetMonitorHighThreshold(mxc_adc_monitor_t monitor)177 int MXC_ADC_GetMonitorHighThreshold(mxc_adc_monitor_t monitor)
178 {
179     return MXC_ADC_RevA_GetMonitorHighThreshold((mxc_adc_reva_regs_t *)MXC_ADC, monitor);
180 }
181 
MXC_ADC_SetMonitorLowThreshold(mxc_adc_monitor_t monitor,uint32_t threshold)182 void MXC_ADC_SetMonitorLowThreshold(mxc_adc_monitor_t monitor, uint32_t threshold)
183 {
184     MXC_ADC_RevA_SetMonitorLowThreshold((mxc_adc_reva_regs_t *)MXC_ADC, monitor, threshold);
185 }
186 
MXC_ADC_GetMonitorLowThreshold(mxc_adc_monitor_t monitor)187 int MXC_ADC_GetMonitorLowThreshold(mxc_adc_monitor_t monitor)
188 {
189     return MXC_ADC_RevA_GetMonitorLowThreshold((mxc_adc_reva_regs_t *)MXC_ADC, monitor);
190 }
191 
MXC_ADC_SetMonitorChannel(mxc_adc_monitor_t monitor,mxc_adc_chsel_t channel)192 void MXC_ADC_SetMonitorChannel(mxc_adc_monitor_t monitor, mxc_adc_chsel_t channel)
193 {
194     initGPIOForChannel(channel);
195 
196     MXC_ADC_RevA_SetMonitorChannel((mxc_adc_reva_regs_t *)MXC_ADC, monitor, channel);
197 }
198 
MXC_ADC_GetMonitorChannel(mxc_adc_monitor_t monitor)199 int MXC_ADC_GetMonitorChannel(mxc_adc_monitor_t monitor)
200 {
201     return MXC_ADC_RevA_GetMonitorChannel((mxc_adc_reva_regs_t *)MXC_ADC, monitor);
202 }
203 
MXC_ADC_EnableMonitorAsync(mxc_adc_monitor_t monitor,mxc_adc_monitor_cb_t callback)204 void MXC_ADC_EnableMonitorAsync(mxc_adc_monitor_t monitor, mxc_adc_monitor_cb_t callback)
205 {
206     MXC_ADC_RevA_EnableMonitorAsync(monitor, callback);
207 }
208 
MXC_ADC_DisableMonitorAsync(mxc_adc_monitor_t monitor)209 void MXC_ADC_DisableMonitorAsync(mxc_adc_monitor_t monitor)
210 {
211     MXC_ADC_RevA_DisableMonitorAsync(monitor);
212 }
213 
MXC_ADC_StartConversion(mxc_adc_chsel_t channel)214 int MXC_ADC_StartConversion(mxc_adc_chsel_t channel)
215 {
216     initGPIOForChannel(channel);
217 
218     return MXC_ADC_RevA_StartConversion((mxc_adc_reva_regs_t *)MXC_ADC, channel);
219 }
220 
MXC_ADC_StartConversionAsync(mxc_adc_chsel_t channel,mxc_adc_complete_cb_t callback)221 int MXC_ADC_StartConversionAsync(mxc_adc_chsel_t channel, mxc_adc_complete_cb_t callback)
222 {
223     initGPIOForChannel(channel);
224 
225     return MXC_ADC_RevA_StartConversionAsync((mxc_adc_reva_regs_t *)MXC_ADC, channel, callback);
226 }
227 
MXC_ADC_StartConversionDMA(mxc_adc_chsel_t channel,uint16_t * data,void (* callback)(int,int))228 int MXC_ADC_StartConversionDMA(mxc_adc_chsel_t channel, uint16_t *data, void (*callback)(int, int))
229 {
230     initGPIOForChannel(channel);
231 
232     return MXC_ADC_RevA_StartConversionDMA((mxc_adc_reva_regs_t *)MXC_ADC, channel, MXC_DMA, data,
233                                            callback);
234 }
235 
MXC_ADC_Handler(void)236 int MXC_ADC_Handler(void)
237 {
238     return MXC_ADC_RevA_Handler((mxc_adc_reva_regs_t *)MXC_ADC);
239 }
240 
MXC_ADC_Convert(mxc_adc_conversion_req_t * req)241 int MXC_ADC_Convert(mxc_adc_conversion_req_t *req)
242 {
243     initGPIOForChannel(req->channel);
244 
245     return MXC_ADC_RevA_Convert((mxc_adc_reva_regs_t *)MXC_ADC, req);
246 }
247 
MXC_ADC_ConvertAsync(mxc_adc_conversion_req_t * req)248 int MXC_ADC_ConvertAsync(mxc_adc_conversion_req_t *req)
249 {
250     initGPIOForChannel(req->channel);
251 
252     return MXC_ADC_RevA_ConvertAsync((mxc_adc_reva_regs_t *)MXC_ADC, req);
253 }
254 
MXC_ADC_Monitor(mxc_adc_monitor_req_t req)255 void MXC_ADC_Monitor(mxc_adc_monitor_req_t req)
256 {
257     MXC_ADC_RevA_Monitor((mxc_adc_reva_regs_t *)MXC_ADC, req);
258 }
259 
MXC_ADC_MonitorAsync(mxc_adc_monitor_req_t req)260 void MXC_ADC_MonitorAsync(mxc_adc_monitor_req_t req)
261 {
262     MXC_ADC_RevA_MonitorAsync((mxc_adc_reva_regs_t *)MXC_ADC, req);
263 }
264 
MXC_ADC_GetData(uint16_t * outdata)265 int MXC_ADC_GetData(uint16_t *outdata)
266 {
267     return MXC_ADC_RevA_GetData((mxc_adc_reva_regs_t *)MXC_ADC, outdata);
268 }
269