1 /**
2   ******************************************************************************
3   * @file    lib_pwm.c
4   * @author  Application Team
5   * @version V4.4.0
6   * @date    2018-09-27
7   * @brief   PWM library.
8   ******************************************************************************
9   * @attention
10   *
11   ******************************************************************************
12   */
13 #include "lib_pwm.h"
14 
15 /**
16   * @brief  PWM timebase initialization.
17   * @param  PWMx: PWM0~PWM3
18             InitStruct:PWM BASE configuration.
19                 ClockDivision:
20                     PWM_CLKDIV_2
21                     PWM_CLKDIV_4
22                     PWM_CLKDIV_8
23                     PWM_CLKDIV_16
24                 Mode:
25                     PWM_MODE_STOP
26                     PWM_MODE_UPCOUNT
27                     PWM_MODE_CONTINUOUS
28                     PWM_MODE_UPDOWN
29                 ClockSource:
30                     PWM_CLKSRC_APB
31                     PWM_CLKSRC_APBD128
32   * @retval None
33   */
PWM_BaseInit(PWM_TypeDef * PWMx,PWM_BaseInitType * InitStruct)34 void PWM_BaseInit(PWM_TypeDef *PWMx, PWM_BaseInitType *InitStruct)
35 {
36   uint32_t tmp;
37 
38   /* Check parameters */
39   assert_parameters(IS_PWM_ALL_INSTANCE(PWMx));
40   assert_parameters(IS_PWM_CLKDIV(InitStruct->ClockDivision));
41   assert_parameters(IS_PWM_CNTMODE(InitStruct->Mode));
42   assert_parameters(IS_PWM_CLKSRC(InitStruct->ClockSource));
43 
44   tmp = PWMx->CTL;
45   tmp &= ~(PWM_CTL_ID\
46           |PWM_CTL_MC\
47           |PWM_CTL_TESL);
48   tmp |= (InitStruct->ClockDivision\
49          |InitStruct->Mode\
50          |InitStruct->ClockSource);
51   PWMx->CTL = tmp;
52 }
53 
54 /**
55   * @brief  Fills each PWM_BaseInitType member with its default value.
56   * @param  InitStruct: pointer to an PWM_BaseInitType structure which will be initialized.
57   * @retval None
58   */
PWM_BaseStructInit(PWM_BaseInitType * InitStruct)59 void PWM_BaseStructInit(PWM_BaseInitType *InitStruct)
60 {
61   /*------------ Reset PWM base init structure parameters values ------------*/
62   /* Initialize the ClockDivision member */
63   InitStruct->ClockDivision = PWM_CLKDIV_2;
64   /* Initialize the ClockSource member */
65   InitStruct->ClockSource = PWM_CLKSRC_APBD128;
66   /* Initialize the Mode member */
67   InitStruct->Mode = PWM_MODE_STOP;
68 }
69 
70 /**
71   * @brief  Fills each PWM_OCInitType member with its default value.
72   * @param  OCInitType: pointer to an PWM_OCInitType structure which will be initialized.
73   * @retval None
74   */
PWM_OCStructInit(PWM_OCInitType * OCInitType)75 void PWM_OCStructInit(PWM_OCInitType *OCInitType)
76 {
77   /*------- Reset PWM output channel init structure parameters values --------*/
78   /* Initialize the OutMode member */
79   OCInitType->OutMode = PWM_OUTMOD_CONST;
80   /* Initialize the Period member */
81   OCInitType->Period = 0;
82 }
83 
84 /**
85   * @brief  PWM output compare channel 0.
86   * @param  PWMx: PWM0~PWM3
87             OCInitType:PWM output compare configuration.
88                 OutMode:
89                     PWM_OUTMOD_CONST
90                     PWM_OUTMOD_SET
91                     PWM_OUTMOD_TOGGLE_RESET
92                     PWM_OUTMOD_SET_RESET
93                     PWM_OUTMOD_TOGGLE
94                     PWM_OUTMOD_RESET
95                     PWM_OUTMOD_TOGGLE_SET
96                     PWM_OUTMOD_RESET_SET
97                 Period: 0 ~ 0xFFFF
98   * @retval None
99   */
PWM_OC0Init(PWM_TypeDef * PWMx,PWM_OCInitType * OCInitType)100 void PWM_OC0Init(PWM_TypeDef *PWMx, PWM_OCInitType *OCInitType)
101 {
102   uint32_t tmp;
103 
104   /* Check parameters */
105   assert_parameters(IS_PWM_ALL_INSTANCE(PWMx));
106   assert_parameters(IS_PWM_OUTMODE(OCInitType->OutMode));
107   assert_parameters(IS_PWM_CCR(OCInitType->Period));
108 
109   tmp = PWMx->CCTL0;
110   tmp &= ~(PWM_CCTL_OUTMOD | PWM_CCTL_CCIGG);
111   tmp |= OCInitType->OutMode;
112   PWMx->CCTL0 = tmp;
113   PWMx->CCR0 = OCInitType->Period;
114 }
115 
116 /**
117   * @brief  PWM output compare channel 1.
118   * @param  PWMx: PWM0~PWM3
119             OCInitType:PWM output compare configuration.
120                 OutMode:
121                     PWM_OUTMOD_CONST
122                     PWM_OUTMOD_SET
123                     PWM_OUTMOD_TOGGLE_RESET
124                     PWM_OUTMOD_SET_RESET
125                     PWM_OUTMOD_TOGGLE
126                     PWM_OUTMOD_RESET
127                     PWM_OUTMOD_TOGGLE_SET
128                     PWM_OUTMOD_RESET_SET
129                 Period: 0 ~ 0xFFFF
130   * @retval None
131   */
PWM_OC1Init(PWM_TypeDef * PWMx,PWM_OCInitType * OCInitType)132 void PWM_OC1Init(PWM_TypeDef *PWMx, PWM_OCInitType *OCInitType)
133 {
134   uint32_t tmp;
135 
136   /* Check parameters */
137   assert_parameters(IS_PWM_ALL_INSTANCE(PWMx));
138   assert_parameters(IS_PWM_OUTMODE(OCInitType->OutMode));
139   assert_parameters(IS_PWM_CCR(OCInitType->Period));
140 
141   tmp = PWMx->CCTL1;
142   tmp &= ~(PWM_CCTL_OUTMOD | PWM_CCTL_CCIGG);
143   tmp |= OCInitType->OutMode;
144   PWMx->CCTL1 = tmp;
145   PWMx->CCR1 = OCInitType->Period;
146 }
147 
148 /**
149   * @brief  PWM output compare channel 2.
150   * @param  PWMx: PWM0~PWM3
151             OCInitType:PWM output compare configuration.
152                 OutMode:
153                     PWM_OUTMOD_CONST
154                     PWM_OUTMOD_SET
155                     PWM_OUTMOD_TOGGLE_RESET
156                     PWM_OUTMOD_SET_RESET
157                     PWM_OUTMOD_TOGGLE
158                     PWM_OUTMOD_RESET
159                     PWM_OUTMOD_TOGGLE_SET
160                     PWM_OUTMOD_RESET_SET
161                 Period: 0 ~ 0xFFFF
162   * @retval None
163   */
PWM_OC2Init(PWM_TypeDef * PWMx,PWM_OCInitType * OCInitType)164 void PWM_OC2Init(PWM_TypeDef *PWMx, PWM_OCInitType *OCInitType)
165 {
166   uint32_t tmp;
167 
168   /* Check parameters */
169   assert_parameters(IS_PWM_ALL_INSTANCE(PWMx));
170   assert_parameters(IS_PWM_OUTMODE(OCInitType->OutMode));
171   assert_parameters(IS_PWM_CCR(OCInitType->Period));
172 
173   tmp = PWMx->CCTL2;
174   tmp &= ~(PWM_CCTL_OUTMOD | PWM_CCTL_CCIGG);
175   tmp |= OCInitType->OutMode;
176   PWMx->CCTL2 = tmp;
177   PWMx->CCR2 = OCInitType->Period;
178 }
179 
180 /**
181   * @brief  PWM base interrupt configure.
182   * @param  PWMx: PWM0~PWM3
183             NewState:
184                 ENABLE
185                 DISABLE
186   * @retval None
187   */
PWM_BaseINTConfig(PWM_TypeDef * PWMx,uint32_t NewState)188 void PWM_BaseINTConfig(PWM_TypeDef *PWMx, uint32_t NewState)
189 {
190   uint32_t tmp;
191 
192   /* Check parameters */
193   assert_parameters(IS_PWM_ALL_INSTANCE(PWMx));
194   assert_parameters(IS_FUNCTIONAL_STATE(NewState));
195 
196   tmp = PWMx->CTL;
197   tmp &= ~(PWM_CTL_IE | PWM_CTL_IFG);
198   if (NewState == ENABLE)
199   {
200     tmp |= PWM_CTL_IE;
201   }
202   PWMx->CTL = tmp;
203 }
204 
205 /**
206   * @brief  Get PWM base interrupt status.
207   * @param  PWMx: PWM0~PWM3
208   * @retval interrupt status.
209   */
PWM_GetBaseINTStatus(PWM_TypeDef * PWMx)210 uint8_t PWM_GetBaseINTStatus(PWM_TypeDef *PWMx)
211 {
212   /* Check parameters */
213   assert_parameters(IS_PWM_ALL_INSTANCE(PWMx));
214 
215   if (PWMx->CTL&PWM_CTL_IFG)
216     return 1;
217   else
218     return 0;
219 }
220 
221 /**
222   * @brief  Clear PWM base interrupt status.
223   * @param  PWMx: PWM0~PWM3
224   * @retval None.
225   */
PWM_ClearBaseINTStatus(PWM_TypeDef * PWMx)226 void PWM_ClearBaseINTStatus(PWM_TypeDef *PWMx)
227 {
228   /* Check parameters */
229   assert_parameters(IS_PWM_ALL_INSTANCE(PWMx));
230 
231   PWMx->CTL |= PWM_CTL_IFG;
232 }
233 
234 /**
235   * @brief  channel interrupt configure.
236   * @param  PWMx: PWM0~PWM3
237             Channel:
238                 PWM_CHANNEL_0
239                 PWM_CHANNEL_1
240                 PWM_CHANNEL_2
241             NewState:
242                 ENABLE
243                 DISABLE
244   * @retval  None
245   */
PWM_ChannelINTConfig(PWM_TypeDef * PWMx,uint32_t Channel,uint32_t NewState)246 void PWM_ChannelINTConfig(PWM_TypeDef *PWMx, uint32_t Channel, uint32_t NewState)
247 {
248   __IO uint32_t *addr;
249   uint32_t tmp;
250 
251   /* Check parameters */
252   assert_parameters(IS_PWM_ALL_INSTANCE(PWMx));
253   assert_parameters(IS_PWM_CHANNEL(Channel));
254   assert_parameters(IS_FUNCTIONAL_STATE(NewState));
255 
256   addr = &PWMx->CCTL0 + Channel;
257   tmp = *addr;
258   tmp &= ~(PWM_CCTL_CCIE | PWM_CCTL_CCIGG);
259   if (NewState == ENABLE)
260   {
261     tmp |= PWM_CCTL_CCIE;
262   }
263   *addr = tmp;
264 }
265 
266 /**
267   * @brief  Get channel interrupt status.
268   * @param  PWMx: PWM0~PWM3
269             Channel:
270                 PWM_CHANNEL_0
271                 PWM_CHANNEL_1
272                 PWM_CHANNEL_2
273   * @retval  interrupt status
274   */
PWM_GetChannelINTStatus(PWM_TypeDef * PWMx,uint32_t Channel)275 uint8_t PWM_GetChannelINTStatus(PWM_TypeDef *PWMx, uint32_t Channel)
276 {
277   __IO uint32_t *addr;
278   uint32_t tmp;
279 
280   /* Check parameters */
281   assert_parameters(IS_PWM_ALL_INSTANCE(PWMx));
282   assert_parameters(IS_PWM_CHANNEL(Channel));
283 
284   addr = &PWMx->CCTL0 + Channel;
285   tmp = *addr;
286   if (tmp & PWM_CCTL_CCIGG)
287   {
288     return 1;
289   }
290   else
291   {
292     return 0;
293   }
294 }
295 
296 /**
297   * @brief  Clear channel interrupt status.
298   * @param  PWMx: PWM0~PWM3
299             Channel:
300                 PWM_CHANNEL_0
301                 PWM_CHANNEL_1
302                 PWM_CHANNEL_2
303   * @retval  None
304   */
PWM_ClearChannelINTStatus(PWM_TypeDef * PWMx,uint32_t Channel)305 void PWM_ClearChannelINTStatus(PWM_TypeDef *PWMx, uint32_t Channel)
306 {
307   __IO uint32_t *addr;
308   uint32_t tmp;
309 
310   /* Check parameters */
311   assert_parameters(IS_PWM_ALL_INSTANCE(PWMx));
312   assert_parameters(IS_PWM_CHANNEL(Channel));
313 
314   addr = &PWMx->CCTL0 + Channel;
315 
316   tmp = *addr;
317   tmp &= ~PWM_CCTL_CCIGG;
318   tmp |= PWM_CCTL_CCIGG;
319   *addr = tmp;
320 }
321 
322 /**
323   * @brief  PWM clear counter.
324   * @param  PWMx: PWM0~PWM3
325   * @retval None
326   */
PWM_ClearCounter(PWM_TypeDef * PWMx)327 void PWM_ClearCounter(PWM_TypeDef *PWMx)
328 {
329   /* Check parameters */
330   assert_parameters(IS_PWM_ALL_INSTANCE(PWMx));
331 
332   PWMx->CTL |= PWM_CTL_CLR;
333 }
334 
335 /**
336   * @brief  Configure PWMx channelx's CCR value.
337   * @param  PWMx: PWM0~PWM3
338             Channel:
339                 PWM_CHANNEL_0
340                 PWM_CHANNEL_1
341                 PWM_CHANNEL_2
342             Period: 0 ~ 0xFFFF
343   * @retval None
344   */
PWM_CCRConfig(PWM_TypeDef * PWMx,uint32_t Channel,uint16_t Period)345 void PWM_CCRConfig(PWM_TypeDef *PWMx, uint32_t Channel, uint16_t Period)
346 {
347   __IO uint32_t *addr;
348 
349   /* Check parameters */
350   assert_parameters(IS_PWM_ALL_INSTANCE(PWMx));
351   assert_parameters(IS_PWM_CHANNEL(Channel));
352 
353   addr = &PWMx->CCR0 + Channel;
354   *addr = Period;
355 }
356 
357 /**
358   * @brief  pwm output line selection.
359   * @param  OutSelection:
360                 PWM0_OUT0
361                 PWM0_OUT1
362                 PWM0_OUT2
363                 PWM1_OUT0
364                 PWM1_OUT1
365                 PWM1_OUT2
366                 PWM2_OUT0
367                 PWM2_OUT1
368                 PWM2_OUT2
369                 PWM3_OUT0
370                 PWM3_OUT1
371                 PWM3_OUT2
372             OLine: can use the ��|�� operator
373                 PWM_OLINE_0
374                 PWM_OLINE_1
375                 PWM_OLINE_2
376                 PWM_OLINE_3
377   * @note    PWM Single channel's output waveform can be output on multiple output lines.
378   *          Multiple-line configuration can be performed by using the ��|�� operator.
379   *            ex: PWM_OLineConfig(PWM0_OUT0, PWM_OLINE_0 | PWM_OLINE_2)
380   *                PWM0 channel0 output by PWM0&PWM2's lien.
381   * @retval  None
382   */
PWM_OLineConfig(uint32_t OutSelection,uint32_t OLine)383 void PWM_OLineConfig(uint32_t OutSelection, uint32_t OLine)
384 {
385   uint32_t tmp;
386   uint32_t position = 0;
387 
388   /* Check parameters */
389   assert_parameters(IS_PWM_OUTLINE(OLine));
390   assert_parameters(IS_PWM_OUTSEL(OutSelection));
391 
392   tmp = PWMMUX->OSEL;
393   while ((OLine >> position) != 0UL)
394   {
395     if ((OLine >> position) & 1UL)
396     {
397       tmp &= ~(PWM_O_SEL_O_SEL0 << (position * 4));
398       tmp |= (OutSelection << (position * 4));
399     }
400     position++;
401   }
402   PWMMUX->OSEL = tmp;
403 }
404 
405 /**
406   * @brief  PWM output enable.
407   * @param  PWMx: PWM0~PWM3
408             Channel:
409                 PWM_CHANNEL_0
410                 PWM_CHANNEL_1
411                 PWM_CHANNEL_2
412             NewState:
413                 ENABLE
414                 DISABLE
415   * @retval  None
416   */
PWM_OutputCmd(PWM_TypeDef * PWMx,uint32_t Channel,uint32_t NewState)417 void PWM_OutputCmd(PWM_TypeDef *PWMx, uint32_t Channel, uint32_t NewState)
418 {
419   __IO uint32_t *addr;
420   uint32_t tmp;
421 
422   /* Check parameters */
423   assert_parameters(IS_PWM_ALL_INSTANCE(PWMx));
424   assert_parameters(IS_PWM_CHANNEL(Channel));
425   assert_parameters(IS_FUNCTIONAL_STATE(NewState));
426 
427   addr = &PWMx->CCTL0 + Channel;
428   tmp = *addr;
429   tmp &= ~PWM_CCTL_CCIGG;
430   if (NewState == ENABLE)
431     tmp |= PWM_CCTL_OUTEN;
432   else
433     tmp &= ~PWM_CCTL_OUTEN;
434   *addr = tmp;
435 }
436 
437 /**
438   * @brief  Set channel output level.
439   * @param  PWMx: PWM0~PWM3
440             Channel:
441                 PWM_CHANNEL_0
442                 PWM_CHANNEL_1
443                 PWM_CHANNEL_2
444             Level:
445                 PWM_LEVEL_HIGH
446                 PWM_LEVEL_LOW
447   * @retval  None
448   */
PWM_SetOutLevel(PWM_TypeDef * PWMx,uint32_t Channel,uint32_t Level)449 void PWM_SetOutLevel(PWM_TypeDef *PWMx, uint32_t Channel, uint32_t Level)
450 {
451   __IO uint32_t *addr;
452   uint32_t tmp;
453 
454   /* Check parameters */
455   assert_parameters(IS_PWM_ALL_INSTANCE(PWMx));
456   assert_parameters(IS_PWM_CHANNEL(Channel));
457   assert_parameters(IS_PWM_OUTLVL(Level));
458 
459   addr = &PWMx->CCTL0 + Channel;
460   tmp = *addr;
461   tmp &= ~(PWM_CCTL_OUT | PWM_CCTL_CCIGG);
462   tmp |= Level;
463   *addr = tmp;
464 }
465 
466 /*********************************** END OF FILE ******************************/
467