1 /*
2 * Copyright (c) 2015, Freescale Semiconductor, Inc.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
7 *
8 * o Redistributions of source code must retain the above copyright notice, this list
9 * of conditions and the following disclaimer.
10 *
11 * o Redistributions in binary form must reproduce the above copyright notice, this
12 * list of conditions and the following disclaimer in the documentation and/or
13 * other materials provided with the distribution.
14 *
15 * o Neither the name of Freescale Semiconductor, Inc. nor the names of its
16 * contributors may be used to endorse or promote products derived from this
17 * software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
23 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
26 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 #include "adc_imx6sx.h"
32
33 /*******************************************************************************
34 * Code
35 ******************************************************************************/
36
37 /*FUNCTION**********************************************************************
38 *
39 * Function Name : ADC_Init
40 * Description : Initialize ADC to reset state and initialize with initialize
41 * structure.
42 *
43 *END**************************************************************************/
ADC_Init(ADC_Type * base,const adc_init_config_t * initConfig)44 void ADC_Init(ADC_Type* base, const adc_init_config_t* initConfig)
45 {
46 assert(initConfig);
47
48 /* Reset ADC register to its default value. */
49 ADC_Deinit(base);
50
51 /* Set hardware average function and number. */
52 if (initConfig->averageNumber != adcAvgNumNone)
53 {
54 ADC_GC_REG(base) |= ADC_GC_AVGE_MASK;
55 ADC_CFG_REG(base) |= ADC_CFG_AVGS(initConfig->averageNumber);
56 }
57
58 /* Set resolution mode. */
59 ADC_CFG_REG(base) |= ADC_CFG_MODE(initConfig->resolutionMode);
60
61 /* Set clock source. */
62 ADC_SetClockSource(base, initConfig->clockSource, initConfig->divideRatio);
63 }
64
65 /*FUNCTION**********************************************************************
66 *
67 * Function Name : ADC_Deinit
68 * Description : This function reset ADC module register content to its
69 * default value.
70 *
71 *END**************************************************************************/
ADC_Deinit(ADC_Type * base)72 void ADC_Deinit(ADC_Type* base)
73 {
74 /* Reset ADC Module Register content to default value */
75 ADC_HC0_REG(base) = ADC_HC0_ADCH_MASK;
76 ADC_HC1_REG(base) = ADC_HC1_ADCH_MASK;
77 ADC_R0_REG(base) = 0x0;
78 ADC_R1_REG(base) = 0x0;
79 ADC_CFG_REG(base) = ADC_CFG_ADSTS(2);
80 ADC_GC_REG(base) = 0x0;
81 ADC_GS_REG(base) = ADC_GS_CALF_MASK | ADC_GS_AWKST_MASK;
82 ADC_CV_REG(base) = 0x0;
83 ADC_OFS_REG(base) = 0x0;
84 ADC_CAL_REG(base) = 0x0;
85 }
86
87 /*FUNCTION**********************************************************************
88 *
89 * Function Name : ADC_SetConvertResultOverwrite
90 * Description : Enable or disable ADC overwrite conversion result register.
91 *
92 *END**************************************************************************/
ADC_SetConvertResultOverwrite(ADC_Type * base,bool enable)93 void ADC_SetConvertResultOverwrite(ADC_Type* base, bool enable)
94 {
95 if(enable)
96 ADC_CFG_REG(base) |= ADC_CFG_OVWREN_MASK;
97 else
98 ADC_CFG_REG(base) &= ~ADC_CFG_OVWREN_MASK;
99 }
100
101 /*FUNCTION**********************************************************************
102 *
103 * Function Name : ADC_SetConvertTrigMode
104 * Description : This function is used to set conversion trigger mode.
105 *
106 *END**************************************************************************/
ADC_SetConvertTrigMode(ADC_Type * base,uint8_t mode)107 void ADC_SetConvertTrigMode(ADC_Type* base, uint8_t mode)
108 {
109 assert(mode <= adcHardwareTrigger);
110
111 if(mode == adcHardwareTrigger)
112 ADC_CFG_REG(base) |= ADC_CFG_ADTRG_MASK;
113 else
114 ADC_CFG_REG(base) &= ~ADC_CFG_ADTRG_MASK;
115 }
116
117 /*FUNCTION**********************************************************************
118 *
119 * Function Name : ADC_SetConvertSpeed
120 * Description : This function is used to set conversion speed mode.
121 *
122 *END**************************************************************************/
ADC_SetConvertSpeed(ADC_Type * base,uint8_t mode)123 void ADC_SetConvertSpeed(ADC_Type* base, uint8_t mode)
124 {
125 assert(mode <= adcHighSpeed);
126
127 if(mode == adcHighSpeed)
128 ADC_CFG_REG(base) |= ADC_CFG_ADHSC_MASK;
129 else
130 ADC_CFG_REG(base) &= ~ADC_CFG_ADHSC_MASK;
131 }
132
133 /*FUNCTION**********************************************************************
134 *
135 * Function Name : ADC_SetSampleTimeDuration
136 * Description : This function is used to set sample time duration.
137 *
138 *END**************************************************************************/
ADC_SetSampleTimeDuration(ADC_Type * base,uint8_t duration)139 void ADC_SetSampleTimeDuration(ADC_Type* base, uint8_t duration)
140 {
141 assert(duration <= adcSamplePeriodClock24);
142
143 switch(duration)
144 {
145 case adcSamplePeriodClock2:
146 ADC_CFG_REG(base) &= ~ADC_CFG_ADLSMP_MASK;
147 ADC_CFG_REG(base) = (ADC_CFG_REG(base) & (~ADC_CFG_ADSTS_MASK)) |
148 ADC_CFG_ADSTS(0U);
149 break;
150
151 case adcSamplePeriodClock4:
152 ADC_CFG_REG(base) &= ~ADC_CFG_ADLSMP_MASK;
153 ADC_CFG_REG(base) = (ADC_CFG_REG(base) & (~ADC_CFG_ADSTS_MASK)) |
154 ADC_CFG_ADSTS(1U);
155 break;
156
157 case adcSamplePeriodClock6:
158 ADC_CFG_REG(base) &= ~ADC_CFG_ADLSMP_MASK;
159 ADC_CFG_REG(base) = (ADC_CFG_REG(base) & (~ADC_CFG_ADSTS_MASK)) |
160 ADC_CFG_ADSTS(2U);
161 break;
162
163 case adcSamplePeriodClock8:
164 ADC_CFG_REG(base) &= ~ADC_CFG_ADLSMP_MASK;
165 ADC_CFG_REG(base) = (ADC_CFG_REG(base) & (~ADC_CFG_ADSTS_MASK)) |
166 ADC_CFG_ADSTS(3U);
167 break;
168
169 case adcSamplePeriodClock12:
170 ADC_CFG_REG(base) |= ADC_CFG_ADLSMP_MASK;
171 ADC_CFG_REG(base) = (ADC_CFG_REG(base) & (~ADC_CFG_ADSTS_MASK)) |
172 ADC_CFG_ADSTS(0U);
173 break;
174
175 case adcSamplePeriodClock16:
176 ADC_CFG_REG(base) |= ADC_CFG_ADLSMP_MASK;
177 ADC_CFG_REG(base) = (ADC_CFG_REG(base) & (~ADC_CFG_ADSTS_MASK)) |
178 ADC_CFG_ADSTS(1U);
179 break;
180
181 case adcSamplePeriodClock20:
182 ADC_CFG_REG(base) |= ADC_CFG_ADLSMP_MASK;
183 ADC_CFG_REG(base) = (ADC_CFG_REG(base) & (~ADC_CFG_ADSTS_MASK)) |
184 ADC_CFG_ADSTS(2U);
185 break;
186
187 case adcSamplePeriodClock24:
188 ADC_CFG_REG(base) |= ADC_CFG_ADLSMP_MASK;
189 ADC_CFG_REG(base) = (ADC_CFG_REG(base) & (~ADC_CFG_ADSTS_MASK)) |
190 ADC_CFG_ADSTS(3U);
191 break;
192 }
193 }
194
195 /*FUNCTION**********************************************************************
196 *
197 * Function Name : ADC_SetPowerMode
198 * Description : This function is used to set power mode.
199 *
200 *END**************************************************************************/
ADC_SetPowerMode(ADC_Type * base,uint8_t powerMode)201 void ADC_SetPowerMode(ADC_Type* base, uint8_t powerMode)
202 {
203 assert(powerMode <= adcLowPowerMode);
204
205 if(powerMode == adcLowPowerMode)
206 ADC_CFG_REG(base) |= ADC_CFG_ADLPC_MASK;
207 else
208 ADC_CFG_REG(base) &= ~ADC_CFG_ADLPC_MASK;
209 }
210
211 /*FUNCTION**********************************************************************
212 *
213 * Function Name : ADC_SetClockSource
214 * Description : This function is used to set ADC clock source.
215 *
216 *END**************************************************************************/
ADC_SetClockSource(ADC_Type * base,uint8_t source,uint8_t div)217 void ADC_SetClockSource(ADC_Type* base, uint8_t source, uint8_t div)
218 {
219 assert(source <= adcAsynClock);
220 assert(div <= adcInputClockDiv8);
221
222 ADC_CFG_REG(base) = (ADC_CFG_REG(base) & (~ADC_CFG_ADIV_MASK)) |
223 ADC_CFG_ADIV(div);
224 ADC_CFG_REG(base) = (ADC_CFG_REG(base) & (~ADC_CFG_ADICLK_MASK)) |
225 ADC_CFG_ADICLK(source);
226 }
227
228 /*FUNCTION**********************************************************************
229 *
230 * Function Name : ADC_SetAsynClockOutput
231 * Description : This function is used to enable asynchronous clock source output
232 * regardless of the state of ADC.
233 *
234 *END**************************************************************************/
ADC_SetAsynClockOutput(ADC_Type * base,bool enable)235 void ADC_SetAsynClockOutput(ADC_Type* base, bool enable)
236 {
237 if(enable)
238 ADC_GC_REG(base) |= ADC_GC_ADACKEN_MASK;
239 else
240 ADC_GC_REG(base) &= ~ADC_GC_ADACKEN_MASK;
241 }
242
243 /*FUNCTION**********************************************************************
244 *
245 * Function Name : ADC_SetCalibration
246 * Description : Enable or disable calibration function.
247 *
248 *END**************************************************************************/
ADC_SetCalibration(ADC_Type * base,bool enable)249 void ADC_SetCalibration(ADC_Type* base, bool enable)
250 {
251 if(enable)
252 ADC_GC_REG(base) |= ADC_GC_CAL_MASK;
253 else
254 ADC_GC_REG(base) &= ~ADC_GC_CAL_MASK;
255 }
256
257 /*FUNCTION**********************************************************************
258 *
259 * Function Name : ADC_SetConvertCmd
260 * Description : Enable continuous conversion and start a conversion on target channel.
261 * This function is only used for software trigger mode. If configured as
262 * hardware trigger mode, this function just enable continuous conversion
263 * and not start the conversion.
264 *
265 *END**************************************************************************/
ADC_SetConvertCmd(ADC_Type * base,uint8_t channel,bool enable)266 void ADC_SetConvertCmd(ADC_Type* base, uint8_t channel, bool enable)
267 {
268 uint8_t triggerMode;
269
270 /* Enable continuous conversion. */
271 if(enable)
272 {
273 ADC_GC_REG(base) |= ADC_GC_ADCO_MASK;
274 /* Start the conversion. */
275 triggerMode = ADC_GetConvertTrigMode(base);
276 if(triggerMode == adcSoftwareTrigger)
277 ADC_HC0_REG(base) = (ADC_HC0_REG(base) & (~ADC_HC0_ADCH_MASK)) |
278 ADC_HC0_ADCH(channel);
279 else /* Just set the channel. */
280 ADC_HC1_REG(base) = (ADC_HC1_REG(base) & (~ADC_HC1_ADCH_MASK)) |
281 ADC_HC1_ADCH(channel);
282 }
283 else
284 ADC_GC_REG(base) &= ~ADC_GC_ADCO_MASK;
285 }
286
287 /*FUNCTION**********************************************************************
288 *
289 * Function Name : ADC_TriggerSingleConvert
290 * Description : Enable single conversion and trigger single time conversion
291 * on target imput channel. If configured as hardware trigger
292 * mode, this function just set input channel and not start a
293 * conversion.
294 *
295 *END**************************************************************************/
ADC_TriggerSingleConvert(ADC_Type * base,uint8_t channel)296 void ADC_TriggerSingleConvert(ADC_Type* base, uint8_t channel)
297 {
298 uint8_t triggerMode;
299
300 /* Enable single conversion. */
301 ADC_GC_REG(base) &= ~ADC_GC_ADCO_MASK;
302 /* Start the conversion. */
303 triggerMode = ADC_GetConvertTrigMode(base);
304 if(triggerMode == adcSoftwareTrigger)
305 ADC_HC0_REG(base) = (ADC_HC0_REG(base) & (~ADC_HC0_ADCH_MASK)) |
306 ADC_HC0_ADCH(channel);
307 else /* Just set the channel. */
308 ADC_HC1_REG(base) = (ADC_HC1_REG(base) & (~ADC_HC1_ADCH_MASK)) |
309 ADC_HC1_ADCH(channel);
310 }
311
312 /*FUNCTION**********************************************************************
313 *
314 * Function Name : ADC_SetAverageNum
315 * Description : This function is used to enable hardware aaverage function
316 * and set hardware average number. If avgNum is equal to
317 * adcAvgNumNone, it means disable hardware average function.
318 *
319 *END**************************************************************************/
ADC_SetAverageNum(ADC_Type * base,uint8_t avgNum)320 void ADC_SetAverageNum(ADC_Type* base, uint8_t avgNum)
321 {
322 assert(avgNum <= adcAvgNumNone);
323
324 if(avgNum != adcAvgNumNone)
325 {
326 /* Enable hardware average function. */
327 ADC_GC_REG(base) |= ADC_GC_AVGE_MASK;
328 /* Set hardware average number. */
329 ADC_CFG_REG(base) = (ADC_CFG_REG(base) & (~ADC_CFG_AVGS_MASK)) |
330 ADC_CFG_AVGS(avgNum);
331 }
332 else
333 {
334 /* Disable hardware average function. */
335 ADC_GC_REG(base) &= ~ADC_GC_AVGE_MASK;
336 }
337 }
338
339 /*FUNCTION**********************************************************************
340 *
341 * Function Name : ADC_StopConvert
342 * Description : This function is used to stop all conversions.
343 *
344 *END**************************************************************************/
ADC_StopConvert(ADC_Type * base)345 void ADC_StopConvert(ADC_Type* base)
346 {
347 uint8_t triggerMode;
348
349 triggerMode = ADC_GetConvertTrigMode(base);
350 /* According trigger mode to set specific register. */
351 if(triggerMode == adcSoftwareTrigger)
352 ADC_HC0_REG(base) |= ADC_HC0_ADCH_MASK;
353 else
354 ADC_HC1_REG(base) |= ADC_HC1_ADCH_MASK;
355 }
356
357 /*FUNCTION**********************************************************************
358 *
359 * Function Name : ADC_GetConvertResult
360 * Description : This function is used to get conversion result.
361 *
362 *END**************************************************************************/
ADC_GetConvertResult(ADC_Type * base)363 uint16_t ADC_GetConvertResult(ADC_Type* base)
364 {
365 uint8_t triggerMode;
366
367 triggerMode = ADC_GetConvertTrigMode(base);
368 if(triggerMode == adcSoftwareTrigger)
369 return (uint16_t)((ADC_R0_REG(base) & ADC_R0_D_MASK) >> ADC_R0_D_SHIFT);
370 else
371 return (uint16_t)((ADC_R1_REG(base) & ADC_R1_D_MASK) >> ADC_R1_D_SHIFT);
372 }
373
374 /*FUNCTION**********************************************************************
375 *
376 * Function Name : ADC_SetCmpMode
377 * Description : This function is used to enable compare function
378 * and set comparer mode.
379 *
380 *END**************************************************************************/
ADC_SetCmpMode(ADC_Type * base,uint8_t cmpMode,uint16_t cmpVal1,uint16_t cmpVal2)381 void ADC_SetCmpMode(ADC_Type* base, uint8_t cmpMode, uint16_t cmpVal1, uint16_t cmpVal2)
382 {
383 assert(cmpMode <= adcCmpModeDisable);
384
385 switch(cmpMode)
386 {
387 case adcCmpModeLessThanCmpVal1:
388 ADC_GC_REG(base) |= ADC_GC_ACFE_MASK;
389 ADC_GC_REG(base) &= ~(ADC_GC_ACFGT_MASK | ADC_GC_ACREN_MASK);
390 ADC_CV_REG(base) = (ADC_CV_REG(base) & (~ADC_CV_CV1_MASK)) | ADC_CV_CV1(cmpVal1);
391 break;
392
393 case adcCmpModeGreaterThanCmpVal1:
394 ADC_GC_REG(base) |= ADC_GC_ACFE_MASK;
395 ADC_GC_REG(base) = (ADC_GC_REG(base) | ADC_GC_ACFGT_MASK) & (~ADC_GC_ACREN_MASK);
396 ADC_CV_REG(base) = (ADC_CV_REG(base) & (~ADC_CV_CV1_MASK)) | ADC_CV_CV1(cmpVal1);
397 break;
398
399 case adcCmpModeOutRangNotInclusive:
400 ADC_GC_REG(base) |= ADC_GC_ACFE_MASK;
401 ADC_GC_REG(base) = (ADC_GC_REG(base) | ADC_GC_ACREN_MASK) & (~ADC_GC_ACFGT_MASK);
402 if(cmpVal1 <= cmpVal2)
403 {
404 ADC_CV_REG(base) = (ADC_CV_REG(base) & (~ADC_CV_CV1_MASK)) | ADC_CV_CV1(cmpVal1);
405 ADC_CV_REG(base) = (ADC_CV_REG(base) & (~ADC_CV_CV2_MASK)) | ADC_CV_CV2(cmpVal2);
406 }
407 break;
408
409 case adcCmpModeInRangNotInclusive:
410 ADC_GC_REG(base) |= ADC_GC_ACFE_MASK;
411 ADC_GC_REG(base) = (ADC_GC_REG(base) | ADC_GC_ACREN_MASK) & (~ADC_GC_ACFGT_MASK);
412 if(cmpVal1 > cmpVal2)
413 {
414 ADC_CV_REG(base) = (ADC_CV_REG(base) & (~ADC_CV_CV1_MASK)) | ADC_CV_CV1(cmpVal1);
415 ADC_CV_REG(base) = (ADC_CV_REG(base) & (~ADC_CV_CV2_MASK)) | ADC_CV_CV2(cmpVal2);
416 }
417 break;
418
419 case adcCmpModeInRangInclusive:
420 ADC_GC_REG(base) |= ADC_GC_ACFE_MASK;
421 ADC_GC_REG(base) |= ADC_GC_ACREN_MASK | ADC_GC_ACFGT_MASK;
422 if(cmpVal1 <= cmpVal2)
423 {
424 ADC_CV_REG(base) = (ADC_CV_REG(base) & (~ADC_CV_CV1_MASK)) | ADC_CV_CV1(cmpVal1);
425 ADC_CV_REG(base) = (ADC_CV_REG(base) & (~ADC_CV_CV2_MASK)) | ADC_CV_CV2(cmpVal2);
426 }
427 break;
428
429 case adcCmpModeOutRangInclusive:
430 ADC_GC_REG(base) |= ADC_GC_ACFE_MASK;
431 ADC_GC_REG(base) |= ADC_GC_ACREN_MASK | ADC_GC_ACFGT_MASK;
432 if(cmpVal1 > cmpVal2)
433 {
434 ADC_CV_REG(base) = (ADC_CV_REG(base) & (~ADC_CV_CV1_MASK)) | ADC_CV_CV1(cmpVal1);
435 ADC_CV_REG(base) = (ADC_CV_REG(base) & (~ADC_CV_CV2_MASK)) | ADC_CV_CV2(cmpVal2);
436 }
437 break;
438
439 case adcCmpModeDisable:
440 ADC_GC_REG(base) &= ~ADC_GC_ACFE_MASK;
441 break;
442 }
443 }
444
445 /*FUNCTION**********************************************************************
446 *
447 * Function Name : ADC_SetCorrectionMode
448 * Description : This function is used to set offset correct mode.
449 *
450 *END**************************************************************************/
ADC_SetCorrectionMode(ADC_Type * base,bool correctMode)451 void ADC_SetCorrectionMode(ADC_Type* base, bool correctMode)
452 {
453 if(correctMode)
454 ADC_OFS_REG(base) |= ADC_OFS_SIGN_MASK;
455 else
456 ADC_OFS_REG(base) &= ~ADC_OFS_SIGN_MASK;
457 }
458
459 /*FUNCTION**********************************************************************
460 *
461 * Function Name : ADC_SetIntCmd
462 * Description : Enables or disables ADC conversion complete interrupt request.
463 *
464 *END**************************************************************************/
ADC_SetIntCmd(ADC_Type * base,bool enable)465 void ADC_SetIntCmd(ADC_Type* base, bool enable)
466 {
467 uint8_t triggerMode;
468
469 triggerMode = ADC_GetConvertTrigMode(base);
470 if(triggerMode == adcSoftwareTrigger)
471 {
472 if(enable)
473 ADC_HC0_REG(base) |= ADC_HC0_AIEN_MASK;
474 else
475 ADC_HC0_REG(base) &= ~ADC_HC0_AIEN_MASK;
476 }
477 else
478 {
479 if(enable)
480 ADC_HC1_REG(base) |= ADC_HC1_AIEN_MASK;
481 else
482 ADC_HC1_REG(base) &= ~ADC_HC1_AIEN_MASK;
483 }
484 }
485
486 /*FUNCTION**********************************************************************
487 *
488 * Function Name : ADC_IsConvertComplete
489 * Description : This function is used to get ADC conversion complete status.
490 *
491 *END**************************************************************************/
ADC_IsConvertComplete(ADC_Type * base)492 bool ADC_IsConvertComplete(ADC_Type* base)
493 {
494 uint8_t triggerMode;
495
496 triggerMode = ADC_GetConvertTrigMode(base);
497 if(triggerMode == adcSoftwareTrigger)
498 return (bool)((ADC_HS_REG(base) & ADC_HS_COCO0_MASK) >> ADC_HS_COCO0_SHIFT);
499 else
500 return (bool)((ADC_HS_REG(base) & ADC_HS_COCO1_MASK) >> ADC_HS_COCO1_SHIFT);
501 }
502
503 /*FUNCTION**********************************************************************
504 *
505 * Function Name : ADC_SetDmaCmd
506 * Description : Enable or disable DMA request.
507 *
508 *END**************************************************************************/
ADC_SetDmaCmd(ADC_Type * base,bool enable)509 void ADC_SetDmaCmd(ADC_Type* base, bool enable)
510 {
511 if (enable)
512 ADC_GC_REG(base) |= ADC_GC_DMAEN_MASK;
513 else
514 ADC_GC_REG(base) &= ~ADC_GC_DMAEN_MASK;
515 }
516
517 /*******************************************************************************
518 * EOF
519 ******************************************************************************/
520