123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965 |
- /*
- * Copyright (c) 2006-2023, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- * 2021-09-23 charlown first version
- * 2022-10-14 hg0720 the first version which add from wch
- * 2022-10-20 MXH add the remaining timers
- */
- #include "drv_pwm.h"
- #ifdef BSP_USING_PWM
- #define LOG_TAG "drv.pwm"
- #include <drv_log.h>
- #define ITEM_NUM(items) sizeof(items) / sizeof(items[0])
- void ch32_tim_clock_init(TIM_TypeDef* timx)
- {
- #ifdef BSP_USING_TIM1_PWM
- if (timx == TIM1)
- {
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
- }
- #endif/* BSP_USING_TIM1_PWM */
- #ifdef BSP_USING_TIM2_PWM
- if (timx == TIM2)
- {
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
- }
- #endif/* BSP_USING_TIM2_PWM */
- #ifdef BSP_USING_TIM3_PWM
- if (timx == TIM3)
- {
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
- }
- #endif/* BSP_USING_TIM3_PWM */
- #ifdef BSP_USING_TIM4_PWM
- if (timx == TIM4)
- {
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
- }
- #endif/* BSP_USING_TIM4_PWM */
- #ifdef BSP_USING_TIM5_PWM
- if (timx == TIM5)
- {
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE);
- }
- #endif/* BSP_USING_TIM5_PWM */
- /* TIM6 and TIM7 don't support PWM Mode. */
- #ifdef BSP_USING_TIM8_PWM
- if (timx == TIM8)
- {
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM8, ENABLE);
- }
- #endif/* BSP_USING_TIM8_PWM */
- #ifdef BSP_USING_TIM9_PWM
- if (timx == TIM9)
- {
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM9, ENABLE);
- }
- #endif/* BSP_USING_TIM9_PWM */
- #ifdef BSP_USING_TIM10_PWM
- if (timx == TIM10)
- {
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM10, ENABLE);
- }
- #endif/* BSP_USING_TIM10_PWM */
- }
- rt_uint32_t ch32_tim_clock_get(TIM_TypeDef* timx)
- {
- RCC_ClocksTypeDef RCC_Clocks;
- RCC_GetClocksFreq(&RCC_Clocks);
- /*tim1~10 all in HCLK*/
- return RCC_Clocks.HCLK_Frequency;
- }
- /*
- * NOTE: some pwm pins of some timers are reused,
- * please keep caution when using pwm
- */
- void ch32_pwm_io_init(TIM_TypeDef* timx, rt_uint8_t channel)
- {
- GPIO_InitTypeDef GPIO_InitStructure;
- #ifdef BSP_USING_TIM1_PWM
- if (timx == TIM1)
- {
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
- #ifdef BSP_USING_TIM1_PWM_CH1
- if (channel == TIM_Channel_1)
- {
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
- GPIO_Init(GPIOA, &GPIO_InitStructure);
- }
- #endif/* BSP_USING_TIM1_PWM_CH1 */
- #ifdef BSP_USING_TIM1_PWM_CH2
- if (channel == TIM_Channel_2)
- {
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
- GPIO_Init(GPIOA, &GPIO_InitStructure);
- }
- #endif/* BSP_USING_TIM1_PWM_CH2 */
- #ifdef BSP_USING_TIM1_PWM_CH3
- if (channel == TIM_Channel_3)
- {
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
- GPIO_Init(GPIOA, &GPIO_InitStructure);
- }
- #endif/* BSP_USING_TIM1_PWM_CH3 */
- #ifdef BSP_USING_TIM1_PWM_CH4
- if (channel == TIM_Channel_4)
- {
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
- GPIO_Init(GPIOA, &GPIO_InitStructure);
- }
- #endif/* BSP_USING_TIM1_PWM_CH4 */
- }
- #endif/* BSP_USING_TIM1_PWM */
- #ifdef BSP_USING_TIM2_PWM
- if (timx == TIM2)
- {
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
- #ifdef BSP_USING_TIM2_PWM_CH1
- if (channel == TIM_Channel_1)
- {
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
- GPIO_Init(GPIOA, &GPIO_InitStructure);
- }
- #endif/* BSP_USING_TIM2_PWM_CH1 */
- #ifdef BSP_USING_TIM2_PWM_CH2
- if (channel == TIM_Channel_2)
- {
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
- GPIO_Init(GPIOA, &GPIO_InitStructure);
- }
- #endif/* BSP_USING_TIM2_PWM_CH2 */
- #ifdef BSP_USING_TIM2_PWM_CH3
- if (channel == TIM_Channel_3)
- {
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
- GPIO_Init(GPIOA, &GPIO_InitStructure);
- }
- #endif/* BSP_USING_TIM2_PWM_CH3 */
- #ifdef BSP_USING_TIM2_PWM_CH4
- if (channel == TIM_Channel_4)
- {
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
- GPIO_Init(GPIOA, &GPIO_InitStructure);
- }
- #endif/* BSP_USING_TIM2_PWM_CH4 */
- }
- #endif/* BSP_USING_TIM2_PWM */
- #ifdef BSP_USING_TIM3_PWM
- if (timx == TIM3)
- {
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
- #ifdef BSP_USING_TIM3_PWM_CH1
- if (channel == TIM_Channel_1)
- {
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
- GPIO_Init(GPIOA, &GPIO_InitStructure);
- }
- #endif/* BSP_USING_TIM3_PWM_CH1 */
- #ifdef BSP_USING_TIM3_PWM_CH2
- if (channel == TIM_Channel_2)
- {
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
- GPIO_Init(GPIOA, &GPIO_InitStructure);
- }
- #endif/* BSP_USING_TIM3_PWM_CH2 */
- #ifdef BSP_USING_TIM3_PWM_CH3
- if (channel == TIM_Channel_3)
- {
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
- GPIO_Init(GPIOB, &GPIO_InitStructure);
- }
- #endif/* BSP_USING_TIM3_PWM_CH3 */
- #ifdef BSP_USING_TIM3_PWM_CH4
- if (channel == TIM_Channel_4)
- {
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
- GPIO_Init(GPIOB, &GPIO_InitStructure);
- }
- #endif/* BSP_USING_TIM3_PWM_CH4 */
- }
- #endif/* BSP_USING_TIM3_PWM */
- #ifdef BSP_USING_TIM4_PWM
- if (timx == TIM4)
- {
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
- #ifdef BSP_USING_TIM4_PWM_CH1
- if (channel == TIM_Channel_1)
- {
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
- GPIO_Init(GPIOB, &GPIO_InitStructure);
- }
- #endif/* BSP_USING_TIM4_PWM_CH1 */
- #ifdef BSP_USING_TIM4_PWM_CH2
- if (channel == TIM_Channel_2)
- {
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
- GPIO_Init(GPIOB, &GPIO_InitStructure);
- }
- #endif/* BSP_USING_TIM4_PWM_CH2 */
- #ifdef BSP_USING_TIM4_PWM_CH3
- if (channel == TIM_Channel_3)
- {
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
- GPIO_Init(GPIOB, &GPIO_InitStructure);
- }
- #endif/* BSP_USING_TIM4_PWM_CH3 */
- #ifdef BSP_USING_TIM4_PWM_CH4
- if (channel == TIM_Channel_4)
- {
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
- GPIO_Init(GPIOB, &GPIO_InitStructure);
- }
- #endif/* BSP_USING_TIM4_PWM_CH4 */
- }
- #endif/* BSP_USING_TIM4_PWM */
- #ifdef BSP_USING_TIM5_PWM
- if (timx == TIM5)
- {
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
- #ifdef BSP_USING_TIM5_PWM_CH1
- if (channel == TIM_Channel_1)
- {
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
- GPIO_Init(GPIOA, &GPIO_InitStructure);
- }
- #endif/* BSP_USING_TIM5_PWM_CH1 */
- #ifdef BSP_USING_TIM5_PWM_CH2
- if (channel == TIM_Channel_2)
- {
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
- GPIO_Init(GPIOA, &GPIO_InitStructure);
- }
- #endif/* BSP_USING_TIM5_PWM_CH2 */
- #ifdef BSP_USING_TIM5_PWM_CH3
- if (channel == TIM_Channel_3)
- {
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
- GPIO_Init(GPIOA, &GPIO_InitStructure);
- }
- #endif/* BSP_USING_TIM5_PWM_CH3 */
- #ifdef BSP_USING_TIM5_PWM_CH4
- if (channel == TIM_Channel_4)
- {
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
- GPIO_Init(GPIOA, &GPIO_InitStructure);
- }
- #endif/* BSP_USING_TIM5_PWM_CH4 */
- }
- #endif/* BSP_USING_TIM5_PWM */
- /* TIM6 and TIM7 don't support PWM Mode. */
- #ifdef BSP_USING_TIM8_PWM
- if (timx == TIM8)
- {
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
- /* I don't test it, because there is a 10M-PHY ETH port on my board,
- * which uses the following four pins.
- * You can try it on a board without a 10M-PHY ETH port. */
- #ifdef BSP_USING_TIM8_PWM_CH1
- if (channel == TIM_Channel_1)
- {
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
- GPIO_Init(GPIOC, &GPIO_InitStructure);
- }
- #endif/* BSP_USING_TIM8_PWM_CH1 */
- #ifdef BSP_USING_TIM8_PWM_CH2
- if (channel == TIM_Channel_2)
- {
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
- GPIO_Init(GPIOC, &GPIO_InitStructure);
- }
- #endif/* BSP_USING_TIM8_PWM_CH2 */
- #ifdef BSP_USING_TIM8_PWM_CH3
- if (channel == TIM_Channel_3)
- {
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
- GPIO_Init(GPIOC, &GPIO_InitStructure);
- }
- #endif/* BSP_USING_TIM8_PWM_CH3 */
- #ifdef BSP_USING_TIM8_PWM_CH4
- if (channel == TIM_Channel_4)
- {
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
- GPIO_Init(GPIOC, &GPIO_InitStructure);
- }
- #endif/* BSP_USING_TIM8_PWM_CH4 */
- }
- #endif/* BSP_USING_TIM8_PWM */
- #ifdef BSP_USING_TIM9_PWM
- if (timx == TIM9)
- {
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
- #ifdef BSP_USING_TIM9_PWM_CH1
- if (channel == TIM_Channel_1)
- {
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
- GPIO_Init(GPIOA, &GPIO_InitStructure);
- }
- #endif/* BSP_USING_TIM9_PWM_CH1 */
- #ifdef BSP_USING_TIM9_PWM_CH2
- if (channel == TIM_Channel_2)
- {
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
- GPIO_Init(GPIOA, &GPIO_InitStructure);
- }
- #endif/* BSP_USING_TIM9_PWM_CH2 */
- #ifdef BSP_USING_TIM9_PWM_CH3
- if (channel == TIM_Channel_3)
- {
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
- GPIO_Init(GPIOA, &GPIO_InitStructure);
- }
- #endif/* BSP_USING_TIM9_PWM_CH3 */
- #ifdef BSP_USING_TIM9_PWM_CH4
- if (channel == TIM_Channel_4)
- {
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
- GPIO_Init(GPIOC, &GPIO_InitStructure);
- }
- #endif/* BSP_USING_TIM9_PWM_CH4 */
- }
- #endif/* BSP_USING_TIM9_PWM */
- #ifdef BSP_USING_TIM10_PWM
- if (timx == TIM10)
- {
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
- #ifdef BSP_USING_TIM10_PWM_CH1
- if (channel == TIM_Channel_1)
- {
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
- GPIO_Init(GPIOB, &GPIO_InitStructure);
- }
- #endif/* BSP_USING_TIM10_PWM_CH1 */
- #ifdef BSP_USING_TIM10_PWM_CH2
- if (channel == TIM_Channel_2)
- {
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
- GPIO_Init(GPIOB, &GPIO_InitStructure);
- }
- #endif/* BSP_USING_TIM10_PWM_CH2 */
- #ifdef BSP_USING_TIM10_PWM_CH3
- if (channel == TIM_Channel_3)
- {
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
- GPIO_Init(GPIOC, &GPIO_InitStructure);
- }
- #endif/* BSP_USING_TIM10_PWM_CH3 */
- #ifdef BSP_USING_TIM10_PWM_CH4
- if (channel == TIM_Channel_4)
- {
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
- GPIO_Init(GPIOC, &GPIO_InitStructure);
- }
- #endif/* BSP_USING_TIM10_PWM_CH4 */
- }
- #endif/* BSP_USING_TIM10_PWM */
- }
- /*
- * channel = FLAG_NOT_INIT: the channel is not use.
- */
- struct rtdevice_pwm_device pwm_device_list[] =
- {
- #ifdef BSP_USING_TIM1_PWM
- {
- .periph = TIM1,
- .name = "pwm1",
- #ifdef BSP_USING_TIM1_PWM_CH1
- .channel[0] = TIM_Channel_1,
- #else
- .channel[0] = FLAG_NOT_INIT,
- #endif/* BSP_USING_TIM1_PWM_CH1 */
- #ifdef BSP_USING_TIM1_PWM_CH2
- .channel[1] = TIM_Channel_2,
- #else
- .channel[1] = FLAG_NOT_INIT,
- #endif/* BSP_USING_TIM1_PWM_CH2 */
- #ifdef BSP_USING_TIM1_PWM_CH3
- .channel[2] = TIM_Channel_3,
- #else
- .channel[2] = FLAG_NOT_INIT,
- #endif/* BSP_USING_TIM1_PWM_CH3 */
- #ifdef BSP_USING_TIM1_PWM_CH4
- .channel[3] = TIM_Channel_4,
- #else
- .channel[3] = FLAG_NOT_INIT,
- #endif/* BSP_USING_TIM1_PWM_CH4 */
- },
- #endif /* BSP_USING_TIM1_PWM */
- #ifdef BSP_USING_TIM2_PWM
- {
- .periph = TIM2,
- .name = "pwm2",
- #ifdef BSP_USING_TIM2_PWM_CH1
- .channel[0] = TIM_Channel_1,
- #else
- .channel[0] = FLAG_NOT_INIT,
- #endif/* BSP_USING_TIM2_PWM_CH1 */
- #ifdef BSP_USING_TIM2_PWM_CH2
- .channel[1] = TIM_Channel_2,
- #else
- .channel[1] = FLAG_NOT_INIT,
- #endif/* BSP_USING_TIM2_PWM_CH2 */
- #ifdef BSP_USING_TIM2_PWM_CH3
- .channel[2] = TIM_Channel_3,
- #else
- .channel[2] = FLAG_NOT_INIT,
- #endif/* BSP_USING_TIM2_PWM_CH3 */
- #ifdef BSP_USING_TIM2_PWM_CH4
- .channel[3] = TIM_Channel_4,
- #else
- .channel[3] = FLAG_NOT_INIT,
- #endif/* BSP_USING_TIM2_PWM_CH4 */
- },
- #endif /* BSP_USING_TIM2_PWM */
- #ifdef BSP_USING_TIM3_PWM
- {
- .periph = TIM3,
- .name = "pwm3",
- #ifdef BSP_USING_TIM3_PWM_CH1
- .channel[0] = TIM_Channel_1,
- #else
- .channel[0] = FLAG_NOT_INIT,
- #endif/* BSP_USING_TIM3_PWM_CH1 */
- #ifdef BSP_USING_TIM3_PWM_CH2
- .channel[1] = TIM_Channel_2,
- #else
- .channel[1] = FLAG_NOT_INIT,
- #endif/* BSP_USING_TIM3_PWM_CH2 */
- #ifdef BSP_USING_TIM3_PWM_CH3
- .channel[2] = TIM_Channel_3,
- #else
- .channel[2] = FLAG_NOT_INIT,
- #endif/* BSP_USING_TIM3_PWM_CH3 */
- #ifdef BSP_USING_TIM3_PWM_CH4
- .channel[3] = TIM_Channel_4,
- #else
- .channel[3] = FLAG_NOT_INIT,
- #endif/* BSP_USING_TIM3_PWM_CH4 */
- },
- #endif /* BSP_USING_TIM3_PWM */
- #ifdef BSP_USING_TIM4_PWM
- {
- .periph = TIM4,
- .name = "pwm4",
- #ifdef BSP_USING_TIM4_PWM_CH1
- .channel[0] = TIM_Channel_1,
- #else
- .channel[0] = FLAG_NOT_INIT,
- #endif/* BSP_USING_TIM4_PWM_CH1 */
- #ifdef BSP_USING_TIM4_PWM_CH2
- .channel[1] = TIM_Channel_2,
- #else
- .channel[1] = FLAG_NOT_INIT,
- #endif/* BSP_USING_TIM4_PWM_CH2 */
- #ifdef BSP_USING_TIM4_PWM_CH3
- .channel[2] = TIM_Channel_3,
- #else
- .channel[2] = FLAG_NOT_INIT,
- #endif/* BSP_USING_TIM4_PWM_CH3 */
- #ifdef BSP_USING_TIM4_PWM_CH4
- .channel[3] = TIM_Channel_4,
- #else
- .channel[3] = FLAG_NOT_INIT,
- #endif/* BSP_USING_TIM4_PWM_CH4 */
- },
- #endif /* BSP_USING_TIM4_PWM */
- #ifdef BSP_USING_TIM5_PWM
- {
- .periph = TIM5,
- .name = "pwm5",
- #ifdef BSP_USING_TIM5_PWM_CH1
- .channel[0] = TIM_Channel_1,
- #else
- .channel[0] = FLAG_NOT_INIT,
- #endif/* BSP_USING_TIM5_PWM_CH1 */
- #ifdef BSP_USING_TIM5_PWM_CH2
- .channel[1] = TIM_Channel_2,
- #else
- .channel[1] = FLAG_NOT_INIT,
- #endif/* BSP_USING_TIM5_PWM_CH2 */
- #ifdef BSP_USING_TIM5_PWM_CH3
- .channel[2] = TIM_Channel_3,
- #else
- .channel[2] = FLAG_NOT_INIT,
- #endif/* BSP_USING_TIM5_PWM_CH3 */
- #ifdef BSP_USING_TIM5_PWM_CH4
- .channel[3] = TIM_Channel_4,
- #else
- .channel[3] = FLAG_NOT_INIT,
- #endif/* BSP_USING_TIM5_PWM_CH4 */
- },
- #endif /* BSP_USING_TIM5_PWM */
- #ifdef BSP_USING_TIM8_PWM
- {
- .periph = TIM8,
- .name = "pwm8",
- #ifdef BSP_USING_TIM8_PWM_CH1
- .channel[0] = TIM_Channel_1,
- #else
- .channel[0] = FLAG_NOT_INIT,
- #endif/* BSP_USING_TIM8_PWM_CH1 */
- #ifdef BSP_USING_TIM8_PWM_CH2
- .channel[1] = TIM_Channel_2,
- #else
- .channel[1] = FLAG_NOT_INIT,
- #endif/* BSP_USING_TIM8_PWM_CH2 */
- #ifdef BSP_USING_TIM8_PWM_CH3
- .channel[2] = TIM_Channel_3,
- #else
- .channel[2] = FLAG_NOT_INIT,
- #endif/* BSP_USING_TIM8_PWM_CH3 */
- #ifdef BSP_USING_TIM8_PWM_CH4
- .channel[3] = TIM_Channel_4,
- #else
- .channel[3] = FLAG_NOT_INIT,
- #endif/* BSP_USING_TIM8_PWM_CH4 */
- },
- #endif /* BSP_USING_TIM8_PWM */
- #ifdef BSP_USING_TIM9_PWM
- {
- .periph = TIM9,
- .name = "pwm9",
- #ifdef BSP_USING_TIM9_PWM_CH1
- .channel[0] = TIM_Channel_1,
- #else
- .channel[0] = FLAG_NOT_INIT,
- #endif/* BSP_USING_TIM9_PWM_CH1 */
- #ifdef BSP_USING_TIM9_PWM_CH2
- .channel[1] = TIM_Channel_2,
- #else
- .channel[1] = FLAG_NOT_INIT,
- #endif/* BSP_USING_TIM9_PWM_CH2 */
- #ifdef BSP_USING_TIM9_PWM_CH3
- .channel[2] = TIM_Channel_3,
- #else
- .channel[2] = FLAG_NOT_INIT,
- #endif/* BSP_USING_TIM9_PWM_CH3 */
- #ifdef BSP_USING_TIM9_PWM_CH4
- .channel[3] = TIM_Channel_4,
- #else
- .channel[3] = FLAG_NOT_INIT,
- #endif/* BSP_USING_TIM9_PWM_CH4 */
- },
- #endif /* BSP_USING_TIM9_PWM */
- #ifdef BSP_USING_TIM10_PWM
- {
- .periph = TIM10,
- .name = "pwm10",
- #ifdef BSP_USING_TIM10_PWM_CH1
- .channel[0] = TIM_Channel_1,
- #else
- .channel[0] = FLAG_NOT_INIT,
- #endif/* BSP_USING_TIM10_PWM_CH1 */
- #ifdef BSP_USING_TIM10_PWM_CH2
- .channel[1] = TIM_Channel_2,
- #else
- .channel[1] = FLAG_NOT_INIT,
- #endif/* BSP_USING_TIM10_PWM_CH2 */
- #ifdef BSP_USING_TIM10_PWM_CH3
- .channel[2] = TIM_Channel_3,
- #else
- .channel[2] = FLAG_NOT_INIT,
- #endif/* BSP_USING_TIM10_PWM_CH3 */
- #ifdef BSP_USING_TIM10_PWM_CH4
- .channel[3] = TIM_Channel_4,
- #else
- .channel[3] = FLAG_NOT_INIT,
- #endif/* BSP_USING_TIM10_PWM_CH4 */
- },
- #endif /* BSP_USING_TIM10_PWM */
- };
- static rt_err_t ch32_pwm_device_enable(struct rt_device_pwm* device, struct rt_pwm_configuration* configuration, rt_bool_t enable)
- {
- struct rtdevice_pwm_device* pwm_device;
- rt_uint32_t channel_index;
- rt_uint16_t ccx_state;
- pwm_device = (struct rtdevice_pwm_device*)device;
- channel_index = configuration->channel;
- if (enable == RT_TRUE)
- {
- ccx_state = TIM_CCx_Enable;
- }
- else
- {
- ccx_state = TIM_CCx_Disable;
- }
- if (channel_index <= 4 && channel_index > 0)
- {
- if (pwm_device->channel[channel_index - 1] == FLAG_NOT_INIT)
- {
- return -RT_EINVAL;
- }
- TIM_CCxCmd(pwm_device->periph, pwm_device->channel[channel_index - 1], ccx_state);
- }
- else
- {
- return -RT_EINVAL;
- }
- TIM_Cmd(pwm_device->periph, ENABLE);
- return RT_EOK;
- }
- static rt_err_t ch32_pwm_device_get(struct rt_device_pwm* device, struct rt_pwm_configuration* configuration)
- {
- struct rtdevice_pwm_device* pwm_device;
- rt_uint32_t arr_counter, ccr_counter, prescaler, sample_freq;
- rt_uint32_t channel_index;
- rt_uint32_t tim_clock;
- pwm_device = (struct rtdevice_pwm_device*)device;
- tim_clock = ch32_tim_clock_get(pwm_device->periph);
- channel_index = configuration->channel;
- arr_counter = pwm_device->periph->ATRLR + 1;
- prescaler = pwm_device->periph->PSC + 1;
- sample_freq = (tim_clock / prescaler) / arr_counter;
- /* unit:ns */
- configuration->period = 1000000000 / sample_freq;
- if (channel_index == 1)
- {
- ccr_counter = pwm_device->periph->CH1CVR + 1;
- configuration->pulse = ((ccr_counter * 100) / arr_counter) * configuration->period / 100;
- }
- else if (channel_index == 2)
- {
- ccr_counter = pwm_device->periph->CH2CVR + 1;
- configuration->pulse = ((ccr_counter * 100) / arr_counter) * configuration->period / 100;
- }
- else if (channel_index == 3)
- {
- ccr_counter = pwm_device->periph->CH3CVR + 1;
- configuration->pulse = ((ccr_counter * 100) / arr_counter) * configuration->period / 100;
- }
- else if (channel_index == 4)
- {
- ccr_counter = pwm_device->periph->CH4CVR + 1;
- configuration->pulse = ((ccr_counter * 100) / arr_counter) * configuration->period / 100;
- }
- else
- {
- return -RT_EINVAL;
- }
- return RT_EOK;
- }
- static rt_err_t ch32_pwm_device_set(struct rt_device_pwm* device, struct rt_pwm_configuration* configuration)
- {
- struct rtdevice_pwm_device* pwm_device;
- rt_uint32_t arr_counter, ccr_counter, prescaler, sample_freq;
- rt_uint32_t channel_index;
- rt_uint32_t tim_clock;
- TIM_TimeBaseInitTypeDef TIM_TimeBaseInitType;
- TIM_OCInitTypeDef TIM_OCInitType;
- pwm_device = (struct rtdevice_pwm_device*)device;
- tim_clock = ch32_tim_clock_get(pwm_device->periph);
- channel_index = configuration->channel;
- /* change to freq, unit:Hz */
- sample_freq = 1000000000 / configuration->period;
- /* counter = (tim_clk / prescaler) / sample_freq */
- /* normally, tim_clk is not need div, if arr_counter over 65536, need div. */
- prescaler = 1;
- arr_counter = (tim_clock / prescaler) / sample_freq;
- if (arr_counter > MAX_COUNTER)
- {
- /* need div tim_clock
- * and round up the prescaler value.
- * (tim_clock >> 16) = tim_clock / 65536
- */
- if ((tim_clock >> 16) % sample_freq == 0)
- prescaler = (tim_clock >> 16) / sample_freq;
- else
- prescaler = (tim_clock >> 16) / sample_freq + 1;
- /* counter = (tim_clk / prescaler) / sample_freq */
- arr_counter = (tim_clock / prescaler) / sample_freq;
- }
- /* ccr_counter = duty cycle * arr_counter */
- ccr_counter = (configuration->pulse * 100 / configuration->period) * arr_counter / 100;
- /* check arr_counter > 1, cxx_counter > 1 */
- if (arr_counter < MIN_COUNTER)
- {
- arr_counter = MIN_COUNTER;
- }
- if (ccr_counter < MIN_PULSE)
- {
- ccr_counter = MIN_PULSE;
- }
- /* TMRe base configuration */
- TIM_TimeBaseStructInit(&TIM_TimeBaseInitType);
- TIM_TimeBaseInitType.TIM_Period = arr_counter - 1;
- TIM_TimeBaseInitType.TIM_Prescaler = prescaler - 1;
- TIM_TimeBaseInitType.TIM_ClockDivision = TIM_CKD_DIV1;
- TIM_TimeBaseInitType.TIM_CounterMode = TIM_CounterMode_Up;
- TIM_TimeBaseInit(pwm_device->periph, &TIM_TimeBaseInitType);
- TIM_OCStructInit(&TIM_OCInitType);
- TIM_OCInitType.TIM_OCMode = TIM_OCMode_PWM1;
- TIM_OCInitType.TIM_OutputState = TIM_OutputState_Enable;
- TIM_OCInitType.TIM_Pulse = ccr_counter - 1;
- TIM_OCInitType.TIM_OCPolarity = TIM_OCPolarity_High;
- if (channel_index == 1)
- {
- TIM_OC1Init(pwm_device->periph, &TIM_OCInitType);
- TIM_OC1PreloadConfig(pwm_device->periph, TIM_OCPreload_Disable);
- }
- else if (channel_index == 2)
- {
- TIM_OC2Init(pwm_device->periph, &TIM_OCInitType);
- TIM_OC2PreloadConfig(pwm_device->periph, TIM_OCPreload_Disable);
- }
- else if (channel_index == 3)
- {
- TIM_OC3Init(pwm_device->periph, &TIM_OCInitType);
- TIM_OC3PreloadConfig(pwm_device->periph, TIM_OCPreload_Disable);
- }
- else if (channel_index == 4)
- {
- TIM_OC4Init(pwm_device->periph, &TIM_OCInitType);
- TIM_OC4PreloadConfig(pwm_device->periph, TIM_OCPreload_Disable);
- }
- else
- {
- return -RT_EINVAL;
- }
- TIM_ARRPreloadConfig(pwm_device->periph, ENABLE);
- TIM_CtrlPWMOutputs(pwm_device->periph, ENABLE);
- return RT_EOK;
- }
- static rt_err_t drv_pwm_control(struct rt_device_pwm* device, int cmd, void* arg)
- {
- struct rt_pwm_configuration* configuration;
- configuration = (struct rt_pwm_configuration*)arg;
- switch (cmd)
- {
- case PWM_CMD_ENABLE:
- return ch32_pwm_device_enable(device, configuration, RT_TRUE);
- case PWM_CMD_DISABLE:
- return ch32_pwm_device_enable(device, configuration, RT_FALSE);
- case PWM_CMD_SET:
- return ch32_pwm_device_set(device, configuration);
- case PWM_CMD_GET:
- return ch32_pwm_device_get(device, configuration);
- default:
- return -RT_EINVAL;
- }
- }
- static struct rt_pwm_ops pwm_ops =
- {
- .control = drv_pwm_control
- };
- static int rt_hw_pwm_init(void)
- {
- int result = RT_EOK;
- int index = 0;
- int channel_index;
- for (index = 0; index < ITEM_NUM(pwm_device_list); index++)
- {
- ch32_tim_clock_init(pwm_device_list[index].periph);
- for (channel_index = 0; channel_index < sizeof(pwm_device_list[index].channel); channel_index++)
- {
- if (pwm_device_list[index].channel[channel_index] != FLAG_NOT_INIT)
- {
- ch32_pwm_io_init(pwm_device_list[index].periph, pwm_device_list[index].channel[channel_index]);
- }
- }
- if (rt_device_pwm_register(&pwm_device_list[index].parent, pwm_device_list[index].name, &pwm_ops, RT_NULL) == RT_EOK)
- {
- LOG_D("%s register success", pwm_device_list[index].name);
- }
- else
- {
- LOG_D("%s register failed", pwm_device_list[index].name);
- result = -RT_ERROR;
- }
- }
- return result;
- }
- INIT_BOARD_EXPORT(rt_hw_pwm_init);
- #endif /* BSP_USING_PWM */
|