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_revb.h"
24 #include "gcr_regs.h"
25 #include "mxc_device.h"
26 #include "mxc_errors.h"
27 #include "mxc_assert.h"
28 #include "mxc_sys.h"
29 #include "mcr_regs.h"
30 #include "mxc_lock.h"
31 #include "mxc_pins.h"
32 #include "pwrseq_regs.h"
33 
34 #define MXC_F_MCR_ADC_CFG2_CH 0x3
35 
36 #define TEMP_FACTOR (double)530.582f / (double)4096.0f
37 #define TEMP_FACTOR1V25 (double)1.25f * TEMP_FACTOR
38 #define TEMP_FACTOR2V048 (double)2.048f * TEMP_FACTOR
39 
initGPIOForChannel(mxc_adc_chsel_t channel)40 static void initGPIOForChannel(mxc_adc_chsel_t channel)
41 {
42     switch (channel) {
43     case MXC_ADC_CH_0:
44         MXC_GPIO_Config(&gpio_cfg_adc_ain0);
45         break;
46 
47     case MXC_ADC_CH_1:
48         MXC_GPIO_Config(&gpio_cfg_adc_ain1);
49         break;
50 
51     case MXC_ADC_CH_2:
52         MXC_GPIO_Config(&gpio_cfg_adc_ain2);
53         break;
54 
55     case MXC_ADC_CH_3:
56         MXC_GPIO_Config(&gpio_cfg_adc_ain3);
57         break;
58 
59     case MXC_ADC_CH_4:
60         MXC_GPIO_Config(&gpio_cfg_adc_ain4);
61         break;
62 
63     case MXC_ADC_CH_5:
64         MXC_GPIO_Config(&gpio_cfg_adc_ain5);
65         break;
66 
67     case MXC_ADC_CH_6:
68         MXC_GPIO_Config(&gpio_cfg_adc_ain6);
69         break;
70 
71     case MXC_ADC_CH_7:
72         MXC_GPIO_Config(&gpio_cfg_adc_ain7);
73         break;
74 
75     default:
76         break;
77     }
78 }
79 
initGPIOForTrigSrc(mxc_adc_trig_sel_t hwTrig)80 static void initGPIOForTrigSrc(mxc_adc_trig_sel_t hwTrig)
81 {
82     switch (hwTrig) {
83     case MXC_ADC_TRIG_SEL_TMR0:
84     case MXC_ADC_TRIG_SEL_TMR1:
85     case MXC_ADC_TRIG_SEL_TMR2:
86     case MXC_ADC_TRIG_SEL_TMR3:
87     case MXC_ADC_TRIG_SEL_TEMP_SENS:
88     default:
89         break;
90 
91     case MXC_ADC_TRIG_SEL_P0_10:
92         MXC_GPIO_Config(&gpio_cfg_adc_trig_p0_10);
93         break;
94     case MXC_ADC_TRIG_SEL_P1_0:
95         MXC_GPIO_Config(&gpio_cfg_adc_trig_p1_0);
96         break;
97     case MXC_ADC_TRIG_SEL_P2_15:
98         MXC_GPIO_Config(&gpio_cfg_adc_trig_p2_15);
99         break;
100     }
101 }
102 
MXC_ADC_Init(mxc_adc_req_t * req)103 int MXC_ADC_Init(mxc_adc_req_t *req)
104 {
105 #ifndef MSDK_NO_GPIO_CLK_INIT
106     MXC_SYS_Reset_Periph(MXC_SYS_RESET0_ADC);
107     MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_ADC);
108 
109     /* This is required for temperature sensor only */
110     MXC_SYS_ClockSourceEnable(MXC_SYS_CLOCK_IBRO);
111 #endif
112 
113     MXC_ADC_ReferenceSelect(req->ref);
114 
115     return MXC_ADC_RevB_Init((mxc_adc_revb_regs_t *)MXC_ADC, req);
116 }
117 
MXC_ADC_Shutdown(void)118 int MXC_ADC_Shutdown(void)
119 {
120     MXC_ADC_RevB_Shutdown((mxc_adc_revb_regs_t *)MXC_ADC);
121 
122     MXC_SYS_ClockDisable(MXC_SYS_PERIPH_CLOCK_ADC);
123 
124     return E_NO_ERROR;
125 }
126 
MXC_ADC_EnableInt(uint32_t flags)127 void MXC_ADC_EnableInt(uint32_t flags)
128 {
129     MXC_ADC_RevB_EnableInt((mxc_adc_revb_regs_t *)MXC_ADC, flags);
130 }
131 
MXC_ADC_DisableInt(uint32_t flags)132 void MXC_ADC_DisableInt(uint32_t flags)
133 {
134     MXC_ADC_RevB_DisableInt((mxc_adc_revb_regs_t *)MXC_ADC, flags);
135 }
136 
MXC_ADC_GetFlags(void)137 int MXC_ADC_GetFlags(void)
138 {
139     return MXC_ADC_RevB_GetFlags((mxc_adc_revb_regs_t *)MXC_ADC);
140 }
141 
MXC_ADC_ClearFlags(uint32_t flags)142 void MXC_ADC_ClearFlags(uint32_t flags)
143 {
144     MXC_ADC_RevB_ClearFlags((mxc_adc_revb_regs_t *)MXC_ADC, flags);
145 }
146 
MXC_ADC_ClockSelect(mxc_adc_clock_t clock)147 void MXC_ADC_ClockSelect(mxc_adc_clock_t clock)
148 {
149     MXC_ADC_RevB_ClockSelect((mxc_adc_revb_regs_t *)MXC_ADC, clock);
150 }
151 
MXC_ADC_StartConversion(void)152 int MXC_ADC_StartConversion(void)
153 {
154     return MXC_ADC_RevB_StartConversion((mxc_adc_revb_regs_t *)MXC_ADC);
155 }
156 
MXC_ADC_StartConversionAsync(mxc_adc_complete_cb_t callback)157 int MXC_ADC_StartConversionAsync(mxc_adc_complete_cb_t callback)
158 {
159     return MXC_ADC_RevB_StartConversionAsync((mxc_adc_revb_regs_t *)MXC_ADC, callback);
160 }
161 
MXC_ADC_StartConversionDMA(mxc_adc_conversion_req_t * req,int * data,void (* callback)(int,int))162 int MXC_ADC_StartConversionDMA(mxc_adc_conversion_req_t *req, int *data, void (*callback)(int, int))
163 {
164     return MXC_ADC_RevB_StartConversionDMA((mxc_adc_revb_regs_t *)MXC_ADC, req, data, callback);
165 }
166 
MXC_ADC_Handler(void)167 int MXC_ADC_Handler(void)
168 {
169     return MXC_ADC_RevB_Handler((mxc_adc_revb_regs_t *)MXC_ADC);
170 }
171 
MXC_ADC_GetData(int * outdata)172 int MXC_ADC_GetData(int *outdata)
173 {
174     return MXC_ADC_RevB_GetData((mxc_adc_revb_regs_t *)MXC_ADC, outdata);
175 }
176 
MXC_ADC_ReferenceSelect(mxc_adc_refsel_t ref)177 int MXC_ADC_ReferenceSelect(mxc_adc_refsel_t ref)
178 {
179     switch (ref) {
180     case MXC_ADC_REF_EXT:
181         MXC_MCR->adccfg0 |= MXC_F_MCR_ADCCFG0_EXT_REF;
182         break;
183     case MXC_ADC_REF_INT_1V25:
184         MXC_MCR->adccfg0 &= ~(MXC_F_MCR_ADCCFG0_EXT_REF | MXC_F_MCR_ADCCFG0_REF_SEL);
185         break;
186     case MXC_ADC_REF_INT_2V048:
187         MXC_MCR->adccfg0 &= ~MXC_F_MCR_ADCCFG0_EXT_REF;
188         MXC_MCR->adccfg0 |= MXC_F_MCR_ADCCFG0_REF_SEL;
189         break;
190     default:
191         return E_BAD_PARAM;
192     }
193 
194     return E_NO_ERROR;
195 }
196 
MXC_ADC_InputDividerSelect(mxc_adc_chsel_t ch)197 int MXC_ADC_InputDividerSelect(mxc_adc_chsel_t ch)
198 {
199     return E_NO_ERROR;
200 }
201 
MXC_ADC_DynamicModeEn(mxc_adc_chsel_t ch)202 int MXC_ADC_DynamicModeEn(mxc_adc_chsel_t ch)
203 {
204     return E_NO_ERROR;
205 }
206 
MXC_ADC_DynamicModeDis(mxc_adc_chsel_t ch)207 int MXC_ADC_DynamicModeDis(mxc_adc_chsel_t ch)
208 {
209     return E_NO_ERROR;
210 }
211 
MXC_ADC_EnableConversion(void)212 void MXC_ADC_EnableConversion(void)
213 {
214     MXC_ADC_RevB_EnableConversion((mxc_adc_revb_regs_t *)MXC_ADC);
215 }
216 
MXC_ADC_DisableConversion(void)217 void MXC_ADC_DisableConversion(void)
218 {
219     MXC_ADC_RevB_DisableConversion((mxc_adc_revb_regs_t *)MXC_ADC);
220 }
221 
MXC_ADC_TS_SelectEnable(void)222 void MXC_ADC_TS_SelectEnable(void)
223 {
224     MXC_ADC_RevB_TS_SelectEnable((mxc_adc_revb_regs_t *)MXC_ADC);
225 }
226 
MXC_ADC_TS_SelectDisable(void)227 void MXC_ADC_TS_SelectDisable(void)
228 {
229     MXC_ADC_RevB_TS_SelectDisable((mxc_adc_revb_regs_t *)MXC_ADC);
230 }
231 
MXC_ADC_FIFO_Level(void)232 uint16_t MXC_ADC_FIFO_Level(void)
233 {
234     return MXC_ADC_RevB_FIFO_Level((mxc_adc_revb_regs_t *)MXC_ADC);
235 }
236 
MXC_ADC_FIFO_Threshold_Config(uint32_t fifo_threshold)237 int MXC_ADC_FIFO_Threshold_Config(uint32_t fifo_threshold)
238 {
239     return MXC_ADC_RevB_FIFO_Threshold_Config((mxc_adc_revb_regs_t *)MXC_ADC, fifo_threshold);
240 }
241 
MXC_ADC_AverageConfig(mxc_adc_avg_t avg_number)242 int MXC_ADC_AverageConfig(mxc_adc_avg_t avg_number)
243 {
244     return MXC_ADC_RevB_AverageConfig((mxc_adc_revb_regs_t *)MXC_ADC, avg_number);
245 }
246 
MXC_ADC_Clear_ChannelSelect(void)247 void MXC_ADC_Clear_ChannelSelect(void)
248 {
249     MXC_ADC_RevB_Clear_ChannelSelect((mxc_adc_revb_regs_t *)MXC_ADC);
250 }
251 
MXC_ADC_TriggerConfig(mxc_adc_conversion_req_t * req)252 void MXC_ADC_TriggerConfig(mxc_adc_conversion_req_t *req)
253 {
254     initGPIOForTrigSrc(req->hwTrig);
255     MXC_ADC_RevB_TriggerConfig((mxc_adc_revb_regs_t *)MXC_ADC, req);
256 }
257 
MXC_ADC_ConversionModeConfig(mxc_adc_conversion_req_t * req)258 void MXC_ADC_ConversionModeConfig(mxc_adc_conversion_req_t *req)
259 {
260     MXC_ADC_RevB_ConversionModeConfig((mxc_adc_revb_regs_t *)MXC_ADC, req);
261 }
262 
MXC_ADC_SetConversionDelay(int delay)263 void MXC_ADC_SetConversionDelay(int delay)
264 {
265     MXC_ADC_RevB_SetConversionDelay((mxc_adc_revb_regs_t *)MXC_ADC, delay);
266 }
267 
MXC_ADC_SlotsConfig(mxc_adc_conversion_req_t * req)268 int MXC_ADC_SlotsConfig(mxc_adc_conversion_req_t *req)
269 {
270     return MXC_ADC_RevB_SlotsConfig((mxc_adc_revb_regs_t *)MXC_ADC, req);
271 }
272 
MXC_ADC_ChSelectConfig(mxc_adc_chsel_t ch,uint32_t slot_num)273 int MXC_ADC_ChSelectConfig(mxc_adc_chsel_t ch, uint32_t slot_num)
274 {
275     return MXC_ADC_RevB_ChSelectConfig((mxc_adc_revb_regs_t *)MXC_ADC, ch, slot_num);
276 }
277 
MXC_ADC_Configuration(mxc_adc_conversion_req_t * req)278 int MXC_ADC_Configuration(mxc_adc_conversion_req_t *req)
279 {
280     MXC_ADC_ConversionModeConfig(req);
281 
282     MXC_ADC_TriggerConfig(req);
283 
284     MXC_ADC_FIFO_Threshold_Config(req->fifo_threshold);
285 
286     MXC_ADC_SlotsConfig(req);
287 
288     MXC_ADC_Clear_ChannelSelect();
289 
290     //number of samples to average
291     MXC_ADC_AverageConfig(req->avg_number);
292 
293     return E_NO_ERROR;
294 }
295 
MXC_ADC_SlotConfiguration(mxc_adc_slot_req_t * req,uint32_t slot_length)296 int MXC_ADC_SlotConfiguration(mxc_adc_slot_req_t *req, uint32_t slot_length)
297 {
298     uint32_t loop_counter = 0;
299 
300     for (loop_counter = 0; loop_counter <= slot_length; loop_counter++) {
301         initGPIOForChannel(req->channel);
302 #if 0
303         if (req->channel <= MAX_ADC_RES_DIV_CH) {
304             MXC_ADC_InputDividerSelect(req->channel, req->div, req->pullup_dyn);
305         }
306 #endif
307         MXC_ADC_ChSelectConfig(req->channel, loop_counter);
308         req++;
309     }
310     return E_NO_ERROR;
311 }
312 
MXC_ConvertTemperature_ToK(uint16_t tempSensor_Readout,mxc_adc_refsel_t ref,float ext_ref,float * temp_k)313 int MXC_ConvertTemperature_ToK(uint16_t tempSensor_Readout, mxc_adc_refsel_t ref, float ext_ref,
314                                float *temp_k)
315 {
316     switch (ref) {
317     case MXC_ADC_REF_EXT:
318         *temp_k = (double)tempSensor_Readout * (double)TEMP_FACTOR * (double)ext_ref;
319         break;
320 
321     case MXC_ADC_REF_INT_1V25:
322         *temp_k = tempSensor_Readout * TEMP_FACTOR1V25;
323         break;
324 
325     case MXC_ADC_REF_INT_2V048:
326         *temp_k = tempSensor_Readout * TEMP_FACTOR2V048;
327         break;
328 
329     default:
330         return E_BAD_PARAM;
331     }
332     return E_NO_ERROR;
333 }
334 
MXC_ConvertTemperature_ToC(uint16_t tempSensor_Readout,mxc_adc_refsel_t ref,float ext_ref,float * temp)335 int MXC_ConvertTemperature_ToC(uint16_t tempSensor_Readout, mxc_adc_refsel_t ref, float ext_ref,
336                                float *temp)
337 {
338     if (MXC_ConvertTemperature_ToK(tempSensor_Readout, ref, ext_ref, temp) == E_NO_ERROR) {
339         *temp = *temp - 273.15f;
340         return E_NO_ERROR;
341     } else {
342         return E_BAD_PARAM;
343     }
344 }
345 
MXC_ConvertTemperature_ToF(uint16_t tempSensor_Readout,mxc_adc_refsel_t ref,float ext_ref,float * temp)346 int MXC_ConvertTemperature_ToF(uint16_t tempSensor_Readout, mxc_adc_refsel_t ref, float ext_ref,
347                                float *temp)
348 {
349     if (MXC_ConvertTemperature_ToK(tempSensor_Readout, ref, ext_ref, temp) == E_NO_ERROR) {
350         *temp = (*temp * 1.8f) - 459.67f;
351         return E_NO_ERROR;
352     } else {
353         return E_BAD_PARAM;
354     }
355 }
356