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