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 lvd.c
44  **
45  ** Low Voltage Detect driver API.
46  ** @link Lvd Group Some description @endlink
47  **
48  **   - 2017-06-28 Alex    First Version
49  **
50  ******************************************************************************/
51 
52 /******************************************************************************
53  * Include files
54  ******************************************************************************/
55 #include "lvd.h"
56 
57 /**
58  ******************************************************************************
59  ** \addtogroup LvdGroup
60  ******************************************************************************/
61 //@{
62 
63 /******************************************************************************
64  * Local pre-processor symbols/macros ('#define')
65  ******************************************************************************/
66 
67 #define IS_VALID_INPUT(x)       ( (x) <= LvdInputPB07 )
68 
69 #define IS_VALID_THRESHOLD(x)   ( (x) <= LvdTH3p3V )
70 
71 #define IS_VALID_FILTER(x)      ( (x) <= LvdFilter29ms )
72 
73 #define IS_VALID_IRQTYPE(x)     ( (x) <= LvdIrqFall )
74 
75 
76 /******************************************************************************
77  * Global variable definitions (declared in header file with 'extern')        *
78  ******************************************************************************/
79 
80 /******************************************************************************
81  * Local type definitions ('typedef')
82  ******************************************************************************/
83 
84 /******************************************************************************
85  * Local function prototypes ('static')
86  ******************************************************************************/
87 // static void LvdEnableNvic(void);
88 // static void LvdDisableNvic(void);
89 // static en_result_t LvdEnable(en_lvd_type_t enType, boolean_t bFlag);
90 
91 /******************************************************************************
92  * Local variable definitions ('static')
93  ******************************************************************************/
94 static func_ptr_t    pfnLvdIrqCbk = NULL;
95 
96 /*****************************************************************************
97  * Function implementation - global ('extern') and local ('static')
98  *****************************************************************************/
99 
100  /**
101  * \brief
102  *          LVD中断服务程序
103  *
104  * \param   [in]  u8Param  未使用
105  *
106  * \retval  无
107  */
Lvd_IRQHandler(uint8_t u8Param)108 void Lvd_IRQHandler(uint8_t u8Param)
109 {
110     M0P_LVD->IFR_f.INTF = 0u;
111     if (NULL != pfnLvdIrqCbk)
112     {
113         pfnLvdIrqCbk();
114     }
115 }
116 
117 /**
118  * \brief
119  *          使能NVIC中LVD中断
120  *
121  * \param   无
122  *
123  * \retval  无
124  */
LvdEnableNvic(void)125 static void LvdEnableNvic(void)
126 {
127     NVIC_ClearPendingIRQ(LVD_IRQn);
128     NVIC_SetPriority(LVD_IRQn, IrqLevel3);
129     NVIC_EnableIRQ(LVD_IRQn);
130 }
131 
132 /**
133  * \brief
134  *          除能NVIC中LVD中断
135  *
136  * \param   无
137  *
138  * \retval  无
139  */
LvdDisableNvic(void)140 static void LvdDisableNvic(void)
141 {
142     NVIC_ClearPendingIRQ(LVD_IRQn);
143     NVIC_DisableIRQ(LVD_IRQn);
144     NVIC_SetPriority(LVD_IRQn, IrqLevel3);
145 }
146 
147 /**
148  * \brief
149  *          使能LVD中断
150  *
151  * \param   [in]  enType  LVD中断类型
152  *
153  * \retval  en_result_t  Ok:  设置成功
154  * \retval  en_result_t  ErrorInvalidParameter:  无效类型
155  */
Lvd_EnableIrq(en_lvd_irq_type_t enType)156 en_result_t Lvd_EnableIrq(en_lvd_irq_type_t enType)
157 {
158     en_result_t enRet = Ok;
159 
160     if (enType > LvdIrqFall)
161     {
162         return ErrorInvalidParameter;
163     }
164     else
165     {   switch (enType)
166         {
167             case LvdIrqHigh:
168                 M0P_LVD->CR_f.HTEN = 1u;
169                 M0P_LVD->CR_f.RTEN = 0u;
170                 M0P_LVD->CR_f.FTEN = 0u;
171                 break;
172             case LvdIrqRise:
173                 M0P_LVD->CR_f.HTEN = 0u;
174                 M0P_LVD->CR_f.RTEN = 1u;
175                 M0P_LVD->CR_f.FTEN = 0u;
176                 break;
177             case LvdIrqFall:
178                 M0P_LVD->CR_f.HTEN = 0u;
179                 M0P_LVD->CR_f.RTEN = 0u;
180                 M0P_LVD->CR_f.FTEN = 1u;
181                 break;
182             default:
183                 break;
184         }
185 
186         M0P_LVD->CR_f.IE = 1u;
187         LvdEnableNvic();
188     }
189     return enRet;
190 }
191 
192 /**
193  * \brief
194  *          除能LVD中断
195  *
196  * \param   无
197  *
198  * \retval  无
199  */
Lvd_DisableIrq(void)200 void Lvd_DisableIrq(void)
201 {
202     LvdDisableNvic();
203     M0P_LVD->CR_f.IE = 0u;
204     M0P_LVD->CR_f.HTEN = 0u;
205     M0P_LVD->CR_f.RTEN = 0u;
206     M0P_LVD->CR_f.FTEN = 0u;
207 }
208 
209 /**
210  * \brief
211  *          LVD初始化
212  *
213  * \param   [in]  pstcConfig  LVD配置指针
214  *
215  * \retval  无
216  */
Lvd_Init(stc_lvd_config_t * pstcConfig)217 void Lvd_Init(stc_lvd_config_t *pstcConfig)
218 {
219     ASSERT(pstcConfig);
220     ASSERT(IS_VALID_INPUT(pstcConfig->enInput));
221     ASSERT(IS_VALID_THRESHOLD(pstcConfig->enThreshold));
222     ASSERT(IS_VALID_FILTER(pstcConfig->enFilterTime));
223     ASSERT(IS_VALID_IRQTYPE(pstcConfig->enIrqType));
224 
225     //NEED to DISABLE first.
226     Lvd_Disable();
227     Lvd_DisableIrq();
228     LvdDisableNvic();
229 
230     M0P_LVD->CR_f.DEBOUNCE_TIME = pstcConfig->enFilterTime;
231     M0P_LVD->CR_f.FLTEN = pstcConfig->bFilter;
232     M0P_LVD->CR_f.VTDS = pstcConfig->enThreshold;
233     M0P_LVD->CR_f.SOURCE_SEL = pstcConfig->enInput;
234     M0P_LVD->CR_f.ACT = pstcConfig->bLvdReset;
235 
236     pfnLvdIrqCbk = pstcConfig->pfnIrqCbk;
237 }
238 
239 /**
240  * \brief
241  *          LVD deinit
242  *
243  * \param   无
244  *
245  * \retval  无
246  */
Lvd_DeInit(void)247 void Lvd_DeInit(void)
248 {
249     Lvd_DisableIrq();
250     LvdDisableNvic();
251 
252     pfnLvdIrqCbk = NULL;
253     Lvd_Disable();
254 }
255 
256 /**
257  * \brief
258  *          使能LVD
259  *
260  * \param   无
261  *
262  * \retval  无
263  *
264  */
Lvd_Enable(void)265 void Lvd_Enable(void)
266 {
267     M0P_LVD->CR_f.LVDEN = 1u;
268 }
269 
270 /**
271  * \brief
272  *          除能LVD
273  *
274  * \param   无
275  *
276  * \retval  无
277  */
Lvd_Disable(void)278 void Lvd_Disable(void)
279 {
280     M0P_LVD->CR_f.LVDEN = 0u;
281 }
282 
283 /**
284  * \brief
285  *          获取LVD中断标志
286  *
287  * \param   无
288  *
289  * \retval  boolean_t  中断标志
290  */
Lvd_GetIrqStat(void)291 boolean_t Lvd_GetIrqStat(void)
292 {
293     return M0P_LVD->IFR_f.INTF;
294 
295 }
296 
297 /**
298  * \brief
299  *          清除LVD中断标志
300  *
301  * \param   无
302  *
303  * \retval  无
304  */
Lvd_ClearIrq(void)305 void Lvd_ClearIrq(void)
306 {
307     M0P_LVD->IFR_f.INTF = 0u;
308 }
309 
310 /**
311  * \brief
312  *          获取Filter结果
313  *
314  * \param   无
315  *
316  * \retval  boolean_t Fliter结果
317  */
Lvd_GetFilterResult(void)318 boolean_t Lvd_GetFilterResult(void)
319 {
320     return (boolean_t)M0P_LVD->IFR_f.FILTER;
321 }
322 //@} // LvdGroup
323 
324 /******************************************************************************
325  * EOF (not truncated)
326  ******************************************************************************/
327 
328