MINI58_BSP V3.01.005
The Board Support Package for Mini58 Series MCU
pwm.c
Go to the documentation of this file.
1/**************************************************************************/
12#include "Mini58Series.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
94 if(u32DutyCycle == 0)
95 *((__IO uint32_t *)((((uint32_t) & ((pwm)->CMPDAT0)) + u32ChannelNum * 4))) = 0;
96 else
97 *((__IO uint32_t *)((((uint32_t) & ((pwm)->CMPDAT0)) + u32ChannelNum * 4))) = u32DutyCycle * (u16CNR + 1) / 100 - 1;
98
99 *((__IO uint32_t *)((((uint32_t) & ((pwm)->PERIOD0)) + (u32ChannelNum) * 4))) = u16CNR;
100
101 return(i);
102}
103
104
112void PWM_Start (PWM_T *pwm, uint32_t u32ChannelMask)
113{
114 uint32_t u32Mask = 0, i;
115 for(i = 0; i < PWM_CHANNEL_NUM; i ++)
116 {
117 if(u32ChannelMask & (1 << i))
118 {
119 u32Mask |= (PWM_CTL_CNTEN0_Msk << (i * 4));
120 }
121 }
122
123 PWM->CTL |= u32Mask;
124}
125
133void PWM_Stop (PWM_T *pwm, uint32_t u32ChannelMask)
134{
135 uint32_t i;
136 for(i = 0; i < PWM_CHANNEL_NUM; i ++)
137 {
138 if(u32ChannelMask & (1 << i))
139 {
140 *((__IO uint32_t *)((((uint32_t) & ((pwm)->PERIOD0)) + (i) * 4))) = 0;
141 }
142 }
143
144}
145
153void PWM_ForceStop (PWM_T *pwm, uint32_t u32ChannelMask)
154{
155 uint32_t u32Mask = 0, i;
156 for(i = 0; i < PWM_CHANNEL_NUM; i ++)
157 {
158 if(u32ChannelMask & (1 << i))
159 {
160 u32Mask |= (PWM_CTL_CNTEN0_Msk << (i * 4));
161 }
162 }
163
164 PWM->CTL &= ~u32Mask;
165}
166
178void PWM_EnableADCTrigger (PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32Condition)
179{
180 if(u32ChannelNum < 4)
181 {
182 PWM->ADCTCTL0 = (PWM->ADCTCTL0 & ~((PWM_TRIGGER_ADC_CNTR_IS_0 |
185 PWM_TRIGGER_ADC_CNTR_IS_CMR_U ) << (8 * u32ChannelNum))) | (u32Condition << (8 * u32ChannelNum));
186 }
187 else
188 {
189 PWM->ADCTCTL1 = (PWM->ADCTCTL1 & ~((PWM_TRIGGER_ADC_CNTR_IS_0 |
192 PWM_TRIGGER_ADC_CNTR_IS_CMR_U ) << (8 * (u32ChannelNum - 4)))) | (u32Condition << (8 * (u32ChannelNum - 4)));
193 }
194}
195
202void PWM_DisableADCTrigger (PWM_T *pwm, uint32_t u32ChannelNum)
203{
204 if(u32ChannelNum < 4)
205 {
206 PWM->ADCTCTL0 = (PWM->ADCTCTL0 & ~((PWM_TRIGGER_ADC_CNTR_IS_0 |
209 PWM_TRIGGER_ADC_CNTR_IS_CMR_U ) << (8 * u32ChannelNum)));
210 }
211 else
212 {
213 PWM->ADCTCTL1 = (PWM->ADCTCTL1 & ~((PWM_TRIGGER_ADC_CNTR_IS_0 |
216 PWM_TRIGGER_ADC_CNTR_IS_CMR_U ) << (8 * (u32ChannelNum - 4))));
217 }
218}
219
227void PWM_ClearADCTriggerFlag (PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32Condition)
228{
229 if(u32ChannelNum < 4)
230 {
231 PWM->ADCTSTS0 |= (u32Condition << (8 * u32ChannelNum));
232 }
233 else
234 {
235 PWM->ADCTSTS1 |= (u32Condition << (8 * (u32ChannelNum - 4)));
236 }
237}
238
246uint32_t PWM_GetADCTriggerFlag (PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32Condition)
247{
248 if(u32ChannelNum < 4)
249 {
250 return(PWM->ADCTSTS0 & (u32Condition << (8 * u32ChannelNum)) ? 1 : 0);
251 }
252 else
253 {
254 return(PWM->ADCTSTS1 & (u32Condition << (8 * (u32ChannelNum - 4))) ? 1 : 0);
255 }
256}
257
273 uint32_t u32ChannelMask,
274 uint32_t u32LevelMask,
275 uint32_t u32BrakeSource)
276{
277 PWM->BRKCTL = (u32LevelMask << PWM_BRKCTL_BKOD0_Pos) | u32BrakeSource;
278}
279
287void PWM_ClearFaultBrakeFlag (PWM_T *pwm, uint32_t u32BrakeSource)
288{
289 PWM->BRKCTL = PWM_BRKCTL_BRKSTS_Msk;
290}
291
299void PWM_EnableOutput (PWM_T *pwm, uint32_t u32ChannelMask)
300{
301 PWM->POEN |= u32ChannelMask;
302}
303
311void PWM_DisableOutput (PWM_T *pwm, uint32_t u32ChannelMask)
312{
313 PWM->POEN &= ~u32ChannelMask;
314}
315
324void PWM_EnableDeadZone (PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32Duration)
325{
326 // every two channels shares the same setting
327 u32ChannelNum >>= 1;
328 // set duration
329 PWM->DTCTL = (PWM->DTCTL & ~(PWM_DTCTL_DTI01_Msk << (8 * u32ChannelNum))) | (u32Duration << (8 * u32ChannelNum));
330 // enable dead zone
331 PWM->CTL |= (PWM_CTL_DTCNT01_Msk << u32ChannelNum);
332}
333
340void PWM_DisableDeadZone (PWM_T *pwm, uint32_t u32ChannelNum)
341{
342 // every two channels shares the same setting
343 u32ChannelNum >>= 1;
344 // enable dead zone
345 PWM->CTL &= ~(PWM_CTL_DTCNT01_Msk << u32ChannelNum);
346}
347
355void PWM_EnableDutyInt (PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32IntDutyType)
356{
357 (pwm)->INTEN |= ((1 << PWM_INTEN_CMPDIEN0_Pos) << u32ChannelNum);
358}
359
366void PWM_DisableDutyInt (PWM_T *pwm, uint32_t u32ChannelNum)
367{
368 (pwm)->INTEN &= ~((1 << PWM_INTEN_CMPDIEN0_Pos) << u32ChannelNum);
369}
370
377void PWM_ClearDutyIntFlag (PWM_T *pwm, uint32_t u32ChannelNum)
378{
379 PWM->INTSTS = (PWM_INTSTS_CMPDIF0_Msk << u32ChannelNum);
380}
381
390uint32_t PWM_GetDutyIntFlag (PWM_T *pwm, uint32_t u32ChannelNum)
391{
392 return(PWM->INTSTS & (PWM_INTSTS_CMPDIF0_Msk << u32ChannelNum) ? 1 : 0);
393}
394
401void PWM_EnablePeriodInt (PWM_T *pwm, uint32_t u32ChannelNum)
402{
403 (pwm)->INTEN |= ((1 << PWM_INTEN_ZIEN0_Pos) << u32ChannelNum);
404}
405
412void PWM_DisablePeriodInt (PWM_T *pwm, uint32_t u32ChannelNum)
413{
414 (pwm)->INTEN &= ~((1 << PWM_INTEN_ZIEN0_Pos) << u32ChannelNum);
415}
416
423void PWM_ClearPeriodIntFlag (PWM_T *pwm, uint32_t u32ChannelNum)
424{
425 PWM->INTSTS = (PWM_INTSTS_ZIF0_Msk << u32ChannelNum);
426}
427
436uint32_t PWM_GetPeriodIntFlag (PWM_T *pwm, uint32_t u32ChannelNum)
437{
438 return(PWM->INTSTS & (PWM_INTSTS_ZIF0_Msk << u32ChannelNum) ? 1 : 0);
439}
440
447void PWM_EnableRiseInt (PWM_T *pwm, uint32_t u32ChannelNum)
448{
449 (pwm)->INTEN |= ((1 << PWM_INTEN_CMPUIEN0_Pos) << u32ChannelNum);
450}
451
458void PWM_DisableRiseInt (PWM_T *pwm, uint32_t u32ChannelNum)
459{
460 (pwm)->INTEN &= ~((1 << PWM_INTEN_CMPUIEN0_Pos) << u32ChannelNum);
461}
462
469void PWM_ClearRiseIntFlag (PWM_T *pwm, uint32_t u32ChannelNum)
470{
471 PWM->INTSTS = (PWM_INTSTS_CMPUIF0_Msk << u32ChannelNum);
472}
473
482uint32_t PWM_GetRiseIntFlag (PWM_T *pwm, uint32_t u32ChannelNum)
483{
484 return(PWM->INTSTS & (PWM_INTSTS_CMPUIF0_Msk << u32ChannelNum) ? 1 : 0);
485}
486
493void PWM_EnableFaultBrakeInt (PWM_T *pwm, uint32_t u32BrakeSource)
494{
495 PWM->INTEN |= PWM_INTEN_BRKIEN_Msk;
496}
497
504void PWM_DisableFaultBrakeInt (PWM_T *pwm, uint32_t u32BrakeSource)
505{
506 PWM->INTEN &= ~PWM_INTEN_BRKIEN_Msk;
507}
508
517void PWM_ClearFaultBrakeIntFlag (PWM_T *pwm, uint32_t u32BrakeSource)
518{
519 PWM->INTSTS = u32BrakeSource;
520}
521
532uint32_t PWM_GetFaultBrakeIntFlag (PWM_T *pwm, uint32_t u32BrakeSource)
533{
534 return (PWM->INTSTS & u32BrakeSource ? 1 : 0);
535}
536
547void PWM_EnableCenterInt (PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32IntPeriodType)
548{
549 PWM->INTEN = (PWM->INTEN & ~PWM_INTEN_PINTTYPE_Msk & ~(PWM_INTEN_PIEN0_Msk << u32ChannelNum)) | (PWM_INTEN_PIEN0_Msk << u32ChannelNum) | u32IntPeriodType;
550}
551
558void PWM_DisableCenterInt (PWM_T *pwm, uint32_t u32ChannelNum)
559{
560 PWM->INTEN &= ~(PWM_INTEN_PIEN0_Msk << u32ChannelNum);
561}
562
569void PWM_ClearCenterIntFlag (PWM_T *pwm, uint32_t u32ChannelNum)
570{
571 PWM->INTSTS = (PWM_INTSTS_PIF0_Msk << u32ChannelNum);
572}
573
582uint32_t PWM_GetCenterIntFlag (PWM_T *pwm, uint32_t u32ChannelNum)
583{
584 return(PWM->INTSTS & (PWM_INTSTS_PIF0_Msk << u32ChannelNum) ? 1 : 0);
585}
586
587 /* end of group Mini58_PWM_EXPORTED_FUNCTIONS */
589 /* end of group Mini58_PWM_Driver */
591 /* end of group Mini58_Device_Driver */
593
594/*** (C) COPYRIGHT 2022 Nuvoton Technology Corp. ***/
Mini58 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_DTCTL_DTI01_Msk
#define PWM_CLKDIV_CLKDIV0_Msk
#define PWM_INTEN_CMPDIEN0_Pos
#define PWM_INTEN_PIEN0_Msk
#define PWM_INTEN_CMPUIEN0_Pos
#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_INTSTS_PIF0_Msk
#define PWM_INTEN_BRKIEN_Msk
#define PWM_CLKPSC_CLKPSC01_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:153
void PWM_Stop(PWM_T *pwm, uint32_t u32ChannelMask)
This function stop PWM module.
Definition: pwm.c:133
void PWM_EnableDeadZone(PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32Duration)
This function enable Dead zone of selected channel.
Definition: pwm.c:324
void PWM_ClearADCTriggerFlag(PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32Condition)
This function clear selected channel trigger ADC flag.
Definition: pwm.c:227
void PWM_DisableADCTrigger(PWM_T *pwm, uint32_t u32ChannelNum)
This function disable selected channel to trigger ADC.
Definition: pwm.c:202
void PWM_DisableRiseInt(PWM_T *pwm, uint32_t u32ChannelNum)
This function disable Rise interrupt of selected channel.
Definition: pwm.c:458
void PWM_ClearRiseIntFlag(PWM_T *pwm, uint32_t u32ChannelNum)
This function clears Rise interrupt flag of selected channel.
Definition: pwm.c:469
void PWM_DisablePeriodInt(PWM_T *pwm, uint32_t u32ChannelNum)
This function disable Period interrupt of selected channel.
Definition: pwm.c:412
void PWM_EnableDutyInt(PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32IntDutyType)
This function enable duty interrupt of selected channel.
Definition: pwm.c:355
uint32_t PWM_GetFaultBrakeIntFlag(PWM_T *pwm, uint32_t u32BrakeSource)
This function get fault brake interrupt of selected source.
Definition: pwm.c:532
void PWM_DisableFaultBrakeInt(PWM_T *pwm, uint32_t u32BrakeSource)
This function disable fault brake interrupt.
Definition: pwm.c:504
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:401
void PWM_DisableCenterInt(PWM_T *pwm, uint32_t u32ChannelNum)
This function disable Central interrupt of selected channel.
Definition: pwm.c:558
void PWM_EnableRiseInt(PWM_T *pwm, uint32_t u32ChannelNum)
This function enable Rise interrupt of selected channel.
Definition: pwm.c:447
void PWM_DisableDutyInt(PWM_T *pwm, uint32_t u32ChannelNum)
This function disable duty interrupt of selected channel.
Definition: pwm.c:366
uint32_t PWM_GetADCTriggerFlag(PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32Condition)
This function get selected channel trigger ADC flag.
Definition: pwm.c:246
void PWM_ClearDutyIntFlag(PWM_T *pwm, uint32_t u32ChannelNum)
This function clears duty interrupt flag of selected channel.
Definition: pwm.c:377
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:272
uint32_t PWM_GetDutyIntFlag(PWM_T *pwm, uint32_t u32ChannelNum)
This function get duty interrupt flag of selected channel.
Definition: pwm.c:390
void PWM_DisableDeadZone(PWM_T *pwm, uint32_t u32ChannelNum)
This function disable Dead zone of selected channel.
Definition: pwm.c:340
void PWM_DisableOutput(PWM_T *pwm, uint32_t u32ChannelMask)
This function disables PWM output generation of selected channels.
Definition: pwm.c:311
void PWM_EnableCenterInt(PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32IntPeriodType)
This function enable Central interrupt of selected channel.
Definition: pwm.c:547
void PWM_ClearCenterIntFlag(PWM_T *pwm, uint32_t u32ChannelNum)
This function clear Central interrupt of selected channel.
Definition: pwm.c:569
uint32_t PWM_GetRiseIntFlag(PWM_T *pwm, uint32_t u32ChannelNum)
This function get Rise interrupt flag of selected channel.
Definition: pwm.c:482
void PWM_ClearFaultBrakeIntFlag(PWM_T *pwm, uint32_t u32BrakeSource)
This function clear fault brake interrupt of selected source.
Definition: pwm.c:517
void PWM_Start(PWM_T *pwm, uint32_t u32ChannelMask)
This function start PWM module.
Definition: pwm.c:112
void PWM_ClearPeriodIntFlag(PWM_T *pwm, uint32_t u32ChannelNum)
This function clears Period interrupt flag of selected channel.
Definition: pwm.c:423
void PWM_EnableOutput(PWM_T *pwm, uint32_t u32ChannelMask)
This function enables PWM output generation of selected channels.
Definition: pwm.c:299
void PWM_EnableFaultBrakeInt(PWM_T *pwm, uint32_t u32BrakeSource)
This function enable fault brake interrupt.
Definition: pwm.c:493
uint32_t PWM_GetPeriodIntFlag(PWM_T *pwm, uint32_t u32ChannelNum)
This function get Period interrupt flag of selected channel.
Definition: pwm.c:436
void PWM_ClearFaultBrakeFlag(PWM_T *pwm, uint32_t u32BrakeSource)
This function clear fault brake flag.
Definition: pwm.c:287
uint32_t PWM_GetCenterIntFlag(PWM_T *pwm, uint32_t u32ChannelNum)
This function get Central interrupt of selected channel.
Definition: pwm.c:582
void PWM_EnableADCTrigger(PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32Condition)
This function enable selected channel to trigger ADC.
Definition: pwm.c:178
uint32_t SystemCoreClock