1 /*
2  * Copyright (c) 2006-2023, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author            Notes
8  * 2021-09-23     charlown          first version
9  * 2022-10-14     hg0720            the first version which add from wch
10  * 2022-10-20     MXH               add the remaining timers
11  */
12 
13 #include "drv_pwm.h"
14 
15 #ifdef BSP_USING_PWM
16 
17 #define LOG_TAG "drv.pwm"
18 #include <drv_log.h>
19 
20 #define ITEM_NUM(items) sizeof(items) / sizeof(items[0])
21 
ch32_tim_clock_init(TIM_TypeDef * timx)22 void ch32_tim_clock_init(TIM_TypeDef* timx)
23 {
24 #ifdef BSP_USING_TIM1_PWM
25     if (timx == TIM1)
26     {
27         RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
28     }
29 #endif/* BSP_USING_TIM1_PWM */
30 
31 #ifdef BSP_USING_TIM2_PWM
32     if (timx == TIM2)
33     {
34         RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
35     }
36 #endif/* BSP_USING_TIM2_PWM */
37 
38 #ifdef BSP_USING_TIM3_PWM
39     if (timx == TIM3)
40     {
41         RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
42     }
43 #endif/* BSP_USING_TIM3_PWM */
44 
45 #ifdef BSP_USING_TIM4_PWM
46     if (timx == TIM4)
47     {
48         RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
49     }
50 #endif/* BSP_USING_TIM4_PWM */
51 
52 #ifdef BSP_USING_TIM5_PWM
53     if (timx == TIM5)
54     {
55         RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE);
56     }
57 #endif/* BSP_USING_TIM5_PWM */
58 
59     /* TIM6 and TIM7 don't support PWM Mode. */
60 
61 #ifdef BSP_USING_TIM8_PWM
62     if (timx == TIM8)
63     {
64         RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM8, ENABLE);
65     }
66 #endif/* BSP_USING_TIM8_PWM */
67 
68 #ifdef BSP_USING_TIM9_PWM
69     if (timx == TIM9)
70     {
71         RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM9, ENABLE);
72     }
73 #endif/* BSP_USING_TIM9_PWM */
74 
75 #ifdef BSP_USING_TIM10_PWM
76     if (timx == TIM10)
77     {
78         RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM10, ENABLE);
79     }
80 #endif/* BSP_USING_TIM10_PWM */
81 }
82 
ch32_tim_clock_get(TIM_TypeDef * timx)83 rt_uint32_t ch32_tim_clock_get(TIM_TypeDef* timx)
84 {
85     RCC_ClocksTypeDef RCC_Clocks;
86     RCC_GetClocksFreq(&RCC_Clocks);
87 
88     /*tim1~10 all in HCLK*/
89     return RCC_Clocks.HCLK_Frequency;
90 }
91 
92 /*
93  * NOTE:  some pwm pins of some timers are reused,
94  *          please keep caution when using pwm
95  */
96 
ch32_pwm_io_init(TIM_TypeDef * timx,rt_uint8_t channel)97 void ch32_pwm_io_init(TIM_TypeDef* timx, rt_uint8_t channel)
98 {
99     GPIO_InitTypeDef GPIO_InitStructure;
100 
101 #ifdef BSP_USING_TIM1_PWM
102     if (timx == TIM1)
103     {
104         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
105 
106 #ifdef BSP_USING_TIM1_PWM_CH1
107         if (channel == TIM_Channel_1)
108         {
109             GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
110             GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
111             GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
112             GPIO_Init(GPIOA, &GPIO_InitStructure);
113         }
114 #endif/* BSP_USING_TIM1_PWM_CH1 */
115 
116 #ifdef BSP_USING_TIM1_PWM_CH2
117         if (channel == TIM_Channel_2)
118         {
119             GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
120             GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
121             GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
122             GPIO_Init(GPIOA, &GPIO_InitStructure);
123         }
124 #endif/* BSP_USING_TIM1_PWM_CH2 */
125 
126 #ifdef BSP_USING_TIM1_PWM_CH3
127         if (channel == TIM_Channel_3)
128         {
129             GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
130             GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
131             GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
132             GPIO_Init(GPIOA, &GPIO_InitStructure);
133         }
134 #endif/* BSP_USING_TIM1_PWM_CH3 */
135 
136 #ifdef BSP_USING_TIM1_PWM_CH4
137         if (channel == TIM_Channel_4)
138         {
139             GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
140             GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
141             GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
142             GPIO_Init(GPIOA, &GPIO_InitStructure);
143         }
144 #endif/* BSP_USING_TIM1_PWM_CH4 */
145     }
146 #endif/* BSP_USING_TIM1_PWM */
147 
148 #ifdef BSP_USING_TIM2_PWM
149     if (timx == TIM2)
150     {
151         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
152 
153 #ifdef BSP_USING_TIM2_PWM_CH1
154         if (channel == TIM_Channel_1)
155         {
156             GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
157             GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
158             GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
159             GPIO_Init(GPIOA, &GPIO_InitStructure);
160         }
161 #endif/* BSP_USING_TIM2_PWM_CH1 */
162 
163 #ifdef BSP_USING_TIM2_PWM_CH2
164         if (channel == TIM_Channel_2)
165         {
166             GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
167             GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
168             GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
169             GPIO_Init(GPIOA, &GPIO_InitStructure);
170         }
171 #endif/* BSP_USING_TIM2_PWM_CH2 */
172 
173 #ifdef BSP_USING_TIM2_PWM_CH3
174         if (channel == TIM_Channel_3)
175         {
176             GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
177             GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
178             GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
179             GPIO_Init(GPIOA, &GPIO_InitStructure);
180         }
181 #endif/* BSP_USING_TIM2_PWM_CH3 */
182 
183 #ifdef BSP_USING_TIM2_PWM_CH4
184         if (channel == TIM_Channel_4)
185         {
186             GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
187             GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
188             GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
189             GPIO_Init(GPIOA, &GPIO_InitStructure);
190         }
191 #endif/* BSP_USING_TIM2_PWM_CH4 */
192     }
193 #endif/* BSP_USING_TIM2_PWM */
194 
195 #ifdef BSP_USING_TIM3_PWM
196     if (timx == TIM3)
197     {
198         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
199         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
200 
201 #ifdef BSP_USING_TIM3_PWM_CH1
202         if (channel == TIM_Channel_1)
203         {
204             GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
205             GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
206             GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
207             GPIO_Init(GPIOA, &GPIO_InitStructure);
208         }
209 #endif/* BSP_USING_TIM3_PWM_CH1 */
210 
211 #ifdef BSP_USING_TIM3_PWM_CH2
212         if (channel == TIM_Channel_2)
213         {
214             GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
215             GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
216             GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
217             GPIO_Init(GPIOA, &GPIO_InitStructure);
218         }
219 #endif/* BSP_USING_TIM3_PWM_CH2 */
220 
221 #ifdef BSP_USING_TIM3_PWM_CH3
222         if (channel == TIM_Channel_3)
223         {
224             GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
225             GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
226             GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
227             GPIO_Init(GPIOB, &GPIO_InitStructure);
228         }
229 #endif/* BSP_USING_TIM3_PWM_CH3 */
230 
231 #ifdef BSP_USING_TIM3_PWM_CH4
232         if (channel == TIM_Channel_4)
233         {
234             GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
235             GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
236             GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
237             GPIO_Init(GPIOB, &GPIO_InitStructure);
238         }
239 #endif/* BSP_USING_TIM3_PWM_CH4 */
240     }
241 #endif/* BSP_USING_TIM3_PWM */
242 
243 #ifdef BSP_USING_TIM4_PWM
244     if (timx == TIM4)
245     {
246         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
247 
248 #ifdef BSP_USING_TIM4_PWM_CH1
249         if (channel == TIM_Channel_1)
250         {
251             GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
252             GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
253             GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
254             GPIO_Init(GPIOB, &GPIO_InitStructure);
255         }
256 #endif/* BSP_USING_TIM4_PWM_CH1 */
257 
258 #ifdef BSP_USING_TIM4_PWM_CH2
259         if (channel == TIM_Channel_2)
260         {
261             GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
262             GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
263             GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
264             GPIO_Init(GPIOB, &GPIO_InitStructure);
265         }
266 #endif/* BSP_USING_TIM4_PWM_CH2 */
267 
268 #ifdef BSP_USING_TIM4_PWM_CH3
269         if (channel == TIM_Channel_3)
270         {
271             GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
272             GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
273             GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
274             GPIO_Init(GPIOB, &GPIO_InitStructure);
275         }
276 #endif/* BSP_USING_TIM4_PWM_CH3 */
277 
278 #ifdef BSP_USING_TIM4_PWM_CH4
279         if (channel == TIM_Channel_4)
280         {
281             GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
282             GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
283             GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
284             GPIO_Init(GPIOB, &GPIO_InitStructure);
285         }
286 #endif/* BSP_USING_TIM4_PWM_CH4 */
287     }
288 #endif/* BSP_USING_TIM4_PWM */
289 
290 #ifdef BSP_USING_TIM5_PWM
291     if (timx == TIM5)
292     {
293         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
294 
295 #ifdef BSP_USING_TIM5_PWM_CH1
296         if (channel == TIM_Channel_1)
297         {
298             GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
299             GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
300             GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
301             GPIO_Init(GPIOA, &GPIO_InitStructure);
302         }
303 #endif/* BSP_USING_TIM5_PWM_CH1 */
304 
305 #ifdef BSP_USING_TIM5_PWM_CH2
306         if (channel == TIM_Channel_2)
307         {
308             GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
309             GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
310             GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
311             GPIO_Init(GPIOA, &GPIO_InitStructure);
312         }
313 #endif/* BSP_USING_TIM5_PWM_CH2 */
314 
315 #ifdef BSP_USING_TIM5_PWM_CH3
316         if (channel == TIM_Channel_3)
317         {
318             GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
319             GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
320             GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
321             GPIO_Init(GPIOA, &GPIO_InitStructure);
322         }
323 #endif/* BSP_USING_TIM5_PWM_CH3 */
324 
325 #ifdef BSP_USING_TIM5_PWM_CH4
326         if (channel == TIM_Channel_4)
327         {
328             GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
329             GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
330             GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
331             GPIO_Init(GPIOA, &GPIO_InitStructure);
332         }
333 #endif/* BSP_USING_TIM5_PWM_CH4 */
334     }
335 #endif/* BSP_USING_TIM5_PWM */
336 
337     /* TIM6 and TIM7 don't support PWM Mode. */
338 
339 #ifdef BSP_USING_TIM8_PWM
340     if (timx == TIM8)
341     {
342         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
343 
344 /* I don't test it, because there is a 10M-PHY ETH port on my board,
345  * which uses the following four pins.
346  * You can try it on a board without a 10M-PHY ETH port. */
347 #ifdef BSP_USING_TIM8_PWM_CH1
348         if (channel == TIM_Channel_1)
349         {
350             GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
351             GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
352             GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
353             GPIO_Init(GPIOC, &GPIO_InitStructure);
354         }
355 #endif/* BSP_USING_TIM8_PWM_CH1 */
356 
357 #ifdef BSP_USING_TIM8_PWM_CH2
358         if (channel == TIM_Channel_2)
359         {
360             GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
361             GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
362             GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
363             GPIO_Init(GPIOC, &GPIO_InitStructure);
364         }
365 #endif/* BSP_USING_TIM8_PWM_CH2 */
366 
367 #ifdef BSP_USING_TIM8_PWM_CH3
368         if (channel == TIM_Channel_3)
369         {
370             GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
371             GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
372             GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
373             GPIO_Init(GPIOC, &GPIO_InitStructure);
374         }
375 #endif/* BSP_USING_TIM8_PWM_CH3 */
376 
377 #ifdef BSP_USING_TIM8_PWM_CH4
378         if (channel == TIM_Channel_4)
379         {
380             GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
381             GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
382             GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
383             GPIO_Init(GPIOC, &GPIO_InitStructure);
384         }
385 #endif/* BSP_USING_TIM8_PWM_CH4 */
386     }
387 #endif/* BSP_USING_TIM8_PWM */
388 
389 #ifdef BSP_USING_TIM9_PWM
390     if (timx == TIM9)
391     {
392         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
393         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
394 
395 #ifdef BSP_USING_TIM9_PWM_CH1
396         if (channel == TIM_Channel_1)
397         {
398             GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
399             GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
400             GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
401             GPIO_Init(GPIOA, &GPIO_InitStructure);
402         }
403 #endif/* BSP_USING_TIM9_PWM_CH1 */
404 
405 #ifdef BSP_USING_TIM9_PWM_CH2
406         if (channel == TIM_Channel_2)
407         {
408             GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
409             GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
410             GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
411             GPIO_Init(GPIOA, &GPIO_InitStructure);
412         }
413 #endif/* BSP_USING_TIM9_PWM_CH2 */
414 
415 #ifdef BSP_USING_TIM9_PWM_CH3
416         if (channel == TIM_Channel_3)
417         {
418             GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
419             GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
420             GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
421             GPIO_Init(GPIOA, &GPIO_InitStructure);
422         }
423 #endif/* BSP_USING_TIM9_PWM_CH3 */
424 
425 #ifdef BSP_USING_TIM9_PWM_CH4
426         if (channel == TIM_Channel_4)
427         {
428             GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
429             GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
430             GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
431             GPIO_Init(GPIOC, &GPIO_InitStructure);
432         }
433 #endif/* BSP_USING_TIM9_PWM_CH4 */
434     }
435 #endif/* BSP_USING_TIM9_PWM */
436 
437 #ifdef BSP_USING_TIM10_PWM
438     if (timx == TIM10)
439     {
440         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
441         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
442 
443 #ifdef BSP_USING_TIM10_PWM_CH1
444         if (channel == TIM_Channel_1)
445         {
446             GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
447             GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
448             GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
449             GPIO_Init(GPIOB, &GPIO_InitStructure);
450         }
451 #endif/* BSP_USING_TIM10_PWM_CH1 */
452 
453 #ifdef BSP_USING_TIM10_PWM_CH2
454         if (channel == TIM_Channel_2)
455         {
456             GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
457             GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
458             GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
459             GPIO_Init(GPIOB, &GPIO_InitStructure);
460         }
461 #endif/* BSP_USING_TIM10_PWM_CH2 */
462 
463 #ifdef BSP_USING_TIM10_PWM_CH3
464         if (channel == TIM_Channel_3)
465         {
466             GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
467             GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
468             GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
469             GPIO_Init(GPIOC, &GPIO_InitStructure);
470         }
471 #endif/* BSP_USING_TIM10_PWM_CH3 */
472 
473 #ifdef BSP_USING_TIM10_PWM_CH4
474         if (channel == TIM_Channel_4)
475         {
476             GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
477             GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
478             GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
479             GPIO_Init(GPIOC, &GPIO_InitStructure);
480         }
481 #endif/* BSP_USING_TIM10_PWM_CH4 */
482     }
483 #endif/* BSP_USING_TIM10_PWM */
484 }
485 
486 /*
487  * channel = FLAG_NOT_INIT: the channel is not use.
488  */
489 struct rtdevice_pwm_device pwm_device_list[] =
490 {
491 #ifdef BSP_USING_TIM1_PWM
492     {
493         .periph = TIM1,
494         .name = "pwm1",
495 #ifdef BSP_USING_TIM1_PWM_CH1
496         .channel[0] = TIM_Channel_1,
497 #else
498         .channel[0] = FLAG_NOT_INIT,
499 #endif/* BSP_USING_TIM1_PWM_CH1 */
500 
501 #ifdef BSP_USING_TIM1_PWM_CH2
502         .channel[1] = TIM_Channel_2,
503 #else
504         .channel[1] = FLAG_NOT_INIT,
505 #endif/* BSP_USING_TIM1_PWM_CH2 */
506 
507 #ifdef BSP_USING_TIM1_PWM_CH3
508         .channel[2] = TIM_Channel_3,
509 #else
510         .channel[2] = FLAG_NOT_INIT,
511 #endif/* BSP_USING_TIM1_PWM_CH3 */
512 
513 #ifdef BSP_USING_TIM1_PWM_CH4
514         .channel[3] = TIM_Channel_4,
515 #else
516         .channel[3] = FLAG_NOT_INIT,
517 #endif/* BSP_USING_TIM1_PWM_CH4 */
518     },
519 #endif /* BSP_USING_TIM1_PWM */
520 
521 #ifdef BSP_USING_TIM2_PWM
522     {
523         .periph = TIM2,
524         .name = "pwm2",
525 #ifdef BSP_USING_TIM2_PWM_CH1
526         .channel[0] = TIM_Channel_1,
527 #else
528         .channel[0] = FLAG_NOT_INIT,
529 #endif/* BSP_USING_TIM2_PWM_CH1 */
530 
531 #ifdef BSP_USING_TIM2_PWM_CH2
532         .channel[1] = TIM_Channel_2,
533 #else
534         .channel[1] = FLAG_NOT_INIT,
535 #endif/* BSP_USING_TIM2_PWM_CH2 */
536 
537 #ifdef BSP_USING_TIM2_PWM_CH3
538         .channel[2] = TIM_Channel_3,
539 #else
540         .channel[2] = FLAG_NOT_INIT,
541 #endif/* BSP_USING_TIM2_PWM_CH3 */
542 
543 #ifdef BSP_USING_TIM2_PWM_CH4
544         .channel[3] = TIM_Channel_4,
545 #else
546         .channel[3] = FLAG_NOT_INIT,
547 #endif/* BSP_USING_TIM2_PWM_CH4 */
548     },
549 #endif /* BSP_USING_TIM2_PWM */
550 
551 #ifdef BSP_USING_TIM3_PWM
552     {
553         .periph = TIM3,
554         .name = "pwm3",
555 #ifdef BSP_USING_TIM3_PWM_CH1
556         .channel[0] = TIM_Channel_1,
557 #else
558         .channel[0] = FLAG_NOT_INIT,
559 #endif/* BSP_USING_TIM3_PWM_CH1 */
560 
561 #ifdef BSP_USING_TIM3_PWM_CH2
562         .channel[1] = TIM_Channel_2,
563 #else
564         .channel[1] = FLAG_NOT_INIT,
565 #endif/* BSP_USING_TIM3_PWM_CH2 */
566 
567 #ifdef BSP_USING_TIM3_PWM_CH3
568         .channel[2] = TIM_Channel_3,
569 #else
570         .channel[2] = FLAG_NOT_INIT,
571 #endif/* BSP_USING_TIM3_PWM_CH3 */
572 
573 #ifdef BSP_USING_TIM3_PWM_CH4
574         .channel[3] = TIM_Channel_4,
575 #else
576         .channel[3] = FLAG_NOT_INIT,
577 #endif/* BSP_USING_TIM3_PWM_CH4 */
578     },
579 #endif /* BSP_USING_TIM3_PWM */
580 
581 #ifdef BSP_USING_TIM4_PWM
582     {
583         .periph = TIM4,
584         .name = "pwm4",
585 #ifdef BSP_USING_TIM4_PWM_CH1
586         .channel[0] = TIM_Channel_1,
587 #else
588         .channel[0] = FLAG_NOT_INIT,
589 #endif/* BSP_USING_TIM4_PWM_CH1 */
590 
591 #ifdef BSP_USING_TIM4_PWM_CH2
592         .channel[1] = TIM_Channel_2,
593 #else
594         .channel[1] = FLAG_NOT_INIT,
595 #endif/* BSP_USING_TIM4_PWM_CH2 */
596 
597 #ifdef BSP_USING_TIM4_PWM_CH3
598         .channel[2] = TIM_Channel_3,
599 #else
600         .channel[2] = FLAG_NOT_INIT,
601 #endif/* BSP_USING_TIM4_PWM_CH3 */
602 
603 #ifdef BSP_USING_TIM4_PWM_CH4
604         .channel[3] = TIM_Channel_4,
605 #else
606         .channel[3] = FLAG_NOT_INIT,
607 #endif/* BSP_USING_TIM4_PWM_CH4 */
608     },
609 #endif /* BSP_USING_TIM4_PWM */
610 
611 #ifdef BSP_USING_TIM5_PWM
612     {
613         .periph = TIM5,
614         .name = "pwm5",
615 #ifdef BSP_USING_TIM5_PWM_CH1
616         .channel[0] = TIM_Channel_1,
617 #else
618         .channel[0] = FLAG_NOT_INIT,
619 #endif/* BSP_USING_TIM5_PWM_CH1 */
620 
621 #ifdef BSP_USING_TIM5_PWM_CH2
622         .channel[1] = TIM_Channel_2,
623 #else
624         .channel[1] = FLAG_NOT_INIT,
625 #endif/* BSP_USING_TIM5_PWM_CH2 */
626 
627 #ifdef BSP_USING_TIM5_PWM_CH3
628         .channel[2] = TIM_Channel_3,
629 #else
630         .channel[2] = FLAG_NOT_INIT,
631 #endif/* BSP_USING_TIM5_PWM_CH3 */
632 
633 #ifdef BSP_USING_TIM5_PWM_CH4
634         .channel[3] = TIM_Channel_4,
635 #else
636         .channel[3] = FLAG_NOT_INIT,
637 #endif/* BSP_USING_TIM5_PWM_CH4 */
638     },
639 #endif /* BSP_USING_TIM5_PWM */
640 
641 #ifdef BSP_USING_TIM8_PWM
642     {
643         .periph = TIM8,
644         .name = "pwm8",
645 #ifdef BSP_USING_TIM8_PWM_CH1
646         .channel[0] = TIM_Channel_1,
647 #else
648         .channel[0] = FLAG_NOT_INIT,
649 #endif/* BSP_USING_TIM8_PWM_CH1 */
650 
651 #ifdef BSP_USING_TIM8_PWM_CH2
652         .channel[1] = TIM_Channel_2,
653 #else
654         .channel[1] = FLAG_NOT_INIT,
655 #endif/* BSP_USING_TIM8_PWM_CH2 */
656 
657 #ifdef BSP_USING_TIM8_PWM_CH3
658         .channel[2] = TIM_Channel_3,
659 #else
660         .channel[2] = FLAG_NOT_INIT,
661 #endif/* BSP_USING_TIM8_PWM_CH3 */
662 
663 #ifdef BSP_USING_TIM8_PWM_CH4
664         .channel[3] = TIM_Channel_4,
665 #else
666         .channel[3] = FLAG_NOT_INIT,
667 #endif/* BSP_USING_TIM8_PWM_CH4 */
668     },
669 #endif /* BSP_USING_TIM8_PWM */
670 
671 #ifdef BSP_USING_TIM9_PWM
672     {
673         .periph = TIM9,
674         .name = "pwm9",
675 #ifdef BSP_USING_TIM9_PWM_CH1
676         .channel[0] = TIM_Channel_1,
677 #else
678         .channel[0] = FLAG_NOT_INIT,
679 #endif/* BSP_USING_TIM9_PWM_CH1 */
680 
681 #ifdef BSP_USING_TIM9_PWM_CH2
682         .channel[1] = TIM_Channel_2,
683 #else
684         .channel[1] = FLAG_NOT_INIT,
685 #endif/* BSP_USING_TIM9_PWM_CH2 */
686 
687 #ifdef BSP_USING_TIM9_PWM_CH3
688         .channel[2] = TIM_Channel_3,
689 #else
690         .channel[2] = FLAG_NOT_INIT,
691 #endif/* BSP_USING_TIM9_PWM_CH3 */
692 
693 #ifdef BSP_USING_TIM9_PWM_CH4
694         .channel[3] = TIM_Channel_4,
695 #else
696         .channel[3] = FLAG_NOT_INIT,
697 #endif/* BSP_USING_TIM9_PWM_CH4 */
698     },
699 #endif /* BSP_USING_TIM9_PWM */
700 
701 #ifdef BSP_USING_TIM10_PWM
702     {
703         .periph = TIM10,
704         .name = "pwm10",
705 #ifdef BSP_USING_TIM10_PWM_CH1
706         .channel[0] = TIM_Channel_1,
707 #else
708         .channel[0] = FLAG_NOT_INIT,
709 #endif/* BSP_USING_TIM10_PWM_CH1 */
710 
711 #ifdef BSP_USING_TIM10_PWM_CH2
712         .channel[1] = TIM_Channel_2,
713 #else
714         .channel[1] = FLAG_NOT_INIT,
715 #endif/* BSP_USING_TIM10_PWM_CH2 */
716 
717 #ifdef BSP_USING_TIM10_PWM_CH3
718         .channel[2] = TIM_Channel_3,
719 #else
720         .channel[2] = FLAG_NOT_INIT,
721 #endif/* BSP_USING_TIM10_PWM_CH3 */
722 
723 #ifdef BSP_USING_TIM10_PWM_CH4
724         .channel[3] = TIM_Channel_4,
725 #else
726         .channel[3] = FLAG_NOT_INIT,
727 #endif/* BSP_USING_TIM10_PWM_CH4 */
728     },
729 #endif /* BSP_USING_TIM10_PWM */
730 };
731 
ch32_pwm_device_enable(struct rt_device_pwm * device,struct rt_pwm_configuration * configuration,rt_bool_t enable)732 static rt_err_t ch32_pwm_device_enable(struct rt_device_pwm* device, struct rt_pwm_configuration* configuration, rt_bool_t enable)
733 {
734     struct rtdevice_pwm_device* pwm_device;
735     rt_uint32_t channel_index;
736     rt_uint16_t ccx_state;
737 
738     pwm_device = (struct rtdevice_pwm_device*)device;
739     channel_index = configuration->channel;
740 
741     if (enable == RT_TRUE)
742     {
743         ccx_state = TIM_CCx_Enable;
744     }
745     else
746     {
747         ccx_state = TIM_CCx_Disable;
748     }
749 
750     if (channel_index <= 4 && channel_index > 0)
751     {
752         if (pwm_device->channel[channel_index - 1] == FLAG_NOT_INIT)
753         {
754             return -RT_EINVAL;
755         }
756         TIM_CCxCmd(pwm_device->periph, pwm_device->channel[channel_index - 1], ccx_state);
757     }
758     else
759     {
760         return -RT_EINVAL;
761     }
762 
763     TIM_Cmd(pwm_device->periph, ENABLE);
764 
765     return RT_EOK;
766 }
767 
ch32_pwm_device_get(struct rt_device_pwm * device,struct rt_pwm_configuration * configuration)768 static rt_err_t ch32_pwm_device_get(struct rt_device_pwm* device, struct rt_pwm_configuration* configuration)
769 {
770     struct rtdevice_pwm_device* pwm_device;
771     rt_uint32_t arr_counter, ccr_counter, prescaler, sample_freq;
772     rt_uint32_t channel_index;
773     rt_uint32_t tim_clock;
774 
775     pwm_device = (struct rtdevice_pwm_device*)device;
776     tim_clock = ch32_tim_clock_get(pwm_device->periph);
777     channel_index = configuration->channel;
778     arr_counter = pwm_device->periph->ATRLR + 1;
779     prescaler = pwm_device->periph->PSC + 1;
780     sample_freq = (tim_clock / prescaler) / arr_counter;
781 
782     /* unit:ns */
783     configuration->period = 1000000000 / sample_freq;
784 
785     if (channel_index == 1)
786     {
787         ccr_counter = pwm_device->periph->CH1CVR + 1;
788         configuration->pulse = ((ccr_counter * 100) / arr_counter) * configuration->period / 100;
789     }
790     else if (channel_index == 2)
791     {
792         ccr_counter = pwm_device->periph->CH2CVR + 1;
793         configuration->pulse = ((ccr_counter * 100) / arr_counter) * configuration->period / 100;
794     }
795     else if (channel_index == 3)
796     {
797         ccr_counter = pwm_device->periph->CH3CVR + 1;
798         configuration->pulse = ((ccr_counter * 100) / arr_counter) * configuration->period / 100;
799     }
800     else if (channel_index == 4)
801     {
802         ccr_counter = pwm_device->periph->CH4CVR + 1;
803         configuration->pulse = ((ccr_counter * 100) / arr_counter) * configuration->period / 100;
804     }
805     else
806     {
807         return -RT_EINVAL;
808     }
809 
810     return RT_EOK;
811 }
812 
ch32_pwm_device_set(struct rt_device_pwm * device,struct rt_pwm_configuration * configuration)813 static rt_err_t ch32_pwm_device_set(struct rt_device_pwm* device, struct rt_pwm_configuration* configuration)
814 {
815     struct rtdevice_pwm_device* pwm_device;
816     rt_uint32_t arr_counter, ccr_counter, prescaler, sample_freq;
817     rt_uint32_t channel_index;
818     rt_uint32_t tim_clock;
819     TIM_TimeBaseInitTypeDef TIM_TimeBaseInitType;
820     TIM_OCInitTypeDef TIM_OCInitType;
821 
822     pwm_device = (struct rtdevice_pwm_device*)device;
823     tim_clock = ch32_tim_clock_get(pwm_device->periph);
824     channel_index = configuration->channel;
825 
826     /* change to freq, unit:Hz */
827     sample_freq = 1000000000 / configuration->period;
828 
829     /* counter = (tim_clk / prescaler) / sample_freq */
830     /* normally, tim_clk is not need div, if arr_counter over 65536, need div. */
831     prescaler = 1;
832     arr_counter = (tim_clock / prescaler) / sample_freq;
833 
834     if (arr_counter > MAX_COUNTER)
835     {
836         /* need div tim_clock
837          * and round up the prescaler value.
838          * (tim_clock >> 16) = tim_clock / 65536
839          */
840         if ((tim_clock >> 16) % sample_freq == 0)
841             prescaler = (tim_clock >> 16) / sample_freq;
842         else
843             prescaler = (tim_clock >> 16) / sample_freq + 1;
844 
845         /* counter = (tim_clk / prescaler) / sample_freq */
846         arr_counter = (tim_clock / prescaler) / sample_freq;
847     }
848     /* ccr_counter = duty cycle * arr_counter */
849     ccr_counter = (configuration->pulse * 100 / configuration->period) * arr_counter / 100;
850 
851     /* check arr_counter > 1, cxx_counter > 1 */
852     if (arr_counter < MIN_COUNTER)
853     {
854         arr_counter = MIN_COUNTER;
855     }
856     if (ccr_counter < MIN_PULSE)
857     {
858         ccr_counter = MIN_PULSE;
859     }
860 
861     /* TMRe base configuration */
862     TIM_TimeBaseStructInit(&TIM_TimeBaseInitType);
863     TIM_TimeBaseInitType.TIM_Period = arr_counter - 1;
864     TIM_TimeBaseInitType.TIM_Prescaler = prescaler - 1;
865     TIM_TimeBaseInitType.TIM_ClockDivision = TIM_CKD_DIV1;
866     TIM_TimeBaseInitType.TIM_CounterMode = TIM_CounterMode_Up;
867     TIM_TimeBaseInit(pwm_device->periph, &TIM_TimeBaseInitType);
868 
869     TIM_OCStructInit(&TIM_OCInitType);
870     TIM_OCInitType.TIM_OCMode = TIM_OCMode_PWM1;
871     TIM_OCInitType.TIM_OutputState = TIM_OutputState_Enable;
872     TIM_OCInitType.TIM_Pulse = ccr_counter - 1;
873     TIM_OCInitType.TIM_OCPolarity = TIM_OCPolarity_High;
874 
875     if (channel_index == 1)
876     {
877         TIM_OC1Init(pwm_device->periph, &TIM_OCInitType);
878         TIM_OC1PreloadConfig(pwm_device->periph, TIM_OCPreload_Disable);
879     }
880     else if (channel_index == 2)
881     {
882         TIM_OC2Init(pwm_device->periph, &TIM_OCInitType);
883         TIM_OC2PreloadConfig(pwm_device->periph, TIM_OCPreload_Disable);
884     }
885     else if (channel_index == 3)
886     {
887         TIM_OC3Init(pwm_device->periph, &TIM_OCInitType);
888         TIM_OC3PreloadConfig(pwm_device->periph, TIM_OCPreload_Disable);
889     }
890     else if (channel_index == 4)
891     {
892         TIM_OC4Init(pwm_device->periph, &TIM_OCInitType);
893         TIM_OC4PreloadConfig(pwm_device->periph, TIM_OCPreload_Disable);
894     }
895     else
896     {
897         return -RT_EINVAL;
898     }
899 
900     TIM_ARRPreloadConfig(pwm_device->periph, ENABLE);
901     TIM_CtrlPWMOutputs(pwm_device->periph, ENABLE);
902 
903     return RT_EOK;
904 }
905 
drv_pwm_control(struct rt_device_pwm * device,int cmd,void * arg)906 static rt_err_t drv_pwm_control(struct rt_device_pwm* device, int cmd, void* arg)
907 {
908     struct rt_pwm_configuration* configuration;
909 
910     configuration = (struct rt_pwm_configuration*)arg;
911 
912     switch (cmd)
913     {
914     case PWM_CMD_ENABLE:
915         return ch32_pwm_device_enable(device, configuration, RT_TRUE);
916     case PWM_CMD_DISABLE:
917         return ch32_pwm_device_enable(device, configuration, RT_FALSE);
918     case PWM_CMD_SET:
919         return ch32_pwm_device_set(device, configuration);
920     case PWM_CMD_GET:
921         return ch32_pwm_device_get(device, configuration);
922     default:
923         return -RT_EINVAL;
924     }
925 }
926 
927 static struct rt_pwm_ops pwm_ops =
928 {
929     .control = drv_pwm_control
930 };
931 
rt_hw_pwm_init(void)932 static int rt_hw_pwm_init(void)
933 {
934     int result = RT_EOK;
935     int index = 0;
936     int channel_index;
937 
938     for (index = 0; index < ITEM_NUM(pwm_device_list); index++)
939     {
940         ch32_tim_clock_init(pwm_device_list[index].periph);
941         for (channel_index = 0; channel_index < sizeof(pwm_device_list[index].channel); channel_index++)
942         {
943             if (pwm_device_list[index].channel[channel_index] != FLAG_NOT_INIT)
944             {
945                 ch32_pwm_io_init(pwm_device_list[index].periph, pwm_device_list[index].channel[channel_index]);
946             }
947         }
948 
949         if (rt_device_pwm_register(&pwm_device_list[index].parent, pwm_device_list[index].name, &pwm_ops, RT_NULL) == RT_EOK)
950         {
951             LOG_D("%s register success", pwm_device_list[index].name);
952         }
953         else
954         {
955             LOG_D("%s register failed", pwm_device_list[index].name);
956             result = -RT_ERROR;
957         }
958     }
959 
960     return result;
961 }
962 
963 INIT_BOARD_EXPORT(rt_hw_pwm_init);
964 
965 #endif /* BSP_USING_PWM */
966