drv_pwm.c 27 KB

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