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