1 /*
2 * Copyright (c) 2006-2022, RT-Thread Development Team
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date Author Notes
8 * 2011-02-21 onelife Initial creation for EFM32
9 * 2011-07-14 onelife Add multiple channels support for scan mode
10 */
11
12 /***************************************************************************//**
13 * @addtogroup efm32
14 * @{
15 ******************************************************************************/
16
17 /* Includes ------------------------------------------------------------------*/
18 #include "board.h"
19 #include "drv_adc.h"
20
21 #if defined(RT_USING_ADC0)
22 /* Private typedef -----------------------------------------------------------*/
23 /* Private define ------------------------------------------------------------*/
24 /* Private macro -------------------------------------------------------------*/
25 #ifdef RT_ADC_DEBUG
26 #define adc_debug(format,args...) rt_kprintf(format, ##args)
27 #else
28 #define adc_debug(format,args...)
29 #endif
30
31 /* Private variables ---------------------------------------------------------*/
32 #ifdef RT_USING_ADC0
33 static struct rt_device adc0_device;
34 #endif
35 static rt_uint32_t adcErrataShift = 0;
36
37 /* Private function prototypes -----------------------------------------------*/
38 /* Private functions ---------------------------------------------------------*/
39 /***************************************************************************//**
40 * @brief
41 * Calibrate offset and gain for the specified reference.
42 * Supports currently only single ended gain calibration.
43 * Could easily be expanded to support differential gain calibration.
44 *
45 * @details
46 * The offset calibration routine measures 0 V with the ADC, and adjust
47 * the calibration register until the converted value equals 0.
48 * The gain calibration routine needs an external reference voltage equal
49 * to the top value for the selected reference. For example if the 2.5 V
50 * reference is to be calibrated, the external supply must also equal 2.5V.
51 *
52 * @param[in] adc
53 * Pointer to ADC peripheral register block.
54 *
55 * @param[in] ref
56 * Reference used during calibration. Can be both external and internal
57 * references.
58 *
59 * @param[in] input
60 * Input channel used during calibration.
61 *
62 * @return
63 * The final value of the calibration register, note that the calibration
64 * register gets updated with this value during the calibration.
65 * No need to load the calibration values after the function returns.
66 ******************************************************************************/
efm32_adc_calibration(ADC_TypeDef * adc,ADC_Ref_TypeDef ref,ADC_SingleInput_TypeDef input)67 rt_uint32_t efm32_adc_calibration(
68 ADC_TypeDef *adc,
69 ADC_Ref_TypeDef ref,
70 ADC_SingleInput_TypeDef input)
71 {
72 rt_uint32_t cal;
73 rt_int32_t sample;
74 rt_int8_t high, mid, low, tmp;
75 ADC_InitSingle_TypeDef singleInit = ADC_INITSINGLE_DEFAULT;
76
77 /* Init for single conversion use, measure diff 0 with selected reference. */
78 singleInit.reference = ref;
79 singleInit.input = adcSingleInpDiff0;
80 singleInit.acqTime = adcAcqTime32;
81 singleInit.diff = true;
82 /* Enable oversampling rate */
83 singleInit.resolution = adcResOVS;
84 ADC_InitSingle(adc, &singleInit);
85
86 /* ADC is now set up for offset calibration */
87 /* Offset calibration register is a 7 bit signed 2's complement value. */
88 /* Use unsigned indexes for binary search, and convert when calibration */
89 /* register is written to. */
90 high = 63;
91 low = -64;
92
93 /* Do binary search for offset calibration*/
94 while (low < high)
95 {
96 /* Calculate midpoint */
97 mid = low + (high - low) / 2;
98
99 /* Midpoint is converted to 2's complement and written to both scan and */
100 /* single calibration registers */
101 cal = adc->CAL & ~(_ADC_CAL_SINGLEOFFSET_MASK | _ADC_CAL_SCANOFFSET_MASK);
102 tmp = mid < 0 ? (((mid & 0x3F) ^ 0x3F) | 0x40) + 1 : mid;
103 cal |= tmp << _ADC_CAL_SINGLEOFFSET_SHIFT;
104 cal |= tmp << _ADC_CAL_SCANOFFSET_SHIFT;
105 adc_debug("adc->CAL = %x, cal = %x, tmp = %x\n", adc->CAL, cal, tmp);
106 adc->CAL = cal;
107
108 /* Do a conversion */
109 ADC_Start(adc, adcStartSingle);
110
111 /* Wait while conversion is active */
112 while (adc->STATUS & ADC_STATUS_SINGLEACT) ;
113
114 /* Get ADC result */
115 sample = ADC_DataSingleGet(adc);
116
117 /* Check result and decide in which part of to repeat search */
118 /* Calibration register has negative effect on result */
119 if (sample < 0)
120 {
121 /* Repeat search in bottom half. */
122 high = mid;
123 }
124 else if (sample > 0)
125 {
126 /* Repeat search in top half. */
127 low = mid + 1;
128 }
129 else
130 {
131 /* Found it, exit while loop */
132 break;
133 }
134 }
135 adc_debug("adc->CAL = %x\n", adc->CAL);
136
137 /* Now do gain calibration, only input and diff settings needs to be changed */
138 adc->SINGLECTRL &= ~(_ADC_SINGLECTRL_INPUTSEL_MASK | _ADC_SINGLECTRL_DIFF_MASK);
139 adc->SINGLECTRL |= (input << _ADC_SINGLECTRL_INPUTSEL_SHIFT);
140 adc->SINGLECTRL |= (false << _ADC_SINGLECTRL_DIFF_SHIFT);
141
142 /* ADC is now set up for gain calibration */
143 /* Gain calibration register is a 7 bit unsigned value. */
144 high = 127;
145 low = 0;
146
147 /* Do binary search for gain calibration */
148 while (low < high)
149 {
150 /* Calculate midpoint and write to calibration register */
151 mid = low + (high - low) / 2;
152
153 /* Midpoint is converted to 2's complement */
154 cal = adc->CAL & ~(_ADC_CAL_SINGLEGAIN_MASK | _ADC_CAL_SCANGAIN_MASK);
155 cal |= mid << _ADC_CAL_SINGLEGAIN_SHIFT;
156 cal |= mid << _ADC_CAL_SCANGAIN_SHIFT;
157 adc_debug("adc->CAL = %x, cal = %x, mid = %x\n", adc->CAL, cal, mid);
158 adc->CAL = cal;
159
160 /* Do a conversion */
161 ADC_Start(adc, adcStartSingle);
162
163 /* Wait while conversion is active */
164 while (adc->STATUS & ADC_STATUS_SINGLEACT) ;
165
166 /* Get ADC result */
167 sample = ADC_DataSingleGet(adc);
168
169 /* Check result and decide in which part to repeat search */
170 /* Compare with a value atleast one LSB's less than top to avoid overshooting */
171 /* Since oversampling is used, the result is 16 bits, but a couple of lsb's */
172 /* applies to the 12 bit result value, if 0xffe is the top value in 12 bit, this */
173 /* is in turn 0xffe0 in the 16 bit result. */
174 /* Calibration register has positive effect on result */
175 if (sample > 0xffd0)
176 {
177 /* Repeat search in bottom half. */
178 high = mid;
179 }
180 else if (sample < 0xffd0)
181 {
182 /* Repeat search in top half. */
183 low = mid + 1;
184 }
185 else
186 {
187 /* Found it, exit while loop */
188 break;
189 }
190 }
191 adc_debug("adc->CAL = %x\n", adc->CAL);
192
193 return adc->CAL;
194 }
195
196 /***************************************************************************//**
197 * @brief
198 * Configure DMA for ADC
199 *
200 * @details
201 *
202 * @note
203 *
204 * @param[in] adc_device
205 * Pointer to ADC registers base address
206 *
207 * @param[in] mode
208 * ADC mode
209 *
210 * @param[in] channel
211 * DMA channel
212 ******************************************************************************/
efm32_adc_cfg_dma(ADC_TypeDef * adc_device,rt_uint8_t mode,rt_uint8_t channel)213 void efm32_adc_cfg_dma(
214 ADC_TypeDef *adc_device,
215 rt_uint8_t mode,
216 rt_uint8_t channel)
217 {
218 DMA_CfgChannel_TypeDef chnlCfg;
219 DMA_CfgDescr_TypeDef descrCfg;
220
221 if (channel == (rt_uint8_t)EFM32_NO_DMA)
222 {
223 return;
224 }
225
226 /* Set up DMA channel */
227 chnlCfg.highPri = false;
228 chnlCfg.enableInt = false;
229 if (adc_device == ADC0)
230 {
231 switch (mode & ADC_MASK_MODE)
232 {
233 case ADC_MODE_SINGLE:
234 chnlCfg.select = DMAREQ_ADC0_SINGLE;
235 break;
236
237 case ADC_MODE_SCAN:
238 chnlCfg.select = DMAREQ_ADC0_SCAN;
239 break;
240
241 default:
242 return;
243 }
244 }
245 else
246 {
247 // TODO: Any other channel?
248 return;
249 }
250 chnlCfg.cb = RT_NULL;
251 DMA_CfgChannel((rt_uint32_t)channel, &chnlCfg);
252
253 /* Setting up DMA channel descriptor */
254 descrCfg.dstInc = dmaDataInc4;
255 descrCfg.srcInc = dmaDataIncNone;
256 descrCfg.size = dmaDataSize4;
257 descrCfg.arbRate = dmaArbitrate1;
258 descrCfg.hprot = 0;
259 DMA_CfgDescr((rt_uint32_t)channel, true, &descrCfg);
260 }
261
262 /***************************************************************************//**
263 * @brief
264 * Activate DMA for ADC
265 *
266 * @details
267 *
268 * @note
269 *
270 * @param[in] adc_device
271 * Pointer to ADC registers base address
272 *
273 * @param[in] mode
274 * ADC mode
275 *
276 * @param[in] count
277 * ADC channel count
278 *
279 * @param[in] channel
280 * DMA channel
281 *
282 * @param[out] buffer
283 * Pointer to ADC results buffer
284 ******************************************************************************/
efm32_adc_on_dma(ADC_TypeDef * adc_device,rt_uint8_t mode,rt_uint8_t count,rt_uint8_t channel,void * buffer)285 void efm32_adc_on_dma(
286 ADC_TypeDef *adc_device,
287 rt_uint8_t mode,
288 rt_uint8_t count,
289 rt_uint8_t channel,
290 void *buffer)
291 {
292 switch (mode & ADC_MASK_MODE)
293 {
294 case ADC_MODE_SINGLE:
295 /* Activate DMA */
296 DMA_ActivateBasic(
297 (rt_uint32_t)channel,
298 true,
299 false,
300 buffer,
301 (void *)&(adc_device->SINGLEDATA),
302 count - 1);
303 break;
304
305 case ADC_MODE_SCAN:
306 DMA_ActivateBasic(
307 (rt_uint32_t)channel,
308 true,
309 false,
310 buffer,
311 (void *)&(adc_device->SCANDATA),
312 count - 1);
313 break;
314
315 default:
316 return;
317 }
318 }
319
320 /***************************************************************************//**
321 * @brief
322 * Initialize ADC device
323 *
324 * @details
325 *
326 * @note
327 *
328 * @param[in] dev
329 * Pointer to device descriptor
330 *
331 * @return
332 * Error code
333 ******************************************************************************/
rt_adc_init(rt_device_t dev)334 static rt_err_t rt_adc_init(rt_device_t dev)
335 {
336 RT_ASSERT(dev != RT_NULL);
337
338 rt_uint32_t temp;
339
340 struct efm32_adc_device_t *adc;
341
342 adc = (struct efm32_adc_device_t *)(dev->user_data);
343
344 temp = efm32_adc_calibration(adc->adc_device, ADC_CALI_REF, ADC_CALI_CH);
345
346 adc_debug("adc->CAL = %x\n", temp);
347 return RT_EOK;
348 }
349
350 /***************************************************************************//**
351 * @brief
352 * Configure ADC device
353 *
354 * @details
355 *
356 * @note
357 *
358 * @param[in] dev
359 * Pointer to device descriptor
360 *
361 * @param[in] cmd
362 * ADC control command
363 *
364 * @param[in] args
365 * Arguments
366 *
367 * @return
368 * Error code
369 ******************************************************************************/
rt_adc_control(rt_device_t dev,rt_uint8_t cmd,void * args)370 static rt_err_t rt_adc_control(
371 rt_device_t dev,
372 rt_uint8_t cmd,
373 void *args)
374 {
375 RT_ASSERT(dev != RT_NULL);
376
377 struct efm32_adc_device_t *adc;
378
379 adc = (struct efm32_adc_device_t *)(dev->user_data);
380
381 switch (cmd)
382 {
383 case RT_DEVICE_CTRL_SUSPEND:
384 /* Suspend device */
385 dev->flag |= RT_DEVICE_FLAG_SUSPENDED;
386 adc->adc_device->CMD = ADC_CMD_SINGLESTOP | ADC_CMD_SCANSTOP;
387 break;
388
389 case RT_DEVICE_CTRL_RESUME:
390 {
391 /* Resume device */
392 struct efm32_adc_result_t *control = \
393 (struct efm32_adc_result_t *)args;
394
395 dev->flag &= ~RT_DEVICE_FLAG_SUSPENDED;
396
397 switch (control->mode)
398 {
399 case ADC_MODE_SINGLE:
400 if (adc->singleDmaChannel != (rt_uint8_t)EFM32_NO_DMA)
401 {
402 efm32_adc_on_dma(
403 adc->adc_device,
404 control->mode,
405 adc->singleCount,
406 adc->singleDmaChannel,
407 control->buffer);
408 }
409 ADC_Start(adc->adc_device, adcStartSingle);
410 break;
411
412 case ADC_MODE_SCAN:
413 if (adc->scanDmaChannel != (rt_uint8_t)EFM32_NO_DMA)
414 {
415 efm32_adc_on_dma(
416 adc->adc_device,
417 control->mode,
418 adc->scanCount,
419 adc->scanDmaChannel,
420 control->buffer);
421 }
422 ADC_Start(adc->adc_device, adcStartScan);
423 break;
424
425 case ADC_MODE_TAILGATE:
426 {
427 void *index = control->buffer;
428
429 if (adc->scanDmaChannel != (rt_uint8_t)EFM32_NO_DMA)
430 {
431 efm32_adc_on_dma(
432 adc->adc_device,
433 control->mode,
434 adc->scanCount,
435 adc->scanDmaChannel,
436 index);
437 index += adc->scanCount;
438 }
439 if (adc->singleDmaChannel != (rt_uint8_t)EFM32_NO_DMA)
440 {
441 efm32_adc_on_dma(
442 adc->adc_device,
443 control->mode,
444 adc->singleCount,
445 adc->singleDmaChannel,
446 index);
447 index += adc->singleCount;
448 }
449 ADC_Start(adc->adc_device, adcStartScanAndSingle);
450 }
451
452 break;
453
454 default:
455 return -RT_ERROR;
456 }
457 }
458 break;
459
460 case RT_DEVICE_CTRL_ADC_MODE:
461 {
462 /* change device setting */
463 struct efm32_adc_control_t *control = \
464 (struct efm32_adc_control_t *)args;
465
466 switch (control->mode)
467 {
468 case ADC_MODE_SINGLE:
469 ADC_InitSingle(adc->adc_device, control->single.init);
470 break;
471
472 case ADC_MODE_SCAN:
473 ADC_InitScan(adc->adc_device, control->scan.init);
474 break;
475
476 case ADC_MODE_TAILGATE:
477 ADC_InitSingle(adc->adc_device, control->single.init);
478 ADC_InitScan(adc->adc_device, control->scan.init);
479 break;
480
481 default:
482 return -RT_ERROR;
483 }
484
485 if (control->mode == ADC_MODE_TAILGATE)
486 {
487 adc->mode = ADC_MODE_TAILGATE;
488 }
489 else
490 {
491 adc->mode &= ~(rt_uint8_t)ADC_MODE_TAILGATE;
492 adc->mode |= control->mode;
493 }
494 if ((control->mode == ADC_MODE_TAILGATE) || \
495 (control->mode == ADC_MODE_SINGLE))
496 {
497 if (control->single.init->rep)
498 {
499 adc->mode |= ADC_OP_SINGLE_REPEAT;
500 }
501 adc->singleCount = control->single.count;
502 adc->singleDmaChannel = control->single.dmaChannel;
503 efm32_adc_cfg_dma(adc->adc_device, control->mode, adc->singleDmaChannel);
504 }
505 if ((control->mode == ADC_MODE_TAILGATE) || \
506 (control->mode == ADC_MODE_SCAN))
507 {
508 if (control->scan.init->rep)
509 {
510 adc->mode |= ADC_OP_SCAN_REPEAT;
511 }
512 adc->scanCount = control->scan.count;
513 adc->scanDmaChannel = control->scan.dmaChannel;
514 efm32_adc_cfg_dma(adc->adc_device, control->mode, adc->scanDmaChannel);
515 }
516 }
517 break;
518
519 case RT_DEVICE_CTRL_ADC_RESULT:
520 {
521 struct efm32_adc_result_t *control = \
522 (struct efm32_adc_result_t *)args;
523
524 switch (control->mode)
525 {
526 case ADC_MODE_SINGLE:
527 if (adc->singleDmaChannel != (rt_uint8_t)EFM32_NO_DMA)
528 {
529 if (adc->mode & ADC_OP_SINGLE_REPEAT)
530 {
531 if (!(DMA->IF & (1 << adc->singleDmaChannel)))
532 {
533 efm32_adc_on_dma(
534 adc->adc_device,
535 control->mode,
536 adc->singleCount,
537 adc->singleDmaChannel,
538 control->buffer);
539 }
540 while (!(DMA->IF & (1 << adc->singleDmaChannel)));
541 }
542 else
543 {
544 while (adc->adc_device->STATUS & ADC_STATUS_SINGLEACT);
545 }
546 }
547 else
548 {
549 while (adc->adc_device->STATUS & ADC_STATUS_SINGLEACT);
550 *((rt_uint32_t *)control->buffer) = \
551 ADC_DataSingleGet(adc->adc_device) << adcErrataShift;
552 }
553 break;
554
555 case ADC_MODE_SCAN:
556 if (adc->scanDmaChannel != (rt_uint8_t)EFM32_NO_DMA)
557 {
558 if (adc->mode & ADC_OP_SCAN_REPEAT)
559 {
560 if (!(DMA->IF & (1 << adc->scanDmaChannel)))
561 {
562 efm32_adc_on_dma(
563 adc->adc_device,
564 control->mode,
565 adc->scanCount,
566 adc->scanDmaChannel,
567 control->buffer);
568 }
569 while (!(DMA->IF & (1 << adc->scanDmaChannel)));
570 }
571 else
572 {
573 while (adc->adc_device->STATUS & ADC_STATUS_SCANACT);
574 }
575 }
576 else
577 {
578 while (adc->adc_device->STATUS & ADC_STATUS_SCANACT);
579 *((rt_uint32_t *)control->buffer) = \
580 ADC_DataScanGet(adc->adc_device) << adcErrataShift;
581 }
582 break;
583
584 case ADC_MODE_TAILGATE:
585 {
586 void *index = control->buffer;
587
588 if ((adc->scanDmaChannel != (rt_uint8_t)EFM32_NO_DMA) && \
589 !(adc->mode & ADC_OP_SCAN_REPEAT))
590 {
591 index += adc->scanCount;
592 }
593 if ((adc->singleDmaChannel != (rt_uint8_t)EFM32_NO_DMA) && \
594 !(adc->mode & ADC_OP_SINGLE_REPEAT))
595 {
596 index += adc->singleCount;
597 }
598
599 if (adc->scanDmaChannel != (rt_uint8_t)EFM32_NO_DMA)
600 {
601 if (adc->mode & ADC_OP_SCAN_REPEAT)
602 {
603 if (!(DMA->IF & (1 << adc->scanDmaChannel)))
604 {
605 efm32_adc_on_dma(
606 adc->adc_device,
607 control->mode,
608 adc->scanCount,
609 adc->scanDmaChannel,
610 index);
611 index += adc->scanCount;
612 }
613 while (!(DMA->IF & (1 << adc->scanDmaChannel)));
614 }
615 else
616 {
617 while (adc->adc_device->STATUS & ADC_STATUS_SCANACT);
618 }
619 }
620 else
621 {
622 while (adc->adc_device->STATUS & ADC_STATUS_SCANACT);
623 *(rt_uint32_t *)(index++) = \
624 ADC_DataScanGet(adc->adc_device) << adcErrataShift;
625 }
626 if (adc->singleDmaChannel != (rt_uint8_t)EFM32_NO_DMA)
627 {
628 if (adc->mode & ADC_OP_SINGLE_REPEAT)
629 {
630 if (!(DMA->IF & (1 << adc->singleDmaChannel)))
631 {
632 efm32_adc_on_dma(
633 adc->adc_device,
634 control->mode,
635 adc->singleCount,
636 adc->singleDmaChannel,
637 index);
638 index += adc->singleCount;
639 }
640 while (!(DMA->IF & (1 << adc->singleDmaChannel)));
641 }
642 else
643 {
644 while (adc->adc_device->STATUS & ADC_STATUS_SINGLEACT);
645 }
646 }
647 else
648 {
649 while (adc->adc_device->STATUS & ADC_STATUS_SINGLEACT);
650 *(rt_uint32_t *)(index++) = \
651 ADC_DataSingleGet(adc->adc_device) << adcErrataShift;
652 }
653 }
654 break;
655
656 default:
657 return -RT_ERROR;
658 }
659 }
660 break;
661
662 default:
663 return -RT_ERROR;
664 }
665
666 return RT_EOK;
667 }
668
669 /***************************************************************************//**
670 * @brief
671 * Register ADC device
672 *
673 * @details
674 *
675 * @note
676 *
677 * @param[in] device
678 * Pointer to device descriptor
679 *
680 * @param[in] name
681 * Device name
682 *
683 * @param[in] flag
684 * Configuration flags
685 *
686 * @param[in] adc
687 * Pointer to ADC device descriptor
688 *
689 * @return
690 * Error code
691 ******************************************************************************/
rt_hw_adc_register(rt_device_t device,const char * name,rt_uint32_t flag,struct efm32_adc_device_t * adc)692 rt_err_t rt_hw_adc_register(
693 rt_device_t device,
694 const char *name,
695 rt_uint32_t flag,
696 struct efm32_adc_device_t *adc)
697 {
698 RT_ASSERT(device != RT_NULL);
699
700 device->type = RT_Device_Class_Char; /* fixme: should be adc type */
701 device->rx_indicate = RT_NULL;
702 device->tx_complete = RT_NULL;
703 device->init = rt_adc_init;
704 device->open = RT_NULL;
705 device->close = RT_NULL;
706 device->read = RT_NULL;
707 device->write = RT_NULL;
708 device->control = rt_adc_control;
709 device->user_data = adc;
710
711 /* register a character device */
712 return rt_device_register(device, name, flag);
713 }
714
715 /***************************************************************************//**
716 * @brief
717 * Initialize the specified ADC unit
718 *
719 * @details
720 *
721 * @note
722 *
723 * @param[in] device
724 * Pointer to device descriptor
725 *
726 * @param[in] unitNumber
727 * Unit number
728 *
729 * @return
730 * Pointer to ADC device
731 ******************************************************************************/
rt_hw_adc_unit_init(rt_device_t device,rt_uint8_t unitNumber)732 static struct efm32_adc_device_t *rt_hw_adc_unit_init(
733 rt_device_t device,
734 rt_uint8_t unitNumber)
735 {
736 struct efm32_adc_device_t *adc;
737 CMU_Clock_TypeDef adcClock;
738 ADC_Init_TypeDef init = ADC_INIT_DEFAULT;
739
740 do
741 {
742 /* Allocate device and set default value */
743 adc = rt_malloc(sizeof(struct efm32_adc_device_t));
744 if (adc == RT_NULL)
745 {
746 adc_debug("no memory for ADC%d driver\n", unitNumber);
747 break;
748 }
749 adc->mode = 0;
750 adc->singleCount = 0;
751 adc->singleDmaChannel = (rt_uint8_t)EFM32_NO_DMA;
752 adc->scanCount = 0;
753 adc->scanDmaChannel = (rt_uint8_t)EFM32_NO_DMA;
754
755 /* Initialization */
756 if (unitNumber >= ADC_COUNT)
757 {
758 break;
759 }
760 switch (unitNumber)
761 {
762 case 0:
763 adc->adc_device = ADC0;
764 adcClock = (CMU_Clock_TypeDef)cmuClock_ADC0;
765 break;
766
767 default:
768 break;
769 }
770
771 /* Enable ADC clock */
772 CMU_ClockEnable(adcClock, true);
773
774 /* Reset */
775 ADC_Reset(adc->adc_device);
776
777 /* Configure ADC */
778 // TODO: Fixed oversampling rate?
779 init.ovsRateSel = adcOvsRateSel4096;
780 init.timebase = ADC_TimebaseCalc(0);
781 init.prescale = ADC_PrescaleCalc(ADC_CONVERT_FREQUENCY, 0);
782 ADC_Init(adc->adc_device, &init);
783
784 return adc;
785 } while(0);
786
787 if (adc)
788 {
789 rt_free(adc);
790 }
791 rt_kprintf("ADC: Init failed!\n");
792 return RT_NULL;
793 }
794
795 /***************************************************************************//**
796 * @brief
797 * Initialize all ADC module related hardware and register ADC device to kernel
798 *
799 * @details
800 *
801 * @note
802 *
803 ******************************************************************************/
rt_hw_adc_init(void)804 void rt_hw_adc_init(void)
805 {
806 SYSTEM_ChipRevision_TypeDef chipRev;
807 struct efm32_adc_device_t *adc;
808
809 #ifdef RT_USING_ADC0
810 if ((adc = rt_hw_adc_unit_init(&adc0_device, 0)) != RT_NULL)
811 {
812 rt_hw_adc_register(&adc0_device, RT_ADC0_NAME, EFM32_NO_DATA, adc);
813 }
814 #endif
815
816 /* ADC errata for rev B when using VDD as reference, need to multiply */
817 /* result by 2 */
818 SYSTEM_ChipRevisionGet(&chipRev);
819 if ((chipRev.major == 0x01) && (chipRev.minor == 0x01))
820 {
821 adcErrataShift = 1;
822 }
823 }
824
825 #endif
826 /***************************************************************************//**
827 * @}
828 ******************************************************************************/
829