1 /**************************************************************************//**
2  * @file     pwm.c
3  * @version  V3.00
4  * $Revision: 1 $
5  * $Date: 19/02/14 4:03p $
6  * @brief    M2L31 series PWM driver source file
7  *
8  * @note
9  * Copyright (C) 2017 Nuvoton Technology Corp. All rights reserved.
10 *****************************************************************************/
11 #include "NuMicro.h"
12 
13 /** @addtogroup Standard_Driver Standard Driver
14   @{
15 */
16 
17 /** @addtogroup PWM_Driver PWM Driver
18   @{
19 */
20 
21 /** @addtogroup PWM_EXPORTED_FUNCTIONS PWM Exported Functions
22   @{
23 */
24 
25 /**
26  * @brief Configure PWM capture and get the nearest unit time.
27  * @param[in] pwm The pointer of the specified PWM module
28  *                - PWM0 : PWM Group 0
29  *                - PWM1 : PWM Group 1
30  * @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5
31  * @param[in] u32UnitTimeNsec The unit time of counter
32  * @param[in] u32CaptureEdge The condition to latch the counter. This parameter is not used
33  * @return The nearest unit time in nano second.
34  * @details This function is used to Configure PWM capture and get the nearest unit time.
35  */
PWM_ConfigCaptureChannel(PWM_T * pwm,uint32_t u32ChannelNum,uint32_t u32UnitTimeNsec,uint32_t u32CaptureEdge)36 uint32_t PWM_ConfigCaptureChannel(PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32UnitTimeNsec, uint32_t u32CaptureEdge)
37 {
38     uint32_t u32Src;
39     uint32_t u32PWMClockSrc;
40     uint32_t u32NearestUnitTimeNsec;
41     uint16_t u16Prescale = 1, u16CNR = 0xFFFF;
42 
43     if(pwm == PWM0)
44         u32Src = CLK->CLKSEL3 & CLK_CLKSEL3_PWM0SEL_Msk;
45     else//(pwm == PWM1)
46         u32Src = CLK->CLKSEL3 & CLK_CLKSEL3_PWM1SEL_Msk;
47 
48     if(u32Src == 0)
49     {
50         /* clock source is from HCLK0 */
51         u32PWMClockSrc = CLK_GetHCLKFreq();
52     }
53     else
54     {
55         /* clock source is from PCLK */
56         SystemCoreClockUpdate();
57         if(pwm == PWM0)
58         {
59             u32PWMClockSrc = CLK_GetPCLK0Freq();
60         }
61         else     /* (epwm == EPWM1) */
62         {
63             u32PWMClockSrc = CLK_GetPCLK1Freq();
64         }
65     }
66 
67     u32PWMClockSrc /= 1000;
68     for(u16Prescale = 1; u16Prescale <= 0x1000; u16Prescale++)
69     {
70         u32NearestUnitTimeNsec = (1000000 * u16Prescale) / u32PWMClockSrc;
71         if(u32NearestUnitTimeNsec < u32UnitTimeNsec)
72         {
73             if(u16Prescale == 0x1000)  //limit to the maximum unit time(nano second)
74                 break;
75             if(!((1000000 * (u16Prescale + 1) > (u32NearestUnitTimeNsec * u32PWMClockSrc))))
76                 break;
77             continue;
78         }
79         break;
80     }
81 
82     /* convert to real register value */
83     /* every two channels share a prescaler */
84     PWM_SET_PRESCALER(pwm, u32ChannelNum, --u16Prescale);
85 
86     // set PWM to down count type(edge aligned)
87     (pwm)->CTL1 = ((pwm)->CTL1 & ~(PWM_CTL1_CNTTYPE0_Msk << (u32ChannelNum << 1))) | (1UL << (u32ChannelNum << 1));
88     // set PWM to auto-reload mode
89     (pwm)->CTL1 &= ~(PWM_CTL1_CNTTYPE0_Msk << u32ChannelNum);
90     PWM_SET_CNR(pwm, u32ChannelNum, u16CNR);
91 
92     return (u32NearestUnitTimeNsec);
93 }
94 
95 /**
96  * @brief This function Configure PWM generator and get the nearest frequency in edge aligned(up counter type) auto-reload mode
97  * @param[in] pwm The pointer of the specified PWM module
98  *                - PWM0 : PWM Group 0
99  *                - PWM1 : PWM Group 1
100  * @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5
101  * @param[in] u32Frequency Target generator frequency
102  * @param[in] u32DutyCycle Target generator duty cycle percentage. Valid range are between 0 ~ 100. 10 means 10%, 20 means 20%...
103  * @return Nearest frequency clock in nano second
104  * @note Since every two channels, (0 & 1), (2 & 3), shares a prescaler. Call this API to configure PWM frequency may affect
105  *       existing frequency of other channel.
106  * @note This function is used for initial stage.
107  *       To change duty cycle later, it should get the configured period value and calculate the new comparator value.
108  */
PWM_ConfigOutputChannel(PWM_T * pwm,uint32_t u32ChannelNum,uint32_t u32Frequency,uint32_t u32DutyCycle)109 uint32_t PWM_ConfigOutputChannel(PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32Frequency, uint32_t u32DutyCycle)
110 {
111     uint32_t u32Src;
112     uint32_t u32PWMClockSrc;
113     uint32_t i;
114     uint16_t u16Prescale = 1, u16CNR = 0xFFFF;
115 
116     if(pwm == PWM0)
117         u32Src = CLK->CLKSEL3 & CLK_CLKSEL3_PWM0SEL_Msk;
118     else//(pwm == PWM1)
119         u32Src = CLK->CLKSEL3 & CLK_CLKSEL3_PWM1SEL_Msk;
120 
121     if(u32Src == 0)
122     {
123         //clock source is from PLL clock
124         u32PWMClockSrc = CLK_GetPLLClockFreq();
125     }
126     else
127     {
128         //clock source is from PCLK
129         SystemCoreClockUpdate();
130 //        u32PWMClockSrc = SystemCoreClock;
131         if(pwm == PWM0)
132         {
133             u32PWMClockSrc = CLK_GetPCLK0Freq();
134         }
135         else     /* (pwm == PWM1) */
136         {
137             u32PWMClockSrc = CLK_GetPCLK1Freq();
138         }
139     }
140 
141     for(u16Prescale = 1; u16Prescale < 0xFFF; u16Prescale++)//prescale could be 0~0xFFF
142     {
143         i = (u32PWMClockSrc / u32Frequency) / u16Prescale;
144         // If target value is larger than CNR, need to use a larger prescaler
145         if(i > (0x10000))
146             continue;
147 
148         u16CNR = i;
149         break;
150     }
151     // Store return value here 'cos we're gonna change u16Prescale & u16CNR to the real value to fill into register
152     i = u32PWMClockSrc / (u16Prescale * u16CNR);
153 
154     // convert to real register value
155     // every two channels share a prescaler
156     PWM_SET_PRESCALER(pwm, u32ChannelNum, --u16Prescale);
157     // set PWM to up counter type(edge aligned) and auto-reload mode
158     (pwm)->CTL1 = ((pwm)->CTL1 & ~((PWM_CTL1_CNTTYPE0_Msk << (u32ChannelNum << 1)) | (PWM_CTL1_CNTTYPE0_Msk << u32ChannelNum)));
159 
160     PWM_SET_CNR(pwm, u32ChannelNum, --u16CNR);
161     PWM_SET_CMR(pwm, u32ChannelNum, u32DutyCycle * (u16CNR + 1) / 100);
162 
163     (pwm)->WGCTL0 = ((pwm)->WGCTL0 & ~((PWM_WGCTL0_PRDPCTL0_Msk | PWM_WGCTL0_ZPCTL0_Msk) << (u32ChannelNum << 1))) | \
164                     (PWM_OUTPUT_HIGH << ((u32ChannelNum << 1) + PWM_WGCTL0_ZPCTL0_Pos));
165     (pwm)->WGCTL1 = ((pwm)->WGCTL1 & ~((PWM_WGCTL1_CMPDCTL0_Msk | PWM_WGCTL1_CMPUCTL0_Msk) << (u32ChannelNum << 1))) | \
166                     (PWM_OUTPUT_LOW << ((u32ChannelNum << 1) + PWM_WGCTL1_CMPUCTL0_Pos));
167 
168     return(i);
169 }
170 
171 /**
172  * @brief Start PWM module
173  * @param[in] pwm The pointer of the specified PWM module
174  *                - PWM0 : PWM Group 0
175  *                - PWM1 : PWM Group 1
176  * @param[in] u32ChannelMask Combination of enabled channels. Each bit corresponds to a channel.
177  *                           Bit 0 is channel 0, bit 1 is channel 1...
178  * @return None
179  * @details This function is used to start PWM module.
180  */
PWM_Start(PWM_T * pwm,uint32_t u32ChannelMask)181 void PWM_Start(PWM_T *pwm, uint32_t u32ChannelMask)
182 {
183     uint32_t i;
184 
185     for (i = 0UL; i < PWM_CHANNEL_NUM; i ++)
186     {
187         if (u32ChannelMask & (1UL << i))
188         {
189             (pwm)->CNTEN |= (1UL << ((i >> 1UL) << 1UL));
190         }
191     }
192 }
193 
194 /**
195  * @brief Stop PWM module
196  * @param[in] pwm The pointer of the specified PWM module
197  *                - PWM0 : PWM Group 0
198  *                - PWM1 : PWM Group 1
199  * @param[in] u32ChannelMask Combination of enabled channels. Each bit corresponds to a channel.
200  *                           Bit 0 is channel 0, bit 1 is channel 1...
201  * @return None
202  * @details This function is used to stop PWM module.
203  */
PWM_Stop(PWM_T * pwm,uint32_t u32ChannelMask)204 void PWM_Stop(PWM_T *pwm, uint32_t u32ChannelMask)
205 {
206     uint32_t i;
207 
208     for (i = 0UL; i < PWM_CHANNEL_NUM; i ++)
209     {
210         if (u32ChannelMask & (1UL << i))
211         {
212             (pwm)->PERIOD[((i >> 1UL) << 1UL)] = 0UL;
213         }
214     }
215 }
216 
217 /**
218  * @brief Stop PWM generation immediately by clear channel enable bit
219  * @param[in] pwm The pointer of the specified PWM module
220  *                - PWM0 : PWM Group 0
221  *                - PWM1 : PWM Group 1
222  * @param[in] u32ChannelMask Combination of enabled channels. Each bit corresponds to a channel.
223  *                           Bit 0 is channel 0, bit 1 is channel 1...
224  * @return None
225  * @details This function is used to stop PWM generation immediately by clear channel enable bit.
226  */
PWM_ForceStop(PWM_T * pwm,uint32_t u32ChannelMask)227 void PWM_ForceStop(PWM_T *pwm, uint32_t u32ChannelMask)
228 {
229     uint32_t i;
230 
231     for (i = 0UL; i < PWM_CHANNEL_NUM; i ++)
232     {
233         if (u32ChannelMask & (1UL << i))
234         {
235             (pwm)->CNTEN &= ~(1UL << ((i >> 1UL) << 1UL));
236         }
237     }
238 }
239 
240 /**
241  * @brief Enable selected channel to trigger ADC
242  * @param[in] pwm The pointer of the specified PWM module
243  *                - PWM0 : PWM Group 0
244  *                - PWM1 : PWM Group 1
245  * @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5
246  * @param[in] u32Condition The condition to trigger ADC. Combination of following conditions:
247  *                  - \ref PWM_TRIGGER_ADC_EVEN_ZERO_POINT
248  *                  - \ref PWM_TRIGGER_ADC_EVEN_PERIOD_POINT
249  *                  - \ref PWM_TRIGGER_ADC_EVEN_ZERO_OR_PERIOD_POINT
250  *                  - \ref PWM_TRIGGER_ADC_EVEN_COMPARE_UP_COUNT_POINT
251  *                  - \ref PWM_TRIGGER_ADC_EVEN_COMPARE_DOWN_COUNT_POINT
252  *                  - \ref PWM_TRIGGER_ADC_ODD_ZERO_POINT
253  *                  - \ref PWM_TRIGGER_ADC_ODD_PERIOD_POINT
254  *                  - \ref PWM_TRIGGER_ADC_ODD_ZERO_OR_PERIOD_POINT
255  *                  - \ref PWM_TRIGGER_ADC_ODD_COMPARE_UP_COUNT_POINT
256  *                  - \ref PWM_TRIGGER_ADC_ODD_COMPARE_DOWN_COUNT_POINT
257  *                  - \ref PWM_TRIGGER_ADC_CH_0_FREE_COMPARE_UP_COUNT_POINT
258  *                  - \ref PWM_TRIGGER_ADC_CH_0_FREE_COMPARE_DOWN_COUNT_POINT
259  *                  - \ref PWM_TRIGGER_ADC_CH_2_FREE_COMPARE_UP_COUNT_POINT
260  *                  - \ref PWM_TRIGGER_ADC_CH_2_FREE_COMPARE_DOWN_COUNT_POINT
261  *                  - \ref PWM_TRIGGER_ADC_CH_4_FREE_COMPARE_UP_COUNT_POINT
262  *                  - \ref PWM_TRIGGER_ADC_CH_4_FREE_COMPARE_DOWN_COUNT_POINT
263  * @return None
264  * @details This function is used to enable selected channel to trigger ADC.
265  */
PWM_EnableADCTrigger(PWM_T * pwm,uint32_t u32ChannelNum,uint32_t u32Condition)266 void PWM_EnableADCTrigger(PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32Condition)
267 {
268     if(u32ChannelNum < 4)
269     {
270         (pwm)->EADCTS0 &= ~((PWM_EADCTS0_TRGSEL0_Msk) << (u32ChannelNum << 3));
271         (pwm)->EADCTS0 |= ((PWM_EADCTS0_TRGEN0_Msk | u32Condition) << (u32ChannelNum << 3));
272     }
273     else
274     {
275         (pwm)->EADCTS1 &= ~((PWM_EADCTS1_TRGSEL4_Msk) << ((u32ChannelNum - 4) << 3));
276         (pwm)->EADCTS1 |= ((PWM_EADCTS1_TRGEN4_Msk | u32Condition) << ((u32ChannelNum - 4) << 3));
277     }
278 }
279 
280 /**
281  * @brief Disable selected channel to trigger ADC
282  * @param[in] pwm The pointer of the specified PWM module
283  *                - PWM0 : PWM Group 0
284  *                - PWM1 : PWM Group 1
285  * @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5
286  * @return None
287  * @details This function is used to disable selected channel to trigger ADC.
288  */
PWM_DisableADCTrigger(PWM_T * pwm,uint32_t u32ChannelNum)289 void PWM_DisableADCTrigger(PWM_T *pwm, uint32_t u32ChannelNum)
290 {
291     if(u32ChannelNum < 4)
292     {
293         (pwm)->EADCTS0 &= ~(PWM_EADCTS0_TRGEN0_Msk << (u32ChannelNum << 3));
294     }
295     else
296     {
297         (pwm)->EADCTS1 &= ~(PWM_EADCTS1_TRGEN4_Msk << ((u32ChannelNum - 4) << 3));
298     }
299 }
300 
301 /**
302  * @brief Clear selected channel trigger ADC flag
303  * @param[in] pwm The pointer of the specified PWM module
304  *                - PWM0 : PWM Group 0
305  *                - PWM1 : PWM Group 1
306  * @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5
307  * @param[in] u32Condition This parameter is not used
308  * @return None
309  * @details This function is used to clear selected channel trigger ADC flag.
310  */
PWM_ClearADCTriggerFlag(PWM_T * pwm,uint32_t u32ChannelNum,uint32_t u32Condition)311 void PWM_ClearADCTriggerFlag(PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32Condition)
312 {
313     (pwm)->STATUS = (PWM_STATUS_EADCTRG0_Msk << u32ChannelNum);
314 }
315 
316 /**
317  * @brief Get selected channel trigger ADC flag
318  * @param[in] pwm The pointer of the specified PWM module
319  *                - PWM0 : PWM Group 0
320  *                - PWM1 : PWM Group 1
321  * @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5
322  * @retval 0 The specified channel trigger ADC to start of conversion flag is not set
323  * @retval 1 The specified channel trigger ADC to start of conversion flag is set
324  * @details This function is used to get PWM trigger ADC to start of conversion flag for specified channel.
325  */
PWM_GetADCTriggerFlag(PWM_T * pwm,uint32_t u32ChannelNum)326 uint32_t PWM_GetADCTriggerFlag(PWM_T *pwm, uint32_t u32ChannelNum)
327 {
328     return (((pwm)->STATUS & (PWM_STATUS_EADCTRG0_Msk << u32ChannelNum)) ? 1 : 0);
329 }
330 
331 /**
332  * @brief This function enable fault brake of selected channel(s)
333  * @param[in] pwm The pointer of the specified PWM module
334  *                - PWM0 : PWM Group 0
335  *                - PWM1 : PWM Group 1
336  * @param[in] u32ChannelMask Combination of enabled channels. Each bit corresponds to a channel.
337  * @param[in] u32LevelMask Output high or low while fault brake occurs, each bit represent the level of a channel
338  *                         while fault brake occurs. Bit 0 represents channel 0, bit 1 represents channel 1...
339  * @param[in] u32BrakeSource Fault brake source, could be one of following source
340  *                  - \ref PWM_FB_EDGE_ADCRM
341  *                  - \ref PWM_FB_EDGE_ACMP0
342  *                  - \ref PWM_FB_EDGE_ACMP1
343  *                  - \ref PWM_FB_EDGE_BKP0
344  *                  - \ref PWM_FB_EDGE_BKP1
345  *                  - \ref PWM_FB_EDGE_SYS_CSS
346  *                  - \ref PWM_FB_EDGE_SYS_BOD
347  *                  - \ref PWM_FB_EDGE_SYS_COR
348  *                  - \ref PWM_FB_LEVEL_ADCRM
349  *                  - \ref PWM_FB_LEVEL_ACMP0
350  *                  - \ref PWM_FB_LEVEL_ACMP1
351  *                  - \ref PWM_FB_LEVEL_BKP0
352  *                  - \ref PWM_FB_LEVEL_BKP1
353  *                  - \ref PWM_FB_LEVEL_SYS_CSS
354  *                  - \ref PWM_FB_LEVEL_SYS_BOD
355  *                  - \ref PWM_FB_LEVEL_SYS_COR
356  * @return None
357  * @details This function is used to enable fault brake of selected channel(s).
358  *          The write-protection function should be disabled before using this function.
359  */
PWM_EnableFaultBrake(PWM_T * pwm,uint32_t u32ChannelMask,uint32_t u32LevelMask,uint32_t u32BrakeSource)360 void PWM_EnableFaultBrake(PWM_T *pwm, uint32_t u32ChannelMask, uint32_t u32LevelMask, uint32_t u32BrakeSource)
361 {
362     uint32_t i;
363     for(i = 0; i < PWM_CHANNEL_NUM; i ++)
364     {
365         if(u32ChannelMask & (1 << i))
366         {
367             if((u32BrakeSource == PWM_FB_EDGE_SYS_CSS) || (u32BrakeSource == PWM_FB_EDGE_SYS_BOD) || \
368                     (u32BrakeSource == PWM_FB_EDGE_SYS_COR) || \
369                     (u32BrakeSource == PWM_FB_LEVEL_SYS_CSS) || (u32BrakeSource == PWM_FB_LEVEL_SYS_BOD) || \
370                     (u32BrakeSource == PWM_FB_LEVEL_SYS_COR))
371             {
372                 *(__IO uint32_t *)(&((pwm)->BRKCTL0_1) + (i >> 1)) |= (u32BrakeSource & (PWM_BRKCTL0_1_SYSEBEN_Msk | PWM_BRKCTL0_1_SYSLBEN_Msk));
373                 (pwm)->FAILBRK |= (u32BrakeSource & 0xF);
374             }
375             else
376             {
377                 *(__IO uint32_t *)(&((pwm)->BRKCTL0_1) + (i >> 1)) |= u32BrakeSource;
378             }
379         }
380 
381         if(u32LevelMask & (1 << i))
382         {
383             if((i & 0x1) == 0)
384             {
385                 //set brake action as high level for even channel
386                 *(__IO uint32_t *)(&((pwm)->BRKCTL0_1) + (i >> 1)) &= ~PWM_BRKCTL0_1_BRKAEVEN_Msk;
387                 *(__IO uint32_t *)(&((pwm)->BRKCTL0_1) + (i >> 1)) |= ((3UL) << PWM_BRKCTL0_1_BRKAEVEN_Pos);
388             }
389             else
390             {
391                 //set brake action as high level for odd channel
392                 *(__IO uint32_t *)(&((pwm)->BRKCTL0_1) + (i >> 1)) &= ~PWM_BRKCTL0_1_BRKAODD_Msk;
393                 *(__IO uint32_t *)(&((pwm)->BRKCTL0_1) + (i >> 1)) |= ((3UL) << PWM_BRKCTL0_1_BRKAODD_Pos);
394             }
395         }
396         else
397         {
398             if((i & 0x1) == 0)
399             {
400                 //set brake action as low level for even channel
401                 *(__IO uint32_t *)(&((pwm)->BRKCTL0_1) + (i >> 1)) &= ~PWM_BRKCTL0_1_BRKAEVEN_Msk;
402                 *(__IO uint32_t *)(&((pwm)->BRKCTL0_1) + (i >> 1)) |= ((2UL) << PWM_BRKCTL0_1_BRKAEVEN_Pos);
403             }
404             else
405             {
406                 //set brake action as low level for odd channel
407                 *(__IO uint32_t *)(&((pwm)->BRKCTL0_1) + (i >> 1)) &= ~PWM_BRKCTL0_1_BRKAODD_Msk;
408                 *(__IO uint32_t *)(&((pwm)->BRKCTL0_1) + (i >> 1)) |= ((2UL) << PWM_BRKCTL0_1_BRKAODD_Pos);
409             }
410         }
411     }
412 }
413 
414 /**
415  * @brief Enable capture of selected channel(s)
416  * @param[in] pwm The pointer of the specified PWM module
417  *                - PWM0 : PWM Group 0
418  *                - PWM1 : PWM Group 1
419  * @param[in] u32ChannelMask Combination of enabled channels. Each bit corresponds to a channel.
420  *                           Bit 0 is channel 0, bit 1 is channel 1...
421  * @return None
422  * @details This function is used to enable capture of selected channel(s).
423  */
PWM_EnableCapture(PWM_T * pwm,uint32_t u32ChannelMask)424 void PWM_EnableCapture(PWM_T *pwm, uint32_t u32ChannelMask)
425 {
426     (pwm)->CAPINEN |= u32ChannelMask;
427     (pwm)->CAPCTL |= u32ChannelMask;
428 }
429 
430 /**
431  * @brief Disable capture of selected channel(s)
432  * @param[in] pwm The pointer of the specified PWM module
433  *                - PWM0 : PWM Group 0
434  *                - PWM1 : PWM Group 1
435  * @param[in] u32ChannelMask Combination of enabled channels. Each bit corresponds to a channel.
436  *                           Bit 0 is channel 0, bit 1 is channel 1...
437  * @return None
438  * @details This function is used to disable capture of selected channel(s).
439  */
PWM_DisableCapture(PWM_T * pwm,uint32_t u32ChannelMask)440 void PWM_DisableCapture(PWM_T *pwm, uint32_t u32ChannelMask)
441 {
442     (pwm)->CAPINEN &= ~u32ChannelMask;
443     (pwm)->CAPCTL &= ~u32ChannelMask;
444 }
445 
446 /**
447  * @brief Enables PWM output generation of selected channel(s)
448  * @param[in] pwm The pointer of the specified PWM module
449  *                - PWM0 : PWM Group 0
450  *                - PWM1 : PWM Group 1
451  * @param[in] u32ChannelMask Combination of enabled channels. Each bit corresponds to a channel.
452  *                           Set bit 0 to 1 enables channel 0 output, set bit 1 to 1 enables channel 1 output...
453  * @return None
454  * @details This function is used to enable PWM output generation of selected channel(s).
455  */
PWM_EnableOutput(PWM_T * pwm,uint32_t u32ChannelMask)456 void PWM_EnableOutput(PWM_T *pwm, uint32_t u32ChannelMask)
457 {
458     (pwm)->POEN |= u32ChannelMask;
459 }
460 
461 /**
462  * @brief Disables PWM output generation of selected channel(s)
463  * @param[in] pwm The pointer of the specified PWM module
464  *                - PWM0 : PWM Group 0
465  *                - PWM1 : PWM Group 1
466  * @param[in] u32ChannelMask Combination of enabled channels. Each bit corresponds to a channel
467  *                           Set bit 0 to 1 disables channel 0 output, set bit 1 to 1 disables channel 1 output...
468  * @return None
469  * @details This function is used to disable PWM output generation of selected channel(s).
470  */
PWM_DisableOutput(PWM_T * pwm,uint32_t u32ChannelMask)471 void PWM_DisableOutput(PWM_T *pwm, uint32_t u32ChannelMask)
472 {
473     (pwm)->POEN &= ~u32ChannelMask;
474 }
475 
476 /**
477  * @brief Enables PDMA transfer of selected channel for PWM capture
478  * @param[in] pwm The pointer of the specified PWM module
479  *                - PWM0 : PWM Group 0
480  *                - PWM1 : PWM Group 1
481  * @param[in] u32ChannelNum PWM channel number.
482  * @param[in] u32RisingFirst The capture order is rising, falling first. Every two channels share the same setting. Valid values are TRUE and FALSE.
483  * @param[in] u32Mode Captured data transferred by PDMA interrupt type. It could be either
484  *              - \ref PWM_CAPTURE_PDMA_RISING_LATCH
485  *              - \ref PWM_CAPTURE_PDMA_FALLING_LATCH
486  *              - \ref PWM_CAPTURE_PDMA_RISING_FALLING_LATCH
487  * @return None
488  * @details This function is used to enable PDMA transfer of selected channel(s) for PWM capture.
489  * @note This function can only selects even or odd channel of pairs to do PDMA transfer.
490  */
PWM_EnablePDMA(PWM_T * pwm,uint32_t u32ChannelNum,uint32_t u32RisingFirst,uint32_t u32Mode)491 void PWM_EnablePDMA(PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32RisingFirst, uint32_t u32Mode)
492 {
493     uint32_t u32IsOddCh;
494     u32IsOddCh = u32ChannelNum & 0x1;
495     (pwm)->PDMACTL = ((pwm)->PDMACTL & ~((PWM_PDMACTL_CHSEL0_1_Msk | PWM_PDMACTL_CAPORD0_1_Msk | PWM_PDMACTL_CAPMOD0_1_Msk) << ((u32ChannelNum >> 1) << 3))) | \
496                      (((u32IsOddCh << PWM_PDMACTL_CHSEL0_1_Pos) | (u32RisingFirst << PWM_PDMACTL_CAPORD0_1_Pos) | \
497                        u32Mode | PWM_PDMACTL_CHEN0_1_Msk) << ((u32ChannelNum >> 1) << 3));
498 }
499 
500 /**
501  * @brief Disables PDMA transfer of selected channel for PWM capture
502  * @param[in] pwm The pointer of the specified PWM module
503  *                - PWM0 : PWM Group 0
504  *                - PWM1 : PWM Group 1
505  * @param[in] u32ChannelNum PWM channel number.
506  * @return None
507  * @details This function is used to enable PDMA transfer of selected channel(s) for PWM capture.
508  */
PWM_DisablePDMA(PWM_T * pwm,uint32_t u32ChannelNum)509 void PWM_DisablePDMA(PWM_T *pwm, uint32_t u32ChannelNum)
510 {
511     (pwm)->PDMACTL &= ~(PWM_PDMACTL_CHEN0_1_Msk << ((u32ChannelNum >> 1) << 3));
512 }
513 
514 /**
515  * @brief Enable Dead zone of selected channel
516  * @param[in] pwm The pointer of the specified PWM module
517  *                - PWM0 : PWM Group 0
518  *                - PWM1 : PWM Group 1
519  * @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5
520  * @param[in] u32Duration Dead zone length in PWM clock count, valid values are between 0~0xFFF, but 0 means there is no Dead zone.
521  * @return None
522  * @details This function is used to enable Dead zone of selected channel.
523  *          The write-protection function should be disabled before using this function.
524  * @note Every two channels share the same setting.
525  */
PWM_EnableDeadZone(PWM_T * pwm,uint32_t u32ChannelNum,uint32_t u32Duration)526 void PWM_EnableDeadZone(PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32Duration)
527 {
528     // every two channels share the same setting
529     *(__IO uint32_t *)(&((pwm)->DTCTL0_1) + (u32ChannelNum >> 1)) &= ~PWM_DTCTL0_1_DTCNT_Msk;
530     *(__IO uint32_t *)(&((pwm)->DTCTL0_1) + (u32ChannelNum >> 1)) |= PWM_DTCTL0_1_DTEN_Msk | u32Duration;
531 }
532 
533 /**
534  * @brief Disable Dead zone of selected channel
535  * @param[in] pwm The pointer of the specified PWM module
536  *                - PWM0 : PWM Group 0
537  *                - PWM1 : PWM Group 1
538  * @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5
539  * @return None
540  * @details This function is used to disable Dead zone of selected channel.
541  *          The write-protection function should be disabled before using this function.
542  */
PWM_DisableDeadZone(PWM_T * pwm,uint32_t u32ChannelNum)543 void PWM_DisableDeadZone(PWM_T *pwm, uint32_t u32ChannelNum)
544 {
545     // every two channels shares the same setting
546     *(__IO uint32_t *)(&((pwm)->DTCTL0_1) + (u32ChannelNum >> 1)) &= ~PWM_DTCTL0_1_DTEN_Msk;
547 }
548 
549 /**
550  * @brief Enable capture interrupt of selected channel.
551  * @param[in] pwm The pointer of the specified PWM module
552  *                - PWM0 : PWM Group 0
553  *                - PWM1 : PWM Group 1
554  * @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5
555  * @param[in] u32Edge Rising or falling edge to latch counter.
556  *              - \ref PWM_CAPTURE_INT_RISING_LATCH
557  *              - \ref PWM_CAPTURE_INT_FALLING_LATCH
558  * @return None
559  * @details This function is used to enable capture interrupt of selected channel.
560  */
PWM_EnableCaptureInt(PWM_T * pwm,uint32_t u32ChannelNum,uint32_t u32Edge)561 void PWM_EnableCaptureInt(PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32Edge)
562 {
563     (pwm)->CAPIEN |= (u32Edge << u32ChannelNum);
564 }
565 
566 /**
567  * @brief Disable capture interrupt of selected channel.
568  * @param[in] pwm The pointer of the specified PWM module
569  *                - PWM0 : PWM Group 0
570  *                - PWM1 : PWM Group 1
571  * @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5
572  * @param[in] u32Edge Rising or falling edge to latch counter.
573  *              - \ref PWM_CAPTURE_INT_RISING_LATCH
574  *              - \ref PWM_CAPTURE_INT_FALLING_LATCH
575  * @return None
576  * @details This function is used to disable capture interrupt of selected channel.
577  */
PWM_DisableCaptureInt(PWM_T * pwm,uint32_t u32ChannelNum,uint32_t u32Edge)578 void PWM_DisableCaptureInt(PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32Edge)
579 {
580     (pwm)->CAPIEN &= ~(u32Edge << u32ChannelNum);
581 }
582 
583 /**
584  * @brief Clear capture interrupt of selected channel.
585  * @param[in] pwm The pointer of the specified PWM module
586  *                - PWM0 : PWM Group 0
587  *                - PWM1 : PWM Group 1
588  * @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5
589  * @param[in] u32Edge Rising or falling edge to latch counter.
590  *              - \ref PWM_CAPTURE_INT_RISING_LATCH
591  *              - \ref PWM_CAPTURE_INT_FALLING_LATCH
592  * @return None
593  * @details This function is used to clear capture interrupt of selected channel.
594  */
PWM_ClearCaptureIntFlag(PWM_T * pwm,uint32_t u32ChannelNum,uint32_t u32Edge)595 void PWM_ClearCaptureIntFlag(PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32Edge)
596 {
597     (pwm)->CAPIF = (u32Edge << u32ChannelNum);
598 }
599 
600 /**
601  * @brief Get capture interrupt of selected channel.
602  * @param[in] pwm The pointer of the specified PWM module
603  *                - PWM0 : PWM Group 0
604  *                - PWM1 : PWM Group 1
605  * @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5
606  * @retval 0 No capture interrupt
607  * @retval 1 Rising edge latch interrupt
608  * @retval 2 Falling edge latch interrupt
609  * @retval 3 Rising and falling latch interrupt
610  * @details This function is used to get capture interrupt of selected channel.
611  */
PWM_GetCaptureIntFlag(PWM_T * pwm,uint32_t u32ChannelNum)612 uint32_t PWM_GetCaptureIntFlag(PWM_T *pwm, uint32_t u32ChannelNum)
613 {
614     return (((((pwm)->CAPIF & (PWM_CAPIF_CFLIF0_Msk << u32ChannelNum)) ? 1 : 0) << 1) | \
615             (((pwm)->CAPIF & (PWM_CAPIF_CRLIF0_Msk << u32ChannelNum)) ? 1 : 0));
616 }
617 /**
618  * @brief Enable duty interrupt of selected channel
619  * @param[in] pwm The pointer of the specified PWM module
620  *                - PWM0 : PWM Group 0
621  *                - PWM1 : PWM Group 1
622  * @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5
623  * @param[in] u32IntDutyType Duty interrupt type, could be either
624  *              - \ref PWM_DUTY_INT_DOWN_COUNT_MATCH_CMP
625  *              - \ref PWM_DUTY_INT_UP_COUNT_MATCH_CMP
626  * @return None
627  * @details This function is used to enable duty interrupt of selected channel.
628  */
PWM_EnableDutyInt(PWM_T * pwm,uint32_t u32ChannelNum,uint32_t u32IntDutyType)629 void PWM_EnableDutyInt(PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32IntDutyType)
630 {
631     (pwm)->INTEN0 |= (u32IntDutyType << u32ChannelNum);
632 }
633 
634 /**
635  * @brief Disable duty interrupt of selected channel
636  * @param[in] pwm The pointer of the specified PWM module
637  *                - PWM0 : PWM Group 0
638  *                - PWM1 : PWM Group 1
639  * @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5
640  * @return None
641  * @details This function is used to disable duty interrupt of selected channel.
642  */
PWM_DisableDutyInt(PWM_T * pwm,uint32_t u32ChannelNum)643 void PWM_DisableDutyInt(PWM_T *pwm, uint32_t u32ChannelNum)
644 {
645     (pwm)->INTEN0 &= ~((PWM_DUTY_INT_DOWN_COUNT_MATCH_CMP | PWM_DUTY_INT_UP_COUNT_MATCH_CMP) << u32ChannelNum);
646 }
647 
648 /**
649  * @brief Clear duty interrupt flag of selected channel
650  * @param[in] pwm The pointer of the specified PWM module
651  *                - PWM0 : PWM Group 0
652  *                - PWM1 : PWM Group 1
653  * @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5
654  * @return None
655  * @details This function is used to clear duty interrupt flag of selected channel.
656  */
PWM_ClearDutyIntFlag(PWM_T * pwm,uint32_t u32ChannelNum)657 void PWM_ClearDutyIntFlag(PWM_T *pwm, uint32_t u32ChannelNum)
658 {
659     (pwm)->INTSTS0 = (PWM_INTSTS0_CMPUIF0_Msk | PWM_INTSTS0_CMPDIF0_Msk) << u32ChannelNum;
660 }
661 
662 /**
663  * @brief Get duty interrupt flag of selected channel
664  * @param[in] pwm The pointer of the specified PWM module
665  *                - PWM0 : PWM Group 0
666  *                - PWM1 : PWM Group 1
667  * @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5
668  * @return Duty interrupt flag of specified channel
669  * @retval 0 Duty interrupt did not occur
670  * @retval 1 Duty interrupt occurred
671  * @details This function is used to get duty interrupt flag of selected channel.
672  */
PWM_GetDutyIntFlag(PWM_T * pwm,uint32_t u32ChannelNum)673 uint32_t PWM_GetDutyIntFlag(PWM_T *pwm, uint32_t u32ChannelNum)
674 {
675     return ((((pwm)->INTSTS0 & ((PWM_INTSTS0_CMPDIF0_Msk | PWM_INTSTS0_CMPUIF0_Msk) << u32ChannelNum))) ? 1 : 0);
676 }
677 
678 /**
679  * @brief This function enable fault brake interrupt
680  * @param[in] pwm The pointer of the specified PWM module
681  * @param[in] u32BrakeSource Fault brake source.
682  *              - \ref PWM_FB_EDGE
683  *              - \ref PWM_FB_LEVEL
684  * @return None
685  * @details This function is used to enable fault brake interrupt.
686  *          The write-protection function should be disabled before using this function.
687  * @note Every two channels share the same setting.
688  */
PWM_EnableFaultBrakeInt(PWM_T * pwm,uint32_t u32BrakeSource)689 void PWM_EnableFaultBrakeInt(PWM_T *pwm, uint32_t u32BrakeSource)
690 {
691     (pwm)->INTEN1 |= (0x7 << u32BrakeSource);
692 }
693 
694 /**
695  * @brief This function disable fault brake interrupt
696  * @param[in] pwm The pointer of the specified PWM module
697  * @param[in] u32BrakeSource Fault brake source.
698  *              - \ref PWM_FB_EDGE
699  *              - \ref PWM_FB_LEVEL
700  * @return None
701  * @details This function is used to disable fault brake interrupt.
702  *          The write-protection function should be disabled before using this function.
703  * @note Every two channels share the same setting.
704  */
PWM_DisableFaultBrakeInt(PWM_T * pwm,uint32_t u32BrakeSource)705 void PWM_DisableFaultBrakeInt(PWM_T *pwm, uint32_t u32BrakeSource)
706 {
707     (pwm)->INTEN1 &= ~(0x7 << u32BrakeSource);
708 }
709 
710 /**
711  * @brief This function clear fault brake interrupt of selected source
712  * @param[in] pwm The pointer of the specified PWM module
713  * @param[in] u32BrakeSource Fault brake source.
714  *              - \ref PWM_FB_EDGE
715  *              - \ref PWM_FB_LEVEL
716  * @return None
717  * @details This function is used to clear fault brake interrupt of selected source.
718  *          The write-protection function should be disabled before using this function.
719  */
PWM_ClearFaultBrakeIntFlag(PWM_T * pwm,uint32_t u32BrakeSource)720 void PWM_ClearFaultBrakeIntFlag(PWM_T *pwm, uint32_t u32BrakeSource)
721 {
722     (pwm)->INTSTS1 = (0x3f << u32BrakeSource);
723 }
724 
725 /**
726  * @brief This function get fault brake interrupt flag of selected source
727  * @param[in] pwm The pointer of the specified PWM module
728  * @param[in] u32BrakeSource Fault brake source, could be either
729  *              - \ref PWM_FB_EDGE
730  *              - \ref PWM_FB_LEVEL
731  * @return Fault brake interrupt flag of specified source
732  * @retval 0 Fault brake interrupt did not occurred
733  * @retval 1 Fault brake interrupt occurred
734  * @details This function is used to get fault brake interrupt flag of selected source.
735  */
PWM_GetFaultBrakeIntFlag(PWM_T * pwm,uint32_t u32BrakeSource)736 uint32_t PWM_GetFaultBrakeIntFlag(PWM_T *pwm, uint32_t u32BrakeSource)
737 {
738     return (((pwm)->INTSTS1 & (0x3f << u32BrakeSource)) ? 1 : 0);
739 }
740 
741 /**
742  * @brief Enable period interrupt of selected channel
743  * @param[in] pwm The pointer of the specified PWM module
744  *                - PWM0 : PWM Group 0
745  *                - PWM1 : PWM Group 1
746  * @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5
747  * @param[in] u32IntPeriodType Period interrupt type. This parameter is not used.
748  * @return None
749  * @details This function is used to enable period interrupt of selected channel.
750  */
PWM_EnablePeriodInt(PWM_T * pwm,uint32_t u32ChannelNum,uint32_t u32IntPeriodType)751 void PWM_EnablePeriodInt(PWM_T *pwm, uint32_t u32ChannelNum,  uint32_t u32IntPeriodType)
752 {
753     (pwm)->INTEN0 |= (PWM_INTEN0_PIEN0_Msk << ((u32ChannelNum>>1)<<1));
754 }
755 
756 /**
757  * @brief Disable period interrupt of selected channel
758  * @param[in] pwm The pointer of the specified PWM module
759  *                - PWM0 : PWM Group 0
760  *                - PWM1 : PWM Group 1
761  * @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5
762  * @return None
763  * @details This function is used to disable period interrupt of selected channel.
764  */
PWM_DisablePeriodInt(PWM_T * pwm,uint32_t u32ChannelNum)765 void PWM_DisablePeriodInt(PWM_T *pwm, uint32_t u32ChannelNum)
766 {
767     (pwm)->INTEN0 &= ~(PWM_INTEN0_PIEN0_Msk << ((u32ChannelNum>>1)<<1));
768 }
769 
770 /**
771  * @brief Clear period interrupt of selected channel
772  * @param[in] pwm The pointer of the specified PWM module
773  *                - PWM0 : PWM Group 0
774  *                - PWM1 : PWM Group 1
775  * @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5
776  * @return None
777  * @details This function is used to clear period interrupt of selected channel.
778  */
PWM_ClearPeriodIntFlag(PWM_T * pwm,uint32_t u32ChannelNum)779 void PWM_ClearPeriodIntFlag(PWM_T *pwm, uint32_t u32ChannelNum)
780 {
781     (pwm)->INTSTS0 = (PWM_INTSTS0_PIF0_Msk << ((u32ChannelNum>>1)<<1));
782 }
783 
784 /**
785  * @brief Get period interrupt of selected channel
786  * @param[in] pwm The pointer of the specified PWM module
787  *                - PWM0 : PWM Group 0
788  *                - PWM1 : PWM Group 1
789  * @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5
790  * @return Period interrupt flag of specified channel
791  * @retval 0 Period interrupt did not occur
792  * @retval 1 Period interrupt occurred
793  * @details This function is used to get period interrupt of selected channel.
794  */
PWM_GetPeriodIntFlag(PWM_T * pwm,uint32_t u32ChannelNum)795 uint32_t PWM_GetPeriodIntFlag(PWM_T *pwm, uint32_t u32ChannelNum)
796 {
797     return ((((pwm)->INTSTS0 & (PWM_INTSTS0_PIF0_Msk << ((u32ChannelNum>>1)<<1)))) ? 1 : 0);
798 }
799 
800 /**
801  * @brief Enable zero interrupt of selected channel
802  * @param[in] pwm The pointer of the specified PWM module
803  *                - PWM0 : PWM Group 0
804  *                - PWM1 : PWM Group 1
805  * @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5
806  * @return None
807  * @details This function is used to enable zero interrupt of selected channel.
808  */
PWM_EnableZeroInt(PWM_T * pwm,uint32_t u32ChannelNum)809 void PWM_EnableZeroInt(PWM_T *pwm, uint32_t u32ChannelNum)
810 {
811     (pwm)->INTEN0 |= (PWM_INTEN0_ZIEN0_Msk << ((u32ChannelNum>>1)<<1));
812 }
813 
814 /**
815  * @brief Disable zero interrupt of selected channel
816  * @param[in] pwm The pointer of the specified PWM module
817  *                - PWM0 : PWM Group 0
818  *                - PWM1 : PWM Group 1
819  * @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5
820  * @return None
821  * @details This function is used to disable zero interrupt of selected channel.
822  */
PWM_DisableZeroInt(PWM_T * pwm,uint32_t u32ChannelNum)823 void PWM_DisableZeroInt(PWM_T *pwm, uint32_t u32ChannelNum)
824 {
825     (pwm)->INTEN0 &= ~(PWM_INTEN0_ZIEN0_Msk << ((u32ChannelNum>>1)<<1));
826 }
827 
828 /**
829  * @brief Clear zero interrupt of selected channel
830  * @param[in] pwm The pointer of the specified PWM module
831  *                - PWM0 : PWM Group 0
832  *                - PWM1 : PWM Group 1
833  * @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5
834  * @return None
835  * @details This function is used to clear zero interrupt of selected channel.
836  */
PWM_ClearZeroIntFlag(PWM_T * pwm,uint32_t u32ChannelNum)837 void PWM_ClearZeroIntFlag(PWM_T *pwm, uint32_t u32ChannelNum)
838 {
839     (pwm)->INTSTS0 = (PWM_INTSTS0_ZIF0_Msk << ((u32ChannelNum>>1)<<1));
840 }
841 
842 /**
843  * @brief Get zero interrupt of selected channel
844  * @param[in] pwm The pointer of the specified PWM module
845  *                - PWM0 : PWM Group 0
846  *                - PWM1 : PWM Group 1
847  * @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5
848  * @return Zero interrupt flag of specified channel
849  * @retval 0 Zero interrupt did not occur
850  * @retval 1 Zero interrupt occurred
851  * @details This function is used to get zero interrupt of selected channel.
852  */
PWM_GetZeroIntFlag(PWM_T * pwm,uint32_t u32ChannelNum)853 uint32_t PWM_GetZeroIntFlag(PWM_T *pwm, uint32_t u32ChannelNum)
854 {
855     return ((((pwm)->INTSTS0 & (PWM_INTSTS0_ZIF0_Msk << ((u32ChannelNum>>1)<<1)))) ? 1 : 0);
856 }
857 
858 /**
859  * @brief Enable interrupt flag accumulator of selected channel
860  * @param[in] pwm The pointer of the specified PWM module
861  *                - PWM0 : PWM Group 0
862  *                - PWM1 : PWM Group 1
863  * @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5
864  * @param[in] u32IntFlagCnt Interrupt flag counter. Valid values are between 0~15.
865  * @param[in] u32IntAccSrc Interrupt flag accumulator source selection.
866  *              - \ref PWM_IFA_EVEN_ZERO_POINT
867  *              - \ref PWM_IFA_EVEN_PERIOD_POINT
868  *              - \ref PWM_IFA_EVEN_COMPARE_UP_COUNT_POINT
869  *              - \ref PWM_IFA_EVEN_COMPARE_DOWN_COUNT_POINT
870  *              - \ref PWM_IFA_ODD_ZERO_POINT
871  *              - \ref PWM_IFA_ODD_PERIOD_POINT
872  *              - \ref PWM_IFA_ODD_COMPARE_UP_COUNT_POINT
873  *              - \ref PWM_IFA_ODD_COMPARE_DOWN_COUNT_POINT
874  * @return None
875  * @details This function is used to enable interrupt flag accumulator of selected channel.
876  * @note Every two channels share the same setting.
877  */
878 
879 /**
880  * @brief Enable load mode of selected channel
881  * @param[in] pwm The pointer of the specified PWM module
882  *                - PWM0 : PWM Group 0
883  *                - PWM1 : PWM Group 1
884  * @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5
885  * @param[in] u32LoadMode PWM counter loading mode.
886  *              - \ref PWM_LOAD_MODE_IMMEDIATE
887  *              - \ref PWM_LOAD_MODE_WINDOW
888  *              - \ref PWM_LOAD_MODE_CENTER
889  * @return None
890  * @details This function is used to enable load mode of selected channel.
891  */
PWM_EnableLoadMode(PWM_T * pwm,uint32_t u32ChannelNum,uint32_t u32LoadMode)892 void PWM_EnableLoadMode(PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32LoadMode)
893 {
894     (pwm)->CTL0 |= (u32LoadMode << u32ChannelNum);
895 }
896 
897 /**
898  * @brief Disable load mode of selected channel
899  * @param[in] pwm The pointer of the specified PWM module
900  *                - PWM0 : PWM Group 0
901  *                - PWM1 : PWM Group 1
902  * @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5
903  * @param[in] u32LoadMode PWM counter loading mode.
904  *              - \ref PWM_LOAD_MODE_IMMEDIATE
905  *              - \ref PWM_LOAD_MODE_WINDOW
906  *              - \ref PWM_LOAD_MODE_CENTER
907  * @return None
908  * @details This function is used to disable load mode of selected channel.
909  */
PWM_DisableLoadMode(PWM_T * pwm,uint32_t u32ChannelNum,uint32_t u32LoadMode)910 void PWM_DisableLoadMode(PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32LoadMode)
911 {
912     (pwm)->CTL0 &= ~(u32LoadMode << u32ChannelNum);
913 }
914 
915 /**
916  * @brief Set PWM clock source
917  * @param[in] pwm The pointer of the specified PWM module
918  *                - PWM0 : PWM Group 0
919  *                - PWM1 : PWM Group 1
920  * @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5
921  * @param[in] u32ClkSrcSel PWM external clock source.
922  *              - \ref PWM_CLKSRC_PWM_CLK
923  *              - \ref PWM_CLKSRC_TIMER0
924  *              - \ref PWM_CLKSRC_TIMER1
925  *              - \ref PWM_CLKSRC_TIMER2
926  *              - \ref PWM_CLKSRC_TIMER3
927  * @return None
928  * @details This function is used to set PWM clock source.
929  * @note Every two channels share the same setting.
930  * @note If the clock source of PWM counter is selected from TIMERn interrupt events, the TRGPWM(TIMERn_TRGCTL[1], n=0,1..3) bit must be set as 1.
931  */
PWM_SetClockSource(PWM_T * pwm,uint32_t u32ChannelNum,uint32_t u32ClkSrcSel)932 void PWM_SetClockSource(PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32ClkSrcSel)
933 {
934     (pwm)->CLKSRC = ((pwm)->CLKSRC & ~(PWM_CLKSRC_ECLKSRC0_Msk << ((u32ChannelNum >> 1) << 3))) | \
935                     (u32ClkSrcSel << ((u32ChannelNum >> 1) << 3));
936 }
937 
938 /**
939  * @brief Enable PWM brake noise filter function
940  * @param[in] pwm The pointer of the specified PWM module
941  *                - PWM0 : PWM Group 0
942  *                - PWM1 : PWM Group 1
943  * @param[in] u32BrakePinNum Brake pin selection. Valid values are 0 or 1.
944  * @param[in] u32ClkCnt SYNC Edge Detector Filter Count. This controls the counter number of edge detector
945  * @param[in] u32ClkDivSel SYNC Edge Detector Filter Clock Selection.
946  *              - \ref PWM_NF_CLK_DIV_1
947  *              - \ref PWM_NF_CLK_DIV_2
948  *              - \ref PWM_NF_CLK_DIV_4
949  *              - \ref PWM_NF_CLK_DIV_8
950  *              - \ref PWM_NF_CLK_DIV_16
951  *              - \ref PWM_NF_CLK_DIV_32
952  *              - \ref PWM_NF_CLK_DIV_64
953  *              - \ref PWM_NF_CLK_DIV_128
954  * @return None
955  * @details This function is used to enable PWM brake noise filter function.
956  */
PWM_EnableBrakeNoiseFilter(PWM_T * pwm,uint32_t u32BrakePinNum,uint32_t u32ClkCnt,uint32_t u32ClkDivSel)957 void PWM_EnableBrakeNoiseFilter(PWM_T *pwm, uint32_t u32BrakePinNum, uint32_t u32ClkCnt, uint32_t u32ClkDivSel)
958 {
959     (pwm)->BNF = ((pwm)->BNF & ~((PWM_BNF_BRK0FCNT_Msk | PWM_BNF_BRK0FSEL_Msk) << (u32BrakePinNum << 3))) | \
960                  (((u32ClkCnt << PWM_BNF_BRK0FCNT_Pos) | (u32ClkDivSel << PWM_BNF_BRK0FSEL_Pos) | PWM_BNF_BRK0NFEN_Msk) << (u32BrakePinNum << 3));
961 }
962 
963 /**
964  * @brief Disable PWM brake noise filter function
965  * @param[in] pwm The pointer of the specified PWM module
966  *                - PWM0 : PWM Group 0
967  *                - PWM1 : PWM Group 1
968  * @param[in] u32BrakePinNum Brake pin selection. Valid values are 0 or 1.
969  * @return None
970  * @details This function is used to disable PWM brake noise filter function.
971  */
PWM_DisableBrakeNoiseFilter(PWM_T * pwm,uint32_t u32BrakePinNum)972 void PWM_DisableBrakeNoiseFilter(PWM_T *pwm, uint32_t u32BrakePinNum)
973 {
974     (pwm)->BNF &= ~(PWM_BNF_BRK0NFEN_Msk << (u32BrakePinNum << 3));
975 }
976 
977 /**
978  * @brief Enable PWM brake pin inverse function
979  * @param[in] pwm The pointer of the specified PWM module
980  *                - PWM0 : PWM Group 0
981  *                - PWM1 : PWM Group 1
982  * @param[in] u32BrakePinNum Brake pin selection. Valid values are 0 or 1.
983  * @return None
984  * @details This function is used to enable PWM brake pin inverse function.
985  */
PWM_EnableBrakePinInverse(PWM_T * pwm,uint32_t u32BrakePinNum)986 void PWM_EnableBrakePinInverse(PWM_T *pwm, uint32_t u32BrakePinNum)
987 {
988     (pwm)->BNF |= (PWM_BNF_BRK0PINV_Msk << (u32BrakePinNum << 3));
989 }
990 
991 /**
992  * @brief Disable PWM brake pin inverse function
993  * @param[in] pwm The pointer of the specified PWM module
994  *                - PWM0 : PWM Group 0
995  *                - PWM1 : PWM Group 1
996  * @param[in] u32BrakePinNum Brake pin selection. Valid values are 0 or 1.
997  * @return None
998  * @details This function is used to disable PWM brake pin inverse function.
999  */
PWM_DisableBrakePinInverse(PWM_T * pwm,uint32_t u32BrakePinNum)1000 void PWM_DisableBrakePinInverse(PWM_T *pwm, uint32_t u32BrakePinNum)
1001 {
1002 //    (pwm)->BNF &= ~(PWM_BNF_BRK0PINV_Msk << (u32BrakePinNum * PWM_BNF_BRK1NFEN_Pos));
1003     (pwm)->BNF &= ~(PWM_BNF_BRK0PINV_Msk << (u32BrakePinNum * PWM_BNF_BRK1NFEN_Pos));
1004 }
1005 
1006 /**
1007  * @brief Set PWM brake pin source
1008  * @param[in] pwm The pointer of the specified PWM module
1009  *                - PWM0 : PWM Group 0
1010  *                - PWM1 : PWM Group 1
1011  * @param[in] u32BrakePinNum Brake pin selection. Valid values are 0 or 1.
1012  * @param[in] u32SelAnotherModule Select to another module. Valid values are TRUE or FALSE.
1013  * @return None
1014  * @details This function is used to set PWM brake pin source.
1015  * @note This function is only supported in M45xD/M45xC.
1016  */
PWM_SetBrakePinSource(PWM_T * pwm,uint32_t u32BrakePinNum,uint32_t u32SelAnotherModule)1017 void PWM_SetBrakePinSource(PWM_T *pwm, uint32_t u32BrakePinNum, uint32_t u32SelAnotherModule)
1018 {
1019     (pwm)->BNF = ((pwm)->BNF & ~(PWM_BNF_BK0SRC_Msk << (u32BrakePinNum << 3))) | (u32SelAnotherModule << (PWM_BNF_BK0SRC_Pos + (u32BrakePinNum << 3)));
1020 }
1021 
1022 /**
1023  * @brief Get the time-base counter reached its maximum value flag of selected channel
1024  * @param[in] pwm The pointer of the specified PWM module
1025  *                - PWM0 : PWM Group 0
1026  *                - PWM1 : PWM Group 1
1027  * @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5
1028  * @return Count to max interrupt flag of specified channel
1029  * @retval 0 Count to max interrupt did not occur
1030  * @retval 1 Count to max interrupt occurred
1031  * @details This function is used to get the time-base counter reached its maximum value flag of selected channel.
1032  */
PWM_GetWrapAroundFlag(PWM_T * pwm,uint32_t u32ChannelNum)1033 uint32_t PWM_GetWrapAroundFlag(PWM_T *pwm, uint32_t u32ChannelNum)
1034 {
1035     return (((pwm)->STATUS & (PWM_STATUS_CNTMAX0_Msk << u32ChannelNum)) ? 1 : 0);
1036 }
1037 
1038 /**
1039  * @brief Clear the time-base counter reached its maximum value flag of selected channel
1040  * @param[in] pwm The pointer of the specified PWM module
1041  *                - PWM0 : PWM Group 0
1042  *                - PWM1 : PWM Group 1
1043  * @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5
1044  * @return None
1045  * @details This function is used to clear the time-base counter reached its maximum value flag of selected channel.
1046  */
PWM_ClearWrapAroundFlag(PWM_T * pwm,uint32_t u32ChannelNum)1047 void PWM_ClearWrapAroundFlag(PWM_T *pwm, uint32_t u32ChannelNum)
1048 {
1049     (pwm)->STATUS = (PWM_STATUS_CNTMAX0_Msk << u32ChannelNum);
1050 }
1051 
1052 /**
1053  * @brief Enable interrupt flag accumulator of selected channel
1054  * @param[in] pwm The pointer of the specified PWM module
1055  *                - PWM0 : PWM Group 0
1056  *                - PWM1 : PWM Group 1
1057  * @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5
1058  * @param[in] u32IntFlagCnt Interrupt flag counter. Valid values are between 0~65535.
1059  * @param[in] u32IntAccSrc Interrupt flag accumulator source selection.
1060  *              - \ref PWM_IFA_ZERO_POINT
1061  *              - \ref PWM_IFA_PERIOD_POINT
1062  *              - \ref PWM_IFA_COMPARE_UP_COUNT_POINT
1063  *              - \ref PWM_IFA_COMPARE_DOWN_COUNT_POINT
1064  * @return None
1065  * @details This function is used to enable interrupt flag accumulator of selected channel.
1066  */
PWM_EnableAcc(PWM_T * pwm,uint32_t u32ChannelNum,uint32_t u32IntFlagCnt,uint32_t u32IntAccSrc)1067 void PWM_EnableAcc(PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32IntFlagCnt, uint32_t u32IntAccSrc)
1068 {
1069     (pwm)->IFA[(u32ChannelNum>>1)<<1] &= ~(PWM_IFA0_IFAEN_Msk | PWM_IFA0_IFACNT_Msk | PWM_IFA0_IFASEL_Msk);
1070     (pwm)->IFA[(u32ChannelNum>>1)<<1] |= (PWM_IFA0_IFAEN_Msk | u32IntFlagCnt | (u32IntAccSrc << PWM_IFA0_IFASEL_Pos));
1071 }
1072 
1073 /**
1074  * @brief Disable interrupt flag accumulator of selected channel
1075  * @param[in] pwm The pointer of the specified PWM module
1076  *                - PWM0 : PWM Group 0
1077  *                - PWM1 : PWM Group 1
1078  * @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5
1079  * @return None
1080  * @details This function is used to Disable interrupt flag accumulator of selected channel.
1081  */
PWM_DisableAcc(PWM_T * pwm,uint32_t u32ChannelNum)1082 void PWM_DisableAcc(PWM_T *pwm, uint32_t u32ChannelNum)
1083 {
1084     (pwm)->IFA[(u32ChannelNum>>1)<<1] &= ~PWM_IFA0_IFAEN_Msk;
1085 }
1086 
1087 /**
1088  * @brief Enable interrupt flag accumulator interrupt of selected channel
1089  * @param[in] pwm The pointer of the specified PWM module
1090  *                - PWM0 : PWM Group 0
1091  *                - PWM1 : PWM Group 1
1092  * @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5
1093  * @return None
1094  * @details This function is used to enable interrupt flag accumulator interrupt of selected channel.
1095  */
PWM_EnableAccInt(PWM_T * pwm,uint32_t u32ChannelNum)1096 void PWM_EnableAccInt(PWM_T *pwm, uint32_t u32ChannelNum)
1097 {
1098     (pwm)->AINTEN |= (1UL << ((u32ChannelNum>>1)<<1));
1099 }
1100 
1101 /**
1102  * @brief Disable interrupt flag accumulator interrupt of selected channel
1103  * @param[in] pwm The pointer of the specified PWM module
1104  *                - PWM0 : PWM Group 0
1105  *                - PWM1 : PWM Group 1
1106  * @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5
1107  * @return None
1108  * @details This function is used to disable interrupt flag accumulator interrupt of selected channel.
1109  */
PWM_DisableAccInt(PWM_T * pwm,uint32_t u32ChannelNum)1110 void PWM_DisableAccInt(PWM_T *pwm, uint32_t u32ChannelNum)
1111 {
1112     (pwm)->AINTEN &= ~(1UL << ((u32ChannelNum>>1)<<1));
1113 }
1114 
1115 /**
1116  * @brief Clear interrupt flag accumulator interrupt of selected channel
1117  * @param[in] pwm The pointer of the specified PWM module
1118  *                - PWM0 : PWM Group 0
1119  *                - PWM1 : PWM Group 1
1120  * @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5
1121  * @return None
1122  * @details This function is used to clear interrupt flag accumulator interrupt of selected channel.
1123  */
PWM_ClearAccInt(PWM_T * pwm,uint32_t u32ChannelNum)1124 void PWM_ClearAccInt(PWM_T *pwm, uint32_t u32ChannelNum)
1125 {
1126     (pwm)->AINTSTS = (1UL << ((u32ChannelNum>>1)<<1));
1127 }
1128 
1129 /**
1130  * @brief Get interrupt flag accumulator interrupt of selected channel
1131  * @param[in] pwm The pointer of the specified PWM module
1132  *                - PWM0 : PWM Group 0
1133  *                - PWM1 : PWM Group 1
1134  * @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5
1135  * @retval 0 Accumulator interrupt did not occur
1136  * @retval 1 Accumulator interrupt occurred
1137  * @details This function is used to Get interrupt flag accumulator interrupt of selected channel.
1138  */
PWM_GetAccInt(PWM_T * pwm,uint32_t u32ChannelNum)1139 uint32_t PWM_GetAccInt(PWM_T *pwm, uint32_t u32ChannelNum)
1140 {
1141     return (((pwm)->AINTSTS & (1UL << ((u32ChannelNum>>1)<<1))) ? 1UL : 0UL);
1142 }
1143 
1144 /**
1145  * @brief Enable accumulator PDMA of selected channel
1146  * @param[in] pwm The pointer of the specified PWM module
1147  *                - PWM0 : PWM Group 0
1148  *                - PWM1 : PWM Group 1
1149  * @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5
1150  * @return None
1151  * @details This function is used to enable accumulator interrupt trigger PDMA of selected channel.
1152  */
PWM_EnableAccPDMA(PWM_T * pwm,uint32_t u32ChannelNum)1153 void PWM_EnableAccPDMA(PWM_T *pwm, uint32_t u32ChannelNum)
1154 {
1155     (pwm)->APDMACTL |= (1UL << ((u32ChannelNum>>1)<<1));
1156 }
1157 
1158 /**
1159  * @brief Disable accumulator PDMA of selected channel
1160  * @param[in] pwm The pointer of the specified PWM module
1161  *                - PWM0 : PWM Group 0
1162  *                - PWM1 : PWM Group 1
1163  * @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5
1164  * @return None
1165  * @details This function is used to disable accumulator interrupt trigger PDMA of selected channel.
1166  */
PWM_DisableAccPDMA(PWM_T * pwm,uint32_t u32ChannelNum)1167 void PWM_DisableAccPDMA(PWM_T *pwm, uint32_t u32ChannelNum)
1168 {
1169     (pwm)->APDMACTL &= ~(1UL << ((u32ChannelNum>>1)<<1));
1170 }
1171 
1172 /**
1173  * @brief Enable interrupt flag accumulator stop mode of selected channel
1174  * @param[in] pwm The pointer of the specified PWM module
1175  *                - PWM0 : PWM Group 0
1176  *                - PWM1 : PWM Group 1
1177  * @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5
1178  * @return None
1179  * @details This function is used to enable interrupt flag accumulator stop mode of selected channel.
1180  */
PWM_EnableAccStopMode(PWM_T * pwm,uint32_t u32ChannelNum)1181 void PWM_EnableAccStopMode(PWM_T *pwm, uint32_t u32ChannelNum)
1182 {
1183     (pwm)->IFA[(u32ChannelNum>>1)<<1] |= PWM_IFA0_STPMOD_Msk;
1184 }
1185 
1186 /**
1187  * @brief Disable interrupt flag accumulator stop mode of selected channel
1188  * @param[in] pwm The pointer of the specified PWM module
1189  *                - PWM0 : PWM Group 0
1190  *                - PWM1 : PWM Group 1
1191  * @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5
1192  * @return None
1193  * @details This function is used to disable interrupt flag accumulator stop mode of selected channel.
1194  */
PWM_DisableAccStopMode(PWM_T * pwm,uint32_t u32ChannelNum)1195 void PWM_DisableAccStopMode(PWM_T *pwm, uint32_t u32ChannelNum)
1196 {
1197     (pwm)->IFA[u32ChannelNum] &= ~PWM_IFA0_STPMOD_Msk;
1198 }
1199 /*@}*/ /* end of group PWM_EXPORTED_FUNCTIONS */
1200 
1201 /*@}*/ /* end of group PWM_Driver */
1202 
1203 /*@}*/ /* end of group Standard_Driver */
1204 
1205 /*** (C) COPYRIGHT 2017 Nuvoton Technology Corp. ***/
1206