1 /*
2 * Copyright (c) 2006-2021, RT-Thread Development Team
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date Author Notes
8 * 2022-05-16 shelton first version
9 * 2024-09-24 shelton update driver
10 */
11
12 #include "drv_common.h"
13
14 #ifdef RT_USING_PWM
15 #include "drv_pwm.h"
16 #include <drivers/dev_pwm.h>
17
18 //#define DRV_DEBUG
19 #define LOG_TAG "drv.pwm"
20 #include <drv_log.h>
21
22 #define MAX_PERIOD 65535
23 #define MIN_PERIOD 3
24 #define MIN_PULSE 2
25
26 struct at32_pwm
27 {
28 struct rt_device_pwm pwm_device;
29 tmr_type* tmr_x;
30 rt_uint8_t channel;
31 char *name;
32 };
33
34 enum
35 {
36 #ifdef BSP_USING_PWM1
37 PWM1_INDEX,
38 #endif
39 #ifdef BSP_USING_PWM2
40 PWM2_INDEX,
41 #endif
42 #ifdef BSP_USING_PWM3
43 PWM3_INDEX,
44 #endif
45 #ifdef BSP_USING_PWM4
46 PWM4_INDEX,
47 #endif
48 #ifdef BSP_USING_PWM5
49 PWM5_INDEX,
50 #endif
51 #ifdef BSP_USING_PWM6
52 PWM6_INDEX,
53 #endif
54 #ifdef BSP_USING_PWM7
55 PWM7_INDEX,
56 #endif
57 #ifdef BSP_USING_PWM8
58 PWM8_INDEX,
59 #endif
60 #ifdef BSP_USING_PWM9
61 PWM9_INDEX,
62 #endif
63 #ifdef BSP_USING_PWM10
64 PWM10_INDEX,
65 #endif
66 #ifdef BSP_USING_PWM11
67 PWM11_INDEX,
68 #endif
69 #ifdef BSP_USING_PWM12
70 PWM12_INDEX,
71 #endif
72 #ifdef BSP_USING_PWM13
73 PWM13_INDEX,
74 #endif
75 };
76
77 static struct at32_pwm at32_pwm_obj[] =
78 {
79 #ifdef BSP_USING_PWM1
80 PWM1_CONFIG,
81 #endif
82
83 #ifdef BSP_USING_PWM2
84 PWM2_CONFIG,
85 #endif
86
87 #ifdef BSP_USING_PWM3
88 PWM3_CONFIG,
89 #endif
90
91 #ifdef BSP_USING_PWM4
92 PWM4_CONFIG,
93 #endif
94
95 #ifdef BSP_USING_PWM5
96 PWM5_CONFIG,
97 #endif
98
99 #ifdef BSP_USING_PWM6
100 PWM6_CONFIG,
101 #endif
102
103 #ifdef BSP_USING_PWM7
104 PWM7_CONFIG,
105 #endif
106
107 #ifdef BSP_USING_PWM8
108 PWM8_CONFIG,
109 #endif
110
111 #ifdef BSP_USING_PWM9
112 PWM9_CONFIG,
113 #endif
114
115 #ifdef BSP_USING_PWM10
116 PWM10_CONFIG,
117 #endif
118
119 #ifdef BSP_USING_PWM11
120 PWM11_CONFIG,
121 #endif
122
123 #ifdef BSP_USING_PWM12
124 PWM12_CONFIG,
125 #endif
126
127 #ifdef BSP_USING_PWM13
128 PWM13_CONFIG,
129 #endif
130 };
131
132 static rt_err_t drv_pwm_control(struct rt_device_pwm *device, int cmd, void *arg);
133 static struct rt_pwm_ops drv_ops =
134 {
135 drv_pwm_control
136 };
137
tmr_pclk_get(rt_uint32_t * pclk1_doubler,rt_uint32_t * pclk2_doubler)138 static void tmr_pclk_get(rt_uint32_t *pclk1_doubler, rt_uint32_t *pclk2_doubler)
139 {
140 crm_clocks_freq_type clocks_struct;
141
142 *pclk1_doubler = 1;
143 *pclk2_doubler = 1;
144
145 crm_clocks_freq_get(&clocks_struct);
146
147 if(clocks_struct.ahb_freq != clocks_struct.apb1_freq)
148 {
149 *pclk1_doubler = 2;
150 }
151
152 if(clocks_struct.ahb_freq != clocks_struct.apb2_freq)
153 {
154 *pclk2_doubler = 2;
155 }
156 }
157
at32_hw_pwm_init(struct at32_pwm * instance)158 static rt_err_t at32_hw_pwm_init(struct at32_pwm *instance)
159 {
160 tmr_output_config_type tmr_oc_config_struct;
161 tmr_type *tmr_x = instance->tmr_x;
162
163 at32_msp_tmr_init(tmr_x);
164
165 tmr_base_init(tmr_x, 0, 0);
166 tmr_clock_source_div_set(tmr_x, TMR_CLOCK_DIV1);
167
168 /* pwm mode configuration */
169 tmr_output_default_para_init(&tmr_oc_config_struct);
170 /* config pwm mode */
171 tmr_oc_config_struct.oc_mode = TMR_OUTPUT_CONTROL_PWM_MODE_A;
172
173 /* config tmr pwm output */
174 if(instance->channel & 0x01)
175 {
176 tmr_output_channel_config(tmr_x, TMR_SELECT_CHANNEL_1, &tmr_oc_config_struct);
177 tmr_output_channel_buffer_enable(tmr_x, TMR_SELECT_CHANNEL_1, TRUE);
178 }
179
180 if(instance->channel & 0x02)
181 {
182 tmr_output_channel_config(tmr_x, TMR_SELECT_CHANNEL_2, &tmr_oc_config_struct);
183 tmr_output_channel_buffer_enable(tmr_x, TMR_SELECT_CHANNEL_2, TRUE);
184 }
185
186 if(instance->channel & 0x04)
187 {
188 tmr_output_channel_config(tmr_x, TMR_SELECT_CHANNEL_3, &tmr_oc_config_struct);
189 tmr_output_channel_buffer_enable(tmr_x, TMR_SELECT_CHANNEL_3, TRUE);
190 }
191
192 if(instance->channel & 0x08)
193 {
194 tmr_output_channel_config(tmr_x, TMR_SELECT_CHANNEL_4, &tmr_oc_config_struct);
195 tmr_output_channel_buffer_enable(tmr_x, TMR_SELECT_CHANNEL_4, TRUE);
196 }
197
198 /* enable output */
199 tmr_output_enable(tmr_x, TRUE);
200 /* enable overflow request */
201 tmr_overflow_request_source_set(tmr_x, TRUE);
202
203 return RT_EOK;
204 }
205
drv_pwm_enable(tmr_type * tmr_x,struct rt_pwm_configuration * configuration,rt_bool_t enable)206 static rt_err_t drv_pwm_enable(tmr_type* tmr_x, struct rt_pwm_configuration *configuration, rt_bool_t enable)
207 {
208 /* get the value of channel */
209 rt_uint32_t channel = configuration->channel;
210
211 if (!configuration->complementary)
212 {
213 if (!enable)
214 {
215 if(channel == 1)
216 {
217 tmr_channel_enable(tmr_x, TMR_SELECT_CHANNEL_1, FALSE);
218 }
219 else if(channel == 2)
220 {
221 tmr_channel_enable(tmr_x, TMR_SELECT_CHANNEL_2, FALSE);
222 }
223 else if(channel == 3)
224 {
225 tmr_channel_enable(tmr_x, TMR_SELECT_CHANNEL_3, FALSE);
226 }
227 else if(channel == 4)
228 {
229 tmr_channel_enable(tmr_x, TMR_SELECT_CHANNEL_4, FALSE);
230 }
231 }
232 else
233 {
234 if(channel == 1)
235 {
236 tmr_channel_enable(tmr_x, TMR_SELECT_CHANNEL_1, TRUE);
237 }
238 else if(channel == 2)
239 {
240 tmr_channel_enable(tmr_x, TMR_SELECT_CHANNEL_2, TRUE);
241 }
242 else if(channel == 3)
243 {
244 tmr_channel_enable(tmr_x, TMR_SELECT_CHANNEL_3, TRUE);
245 }
246 else if(channel == 4)
247 {
248 tmr_channel_enable(tmr_x, TMR_SELECT_CHANNEL_4, TRUE);
249 }
250 }
251 }
252 else
253 {
254 if (!enable)
255 {
256 if(channel == 1)
257 {
258 tmr_channel_enable(tmr_x, TMR_SELECT_CHANNEL_1C, FALSE);
259 }
260 else if(channel == 2)
261 {
262 tmr_channel_enable(tmr_x, TMR_SELECT_CHANNEL_2C, FALSE);
263 }
264 else if(channel == 3)
265 {
266 tmr_channel_enable(tmr_x, TMR_SELECT_CHANNEL_3C, FALSE);
267 }
268 }
269 else
270 {
271 if(channel == 1)
272 {
273 tmr_channel_enable(tmr_x, TMR_SELECT_CHANNEL_1C, TRUE);
274 }
275 else if(channel == 2)
276 {
277 tmr_channel_enable(tmr_x, TMR_SELECT_CHANNEL_2C, TRUE);
278 }
279 else if(channel == 3)
280 {
281 tmr_channel_enable(tmr_x, TMR_SELECT_CHANNEL_3C, TRUE);
282 }
283 }
284 }
285
286 /* tmr_x enable counter */
287 tmr_counter_enable(tmr_x, TRUE);
288
289 return RT_EOK;
290 }
291
drv_pwm_get(tmr_type * tmr_x,struct rt_pwm_configuration * configuration)292 static rt_err_t drv_pwm_get(tmr_type* tmr_x, struct rt_pwm_configuration *configuration)
293 {
294 crm_clocks_freq_type clocks_struct;
295 rt_uint32_t pr, div, c1dt, c2dt, c3dt, c4dt, tmr_clock;
296 rt_uint32_t pclk1_doubler = 0, pclk2_doubler = 0;
297 rt_uint32_t channel = configuration->channel;
298
299 pr = tmr_x->pr;
300 div = tmr_x->div;
301 c1dt = tmr_x->c1dt;
302 c2dt = tmr_x->c2dt;
303 c3dt = tmr_x->c3dt;
304 c4dt = tmr_x->c4dt;
305
306 tmr_pclk_get(&pclk1_doubler, &pclk2_doubler);
307 crm_clocks_freq_get(&clocks_struct);
308
309 if(
310 #if defined (TMR1)
311 (tmr_x == TMR1)
312 #endif
313 #if defined (TMR8)
314 || (tmr_x == TMR8)
315 #endif
316 #if defined (TMR9)
317 || (tmr_x == TMR9)
318 #endif
319 #if defined (TMR10)
320 || (tmr_x == TMR10)
321 #endif
322 #if defined (TMR11)
323 || (tmr_x == TMR11)
324 #endif
325 )
326 {
327 tmr_clock = clocks_struct.apb2_freq * pclk2_doubler;
328 }
329 else
330 {
331 tmr_clock = clocks_struct.apb1_freq * pclk1_doubler;
332 }
333
334 /* convert nanosecond to frequency and duty cycle. */
335 tmr_clock /= 1000000UL;
336 configuration->period = (pr + 1) * (div + 1) * 1000UL / tmr_clock;
337
338 if(channel == 1)
339 configuration->pulse = (c1dt) * (div + 1) * 1000UL / tmr_clock;
340 if(channel == 2)
341 configuration->pulse = (c2dt) * (div + 1) * 1000UL / tmr_clock;
342 if(channel == 3)
343 configuration->pulse = (c3dt) * (div + 1) * 1000UL / tmr_clock;
344 if(channel == 4)
345 configuration->pulse = (c4dt) * (div + 1) * 1000UL / tmr_clock;
346
347 return RT_EOK;
348 }
349
drv_pwm_set(tmr_type * tmr_x,struct rt_pwm_configuration * configuration)350 static rt_err_t drv_pwm_set(tmr_type* tmr_x, struct rt_pwm_configuration *configuration)
351 {
352 crm_clocks_freq_type clocks_struct;
353 tmr_channel_select_type channel_select;
354 rt_uint32_t period, pulse, channel, psc, tmr_clock;
355 rt_uint32_t pclk1_doubler = 0, pclk2_doubler = 0;
356
357 tmr_pclk_get(&pclk1_doubler, &pclk2_doubler);
358 crm_clocks_freq_get(&clocks_struct);
359
360 if(
361 #if defined (TMR1)
362 (tmr_x == TMR1)
363 #endif
364 #if defined (TMR8)
365 || (tmr_x == TMR8)
366 #endif
367 #if defined (TMR9)
368 || (tmr_x == TMR9)
369 #endif
370 #if defined (TMR10)
371 || (tmr_x == TMR10)
372 #endif
373 #if defined (TMR11)
374 || (tmr_x == TMR11)
375 #endif
376 )
377 {
378 tmr_clock = clocks_struct.apb2_freq * pclk2_doubler;
379 }
380 else
381 {
382 tmr_clock = clocks_struct.apb1_freq * pclk1_doubler;
383 }
384
385 /* convert nanosecond to frequency and duty cycle. */
386 tmr_clock /= 1000000UL;
387 /* calculate pwm period */
388 period = (unsigned long long)configuration->period * tmr_clock / 1000ULL;;
389 psc = period / MAX_PERIOD + 1;
390 period = period / psc;
391 tmr_div_value_set(tmr_x, psc - 1);
392
393 if(period < MIN_PERIOD)
394 {
395 period = MIN_PERIOD;
396 }
397
398 tmr_period_value_set(tmr_x, period - 1);
399
400 /* calculate pulse width */
401 pulse = (unsigned long long)configuration->pulse * tmr_clock / psc / 1000ULL;
402 if(pulse < MIN_PULSE)
403 {
404 pulse = MIN_PULSE;
405 }
406 else if(pulse >= period)
407 {
408 pulse = period + 1;
409 }
410
411 /* get channel parameter */
412 channel = configuration->channel;
413 if(channel == 1)
414 {
415 channel_select = TMR_SELECT_CHANNEL_1;
416 }
417 else if(channel == 2)
418 {
419 channel_select = TMR_SELECT_CHANNEL_2;
420 }
421 else if(channel == 3)
422 {
423 channel_select = TMR_SELECT_CHANNEL_3;
424 }
425 else if(channel == 4)
426 {
427 channel_select = TMR_SELECT_CHANNEL_4;
428 }
429
430 tmr_channel_value_set(tmr_x, channel_select, pulse);
431
432 /* if you want the pwm setting to take effect immediately,
433 please uncommon the following code, but it will cause the last pwm cycle not complete. */
434 //tmr_counter_value_set(tmr_x, 0);
435 //tmr_x->swevt_bit.ovfswtr = TRUE;
436
437 return RT_EOK;
438 }
439
drv_pwm_set_period(tmr_type * tmr_x,struct rt_pwm_configuration * configuration)440 static rt_err_t drv_pwm_set_period(tmr_type* tmr_x, struct rt_pwm_configuration *configuration)
441 {
442 crm_clocks_freq_type clocks_struct;
443 rt_uint32_t period, psc, tmr_clock;
444 rt_uint32_t pclk1_doubler = 0, pclk2_doubler = 0;
445
446 tmr_pclk_get(&pclk1_doubler, &pclk2_doubler);
447 crm_clocks_freq_get(&clocks_struct);
448
449 if(
450 #if defined (TMR1)
451 (tmr_x == TMR1)
452 #endif
453 #if defined (TMR8)
454 || (tmr_x == TMR8)
455 #endif
456 #if defined (TMR9)
457 || (tmr_x == TMR9)
458 #endif
459 #if defined (TMR10)
460 || (tmr_x == TMR10)
461 #endif
462 #if defined (TMR11)
463 || (tmr_x == TMR11)
464 #endif
465 )
466 {
467 tmr_clock = clocks_struct.apb2_freq * pclk2_doubler;
468 }
469 else
470 {
471 tmr_clock = clocks_struct.apb1_freq * pclk1_doubler;
472 }
473
474 /* convert nanosecond to frequency and duty cycle. */
475 tmr_clock /= 1000000UL;
476 /* calculate pwm period */
477 period = (unsigned long long)configuration->period * tmr_clock / 1000ULL;;
478 psc = period / MAX_PERIOD + 1;
479 period = period / psc;
480 tmr_div_value_set(tmr_x, psc - 1);
481
482 if(period < MIN_PERIOD)
483 {
484 period = MIN_PERIOD;
485 }
486
487 tmr_period_value_set(tmr_x, period - 1);
488
489 return RT_EOK;
490 }
491
drv_pwm_set_pulse(tmr_type * tmr_x,struct rt_pwm_configuration * configuration)492 static rt_err_t drv_pwm_set_pulse(tmr_type* tmr_x, struct rt_pwm_configuration *configuration)
493 {
494 crm_clocks_freq_type clocks_struct;
495 tmr_channel_select_type channel_select;
496 rt_uint32_t period, pulse, channel, psc, tmr_clock;
497 rt_uint32_t pclk1_doubler = 0, pclk2_doubler = 0;
498
499 tmr_pclk_get(&pclk1_doubler, &pclk2_doubler);
500 crm_clocks_freq_get(&clocks_struct);
501
502 if(
503 #if defined (TMR1)
504 (tmr_x == TMR1)
505 #endif
506 #if defined (TMR8)
507 || (tmr_x == TMR8)
508 #endif
509 #if defined (TMR9)
510 || (tmr_x == TMR9)
511 #endif
512 #if defined (TMR10)
513 || (tmr_x == TMR10)
514 #endif
515 #if defined (TMR11)
516 || (tmr_x == TMR11)
517 #endif
518 )
519 {
520 tmr_clock = clocks_struct.apb2_freq * pclk2_doubler;
521 }
522 else
523 {
524 tmr_clock = clocks_struct.apb1_freq * pclk1_doubler;
525 }
526
527 /* convert nanosecond to frequency and duty cycle. */
528 tmr_clock /= 1000000UL;
529 /* calculate pwm period */
530 period = (unsigned long long)configuration->period * tmr_clock / 1000ULL;;
531 psc = period / MAX_PERIOD + 1;
532
533 /* calculate pulse width */
534 pulse = (unsigned long long)configuration->pulse * tmr_clock / psc / 1000ULL;
535 if(pulse < MIN_PULSE)
536 {
537 pulse = MIN_PULSE;
538 }
539 else if(pulse >= period)
540 {
541 pulse = period + 1;
542 }
543
544 /* get channel parameter */
545 channel = configuration->channel;
546 if(channel == 1)
547 {
548 channel_select = TMR_SELECT_CHANNEL_1;
549 }
550 else if(channel == 2)
551 {
552 channel_select = TMR_SELECT_CHANNEL_2;
553 }
554 else if(channel == 3)
555 {
556 channel_select = TMR_SELECT_CHANNEL_3;
557 }
558 else if(channel == 4)
559 {
560 channel_select = TMR_SELECT_CHANNEL_4;
561 }
562
563 tmr_channel_value_set(tmr_x, channel_select, pulse);
564
565 return RT_EOK;
566 }
567
drv_pwm_control(struct rt_device_pwm * device,int cmd,void * arg)568 static rt_err_t drv_pwm_control(struct rt_device_pwm *device, int cmd, void *arg)
569 {
570 struct rt_pwm_configuration *configuration = (struct rt_pwm_configuration *)arg;
571 tmr_type *tmr_x = (tmr_type *)device->parent.user_data;
572
573 switch (cmd)
574 {
575 case PWM_CMD_ENABLE:
576 return drv_pwm_enable(tmr_x, configuration, RT_TRUE);
577 case PWM_CMD_DISABLE:
578 return drv_pwm_enable(tmr_x, configuration, RT_FALSE);
579 case PWM_CMD_SET:
580 return drv_pwm_set(tmr_x, configuration);
581 case PWM_CMD_SET_PERIOD:
582 return drv_pwm_set_period(tmr_x, configuration);
583 case PWM_CMD_SET_PULSE:
584 return drv_pwm_set_pulse(tmr_x, configuration);
585 case PWM_CMD_GET:
586 return drv_pwm_get(tmr_x, configuration);
587 default:
588 return -RT_EINVAL;
589 }
590 }
591
pwm_get_channel(void)592 static void pwm_get_channel(void)
593 {
594 #ifdef BSP_USING_PWM1_CH1
595 at32_pwm_obj[PWM1_INDEX].channel |= 1 << 0;
596 #endif
597 #ifdef BSP_USING_PWM1_CH2
598 at32_pwm_obj[PWM1_INDEX].channel |= 1 << 1;
599 #endif
600 #ifdef BSP_USING_PWM1_CH3
601 at32_pwm_obj[PWM1_INDEX].channel |= 1 << 2;
602 #endif
603 #ifdef BSP_USING_PWM1_CH4
604 at32_pwm_obj[PWM1_INDEX].channel |= 1 << 3;
605 #endif
606 #ifdef BSP_USING_PWM2_CH1
607 at32_pwm_obj[PWM2_INDEX].channel |= 1 << 0;
608 #endif
609 #ifdef BSP_USING_PWM2_CH2
610 at32_pwm_obj[PWM2_INDEX].channel |= 1 << 1;
611 #endif
612 #ifdef BSP_USING_PWM2_CH3
613 at32_pwm_obj[PWM2_INDEX].channel |= 1 << 2;
614 #endif
615 #ifdef BSP_USING_PWM2_CH4
616 at32_pwm_obj[PWM2_INDEX].channel |= 1 << 3;
617 #endif
618 #ifdef BSP_USING_PWM3_CH1
619 at32_pwm_obj[PWM3_INDEX].channel |= 1 << 0;
620 #endif
621 #ifdef BSP_USING_PWM3_CH2
622 at32_pwm_obj[PWM3_INDEX].channel |= 1 << 1;
623 #endif
624 #ifdef BSP_USING_PWM3_CH3
625 at32_pwm_obj[PWM3_INDEX].channel |= 1 << 2;
626 #endif
627 #ifdef BSP_USING_PWM3_CH4
628 at32_pwm_obj[PWM3_INDEX].channel |= 1 << 3;
629 #endif
630 #ifdef BSP_USING_PWM4_CH1
631 at32_pwm_obj[PWM4_INDEX].channel |= 1 << 0;
632 #endif
633 #ifdef BSP_USING_PWM4_CH2
634 at32_pwm_obj[PWM4_INDEX].channel |= 1 << 1;
635 #endif
636 #ifdef BSP_USING_PWM4_CH3
637 at32_pwm_obj[PWM4_INDEX].channel |= 1 << 2;
638 #endif
639 #ifdef BSP_USING_PWM4_CH4
640 at32_pwm_obj[PWM4_INDEX].channel |= 1 << 3;
641 #endif
642 #ifdef BSP_USING_PWM5_CH1
643 at32_pwm_obj[PWM5_INDEX].channel |= 1 << 0;
644 #endif
645 #ifdef BSP_USING_PWM5_CH2
646 at32_pwm_obj[PWM5_INDEX].channel |= 1 << 1;
647 #endif
648 #ifdef BSP_USING_PWM5_CH3
649 at32_pwm_obj[PWM5_INDEX].channel |= 1 << 2;
650 #endif
651 #ifdef BSP_USING_PWM5_CH4
652 at32_pwm_obj[PWM5_INDEX].channel |= 1 << 3;
653 #endif
654 #ifdef BSP_USING_PWM6_CH1
655 at32_pwm_obj[PWM6_INDEX].channel |= 1 << 0;
656 #endif
657 #ifdef BSP_USING_PWM6_CH2
658 at32_pwm_obj[PWM6_INDEX].channel |= 1 << 1;
659 #endif
660 #ifdef BSP_USING_PWM6_CH3
661 at32_pwm_obj[PWM6_INDEX].channel |= 1 << 2;
662 #endif
663 #ifdef BSP_USING_PWM6_CH4
664 at32_pwm_obj[PWM6_INDEX].channel |= 1 << 3;
665 #endif
666 #ifdef BSP_USING_PWM7_CH1
667 at32_pwm_obj[PWM7_INDEX].channel |= 1 << 0;
668 #endif
669 #ifdef BSP_USING_PWM7_CH2
670 at32_pwm_obj[PWM7_INDEX].channel |= 1 << 1;
671 #endif
672 #ifdef BSP_USING_PWM7_CH3
673 at32_pwm_obj[PWM7_INDEX].channel |= 1 << 2;
674 #endif
675 #ifdef BSP_USING_PWM7_CH4
676 at32_pwm_obj[PWM7_INDEX].channel |= 1 << 3;
677 #endif
678 #ifdef BSP_USING_PWM8_CH1
679 at32_pwm_obj[PWM8_INDEX].channel |= 1 << 0;
680 #endif
681 #ifdef BSP_USING_PWM8_CH2
682 at32_pwm_obj[PWM8_INDEX].channel |= 1 << 1;
683 #endif
684 #ifdef BSP_USING_PWM8_CH3
685 at32_pwm_obj[PWM8_INDEX].channel |= 1 << 2;
686 #endif
687 #ifdef BSP_USING_PWM8_CH4
688 at32_pwm_obj[PWM8_INDEX].channel |= 1 << 3;
689 #endif
690 #ifdef BSP_USING_PWM9_CH1
691 at32_pwm_obj[PWM9_INDEX].channel |= 1 << 0;
692 #endif
693 #ifdef BSP_USING_PWM9_CH2
694 at32_pwm_obj[PWM9_INDEX].channel |= 1 << 1;
695 #endif
696 #ifdef BSP_USING_PWM9_CH3
697 at32_pwm_obj[PWM9_INDEX].channel |= 1 << 2;
698 #endif
699 #ifdef BSP_USING_PWM9_CH4
700 at32_pwm_obj[PWM9_INDEX].channel |= 1 << 3;
701 #endif
702 #ifdef BSP_USING_PWM12_CH1
703 at32_pwm_obj[PWM12_INDEX].channel |= 1 << 0;
704 #endif
705 #ifdef BSP_USING_PWM12_CH2
706 at32_pwm_obj[PWM12_INDEX].channel |= 1 << 1;
707 #endif
708 }
709
rt_hw_pwm_init(void)710 static int rt_hw_pwm_init(void)
711 {
712 int i = 0;
713 int result = RT_EOK;
714
715 pwm_get_channel();
716
717 for(i = 0; i < sizeof(at32_pwm_obj) / sizeof(at32_pwm_obj[0]); i++)
718 {
719 if(at32_hw_pwm_init(&at32_pwm_obj[i]) != RT_EOK)
720 {
721 LOG_E("%s init failed", at32_pwm_obj[i].name);
722 result = -RT_ERROR;
723 goto __exit;
724 }
725 else
726 {
727 if(rt_device_pwm_register(&at32_pwm_obj[i].pwm_device, at32_pwm_obj[i].name, &drv_ops, at32_pwm_obj[i].tmr_x) == RT_EOK)
728 {
729 LOG_D("%s register success", at32_pwm_obj[i].name);
730 }
731 else
732 {
733 LOG_D("%s register failed", at32_pwm_obj[i].name);
734 result = -RT_ERROR;
735 }
736 }
737 }
738 __exit:
739 return result;
740 }
741
742 INIT_BOARD_EXPORT(rt_hw_pwm_init);
743
744 #endif /* RT_USING_PWM */
745