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 pcnt.c
44 **
45 ** pcnt driver API.
46 ** @link pcnt Group Some description @endlink
47 **
48 ** - 2018-04-15 Devi First Version
49 **
50 ******************************************************************************/
51
52 /******************************************************************************
53 * Include files
54 ******************************************************************************/
55 #include "pcnt.h"
56
57 /**
58 ******************************************************************************
59 ** \addtogroup PCNTGroup
60 ******************************************************************************/
61 //@{
62
63 /******************************************************************************
64 * Local pre-processor symbols/macros ('#define')
65 ******************************************************************************/
66
67 #define IS_VALID_pagagain(x) ( (x) <= 7 )
68
69 #define IS_VALID_channel(x) ( (OPA0 == (x)) ||\
70 (OPA1 == (x)) ||\
71 (OPA2 == (x)) )
72
73 #define IS_VALID_STAT(x) ( (PCNT_S1E == (x)) ||\
74 (PCNT_S0E == (x)) ||\
75 (PCNT_BB == (x)) ||\
76 (PCNT_FE == (x)) ||\
77 (PCNT_DIR == (x)) ||\
78 (PCNT_TO == (x)) ||\
79 (PCNT_OV == (x)) ||\
80 (PCNT_UF == (x)) )
81
82
83
84 /******************************************************************************
85 * Global variable definitions (declared in header file with 'extern')
86 ******************************************************************************/
87
88
89 /******************************************************************************
90 * Local type definitions ('typedef')
91 ******************************************************************************/
92
93 /******************************************************************************
94 * Local function prototypes ('static')
95 ******************************************************************************/
96 static func_ptr_t pfnPcntCallback = NULL; ///< callback function pointer for PCNT Irq
97 /******************************************************************************
98 * Local variable definitions ('static')
99 ******************************************************************************/
100
101 /*****************************************************************************
102 * Function implementation - global ('extern') and local ('static')
103 *****************************************************************************/
104
Pcnt_IRQHandler(void)105 void Pcnt_IRQHandler(void)
106 {
107 if(NULL != pfnPcntCallback)
108 {
109 pfnPcntCallback();
110 }
111 }
112
113 /**
114 * \brief
115 * PCNT 初始化
116 *
117 * \param 无
118 * \param 无
119 *
120 * \retval 无
121 * \retval 无
122 */
PCNT_Init(stc_pcnt_config_t * pstcPcntConfig)123 en_result_t PCNT_Init(stc_pcnt_config_t* pstcPcntConfig)
124 {
125
126
127 M0P_SYSCTRL->PERI_CLKEN_f.PCNT = 1;
128
129 M0P_PCNT->CR_f.S1P = pstcPcntConfig->bS1Sel;
130 M0P_PCNT->CR_f.S0P = pstcPcntConfig->bS0Sel;
131 M0P_PCNT->CR_f.DIR = pstcPcntConfig->u8Direc; //计数方式
132 M0P_PCNT->CR_f.CLKSEL = pstcPcntConfig->u8Clk;
133 M0P_PCNT->CR_f.MODE = pstcPcntConfig->u8Mode;
134
135 M0P_PCNT->FLT_f.CLKDIV = pstcPcntConfig->u8FLTClk;
136
137 if(pstcPcntConfig->bFLTEn)
138 {
139 if(pstcPcntConfig->u8FLTDep == 0)
140 {
141 M0P_PCNT->FLT_f.DEBTOP = 2;
142 }
143 else
144 {
145 M0P_PCNT->FLT_f.DEBTOP = pstcPcntConfig->u8FLTDep;
146 }
147 }
148 M0P_PCNT->FLT_f.EN = pstcPcntConfig->bFLTEn;
149
150 M0P_PCNT->TOCR_f.TH = pstcPcntConfig->u16TODep;
151 M0P_PCNT->TOCR_f.EN = pstcPcntConfig->bTOEn;
152
153 if (TRUE == pstcPcntConfig->bIrqEn)
154 {
155 M0P_PCNT->IEN = pstcPcntConfig->u8IrqStatus;
156 EnableNvic(PCNT_IRQn,IrqLevel3,TRUE);
157 }
158 else
159 {
160 M0P_PCNT->IEN = 0x00;
161 EnableNvic(PCNT_IRQn,IrqLevel3,FALSE);
162 }
163 if(NULL != pstcPcntConfig->pfnIrqCb)
164 {
165 pfnPcntCallback = pstcPcntConfig->pfnIrqCb;
166 }
167 return Ok;
168 }
169
170 /**
171 * \brief
172 * PCNT 去初始化
173 *
174 * \param 无
175 * \param 无
176 *
177 * \retval 无
178 * \retval 无
179 */
PCNT_DeInit(void)180 void PCNT_DeInit(void)
181 {
182 M0P_PCNT->CR = 0;
183 M0P_PCNT->RUN = 0;
184 M0P_SYSCTRL->PERI_CLKEN_f.PCNT = 0;
185
186 }
187
188 /**
189 * \brief
190 * PCNT 脉冲计数设置
191 *
192 * \param [in] start 开始计数设置
193 * \param [in] end 结束计数设置
194 *
195 * \retval 无
196 */
PCNT_Parameter(uint8_t start,uint8_t end)197 en_result_t PCNT_Parameter(uint8_t start,uint8_t end)
198 {
199 uint32_t u32TimeOut;
200
201 u32TimeOut = 1000;
202 M0P_PCNT->BUF = end; //加载结束溢出值
203 M0P_PCNT->CMD_f.B2T = 1;
204
205 while(u32TimeOut--)
206 {
207 if(FALSE == M0P_PCNT->SR2_f.B2T)
208 {
209 break;
210 }
211 }
212 if(u32TimeOut == 0)
213 {
214 return ErrorTimeout;
215 }
216
217 u32TimeOut = 1000;
218 M0P_PCNT->BUF = start; //加载初始值
219 M0P_PCNT->CMD_f.B2C = 1;
220
221 while(u32TimeOut--)
222 {
223 if(FALSE == M0P_PCNT->SR2_f.B2C)
224 {
225 break;
226 }
227 }
228 if(u32TimeOut == 0)
229 {
230 return ErrorTimeout;
231 }
232 return Ok;
233 }
234
235 /**
236 * \brief
237 * 获取PCNT计数方向
238 * \param [in]
239 *
240 * \retval 无
241 */
PCNT_Direction(void)242 en_pcnt_direcsel_t PCNT_Direction(void)
243 {
244 return (en_pcnt_direcsel_t)M0P_PCNT->SR1_f.DIR;
245 }
246
247 /**
248 * \brief
249 * 获取PCNT计数值
250 * \param [in]
251 *
252 * \retval 无
253 */
PCNT_Count(void)254 uint16_t PCNT_Count(void)
255 {
256 return M0P_PCNT->CNT;
257 }
258
259 /**
260 * \brief
261 * 获取PCNT溢出值
262 * \param [in]
263 *
264 * \retval 无
265 */
PCNT_TopCount(void)266 uint16_t PCNT_TopCount(void)
267 {
268 return M0P_PCNT->TOP;
269 }
270
271 /**
272 * \brief
273 * PCNT使能
274 * \param [in]
275 *
276 * \retval 无
277 */
PCNT_Run(boolean_t work)278 void PCNT_Run(boolean_t work)
279 {
280 M0P_PCNT->RUN_f.RUN = work;
281 }
282
283 /**
284 * \brief
285 * PCNT 读取状态
286 * \param [in] en_pcnt_status_t PCNT状态
287 *
288 * \retval 无
289 */
PCNT_GetStatus(en_pcnt_status_t enStatus)290 boolean_t PCNT_GetStatus(en_pcnt_status_t enStatus)
291 {
292 boolean_t bFlag = FALSE;
293
294 ASSERT(IS_VALID_STAT(enStatus));
295
296 switch (enStatus)
297 {
298 case PCNT_S1E:
299 bFlag = M0P_PCNT->IFR_f.S1E;
300 break;
301 case PCNT_S0E:
302 bFlag = M0P_PCNT->IFR_f.S0E;
303 break;
304 case PCNT_BB:
305 bFlag = M0P_PCNT->IFR_f.BB;
306 break;
307 case PCNT_FE:
308 bFlag = M0P_PCNT->IFR_f.FE;
309 break;
310 case PCNT_DIR:
311 bFlag = M0P_PCNT->IFR_f.DIR;
312 break;
313 case PCNT_TO:
314 bFlag = M0P_PCNT->IFR_f.TO;
315 break;
316 case PCNT_OV:
317 bFlag = M0P_PCNT->IFR_f.OV;
318 break;
319 case PCNT_UF:
320 bFlag = M0P_PCNT->IFR_f.UF;
321 break;
322 default:
323 break;
324 }
325 return bFlag;
326 }
327 /**
328 * \brief
329 * PCNT 清除状态
330 * \param [in] en_pcnt_status_t PCNT状态
331 *
332 * \retval 无
333 */
PCNT_ClrStatus(en_pcnt_status_t enStatus)334 void PCNT_ClrStatus(en_pcnt_status_t enStatus)
335 {
336
337 ASSERT(IS_VALID_STAT(enStatus));
338
339 switch (enStatus)
340 {
341 case PCNT_S1E:
342 M0P_PCNT->ICR_f.S1E = 0;
343 break;
344 case PCNT_S0E:
345 M0P_PCNT->ICR_f.S0E = 0;
346 break;
347 case PCNT_BB:
348 M0P_PCNT->ICR_f.BB = 0;
349 break;
350 case PCNT_FE:
351 M0P_PCNT->ICR_f.FE = 0;
352 break;
353 case PCNT_DIR:
354 M0P_PCNT->ICR_f.DIR = 0;
355 break;
356 case PCNT_TO:
357 M0P_PCNT->ICR_f.TO = 0;
358 break;
359 case PCNT_OV:
360 M0P_PCNT->ICR_f.OV = 0;
361 break;
362 case PCNT_UF:
363 M0P_PCNT->ICR_f.UF = 0;
364 break;
365 default:
366 break;
367 }
368 }
369 /**
370 * \brief
371 * PCNT 中断设置
372 * \param [in] en_pcnt_status_t PCNT状态
373 *
374 * \retval 无
375 */
PCNT_SetIrqStatus(en_pcnt_status_t enStatus)376 void PCNT_SetIrqStatus(en_pcnt_status_t enStatus)
377 {
378
379 ASSERT(IS_VALID_STAT(enStatus));
380
381 switch (enStatus)
382 {
383 case PCNT_S1E:
384 M0P_PCNT->IEN_f.S1E = 1;
385 break;
386 case PCNT_S0E:
387 M0P_PCNT->IEN_f.S0E = 1;
388 break;
389 case PCNT_BB:
390 M0P_PCNT->IEN_f.BB = 1;
391 break;
392 case PCNT_FE:
393 M0P_PCNT->IEN_f.FE = 1;
394 break;
395 case PCNT_DIR:
396 M0P_PCNT->IEN_f.DIR = 1;
397 break;
398 case PCNT_TO:
399 M0P_PCNT->IEN_f.TO = 1;
400 break;
401 case PCNT_OV:
402 M0P_PCNT->IEN_f.OV = 1;
403 break;
404 case PCNT_UF:
405 M0P_PCNT->IEN_f.UF = 1;
406 break;
407 default:
408 break;
409 }
410 }
411 //@} // OPAGroup
412
413
414 /******************************************************************************
415 * EOF (not truncated)
416 ******************************************************************************/
417
418