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 vc.c
44 **
45 ** voltage comparator driver API.
46 ** @link VC Group Some description @endlink
47 **
48 ** - 2017-06-28 Alex First Version
49 **
50 ******************************************************************************/
51
52 /******************************************************************************
53 * Include files
54 ******************************************************************************/
55 #include "vc.h"
56
57 /**
58 ******************************************************************************
59 ** \addtogroup VcGroup
60 ******************************************************************************/
61 //@{
62
63 /******************************************************************************
64 * Local pre-processor symbols/macros ('#define')
65 ******************************************************************************/
66 #define IS_VALID_CHANNEL(x) ( VcChannel0==(x) || VcChannel1 == (x))
67 #define IS_VALID_STAT(x) ( VcCmpResult==(x) || VcIntrResult == (x))
68 #define IS_VALID_DIV(x) ( (x) <= 64u )
69
70 #define IS_VALID_INPUT_P(x) ( (x) <= VcInPCh15 )
71
72 #define IS_VALID_INPUT_N(x) ( (x) <= AiLdo )
73
74 #define IS_VALID_DLY(x) ( (VcDelay30mv == (x)) ||\
75 (VcDelay20mv == (x)) ||\
76 (VcDelay10mv == (x)) ||\
77 (VcDelayoff == (x)) )
78
79 #define IS_VALID_BIAS(x) ( (VcBias300na == (x)) ||\
80 (VcBias1200na == (x)) ||\
81 (VcBias10ua == (x)) ||\
82 (VcBias20ua == (x)) )
83
84 #define IS_VALID_FILTER(x) ( (x) <= VcFilter28800us )
85
86
87
88 /******************************************************************************
89 * Global variable definitions (declared in header file with 'extern')
90 ******************************************************************************/
91
92
93 /******************************************************************************
94 * Local type definitions ('typedef')
95 ******************************************************************************/
96
97 /******************************************************************************
98 * Local function prototypes ('static')
99 ******************************************************************************/
100 static en_result_t VcEnableIrq(en_vc_channel_t enChannel, boolean_t bFlag);
101 static void VcEnableNvic(IRQn_Type enIrqn);
102 static void VcDisableNvic(IRQn_Type enIrqn);
103
104 /******************************************************************************
105 * Local variable definitions ('static')
106 ******************************************************************************/
107 static func_ptr_t pfnVc0IrqCb = NULL;
108 static func_ptr_t pfnVc1IrqCb = NULL;
109
110 /*****************************************************************************
111 * Function implementation - global ('extern') and local ('static')
112 *****************************************************************************/
113
114 /**
115 * \brief
116 * 指定VC通道中断使能/除能
117 *
118 * \param [in] enChannel VC通道号
119 * \param [in] bFlag 使能/除能标志
120 *
121 * \retval en_result_t Ok: 设置成功
122 * \retval en_result_t ErrorInvalidParameter: 无效参数
123 */
VcEnableIrq(en_vc_channel_t enChannel,boolean_t bFlag)124 static en_result_t VcEnableIrq(en_vc_channel_t enChannel, boolean_t bFlag)
125 {
126 if (VcChannel0 == enChannel)
127 {
128 if (bFlag)
129 {
130 VcEnableNvic(VC0_IRQn);
131 M0P_VC->VC0_CR_f.IE = 1u;
132 }
133 else
134 {
135 M0P_VC->VC0_CR_f.IE = 0u;
136 VcDisableNvic(VC0_IRQn);
137 }
138 }
139 else if (VcChannel1 == enChannel)
140 {
141 if (bFlag)
142 {
143 VcEnableNvic(VC1_IRQn);
144 M0P_VC->VC1_CR_f.IE = 1u;
145 }
146 else
147 {
148 M0P_VC->VC1_CR_f.IE = 0u;
149 VcDisableNvic(VC1_IRQn);
150 }
151 }
152 else
153 {
154 return ErrorInvalidParameter;
155 }
156
157 return Ok;
158 }
159
160 /**
161 * \brief
162 * 使能NVIC中VC中断
163 *
164 * \param [in] enIrqn 中断号
165 *
166 * \retval 无
167 */
VcEnableNvic(IRQn_Type enIrqn)168 static void VcEnableNvic(IRQn_Type enIrqn)
169 {
170 NVIC_ClearPendingIRQ(enIrqn);
171 NVIC_EnableIRQ(enIrqn);
172 NVIC_SetPriority(enIrqn, IrqLevel3);
173 }
174
175 /**
176 * \brief
177 * 除能NVIC中VC中断
178 *
179 * \param [in] enIrqn 中断号
180 *
181 * \retval 无
182 */
VcDisableNvic(IRQn_Type enIrqn)183 static void VcDisableNvic(IRQn_Type enIrqn)
184 {
185 NVIC_ClearPendingIRQ(enIrqn);
186 NVIC_DisableIRQ(enIrqn);
187 NVIC_SetPriority(enIrqn, IrqLevel3);
188 }
189
190 /**
191 * \brief
192 * VC中断服务程序
193 *
194 * \param [in] u8Param VC通道号
195 *
196 * \retval 无
197 */
Vc_IRQHandler(uint8_t u8Param)198 void Vc_IRQHandler(uint8_t u8Param)
199 {
200 if (0 == u8Param)
201 {
202 if (TRUE == M0P_VC->IFR_f.VC0_INTF)
203 {
204 if (NULL != pfnVc0IrqCb)
205 {
206 pfnVc0IrqCb();
207 }
208 M0P_VC->IFR_f.VC0_INTF = 0;
209 }
210 }
211 else if (1 == u8Param)
212 {
213 if (TRUE == M0P_VC->IFR_f.VC1_INTF)
214 {
215 if (NULL != pfnVc1IrqCb)
216 {
217 pfnVc1IrqCb();
218 }
219 M0P_VC->IFR_f.VC1_INTF = 0;
220 }
221 }
222 else
223 {
224 ; // just return
225 }
226 }
227
228 /**
229 * \brief
230 * 配置VC中断触发方式
231 *
232 * \param [in] enChannel VC通道号
233 * \param [in] enSel 中断触发方式选择
234 *
235 * \retval en_result_t Ok: 设置成功
236 * \retval en_result_t ErrorInvalidParameter: 无效参数
237 */
Vc_ConfigIrq(en_vc_channel_t enChannel,en_vc_irq_sel_t enSel)238 en_result_t Vc_ConfigIrq(en_vc_channel_t enChannel, en_vc_irq_sel_t enSel)
239 {
240 stc_vc_vc0_cr_field_t *stcVcnCr;
241 en_result_t enRet = Ok;
242
243 if (VcChannel0 == enChannel)
244 {
245 stcVcnCr = (stc_vc_vc0_cr_field_t*)&M0P_VC->VC0_CR_f;
246 }
247 else if (VcChannel1 == enChannel)
248 {
249 stcVcnCr = (stc_vc_vc0_cr_field_t*)&M0P_VC->VC1_CR_f;
250 }
251 else
252 {
253 return ErrorInvalidParameter;
254 }
255
256 switch (enSel)
257 {
258 case VcIrqRise:
259 stcVcnCr->RISING = 1u;
260 break;
261 case VcIrqFall:
262 stcVcnCr->FALLING = 1u;
263 break;
264 case VcIrqHigh:
265 stcVcnCr->LEVEL = 1u;
266 break;
267
268 default:
269 enRet= ErrorInvalidParameter;
270 break;
271 }
272
273 return enRet;
274 }
275
276 /**
277 * \brief
278 * 获取VC状态
279 *
280 * \param [in] enChannel VC通道号
281 * \param [in] enStat VC状态类型
282 *
283 * \retval boolean_t TRUE: 状态为高
284 * \retval boolean_t FALSE: 状态为低
285 */
Vc_GetStat(en_vc_channel_t enChannel,en_vc_stat_t enStat)286 boolean_t Vc_GetStat(en_vc_channel_t enChannel, en_vc_stat_t enStat)
287 {
288 boolean_t bFlag = FALSE;
289
290 ASSERT( IS_VALID_CHANNEL(enChannel) );
291 ASSERT( IS_VALID_STAT(enStat) );
292
293 if (VcChannel0 == enChannel)
294 {
295 switch (enStat)
296 {
297 case VcCmpResult:
298 bFlag = M0P_VC->IFR_f.VC0_FILTER;
299 break;
300 case VcIntrResult:
301 bFlag = M0P_VC->IFR_f.VC0_INTF;
302 break;
303 default:
304 break;
305 }
306 }
307 else
308 {
309 switch (enStat)
310 {
311 case VcCmpResult:
312 bFlag = M0P_VC->IFR_f.VC1_FILTER;
313 break;
314 case VcIntrResult:
315 bFlag = M0P_VC->IFR_f.VC1_INTF;
316 break;
317 default:
318 break;
319 }
320 }
321
322 return bFlag;
323 }
324
325 /**
326 * \brief
327 * 清除VC中断标志
328 *
329 * \param [in] enChannel VC通道号
330 *
331 * \retval 无
332 */
Vc_ClearIrq(en_vc_channel_t enChannel)333 void Vc_ClearIrq(en_vc_channel_t enChannel)
334 {
335 ASSERT( IS_VALID_CHANNEL(enChannel) );
336
337 if (VcChannel0 == enChannel)
338 {
339 M0P_VC->IFR_f.VC0_INTF = 0u;
340 }
341 else
342 {
343 M0P_VC->IFR_f.VC1_INTF = 0u;
344 }
345 }
346
347 /**
348 * \brief
349 * 指定VC通道中断使能
350 *
351 * \param [in] enChannel VC通道号
352 *
353 * \retval en_result_t Ok: 设置成功
354 * \retval en_result_t ErrorInvalidParameter: 无效参数
355 */
Vc_EnableIrq(en_vc_channel_t enChannel)356 en_result_t Vc_EnableIrq(en_vc_channel_t enChannel)
357 {
358 return VcEnableIrq(enChannel, TRUE);
359 }
360
361 /**
362 * \brief
363 * 指定VC通道中断除能
364 *
365 * \param [in] enChannel VC通道号
366 *
367 * \retval en_result_t Ok: 设置成功
368 * ErrorInvalidParameter: 无效参数
369 */
Vc_DisableIrq(en_vc_channel_t enChannel)370 en_result_t Vc_DisableIrq(en_vc_channel_t enChannel)
371 {
372 return VcEnableIrq(enChannel, FALSE);
373 }
374
375 /**
376 * \brief
377 * VC模块初始化
378 *
379 * \param [in] pstcGeneralConfig VC模块配置指针
380 *
381 * \retval en_result_t Ok: 配置成功
382 * \retval en_result_t ErrorInvalidParameter: 无效参数
383 */
Vc_DACInit(stc_vc_dac_config_t * pstcDacConfig)384 en_result_t Vc_DACInit(stc_vc_dac_config_t *pstcDacConfig)
385 {
386 if (NULL == pstcDacConfig)
387 {
388 return ErrorInvalidParameter;
389 }
390
391 M0P_VC->CR_f.DIV_EN = pstcDacConfig->bDivEn;
392 M0P_VC->CR_f.REF2P5_SEL = pstcDacConfig->enDivVref;
393
394 if (pstcDacConfig->u8DivVal < 0x40)
395 {
396 M0P_VC->CR_f.DIV = pstcDacConfig->u8DivVal;
397 }
398 else
399 {
400 return ErrorInvalidParameter;
401 }
402
403 return Ok;
404 }
405
406 /**
407 * \brief
408 * VC模块deinit
409 *
410 * \param 无
411 *
412 * \retval 无
413 */
Vc_DACDeInit(void)414 void Vc_DACDeInit(void)
415 {
416 M0P_VC->CR_f.DIV_EN = 0u;
417 M0P_VC->CR_f.DIV = 0x20u;
418 M0P_VC->CR_f.REF2P5_SEL = 0u;
419 }
420
421 /**
422 * \brief
423 * VC通道初始化
424 *
425 * \param [in] enChannel VC通道号
426 * \param [in] pstcChannelConfig VC通道配置指针
427 *
428 * \retval en_result_t Ok: 配置成功
429 * \retval en_result_t ErrorInvalidParameter: 无效参数
430 */
Vc_ChannelInit(en_vc_channel_t enChannel,stc_vc_channel_config_t * pstcChannelConfig)431 en_result_t Vc_ChannelInit(en_vc_channel_t enChannel,
432 stc_vc_channel_config_t *pstcChannelConfig)
433 {
434 //en_result_t enRet = Ok;
435
436 ASSERT(NULL != pstcChannelConfig);
437 ASSERT(IS_VALID_INPUT_P(pstcChannelConfig->enVcInPin_P));
438 ASSERT(IS_VALID_INPUT_N(pstcChannelConfig->enVcInPin_N));
439 ASSERT(IS_VALID_DLY(pstcChannelConfig->enVcCmpDly));
440 ASSERT(IS_VALID_BIAS(pstcChannelConfig->enVcBiasCurrent));
441 ASSERT(IS_VALID_FILTER(pstcChannelConfig->enVcFilterTime));
442
443 if (VcChannel0 == enChannel)
444 {
445 M0P_VC->CR_f.VC0_HYS_SEL = pstcChannelConfig->enVcCmpDly;
446 M0P_VC->CR_f.VC0_BIAS_SEL = pstcChannelConfig->enVcBiasCurrent;
447 M0P_VC->VC0_CR_f.DEBOUNCE_TIME = pstcChannelConfig->enVcFilterTime;
448 M0P_VC->VC0_CR_f.P_SEL = pstcChannelConfig->enVcInPin_P;
449 M0P_VC->VC0_CR_f.N_SEL = pstcChannelConfig->enVcInPin_N;
450 M0P_VC->VC0_OUT_CFG = 1<<pstcChannelConfig->enVcOutConfig;
451
452 switch(pstcChannelConfig->enVcIrqSel)
453 {
454 case VcIrqRise:
455 M0P_VC->VC0_CR_f.RISING = 1u;
456 break;
457 case VcIrqFall:
458 M0P_VC->VC0_CR_f.FALLING = 1u;
459 break;
460 case VcIrqHigh:
461 M0P_VC->VC0_CR_f.LEVEL = 1u;
462 break;
463 default:
464 M0P_VC->VC0_CR_f.LEVEL = 0u;
465 M0P_VC->VC0_CR_f.RISING = 0u;
466 M0P_VC->VC0_CR_f.FALLING = 0u;
467 break;
468 }
469
470 pfnVc0IrqCb = pstcChannelConfig->pfnAnalogCmpCb;
471 }
472 else if (VcChannel1 == enChannel)
473 {
474 M0P_VC->CR_f.VC1_HYS_SEL = pstcChannelConfig->enVcCmpDly;
475 M0P_VC->CR_f.VC1_BIAS_SEL = pstcChannelConfig->enVcBiasCurrent;
476 M0P_VC->VC1_CR_f.DEBOUNCE_TIME = pstcChannelConfig->enVcFilterTime;
477 M0P_VC->VC1_CR_f.P_SEL = pstcChannelConfig->enVcInPin_P;
478 M0P_VC->VC1_CR_f.N_SEL = pstcChannelConfig->enVcInPin_N;
479 M0P_VC->VC1_OUT_CFG = 1<<pstcChannelConfig->enVcOutConfig;
480
481 switch(pstcChannelConfig->enVcIrqSel)
482 {
483 case VcIrqRise:
484 M0P_VC->VC1_CR_f.RISING = 1u;
485 break;
486 case VcIrqFall:
487 M0P_VC->VC1_CR_f.FALLING = 1u;
488 break;
489 case VcIrqHigh:
490 M0P_VC->VC1_CR_f.LEVEL = 1u;
491 break;
492 default:
493 M0P_VC->VC1_CR_f.LEVEL = 0u;
494 M0P_VC->VC1_CR_f.RISING = 0u;
495 M0P_VC->VC1_CR_f.FALLING = 0u;
496 break;
497 }
498
499 pfnVc1IrqCb = pstcChannelConfig->pfnAnalogCmpCb;
500 }
501 else
502 {
503 return ErrorInvalidParameter;
504 }
505
506 return Ok;
507 }
508
509 /**
510 * \brief
511 * VC通道Deinit
512 *
513 * \param [in] enChannel VC通道号
514 *
515 * \retval en_result_t Ok: 配置成功
516 * \retval en_result_t ErrorInvalidParameter: 无效参数
517 */
Vc_ChannelDeInit(en_vc_channel_t enChannel)518 en_result_t Vc_ChannelDeInit(en_vc_channel_t enChannel)
519 {
520 if (VcChannel0 == enChannel)
521 {
522 M0P_VC->VC0_CR_f.EN = 0u;
523 M0P_VC->CR_f.VC0_HYS_SEL = 0;
524 M0P_VC->CR_f.VC0_BIAS_SEL = 0;
525 M0P_VC->VC0_CR_f.DEBOUNCE_TIME = 0;
526 M0P_VC->VC0_CR_f.P_SEL = 0;
527 M0P_VC->VC0_CR_f.N_SEL = 0;
528 M0P_VC->VC0_OUT_CFG = 0;
529 M0P_VC->VC0_CR_f.LEVEL = 0u;
530 M0P_VC->VC0_CR_f.RISING = 0u;
531 M0P_VC->VC0_CR_f.FALLING = 0u;
532 pfnVc0IrqCb = NULL;
533 M0P_VC->VC0_CR_f.IE = 0u;
534 VcDisableNvic(VC0_IRQn);
535 }
536 else if (VcChannel1 == enChannel)
537 {
538 M0P_VC->VC1_CR_f.EN = 0u;
539 M0P_VC->CR_f.VC1_HYS_SEL = 0;
540 M0P_VC->CR_f.VC1_BIAS_SEL = 0;
541 M0P_VC->VC1_CR_f.DEBOUNCE_TIME = 0;
542 M0P_VC->VC1_CR_f.P_SEL = 0;
543 M0P_VC->VC1_CR_f.N_SEL = 0;
544 M0P_VC->VC1_OUT_CFG = 0;
545 M0P_VC->VC1_CR_f.LEVEL = 0u;
546 M0P_VC->VC1_CR_f.RISING = 0u;
547 M0P_VC->VC1_CR_f.FALLING = 0u;
548 pfnVc1IrqCb = NULL;
549 M0P_VC->VC1_CR_f.IE = 0u;
550 VcDisableNvic(VC1_IRQn);
551 }
552 else
553 {
554 return ErrorInvalidParameter;
555 }
556
557 return Ok;
558 }
559
560 /**
561 * \brief
562 * VC通道使能
563 *
564 * \param [in] enChannel VC通道号
565 *
566 * \retval en_result_t Ok: 配置成功
567 * \retval en_result_t ErrorInvalidParameter: 无效参数
568 */
Vc_EnableChannel(en_vc_channel_t enChannel)569 en_result_t Vc_EnableChannel(en_vc_channel_t enChannel)
570 {
571 if (VcChannel0 == enChannel)
572 {
573 M0P_VC->VC0_CR_f.EN = 1u;
574 }
575 else if (VcChannel1 == enChannel)
576 {
577 M0P_VC->VC1_CR_f.EN = 1u;
578 }
579 else
580 {
581 return ErrorInvalidParameter;
582 }
583
584 return Ok;
585 }
586
587 /**
588 * \brief
589 * VC通道除能
590 *
591 * \param [in] enChannel VC通道号
592 *
593 * \retval en_result_t Ok: 配置成功
594 * \retval en_result_t ErrorInvalidParameter: 无效参数
595 */
Vc_DisableChannel(en_vc_channel_t enChannel)596 en_result_t Vc_DisableChannel(en_vc_channel_t enChannel)
597 {
598 if (VcChannel0 == enChannel)
599 {
600 M0P_VC->VC0_CR_f.EN = 0u;
601 }
602 else if (VcChannel1 == enChannel)
603 {
604 M0P_VC->VC1_CR_f.EN = 0u;
605 }
606 else
607 {
608 return ErrorInvalidParameter;
609 }
610
611 return Ok;
612 }
613
614 /**
615 * \brief
616 * VC输出滤波使能
617 *
618 * \param [in] enChannel VC通道号
619 *
620 * \retval en_result_t Ok: 配置成功
621 * \retval en_result_t ErrorInvalidParameter: 无效参数
622 */
Vc_EnableFilter(en_vc_channel_t enChannel)623 en_result_t Vc_EnableFilter(en_vc_channel_t enChannel)
624 {
625 if (VcChannel0 == enChannel)
626 {
627 M0P_VC->VC0_CR_f.FLTEN = 1u;
628 }
629 else if (VcChannel1 == enChannel)
630 {
631 M0P_VC->VC1_CR_f.FLTEN = 1u;
632 }
633 else
634 {
635 return ErrorInvalidParameter;
636 }
637
638 return Ok;
639 }
640
641 /**
642 * \brief
643 * VC输出滤波除能
644 *
645 * \param [in] enChannel VC通道号
646 *
647 * \retval en_result_t Ok: 配置成功
648 * \retval en_result_t ErrorInvalidParameter: 无效参数
649 */
Vc_DisableFilter(en_vc_channel_t enChannel)650 en_result_t Vc_DisableFilter(en_vc_channel_t enChannel)
651 {
652 if (VcChannel0 == enChannel)
653 {
654 M0P_VC->VC0_CR_f.FLTEN = 0u;
655 }
656 else if (VcChannel1 == enChannel)
657 {
658 M0P_VC->VC1_CR_f.FLTEN = 0u;
659 }
660 else
661 {
662 return ErrorInvalidParameter;
663 }
664
665 return Ok;
666 }
667
668 //@} // VcGroup
669
670
671 /******************************************************************************
672 * EOF (not truncated)
673 ******************************************************************************/
674
675