MINI55_BSP V3.02.004
The Board Support Package for Mini55 Series MCU
pwm.c
Go to the documentation of this file.
1/**************************************************************************/
12#include "Mini55Series.h"
13
38 uint32_t u32ChannelNum,
39 uint32_t u32Frequency,
40 uint32_t u32DutyCycle)
41{
42 uint32_t i = SystemCoreClock / u32Frequency;
43 uint8_t u8Divider = 1, u8Prescale = 0xFF;
44 uint16_t u16CNR = 0xFFFF;
45
46 for(; u8Divider < 17; u8Divider <<= 1) // clk divider could only be 1, 2, 4, 8, 16
47 {
48 i = (SystemCoreClock / u32Frequency) / u8Divider;
49 // If target value is larger than CNR * prescale, need to use a larger divider
50 if(i > (0x10000 * 0x100))
51 continue;
52
53 // CNR = 0xFFFF + 1, get a prescaler that CNR value is below 0xFFFF
54 u8Prescale = (i + 0xFFFF)/ 0x10000;
55
56 // u8Prescale must at least be 2, otherwise the output stop
57 if(u8Prescale < 3)
58 u8Prescale = 2;
59
60 i /= u8Prescale;
61
62 if(i <= 0x10000)
63 {
64 if(i == 1)
65 u16CNR = 1; // Too fast, and PWM cannot generate expected frequency...
66 else
67 u16CNR = i;
68 break;
69 }
70
71 }
72 // Store return value here 'cos we're gonna change u8Divider & u8Prescale & u16CNR to the real value to fill into register
73 i = SystemCoreClock / (u8Prescale * u8Divider * u16CNR);
74
75 u8Prescale -= 1;
76 u16CNR -= 1;
77 // convert to real register value
78 if(u8Divider == 1)
79 u8Divider = 4;
80 else if (u8Divider == 2)
81 u8Divider = 0;
82 else if (u8Divider == 4)
83 u8Divider = 1;
84 else if (u8Divider == 8)
85 u8Divider = 2;
86 else // 16
87 u8Divider = 3;
88
89 // every two channels share a prescaler
90 PWM->CLKPSC = (PWM->CLKPSC & ~(PWM_CLKPSC_CLKPSC01_Msk << ((u32ChannelNum >> 1) * 8))) | (u8Prescale << ((u32ChannelNum >> 1) * 8));
91 PWM->CLKDIV = (PWM->CLKDIV & ~(PWM_CLKDIV_CLKDIV0_Msk << (4 * u32ChannelNum))) | (u8Divider << (4 * u32ChannelNum));
92 PWM->CTL = (PWM->CTL & ~PWM_CTL_CNTTYPE_Msk) | (PWM_CTL_CNTMODE0_Msk << (4 * u32ChannelNum));
93 if(u32DutyCycle == 0)
94 PWM->CMPDAT[u32ChannelNum] = 0;
95 else
96 PWM->CMPDAT[u32ChannelNum] = u32DutyCycle * (u16CNR + 1) / 100 - 1;
97 PWM->PERIOD[u32ChannelNum] = u16CNR;
98
99 return(i);
100}
101
102
110void PWM_Start (PWM_T *pwm, uint32_t u32ChannelMask)
111{
112 uint32_t u32Mask = 0, i;
113 for(i = 0; i < PWM_CHANNEL_NUM; i ++)
114 {
115 if(u32ChannelMask & (1 << i))
116 {
117 u32Mask |= (PWM_CTL_CNTEN0_Msk << (i * 4));
118 }
119 }
120
121 PWM->CTL |= u32Mask;
122}
123
131void PWM_Stop (PWM_T *pwm, uint32_t u32ChannelMask)
132{
133 uint32_t i;
134 for(i = 0; i < PWM_CHANNEL_NUM; i ++)
135 {
136 if(u32ChannelMask & (1 << i))
137 {
138 PWM->PERIOD[i] = 0;
139 }
140 }
141
142}
143
151void PWM_ForceStop (PWM_T *pwm, uint32_t u32ChannelMask)
152{
153 uint32_t u32Mask = 0, i;
154 for(i = 0; i < PWM_CHANNEL_NUM; i ++)
155 {
156 if(u32ChannelMask & (1 << i))
157 {
158 u32Mask |= (PWM_CTL_CNTEN0_Msk << (i * 4));
159 }
160 }
161
162 PWM->CTL &= ~u32Mask;
163}
164
176void PWM_EnableADCTrigger (PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32Condition)
177{
178 if(u32ChannelNum < 4)
179 {
180 PWM->ADCTCTL0 = (PWM->ADCTCTL0 & ~((PWM_TRIGGER_ADC_CNTR_IS_0 |
183 PWM_TRIGGER_ADC_CNTR_IS_CMR_U ) << (8 * u32ChannelNum))) | (u32Condition << (8 * u32ChannelNum));
184 }
185 else
186 {
187 PWM->ADCTCTL1 = (PWM->ADCTCTL1 & ~((PWM_TRIGGER_ADC_CNTR_IS_0 |
190 PWM_TRIGGER_ADC_CNTR_IS_CMR_U ) << (8 * (u32ChannelNum - 4)))) | (u32Condition << (8 * (u32ChannelNum - 4)));
191
192 }
193}
194
201void PWM_DisableADCTrigger (PWM_T *pwm, uint32_t u32ChannelNum)
202{
203 if(u32ChannelNum < 4)
204 {
205 PWM->ADCTCTL0 = (PWM->ADCTCTL0 & ~((PWM_TRIGGER_ADC_CNTR_IS_0 |
208 PWM_TRIGGER_ADC_CNTR_IS_CMR_U ) << (8 * u32ChannelNum)));
209 }
210 else
211 {
212 PWM->ADCTCTL1 = (PWM->ADCTCTL1 & ~((PWM_TRIGGER_ADC_CNTR_IS_0 |
215 PWM_TRIGGER_ADC_CNTR_IS_CMR_U ) << (8 * (u32ChannelNum - 4))));
216 }
217}
218
230void PWM_ClearADCTriggerFlag (PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32Condition)
231{
232 if(u32ChannelNum < 4)
233 {
234 PWM->ADCTSTS0 |= (u32Condition << (8 * u32ChannelNum));
235 }
236 else
237 {
238 PWM->ADCTSTS1 |= (u32Condition << (8 * (u32ChannelNum - 4)));
239 }
240}
241
249uint32_t PWM_GetADCTriggerFlag (PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32Condition)
250{
251 if(u32ChannelNum < 4)
252 {
253 return(PWM->ADCTSTS0 & (u32Condition << (8 * u32ChannelNum)) ? 1 : 0);
254 }
255 else
256 {
257 return(PWM->ADCTSTS1 & (u32Condition << (8 * (u32ChannelNum - 4))) ? 1 : 0);
258 }
259}
260
276 uint32_t u32ChannelMask,
277 uint32_t u32LevelMask,
278 uint32_t u32BrakeSource)
279{
280 PWM->BRKCTL = (u32LevelMask << PWM_BRKCTL_BKOD0_Pos) | u32BrakeSource;
281}
282
290void PWM_ClearFaultBrakeFlag (PWM_T *pwm, uint32_t u32BrakeSource)
291{
292 PWM->BRKCTL = PWM_BRKCTL_BRKSTS_Msk;
293}
294
302void PWM_EnableOutput (PWM_T *pwm, uint32_t u32ChannelMask)
303{
304 PWM->POEN |= u32ChannelMask;
305}
306
314void PWM_DisableOutput (PWM_T *pwm, uint32_t u32ChannelMask)
315{
316 PWM->POEN &= ~u32ChannelMask;
317}
318
327void PWM_EnableDeadZone (PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32Duration)
328{
329 // every two channels shares the same setting
330 u32ChannelNum >>= 1;
331 // set duration
332 PWM->DTCTL = (PWM->DTCTL & ~(PWM_DTCTL_DTCNT01_Msk << (8 * u32ChannelNum))) | (u32Duration << (8 * u32ChannelNum));
333 // enable dead zone
334 PWM->CTL |= (PWM_CTL_DTCNT01_Msk << u32ChannelNum);
335}
336
343void PWM_DisableDeadZone (PWM_T *pwm, uint32_t u32ChannelNum)
344{
345 // every two channels shares the same setting
346 u32ChannelNum >>= 1;
347 // enable dead zone
348 PWM->CTL &= ~(PWM_CTL_DTCNT01_Msk << u32ChannelNum);
349}
350
358void PWM_EnableDutyInt (PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32IntDutyType)
359{
360 PWM->INTEN |= (PWM_INTEN_CMPDIEN0_Msk << u32ChannelNum);
361}
362
369void PWM_DisableDutyInt (PWM_T *pwm, uint32_t u32ChannelNum)
370{
371 PWM->INTEN &= ~(PWM_INTEN_CMPDIEN0_Msk << u32ChannelNum);
372}
373
380void PWM_ClearDutyIntFlag (PWM_T *pwm, uint32_t u32ChannelNum)
381{
382 PWM->INTSTS = (PWM_INTSTS_CMPDIF0_Msk << u32ChannelNum);
383}
384
393uint32_t PWM_GetDutyIntFlag (PWM_T *pwm, uint32_t u32ChannelNum)
394{
395 return(PWM->INTSTS & (PWM_INTSTS_CMPDIF0_Msk << u32ChannelNum) ? 1 : 0);
396}
397
404void PWM_EnablePeriodInt (PWM_T *pwm, uint32_t u32ChannelNum)
405{
406 (pwm)->INTEN |= ((1 << PWM_INTEN_ZIEN0_Pos) << u32ChannelNum);
407}
408
415void PWM_DisablePeriodInt (PWM_T *pwm, uint32_t u32ChannelNum)
416{
417 PWM->INTEN &= ~(PWM_INTEN_ZIEN0_Msk << u32ChannelNum);
418}
419
426void PWM_ClearPeriodIntFlag (PWM_T *pwm, uint32_t u32ChannelNum)
427{
428 PWM->INTSTS = (PWM_INTSTS_ZIF0_Msk << u32ChannelNum);
429}
430
439uint32_t PWM_GetPeriodIntFlag (PWM_T *pwm, uint32_t u32ChannelNum)
440{
441 return(PWM->INTSTS & (PWM_INTSTS_ZIF0_Msk << u32ChannelNum) ? 1 : 0);
442}
443
450void PWM_EnableRiseInt (PWM_T *pwm, uint32_t u32ChannelNum)
451{
452 (pwm)->INTEN |= ((1 << PWM_INTEN_CMPUIEN0_Pos) << u32ChannelNum);
453}
454
461void PWM_DisableRiseInt (PWM_T *pwm, uint32_t u32ChannelNum)
462{
463 (pwm)->INTEN &= ~((1 << PWM_INTEN_CMPUIEN0_Pos) << u32ChannelNum);
464}
465
472void PWM_ClearRiseIntFlag (PWM_T *pwm, uint32_t u32ChannelNum)
473{
474 PWM->INTSTS = (PWM_INTSTS_CMPUIF0_Msk << u32ChannelNum);
475}
476
485uint32_t PWM_GetRiseIntFlag (PWM_T *pwm, uint32_t u32ChannelNum)
486{
487 return(PWM->INTSTS & (PWM_INTSTS_CMPUIF0_Msk << u32ChannelNum) ? 1 : 0);
488}
489
496void PWM_EnableFaultBrakeInt (PWM_T *pwm, uint32_t u32BrakeSource)
497{
498 PWM->INTEN |= PWM_INTEN_BRKIEN_Msk;
499}
500
507void PWM_DisableFaultBrakeInt (PWM_T *pwm, uint32_t u32BrakeSource)
508{
509 PWM->INTEN &= ~PWM_INTEN_BRKIEN_Msk;
510}
511
520void PWM_ClearFaultBrakeIntFlag (PWM_T *pwm, uint32_t u32BrakeSource)
521{
522 PWM->INTSTS = u32BrakeSource;
523}
524
535uint32_t PWM_GetFaultBrakeIntFlag (PWM_T *pwm, uint32_t u32BrakeSource)
536{
537 return (PWM->INTSTS & u32BrakeSource ? 1 : 0);
538}
539
550void PWM_EnableCenterInt (PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32IntPeriodType)
551{
552 PWM->INTEN = (PWM->INTEN & ~PWM_INTEN_PINTTYPE_Msk & ~(PWM_INTEN_PIEN0_Msk << u32ChannelNum)) | (PWM_INTEN_PIEN0_Msk << u32ChannelNum) | u32IntPeriodType;
553}
554
561void PWM_DisableCenterInt (PWM_T *pwm, uint32_t u32ChannelNum)
562{
563 PWM->INTEN &= ~(PWM_INTEN_PIEN0_Msk << u32ChannelNum);
564}
565
572void PWM_ClearCenterIntFlag (PWM_T *pwm, uint32_t u32ChannelNum)
573{
574 PWM->INTSTS = (PWM_INTSTS_PIF0_Msk << u32ChannelNum);
575}
576
585uint32_t PWM_GetCenterIntFlag (PWM_T *pwm, uint32_t u32ChannelNum)
586{
587 return(PWM->INTSTS & (PWM_INTSTS_PIF0_Msk << u32ChannelNum) ? 1 : 0);
588}
589
590
591 /* end of group MINI55_PWM_EXPORTED_FUNCTIONS */
593 /* end of group MINI55_PWM_Driver */
595 /* end of group MINI55_Device_Driver */
597
598/*** (C) COPYRIGHT 2014 Nuvoton Technology Corp. ***/
Mini55 series peripheral access layer header file. This file contains all the peripheral register's d...
#define PWM_INTSTS_CMPDIF0_Msk
#define PWM_CTL_CNTEN0_Msk
#define PWM_INTSTS_CMPUIF0_Msk
#define PWM_CLKDIV_CLKDIV0_Msk
#define PWM_INTEN_PIEN0_Msk
#define PWM_INTEN_CMPUIEN0_Pos
#define PWM_DTCTL_DTCNT01_Msk
#define PWM_BRKCTL_BKOD0_Pos
#define PWM_CTL_CNTMODE0_Msk
#define PWM_CTL_DTCNT01_Msk
#define PWM_BRKCTL_BRKSTS_Msk
#define PWM_INTEN_ZIEN0_Pos
#define PWM_INTSTS_ZIF0_Msk
#define PWM_INTEN_ZIEN0_Msk
#define PWM_INTEN_CMPDIEN0_Msk
#define PWM_INTSTS_PIF0_Msk
#define PWM_INTEN_BRKIEN_Msk
#define PWM_CLKPSC_CLKPSC01_Msk
#define PWM_TRIGGER_ADC_CNTR_IS_0
Definition: pwm.h:40
#define PWM_TRIGGER_ADC_CNTR_IS_CMR_U
Definition: pwm.h:43
#define PWM_CHANNEL_NUM
Definition: pwm.h:32
#define PWM_TRIGGER_ADC_CNTR_IS_CNR
Definition: pwm.h:42
#define PWM_TRIGGER_ADC_CNTR_IS_CMR_D
Definition: pwm.h:41
void PWM_ForceStop(PWM_T *pwm, uint32_t u32ChannelMask)
This function stop PWM generation immediately by clear channel enable bit.
Definition: pwm.c:151
void PWM_Stop(PWM_T *pwm, uint32_t u32ChannelMask)
This function stop PWM module.
Definition: pwm.c:131
void PWM_EnableDeadZone(PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32Duration)
This function enable Dead zone of selected channel.
Definition: pwm.c:327
void PWM_ClearADCTriggerFlag(PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32Condition)
This function clear selected channel trigger ADC flag.
Definition: pwm.c:230
void PWM_DisableADCTrigger(PWM_T *pwm, uint32_t u32ChannelNum)
This function disable selected channel to trigger ADC.
Definition: pwm.c:201
void PWM_DisableRiseInt(PWM_T *pwm, uint32_t u32ChannelNum)
This function disable Rise interrupt of selected channel.
Definition: pwm.c:461
void PWM_ClearRiseIntFlag(PWM_T *pwm, uint32_t u32ChannelNum)
This function clears Rise interrupt flag of selected channel.
Definition: pwm.c:472
void PWM_DisablePeriodInt(PWM_T *pwm, uint32_t u32ChannelNum)
This function disable Period interrupt of selected channel.
Definition: pwm.c:415
void PWM_EnableDutyInt(PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32IntDutyType)
This function enable duty interrupt of selected channel.
Definition: pwm.c:358
uint32_t PWM_GetFaultBrakeIntFlag(PWM_T *pwm, uint32_t u32BrakeSource)
This function get fault brake interrupt of selected source.
Definition: pwm.c:535
void PWM_DisableFaultBrakeInt(PWM_T *pwm, uint32_t u32BrakeSource)
This function disable fault brake interrupt.
Definition: pwm.c:507
uint32_t PWM_ConfigOutputChannel(PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32Frequency, uint32_t u32DutyCycle)
This function config PWM generator and get the nearest frequency in edge aligned auto-reload mode.
Definition: pwm.c:37
void PWM_EnablePeriodInt(PWM_T *pwm, uint32_t u32ChannelNum)
This function enable Period interrupt of selected channel.
Definition: pwm.c:404
void PWM_DisableCenterInt(PWM_T *pwm, uint32_t u32ChannelNum)
This function disable Central interrupt of selected channel.
Definition: pwm.c:561
void PWM_EnableRiseInt(PWM_T *pwm, uint32_t u32ChannelNum)
This function enable Rise interrupt of selected channel.
Definition: pwm.c:450
void PWM_DisableDutyInt(PWM_T *pwm, uint32_t u32ChannelNum)
This function disable duty interrupt of selected channel.
Definition: pwm.c:369
uint32_t PWM_GetADCTriggerFlag(PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32Condition)
This function get selected channel trigger ADC flag.
Definition: pwm.c:249
void PWM_ClearDutyIntFlag(PWM_T *pwm, uint32_t u32ChannelNum)
This function clears duty interrupt flag of selected channel.
Definition: pwm.c:380
void PWM_EnableFaultBrake(PWM_T *pwm, uint32_t u32ChannelMask, uint32_t u32LevelMask, uint32_t u32BrakeSource)
This function enable fault brake of selected channels.
Definition: pwm.c:275
uint32_t PWM_GetDutyIntFlag(PWM_T *pwm, uint32_t u32ChannelNum)
This function get duty interrupt flag of selected channel.
Definition: pwm.c:393
void PWM_DisableDeadZone(PWM_T *pwm, uint32_t u32ChannelNum)
This function disable Dead zone of selected channel.
Definition: pwm.c:343
void PWM_DisableOutput(PWM_T *pwm, uint32_t u32ChannelMask)
This function disables PWM output generation of selected channels.
Definition: pwm.c:314
void PWM_EnableCenterInt(PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32IntPeriodType)
This function enable Central interrupt of selected channel.
Definition: pwm.c:550
void PWM_ClearCenterIntFlag(PWM_T *pwm, uint32_t u32ChannelNum)
This function clear Central interrupt of selected channel.
Definition: pwm.c:572
uint32_t PWM_GetRiseIntFlag(PWM_T *pwm, uint32_t u32ChannelNum)
This function get Rise interrupt flag of selected channel.
Definition: pwm.c:485
void PWM_ClearFaultBrakeIntFlag(PWM_T *pwm, uint32_t u32BrakeSource)
This function clear fault brake interrupt of selected source.
Definition: pwm.c:520
void PWM_Start(PWM_T *pwm, uint32_t u32ChannelMask)
This function start PWM module.
Definition: pwm.c:110
void PWM_ClearPeriodIntFlag(PWM_T *pwm, uint32_t u32ChannelNum)
This function clears Period interrupt flag of selected channel.
Definition: pwm.c:426
void PWM_EnableOutput(PWM_T *pwm, uint32_t u32ChannelMask)
This function enables PWM output generation of selected channels.
Definition: pwm.c:302
void PWM_EnableFaultBrakeInt(PWM_T *pwm, uint32_t u32BrakeSource)
This function enable fault brake interrupt.
Definition: pwm.c:496
uint32_t PWM_GetPeriodIntFlag(PWM_T *pwm, uint32_t u32ChannelNum)
This function get Period interrupt flag of selected channel.
Definition: pwm.c:439
void PWM_ClearFaultBrakeFlag(PWM_T *pwm, uint32_t u32BrakeSource)
This function clear fault brake flag.
Definition: pwm.c:290
uint32_t PWM_GetCenterIntFlag(PWM_T *pwm, uint32_t u32ChannelNum)
This function get Central interrupt of selected channel.
Definition: pwm.c:585
void PWM_EnableADCTrigger(PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32Condition)
This function enable selected channel to trigger ADC.
Definition: pwm.c:176
#define PWM
Pointer to PWM register structure.
uint32_t SystemCoreClock