1 /******************************************************************************
2 * Copyright (C) 2017, Huada Semiconductor Co.,Ltd All rights reserved.
3 *
4 * This software is owned and published by:
5 * Huada Semiconductor Co.,Ltd ("HDSC").
6 *
7 * BY DOWNLOADING, INSTALLING OR USING THIS SOFTWARE, YOU AGREE TO BE BOUND
8 * BY ALL THE TERMS AND CONDITIONS OF THIS AGREEMENT.
9 *
10 * This software contains source code for use with HDSC
11 * components. This software is licensed by HDSC to be adapted only
12 * for use in systems utilizing HDSC components. HDSC shall not be
13 * responsible for misuse or illegal use of this software for devices not
14 * supported herein. HDSC is providing this software "AS IS" and will
15 * not be responsible for issues arising from incorrect user implementation
16 * of the software.
17 *
18 * Disclaimer:
19 * HDSC MAKES NO WARRANTY, EXPRESS OR IMPLIED, ARISING BY LAW OR OTHERWISE,
20 * REGARDING THE SOFTWARE (INCLUDING ANY ACOOMPANYING WRITTEN MATERIALS),
21 * ITS PERFORMANCE OR SUITABILITY FOR YOUR INTENDED USE, INCLUDING,
22 * WITHOUT LIMITATION, THE IMPLIED WARRANTY OF MERCHANTABILITY, THE IMPLIED
23 * WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE OR USE, AND THE IMPLIED
24 * WARRANTY OF NONINFRINGEMENT.
25 * HDSC SHALL HAVE NO LIABILITY (WHETHER IN CONTRACT, WARRANTY, TORT,
26 * NEGLIGENCE OR OTHERWISE) FOR ANY DAMAGES WHATSOEVER (INCLUDING, WITHOUT
27 * LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION,
28 * LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY LOSS) ARISING FROM USE OR
29 * INABILITY TO USE THE SOFTWARE, INCLUDING, WITHOUT LIMITATION, ANY DIRECT,
30 * INDIRECT, INCIDENTAL, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOSS OF DATA,
31 * SAVINGS OR PROFITS,
32 * EVEN IF Disclaimer HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
33 * YOU ASSUME ALL RESPONSIBILITIES FOR SELECTION OF THE SOFTWARE TO ACHIEVE YOUR
34 * INTENDED RESULTS, AND FOR THE INSTALLATION OF, USE OF, AND RESULTS OBTAINED
35 * FROM, THE SOFTWARE.
36 *
37 * This software may be replicated in part or whole for the licensed use,
38 * with the restriction that this Disclaimer and Copyright notice must be
39 * included with each copy of this software, whether used in part or whole,
40 * at all times.
41 */
42 /******************************************************************************/
43 /** \file adc.c
44 **
45 ** ADC driver API.
46 **
47 ** - 2017-06-28 Alex First Version
48 **
49 ******************************************************************************/
50
51 /******************************************************************************
52 * Include files
53 ******************************************************************************/
54 #include "hc32l196_adc.h"
55
56 /**
57 ******************************************************************************
58 ** \addtogroup AdcGroup
59 ******************************************************************************/
60 //@{
61
62 /******************************************************************************
63 * Local pre-processor symbols/macros ('#define')
64 ******************************************************************************/
65
66 /******************************************************************************
67 * Global variable definitions (declared in header file with 'extern')
68 ******************************************************************************/
69
70 /******************************************************************************
71 * Local type definitions ('typedef')
72 ******************************************************************************/
73
74 /******************************************************************************
75 * Local function prototypes ('static')
76 ******************************************************************************/
77
78 /******************************************************************************
79 * Local variable definitions ('static')
80 ******************************************************************************/
81
82 /*****************************************************************************
83 * Function implementation - global ('extern') and local ('static')
84 *****************************************************************************/
85 /**
86 * \brief
87 * 获取ADC中断状态
88 *
89 * \param [in] enAdcIrq ADC中断类型 @ref en_adc_irq_type_t
90 *
91 * \retval 中断标志
92 */
Adc_GetIrqStatus(en_adc_irq_type_t enAdcIrq)93 boolean_t Adc_GetIrqStatus(en_adc_irq_type_t enAdcIrq)
94 {
95 if(M0P_ADC->IFR&enAdcIrq)
96 {
97 return TRUE;
98 }
99 else
100 {
101 return FALSE;
102 }
103 }
104
105 /**
106 * \brief
107 * 获取ADC中断状态
108 *
109 * \param [in] enAdcIrq ADC中断类型 @ref en_adc_irq_type_t
110 *
111 * \retval Null
112 */
Adc_ClrIrqStatus(en_adc_irq_type_t enAdcIrq)113 void Adc_ClrIrqStatus(en_adc_irq_type_t enAdcIrq)
114 {
115 M0P_ADC->ICR &= ~(uint32_t)enAdcIrq;
116 }
117
118 /**
119 * \brief
120 * ADC中断使能
121 *
122 * \param 无
123 *
124 * \retval 无
125 */
Adc_EnableIrq(void)126 void Adc_EnableIrq(void)
127 {
128 M0P_ADC->CR0_f.IE = 1u;
129 }
130
131 /**
132 * \brief
133 * ADC中断禁止
134 *
135 * \param 无
136 *
137 * \retval 无
138 */
Adc_DisableIrq(void)139 void Adc_DisableIrq(void)
140 {
141 M0P_ADC->CR0_f.IE = 0u;
142 }
143
144 /**
145 * \brief
146 * ADC初始化
147 *
148 * \param [in] pstcAdcCfg ADC配置指针
149 *
150 * \retval en_result_t Ok: 配置成功
151 * \retval en_result_t ErrorInvalidParameter: 无效参数
152 */
Adc_Init(stc_adc_cfg_t * pstcAdcCfg)153 en_result_t Adc_Init(stc_adc_cfg_t* pstcAdcCfg)
154 {
155 if (NULL == pstcAdcCfg)
156 {
157 return ErrorInvalidParameter;
158 }
159
160 M0P_ADC->CR0 = 0x1u; ///< ADC 使能
161 delay10us(2);
162
163 M0P_ADC->CR0 |= (uint32_t)pstcAdcCfg->enAdcClkDiv |
164 (uint32_t)pstcAdcCfg->enAdcRefVolSel |
165 (uint32_t)pstcAdcCfg->enAdcOpBuf |
166 (uint32_t)pstcAdcCfg->enAdcSampCycleSel |
167 (uint32_t)pstcAdcCfg->enInRef;
168
169 M0P_ADC->CR1_f.MODE = pstcAdcCfg->enAdcMode;
170 M0P_ADC->CR1_f.ALIGN = pstcAdcCfg->enAdcAlign;
171
172 return Ok;
173 }
174
175
176 /**
177 * \brief
178 * ADC单次转换外部中断触发源配置
179 *
180 * \param [in] enAdcTrigSel 触发源
181 *
182 * \retval en_result_t Null
183 */
Adc_SglExtTrigCfg(en_adc_trig_sel_t enAdcTrigSel,boolean_t bValue)184 void Adc_SglExtTrigCfg(en_adc_trig_sel_t enAdcTrigSel, boolean_t bValue)
185 {
186 if(TRUE == bValue)
187 {
188 M0P_ADC->EXTTRIGGER0 |= (uint32_t)enAdcTrigSel;
189 }
190 else
191 {
192 M0P_ADC->EXTTRIGGER0 &= ~(uint32_t)enAdcTrigSel;
193 }
194
195 }
196
197 /**
198 * \brief
199 * ADC顺序扫描转换外部中断触发源配置
200 *
201 * \param [in] enAdcTrigSel 触发源
202 * \param [in] TRUE or FALSE
203 *
204 * \retval en_result_t Null
205 */
Adc_SqrExtTrigCfg(en_adc_trig_sel_t enAdcTrigSel,boolean_t bValue)206 void Adc_SqrExtTrigCfg(en_adc_trig_sel_t enAdcTrigSel, boolean_t bValue)
207 {
208 if(TRUE == bValue)
209 {
210 M0P_ADC->EXTTRIGGER0 |= (uint32_t)enAdcTrigSel;
211 }
212 else
213 {
214 M0P_ADC->EXTTRIGGER0 &= ~(uint32_t)enAdcTrigSel;
215 }
216
217 }
218
219 /**
220 * \brief
221 * ADC插队扫描转换外部中断触发源配置
222 *
223 * \param [in] enAdcTrigSel 触发源
224 * \param [in] TRUE or FALSE
225 *
226 * \retval en_result_t Null
227 */
Adc_JqrExtTrigCfg(en_adc_trig_sel_t enAdcTrigSel,boolean_t bValue)228 void Adc_JqrExtTrigCfg(en_adc_trig_sel_t enAdcTrigSel, boolean_t bValue)
229 {
230 if(TRUE == bValue)
231 {
232 M0P_ADC->EXTTRIGGER1 |= (uint32_t)enAdcTrigSel;
233 }
234 else
235 {
236 M0P_ADC->EXTTRIGGER1 &= ~(uint32_t)enAdcTrigSel;
237 }
238
239 }
240
241
242 /**
243 * \brief
244 * ADC 单次转换开始
245 *
246 * \param 无
247 *
248 * \retval 无
249 */
250
Adc_SGL_Start(void)251 void Adc_SGL_Start(void)
252 {
253 M0P_ADC->SGLSTART = 1u;
254 }
255
256 /**
257 * \brief
258 * ADC 单次转换停止
259 *
260 * \param 无
261 *
262 * \retval 无
263 */
Adc_SGL_Stop(void)264 void Adc_SGL_Stop(void)
265 {
266 M0P_ADC->SGLSTART = 0u;
267 }
268
269 /**
270 * \brief
271 * ADC 单次转换一直转换开始
272 *
273 * \param 无
274 *
275 * \retval 无
276 */
277
Adc_SGL_Always_Start(void)278 void Adc_SGL_Always_Start(void)
279 {
280 M0P_ADC->ALLSTART = 1u;
281 }
282
283 /**
284 * \brief
285 * ADC 单次转换一直转换停止
286 *
287 * \param 无
288 *
289 * \retval 无
290 */
291
Adc_SGL_Always_Stop(void)292 void Adc_SGL_Always_Stop(void)
293 {
294 M0P_ADC->ALLSTART = 0u;
295 }
296
297 /**
298 * \brief
299 * ADC 顺序扫描转换开始
300 *
301 * \param 无
302 *
303 * \retval 无
304 */
305
Adc_SQR_Start(void)306 void Adc_SQR_Start(void)
307 {
308 M0P_ADC->SQRSTART = 1u;
309 }
310
311 /**
312 * \brief
313 * ADC 顺序扫描转换停止
314 *
315 * \param 无
316 *
317 * \retval 无
318 */
Adc_SQR_Stop(void)319 void Adc_SQR_Stop(void)
320 {
321 M0P_ADC->SQRSTART = 0u;
322 }
323 /**
324 * \brief
325 * ADC 插队扫描转换开始
326 *
327 * \param 无
328 *
329 * \retval 无
330 */
331
Adc_JQR_Start(void)332 void Adc_JQR_Start(void)
333 {
334 M0P_ADC->JQRSTART = 1u;
335 }
336
337 /**
338 * \brief
339 * ADC 插队扫描转换停止
340 *
341 * \param 无
342 *
343 * \retval 无
344 */
Adc_JQR_Stop(void)345 void Adc_JQR_Stop(void)
346 {
347 M0P_ADC->JQRSTART = 0u;
348 }
349
350 /**
351 * \brief
352 * ADC使能
353 *
354 * \param 无
355 *
356 * \retval 无
357 */
Adc_Enable(void)358 void Adc_Enable(void)
359 {
360 M0P_ADC->CR0_f.EN = 1u;
361 }
362
363 /**
364 * \brief
365 * ADC除能
366 *
367 * \param 无
368 *
369 * \retval 无
370 */
Adc_Disable(void)371 void Adc_Disable(void)
372 {
373 M0P_ADC->CR0_f.EN = 0u;
374 }
375
376 /**
377 * \brief
378 * 配置顺序扫描转换模式
379 *
380 * \param [in] pstcAdcCfg ADC配置指针
381 * \param [in] pstcAdcNormCfg 连续转换模式配置指针
382 *
383 * \retval en_result_t Ok: 配置成功
384 * \retval en_result_t ErrorInvalidParameter: 无效参数
385 */
Adc_SqrModeCfg(stc_adc_sqr_cfg_t * pstcAdcSqrCfg)386 en_result_t Adc_SqrModeCfg(stc_adc_sqr_cfg_t* pstcAdcSqrCfg)
387 {
388 if ((NULL == pstcAdcSqrCfg) || (pstcAdcSqrCfg->u8SqrCnt > 16))
389 {
390 return ErrorInvalidParameter;
391 }
392
393 M0P_ADC->CR1_f.RACCCLR = 0; //ADC转换结果累加寄存器(ADC_ResultAcc)清零
394 M0P_ADC->CR1_f.RACCEN = pstcAdcSqrCfg->enResultAcc;
395 M0P_ADC->CR1_f.DMASQR = pstcAdcSqrCfg->bSqrDmaTrig;
396
397 M0P_ADC->SQR2_f.CNT = pstcAdcSqrCfg->u8SqrCnt - 1;
398
399 return Ok;
400 }
401
402 /**
403 * \brief
404 * 配置插队扫描转换模式
405 *
406 * \param [in] pstcAdcCfg ADC配置指针
407 * \param [in] pstcAdcNormCfg 扫描转换模式配置指针
408 *
409 * \retval en_result_t Ok: 配置成功
410 * \retval en_result_t ErrorInvalidParameter: 无效参数
411 */
Adc_JqrModeCfg(stc_adc_jqr_cfg_t * pstcAdcJqrCfg)412 en_result_t Adc_JqrModeCfg(stc_adc_jqr_cfg_t* pstcAdcJqrCfg)
413 {
414 if ((NULL == pstcAdcJqrCfg) || (pstcAdcJqrCfg->u8JqrCnt > 4))
415 {
416 return ErrorInvalidParameter;
417 }
418
419 M0P_ADC->CR1_f.DMASQR = pstcAdcJqrCfg->bJqrDmaTrig;
420
421 M0P_ADC->JQR_f.CNT = pstcAdcJqrCfg->u8JqrCnt - 1;
422
423 return Ok;
424 }
425
426 /**
427 * \brief
428 * 配置单次转换通道
429 *
430 * \param [in]enstcAdcSampCh 转换通道
431 *
432 * \retval en_result_t Ok: 成功
433 * \retval en_result_t ErrorInvalidParameter: 无效参数
434 */
Adc_CfgSglChannel(en_adc_samp_ch_sel_t enstcAdcSampCh)435 en_result_t Adc_CfgSglChannel( en_adc_samp_ch_sel_t enstcAdcSampCh)
436 {
437 M0P_ADC->CR0_f.SGLMUX = enstcAdcSampCh;
438
439 return Ok;
440 }
441
442 /**
443 * \brief
444 * 配置顺序扫描转换通道
445 *
446 * \param [in]enstcAdcSqrChMux 顺序扫描转换通道顺序
447 * \param [in]enstcAdcSampCh 转换通道
448 *
449 * \retval en_result_t Ok: 成功
450 * \retval en_result_t ErrorInvalidParameter: 无效参数
451 */
Adc_CfgSqrChannel(en_adc_sqr_chmux_t enstcAdcSqrChMux,en_adc_samp_ch_sel_t enstcAdcSampCh)452 en_result_t Adc_CfgSqrChannel(en_adc_sqr_chmux_t enstcAdcSqrChMux, en_adc_samp_ch_sel_t enstcAdcSampCh)
453 {
454 en_result_t enResult = Ok;
455
456 switch(enstcAdcSqrChMux)
457 {
458 case AdcSQRCH0MUX:
459 M0P_ADC->SQR0_f.CH0MUX = enstcAdcSampCh;
460 break;
461 case AdcSQRCH1MUX:
462 M0P_ADC->SQR0_f.CH1MUX = enstcAdcSampCh;
463 break;
464 case AdcSQRCH2MUX:
465 M0P_ADC->SQR0_f.CH2MUX = enstcAdcSampCh;
466 break;
467 case AdcSQRCH3MUX:
468 M0P_ADC->SQR0_f.CH3MUX = enstcAdcSampCh;
469 break;
470 case AdcSQRCH4MUX:
471 M0P_ADC->SQR0_f.CH4MUX = enstcAdcSampCh;
472 break;
473 case AdcSQRCH5MUX:
474 M0P_ADC->SQR0_f.CH5MUX = enstcAdcSampCh;
475 break;
476 case AdcSQRCH6MUX:
477 M0P_ADC->SQR1_f.CH6MUX = enstcAdcSampCh;
478 break;
479 case AdcSQRCH7MUX:
480 M0P_ADC->SQR1_f.CH7MUX = enstcAdcSampCh;
481 break;
482 case AdcSQRCH8MUX:
483 M0P_ADC->SQR1_f.CH8MUX = enstcAdcSampCh;
484 break;
485 case AdcSQRCH9MUX:
486 M0P_ADC->SQR1_f.CH9MUX = enstcAdcSampCh;
487 break;
488 case AdcSQRCH10MUX:
489 M0P_ADC->SQR1_f.CH10MUX = enstcAdcSampCh;
490 break;
491 case AdcSQRCH11MUX:
492 M0P_ADC->SQR1_f.CH11MUX = enstcAdcSampCh;
493 break;
494 case AdcSQRCH12MUX:
495 M0P_ADC->SQR2_f.CH12MUX = enstcAdcSampCh;
496 break;
497 case AdcSQRCH13MUX:
498 M0P_ADC->SQR2_f.CH13MUX = enstcAdcSampCh;
499 break;
500 case AdcSQRCH14MUX:
501 M0P_ADC->SQR2_f.CH14MUX = enstcAdcSampCh;
502 break;
503 case AdcSQRCH15MUX:
504 M0P_ADC->SQR2_f.CH15MUX = enstcAdcSampCh;
505 break;
506 default:
507 enResult = ErrorInvalidParameter;
508 break;
509
510 }
511
512 return enResult;
513 }
514 /**
515 * \brief
516 * 配置插队扫描转换通道
517 *
518 * \param [in]enstcAdcSqrChMux 插队扫描转换通道顺序
519 * \param [in]enstcAdcSampCh 转换通道
520 *
521 * \retval en_result_t Ok: 成功
522 * \retval en_result_t ErrorInvalidParameter: 无效参数
523 */
Adc_CfgJqrChannel(en_adc_jqr_chmux_t enstcAdcJqrChMux,en_adc_samp_ch_sel_t enstcAdcSampCh)524 en_result_t Adc_CfgJqrChannel(en_adc_jqr_chmux_t enstcAdcJqrChMux, en_adc_samp_ch_sel_t enstcAdcSampCh)
525 {
526 en_result_t enResult = Ok;
527
528 switch(enstcAdcJqrChMux)
529 {
530 case AdcJQRCH0MUX:
531 M0P_ADC->JQR_f.CH0MUX = enstcAdcSampCh;
532 break;
533 case AdcJQRCH1MUX:
534 M0P_ADC->JQR_f.CH1MUX = enstcAdcSampCh;
535 break;
536 case AdcJQRCH2MUX:
537 M0P_ADC->JQR_f.CH2MUX = enstcAdcSampCh;
538 break;
539 case AdcJQRCH3MUX:
540 M0P_ADC->JQR_f.CH3MUX = enstcAdcSampCh;
541 break;
542 default:
543 enResult = ErrorInvalidParameter;
544 break;
545 }
546
547 return enResult;
548 }
549
550 /**
551 * \brief
552 * 获取采样值
553 *
554 *
555 * \retval en_result_t 采样值
556 */
Adc_GetSglResult(void)557 uint32_t Adc_GetSglResult(void)
558 {
559 return M0P_ADC->RESULT;
560 }
561
562 /**
563 * \brief
564 * 获取采样值
565 *
566 * \param [in] enstcAdcSqrChMux 顺序扫描通道序号 @ref en_adc_sqr_chmux_t
567 *
568 * \retval en_result_t 采样值
569 */
Adc_GetSqrResult(en_adc_sqr_chmux_t enstcAdcSqrChMux)570 uint32_t Adc_GetSqrResult(en_adc_sqr_chmux_t enstcAdcSqrChMux)
571 {
572 volatile uint32_t *BaseSqrResultAddress = &(M0P_ADC->SQRRESULT0);
573
574 return *(BaseSqrResultAddress + enstcAdcSqrChMux);
575
576 }
577
578 /**
579 * \brief
580 * 获取插队扫描采样值
581 *
582 * \param [in] enstcAdcJqrChMux 插队扫描通道序号@ref en_adc_jqr_chmux_t
583 *
584 * \retval en_result_t 采样值
585 */
Adc_GetJqrResult(en_adc_jqr_chmux_t enstcAdcJqrChMux)586 uint32_t Adc_GetJqrResult(en_adc_jqr_chmux_t enstcAdcJqrChMux)
587 {
588 volatile uint32_t *BaseJqrResultAddress = &(M0P_ADC->JQRRESULT0);
589
590 return *(BaseJqrResultAddress + enstcAdcJqrChMux);
591
592 }
593
594 /**
595 * \brief
596 * 获取累加采样值
597 *
598 *
599 * \retval en_result_t 累加采样结果
600 */
Adc_GetAccResult(void)601 uint32_t Adc_GetAccResult(void)
602 {
603 return M0P_ADC->RESULTACC;
604
605 }
606
607 /**
608 * \brief
609 * 清零累加采样值
610 *
611 * \param 无
612 *
613 * \retval 无
614 */
Adc_ClrAccResult(void)615 void Adc_ClrAccResult(void)
616 {
617 M0P_ADC->CR1_f.RACCCLR = 0u;
618 }
619
620 /**
621 * \brief
622 * ADC比较使能(比较中断)
623 *
624 * \param [in] pstcAdcIrqCfg ADC比较配置 @ref stc_adc_threshold_cfg_t
625 *
626 * \retval 无
627 */
628
Adc_ThresholdCfg(stc_adc_threshold_cfg_t * pstcAdcThrCfg)629 void Adc_ThresholdCfg(stc_adc_threshold_cfg_t* pstcAdcThrCfg)
630 {
631 M0P_ADC->HT = pstcAdcThrCfg->u32AdcHighThd;
632 M0P_ADC->LT = pstcAdcThrCfg->u32AdcLowThd;
633
634 M0P_ADC->CR1_f.THCH = pstcAdcThrCfg->enSampChSel;
635
636 M0P_ADC->CR1_f.REGCMP = pstcAdcThrCfg->bAdcRegCmp;
637 M0P_ADC->CR1_f.HTCMP = pstcAdcThrCfg->bAdcHtCmp;
638 M0P_ADC->CR1_f.LTCMP = pstcAdcThrCfg->bAdcLtCmp;
639
640 }
641
642
643 //@} // AdcGroup
644
645
646 /******************************************************************************
647 * EOF (not truncated)
648 ******************************************************************************/
649
650