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