MINI51DE_BSP V3.02.004
The Board Support Package for Mini51DE Series MCU
pwm.c
Go to the documentation of this file.
1/**************************************************************************/
12#include "Mini51Series.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->PPR = (PWM->PPR & ~(PWM_PPR_CP01_Msk << ((u32ChannelNum >> 1) * 8))) | (u8Prescale << ((u32ChannelNum >> 1) * 8));
91 PWM->CSR = (PWM->CSR & ~(PWM_CSR_CSR0_Msk << (4 * u32ChannelNum))) | (u8Divider << (4 * u32ChannelNum));
92 PWM->PCR = (PWM->PCR & ~PWM_PCR_PWMTYPE_Msk) | (PWM_PCR_CH0MOD_Msk << (4 * u32ChannelNum));
93 if(u32DutyCycle == 0)
94 PWM->CMR[u32ChannelNum] = 0;
95 else
96 PWM->CMR[u32ChannelNum] = u32DutyCycle * (u16CNR + 1) / 100 - 1;
97 PWM->CNR[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_PCR_CH0EN_Msk << (i * 4));
118 }
119 }
120
121 PWM->PCR |= 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->CNR[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_PCR_CH0EN_Msk << (i * 4));
159 }
160 }
161
162 PWM->PCR &= ~u32Mask;
163}
164
176void PWM_EnableADCTrigger (PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32Condition)
177{
178 if(u32ChannelNum < 4)
179 {
180 PWM->TRGCON0 = (PWM->TRGCON0 & ~((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->TRGCON1 = (PWM->TRGCON1 & ~((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->TRGCON0 = (PWM->TRGCON0 & ~((PWM_TRIGGER_ADC_CNTR_IS_0 |
208 PWM_TRIGGER_ADC_CNTR_IS_CMR_U ) << (8 * u32ChannelNum)));
209 }
210 else
211 {
212 PWM->TRGCON1 = (PWM->TRGCON1 & ~((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->TRGSTS0 |= (u32Condition << (8 * u32ChannelNum));
235 }
236 else
237 {
238 PWM->TRGSTS1 |= (u32Condition << (8 * (u32ChannelNum - 4)));
239 }
240}
241
252uint32_t PWM_GetADCTriggerFlag (PWM_T *pwm, uint32_t u32ChannelNum)
253{
254 uint32_t u32Ret;
255
256 if(u32ChannelNum < 4)
257 {
258 u32Ret = PWM->TRGSTS0 >> (8 * u32ChannelNum);
259 }
260 else
261 {
262 u32Ret = PWM->TRGSTS1 >> (8 * (u32ChannelNum - 4 ));
263 }
264
265 return (u32Ret & (PWM_TRIGGER_ADC_CNTR_IS_0 |
269}
270
286 uint32_t u32ChannelMask,
287 uint32_t u32LevelMask,
288 uint32_t u32BrakeSource)
289{
290 PWM->PFBCON = (u32LevelMask << PWM_PFBCON_PWMBKO0_Pos) | u32BrakeSource;
291}
292
300void PWM_ClearFaultBrakeFlag (PWM_T *pwm, uint32_t u32BrakeSource)
301{
302 PWM->PFBCON = PWM_PFBCON_BKF_Msk;
303}
304
312void PWM_EnableOutput (PWM_T *pwm, uint32_t u32ChannelMask)
313{
314 PWM->POE |= u32ChannelMask;
315}
316
324void PWM_DisableOutput (PWM_T *pwm, uint32_t u32ChannelMask)
325{
326 PWM->POE &= ~u32ChannelMask;
327}
328
337void PWM_EnableDeadZone (PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32Duration)
338{
339 // every two channels shares the same setting
340 u32ChannelNum >>= 1;
341 // set duration
342 PWM->PDZIR = (PWM->PDZIR & ~(PWM_DZIR_DZI01_Msk << (8 * u32ChannelNum))) | (u32Duration << (8 * u32ChannelNum));
343 // enable dead zone
344 PWM->PCR |= (PWM_PCR_DZEN01_Msk << u32ChannelNum);
345}
346
353void PWM_DisableDeadZone (PWM_T *pwm, uint32_t u32ChannelNum)
354{
355 // every two channels shares the same setting
356 u32ChannelNum >>= 1;
357 // enable dead zone
358 PWM->PCR &= ~(PWM_PCR_DZEN01_Msk << u32ChannelNum);
359}
360
368void PWM_EnableDutyInt (PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32IntDutyType)
369{
370 PWM->PIER |= (PWM_PIER_PWMDIE0_Msk << u32ChannelNum);
371}
372
379void PWM_DisableDutyInt (PWM_T *pwm, uint32_t u32ChannelNum)
380{
381 PWM->PIER &= ~(PWM_PIER_PWMDIE0_Msk << u32ChannelNum);
382}
383
390void PWM_ClearDutyIntFlag (PWM_T *pwm, uint32_t u32ChannelNum)
391{
392 PWM->PIIR = (PWM_PIIR_PWMDIF0_Msk << u32ChannelNum);
393}
394
403uint32_t PWM_GetDutyIntFlag (PWM_T *pwm, uint32_t u32ChannelNum)
404{
405 return(PWM->PIIR & (PWM_PIIR_PWMDIF0_Msk << u32ChannelNum) ? 1 : 0);
406}
407
414void PWM_EnableFaultBrakeInt (PWM_T *pwm, uint32_t u32BrakeSource)
415{
416 PWM->PIER |= PWM_PIER_BRKIE_Msk;
417}
418
425void PWM_DisableFaultBrakeInt (PWM_T *pwm, uint32_t u32BrakeSource)
426{
427 PWM->PIER &= ~PWM_PIER_BRKIE_Msk;
428}
429
438void PWM_ClearFaultBrakeIntFlag (PWM_T *pwm, uint32_t u32BrakeSource)
439{
440 PWM->PIIR = u32BrakeSource;
441}
442
453uint32_t PWM_GetFaultBrakeIntFlag (PWM_T *pwm, uint32_t u32BrakeSource)
454{
455 return (PWM->PIIR & u32BrakeSource ? 1 : 0);
456}
457
468void PWM_EnablePeriodInt (PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32IntPeriodType)
469{
470 PWM->PIER = (PWM->PIER & ~PWM_PIER_INT_TYPE_Msk) | (PWM_PIER_PWMPIE0_Msk << u32ChannelNum) | u32IntPeriodType;
471}
472
479void PWM_DisablePeriodInt (PWM_T *pwm, uint32_t u32ChannelNum)
480{
481 PWM->PIER &= ~(PWM_PIER_PWMPIE0_Msk << u32ChannelNum);
482}
483
490void PWM_ClearPeriodIntFlag (PWM_T *pwm, uint32_t u32ChannelNum)
491{
492 PWM->PIIR = (PWM_PIIR_PWMPIF0_Msk << u32ChannelNum);
493}
494
503uint32_t PWM_GetPeriodIntFlag (PWM_T *pwm, uint32_t u32ChannelNum)
504{
505 return(PWM->PIIR & (PWM_PIIR_PWMPIF0_Msk << u32ChannelNum) ? 1 : 0);
506}
507
508
509 /* end of group MINI51_PWM_EXPORTED_FUNCTIONS */
511 /* end of group MINI51_PWM_Driver */
513 /* end of group MINI51_Device_Driver */
515
516/*** (C) COPYRIGHT 2013 Nuvoton Technology Corp. ***/
Mini51 series peripheral access layer header file. This file contains all the peripheral register's d...
#define PWM_PCR_CH0EN_Msk
#define PWM_PIER_PWMDIE0_Msk
#define PWM_PFBCON_PWMBKO0_Pos
#define PWM_PPR_CP01_Msk
#define PWM_PIIR_PWMPIF0_Msk
#define PWM_PCR_DZEN01_Msk
#define PWM_PCR_CH0MOD_Msk
#define PWM_PIER_PWMPIE0_Msk
#define PWM_PIIR_PWMDIF0_Msk
#define PWM_PIER_BRKIE_Msk
#define PWM_CSR_CSR0_Msk
#define PWM_DZIR_DZI01_Msk
#define PWM_PFBCON_BKF_Msk
#define PWM
Pointer to PWM register structure.
#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:337
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_DisablePeriodInt(PWM_T *pwm, uint32_t u32ChannelNum)
This function disable period interrupt of selected channel.
Definition: pwm.c:479
void PWM_EnableDutyInt(PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32IntDutyType)
This function enable duty interrupt of selected channel.
Definition: pwm.c:368
uint32_t PWM_GetFaultBrakeIntFlag(PWM_T *pwm, uint32_t u32BrakeSource)
This function get fault brake interrupt of selected source.
Definition: pwm.c:453
void PWM_DisableFaultBrakeInt(PWM_T *pwm, uint32_t u32BrakeSource)
This function disable fault brake interrupt.
Definition: pwm.c:425
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
uint32_t PWM_GetADCTriggerFlag(PWM_T *pwm, uint32_t u32ChannelNum)
This function get selected channel trigger ADC flag.
Definition: pwm.c:252
void PWM_DisableDutyInt(PWM_T *pwm, uint32_t u32ChannelNum)
This function disable duty interrupt of selected channel.
Definition: pwm.c:379
void PWM_ClearDutyIntFlag(PWM_T *pwm, uint32_t u32ChannelNum)
This function clears duty interrupt flag of selected channel.
Definition: pwm.c:390
void PWM_EnablePeriodInt(PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32IntPeriodType)
This function enable period interrupt of selected channel.
Definition: pwm.c:468
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:285
uint32_t PWM_GetDutyIntFlag(PWM_T *pwm, uint32_t u32ChannelNum)
This function get duty interrupt flag of selected channel.
Definition: pwm.c:403
void PWM_DisableDeadZone(PWM_T *pwm, uint32_t u32ChannelNum)
This function disable Dead zone of selected channel.
Definition: pwm.c:353
void PWM_DisableOutput(PWM_T *pwm, uint32_t u32ChannelMask)
This function disables PWM output generation of selected channels.
Definition: pwm.c:324
void PWM_ClearFaultBrakeIntFlag(PWM_T *pwm, uint32_t u32BrakeSource)
This function clear fault brake interrupt of selected source.
Definition: pwm.c:438
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 clear period interrupt of selected channel.
Definition: pwm.c:490
void PWM_EnableOutput(PWM_T *pwm, uint32_t u32ChannelMask)
This function enables PWM output generation of selected channels.
Definition: pwm.c:312
void PWM_EnableFaultBrakeInt(PWM_T *pwm, uint32_t u32BrakeSource)
This function enable fault brake interrupt.
Definition: pwm.c:414
uint32_t PWM_GetPeriodIntFlag(PWM_T *pwm, uint32_t u32ChannelNum)
This function get period interrupt of selected channel.
Definition: pwm.c:503
void PWM_ClearFaultBrakeFlag(PWM_T *pwm, uint32_t u32BrakeSource)
This function clear fault brake flag.
Definition: pwm.c:300
void PWM_EnableADCTrigger(PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32Condition)
This function enable selected channel to trigger ADC.
Definition: pwm.c:176
uint32_t SystemCoreClock