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