drv_pwm.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628
  1. /*
  2. * Copyright (c) 2006-2022, 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. */
  11. #include <rtthread.h>
  12. #include <rtdevice.h>
  13. #include <drivers/rt_drv_pwm.h>
  14. #include <drivers/hwtimer.h>
  15. #include <board.h>
  16. #ifdef BSP_USING_PWM
  17. #define LOG_TAG "drv.pwm"
  18. #include <drv_log.h>
  19. #ifndef ITEM_NUM
  20. #define ITEM_NUM(items) sizeof(items) / sizeof(items[0])
  21. #endif
  22. #define MAX_COUNTER 65535
  23. #define MIN_COUNTER 2
  24. #define MIN_PULSE 2
  25. struct rtdevice_pwm_device
  26. {
  27. struct rt_device_pwm parent;
  28. TIM_TypeDef* periph;
  29. rt_uint8_t channel[4];
  30. char* name;
  31. };
  32. void ch32_tim_clock_init(TIM_TypeDef* timx)
  33. {
  34. if (timx == TIM1)
  35. {
  36. RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
  37. }
  38. if (timx == TIM2)
  39. {
  40. RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
  41. }
  42. if (timx == TIM3)
  43. {
  44. RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
  45. }
  46. if (timx == TIM4)
  47. {
  48. RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
  49. }
  50. }
  51. rt_uint32_t ch32_tim_clock_get(TIM_TypeDef* timx)
  52. {
  53. RCC_ClocksTypeDef RCC_Clocks;
  54. RCC_GetClocksFreq(&RCC_Clocks);
  55. /*tim1~4 all in HCLK*/
  56. return RCC_Clocks.HCLK_Frequency;
  57. }
  58. struct rt_hwtimer_info hwtimer_info1 =
  59. {
  60. .maxfreq = 1000000,
  61. .minfreq = 2000,
  62. .maxcnt = 0xFFFF,
  63. .cntmode = HWTIMER_CNTMODE_UP,
  64. };
  65. struct rt_hwtimer_info hwtimer_info2 =
  66. {
  67. .maxfreq = 1000000,
  68. .minfreq = 2000,
  69. .maxcnt = 0xFFFF,
  70. .cntmode = HWTIMER_CNTMODE_UP,
  71. };
  72. struct rt_hwtimer_info hwtimer_info3 =
  73. {
  74. .maxfreq = 1000000,
  75. .minfreq = 2000,
  76. .maxcnt = 0xFFFF,
  77. .cntmode = HWTIMER_CNTMODE_UP,
  78. };
  79. struct rt_hwtimer_info hwtimer_info4 =
  80. {
  81. .maxfreq = 1000000,
  82. .minfreq = 2000,
  83. .maxcnt = 0xFFFF,
  84. .cntmode = HWTIMER_CNTMODE_UP,
  85. };
  86. struct rt_hwtimer_info* ch32_hwtimer_info_config_get(TIM_TypeDef* timx)
  87. {
  88. struct rt_hwtimer_info* info = RT_NULL;
  89. if (timx == TIM1)
  90. {
  91. info = &hwtimer_info1;
  92. }
  93. else if (timx == TIM2)
  94. {
  95. info = &hwtimer_info2;
  96. }
  97. else if (timx == TIM3)
  98. {
  99. info = &hwtimer_info3;
  100. }
  101. else if (timx == TIM4)
  102. {
  103. info = &hwtimer_info4;
  104. }
  105. return info;
  106. }
  107. void ch32_pwm_io_init(TIM_TypeDef* timx, rt_uint8_t channel)
  108. {
  109. GPIO_InitTypeDef GPIO_InitStructure;
  110. if (timx == TIM1)
  111. {
  112. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
  113. if (channel == TIM_Channel_1)
  114. {
  115. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
  116. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  117. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  118. GPIO_Init(GPIOA, &GPIO_InitStructure);
  119. }
  120. if (channel == TIM_Channel_2)
  121. {
  122. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
  123. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  124. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  125. GPIO_Init(GPIOA, &GPIO_InitStructure);
  126. }
  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. if (channel == TIM_Channel_4)
  135. {
  136. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
  137. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  138. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  139. GPIO_Init(GPIOA, &GPIO_InitStructure);
  140. }
  141. }
  142. if (timx == TIM2)
  143. {
  144. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
  145. if (channel == TIM_Channel_1)
  146. {
  147. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
  148. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  149. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  150. GPIO_Init(GPIOA, &GPIO_InitStructure);
  151. }
  152. if (channel == TIM_Channel_2)
  153. {
  154. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
  155. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  156. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  157. GPIO_Init(GPIOA, &GPIO_InitStructure);
  158. }
  159. if (channel == TIM_Channel_3)
  160. {
  161. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
  162. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  163. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  164. GPIO_Init(GPIOA, &GPIO_InitStructure);
  165. }
  166. if (channel == TIM_Channel_4)
  167. {
  168. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
  169. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  170. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  171. GPIO_Init(GPIOA, &GPIO_InitStructure);
  172. }
  173. }
  174. if (timx == TIM3)
  175. {
  176. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
  177. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
  178. if (channel == TIM_Channel_1)
  179. {
  180. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
  181. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  182. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  183. GPIO_Init(GPIOA, &GPIO_InitStructure);
  184. }
  185. if (channel == TIM_Channel_2)
  186. {
  187. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
  188. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  189. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  190. GPIO_Init(GPIOA, &GPIO_InitStructure);
  191. }
  192. if (channel == TIM_Channel_3)
  193. {
  194. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
  195. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  196. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  197. GPIO_Init(GPIOB, &GPIO_InitStructure);
  198. }
  199. if (channel == TIM_Channel_4)
  200. {
  201. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
  202. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  203. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  204. GPIO_Init(GPIOB, &GPIO_InitStructure);
  205. }
  206. }
  207. if (timx == TIM4)
  208. {
  209. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
  210. if (channel == TIM_Channel_1)
  211. {
  212. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
  213. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  214. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  215. GPIO_Init(GPIOB, &GPIO_InitStructure);
  216. }
  217. if (channel == TIM_Channel_2)
  218. {
  219. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
  220. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  221. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  222. GPIO_Init(GPIOB, &GPIO_InitStructure);
  223. }
  224. if (channel == TIM_Channel_3)
  225. {
  226. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
  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. if (channel == TIM_Channel_4)
  232. {
  233. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
  234. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  235. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  236. GPIO_Init(GPIOB, &GPIO_InitStructure);
  237. }
  238. }
  239. }
  240. /*
  241. * channel = 0xFF: the channel is not use.
  242. */
  243. struct rtdevice_pwm_device pwm_device_list[] =
  244. {
  245. #ifdef BSP_USING_TIM1_PWM
  246. {
  247. .periph = TIM1,
  248. .name = "pwm1",
  249. #ifdef BSP_USING_TIM1_PWM_CH1
  250. .channel[0] = TIM_Channel_1,
  251. #else
  252. .channel[0] = 0xFF,
  253. #endif
  254. #ifdef BSP_USING_TIM1_PWM_CH2
  255. .channel[1] = TIM_Channel_2,
  256. #else
  257. .channel[1] = 0xFF,
  258. #endif
  259. #ifdef BSP_USING_TIM1_PWM_CH3
  260. .channel[2] = TIM_Channel_3,
  261. #else
  262. .channel[2] = 0xFF,
  263. #endif
  264. #ifdef BSP_USING_TIM1_PWM_CH4
  265. .channel[3] = TIM_Channel_4,
  266. #else
  267. .channel[3] = 0xFF,
  268. #endif
  269. },
  270. #endif /* BSP_USING_TIM1_PWM */
  271. #ifdef BSP_USING_TIM2_PWM
  272. {
  273. .periph = TIM2,
  274. .name = "pwm2",
  275. #ifdef BSP_USING_TIM2_PWM_CH1
  276. .channel[0] = TIM_Channel_1,
  277. #else
  278. .channel[0] = 0xFF,
  279. #endif
  280. #ifdef BSP_USING_TIM2_PWM_CH2
  281. .channel[1] = TIM_Channel_2,
  282. #else
  283. .channel[1] = 0xFF,
  284. #endif
  285. #ifdef BSP_USING_TIM2_PWM_CH3
  286. .channel[2] = TIM_Channel_3,
  287. #else
  288. .channel[2] = 0xFF,
  289. #endif
  290. #ifdef BSP_USING_TIM2_PWM_CH4
  291. .channel[3] = TIM_Channel_4,
  292. #else
  293. .channel[3] = 0xFF,
  294. #endif
  295. },
  296. #endif /* BSP_USING_TIM2_PWM */
  297. #ifdef BSP_USING_TIM3_PWM
  298. {
  299. .periph = TIM3,
  300. .name = "pwm3",
  301. #ifdef BSP_USING_TIM3_PWM_CH1
  302. .channel[0] = TIM_Channel_1,
  303. #else
  304. .channel[0] = 0xFF,
  305. #endif
  306. #ifdef BSP_USING_TIM3_PWM_CH2
  307. .channel[1] = TIM_Channel_2,
  308. #else
  309. .channel[1] = 0xFF,
  310. #endif
  311. #ifdef BSP_USING_TIM3_PWM_CH3
  312. .channel[2] = TIM_Channel_3,
  313. #else
  314. .channel[2] = 0xFF,
  315. #endif
  316. #ifdef BSP_USING_TIM3_PWM_CH4
  317. .channel[3] = TIM_Channel_4,
  318. #else
  319. .channel[3] = 0xFF,
  320. #endif
  321. },
  322. #endif /* BSP_USING_TIM3_PWM */
  323. #ifdef BSP_USING_TIM4_PWM
  324. {
  325. .periph = TIM4,
  326. .name = "pwm4",
  327. #ifdef BSP_USING_TIM4_PWM_CH1
  328. .channel[0] = TIM_Channel_1,
  329. #else
  330. .channel[0] = 0xFF,
  331. #endif
  332. #ifdef BSP_USING_TIM4_PWM_CH2
  333. .channel[1] = TIM_Channel_2,
  334. #else
  335. .channel[1] = 0xFF,
  336. #endif
  337. #ifdef BSP_USING_TIM4_PWM_CH3
  338. .channel[2] = TIM_Channel_3,
  339. #else
  340. .channel[2] = 0xFF,
  341. #endif
  342. #ifdef BSP_USING_TIM4_PWM_CH4
  343. .channel[3] = TIM_Channel_4,
  344. #else
  345. .channel[3] = 0xFF,
  346. #endif
  347. },
  348. #endif /* BSP_USING_TIM4_PWM */
  349. };
  350. static rt_err_t ch32_pwm_device_enable(struct rt_device_pwm* device, struct rt_pwm_configuration* configuration, rt_bool_t enable)
  351. {
  352. struct rtdevice_pwm_device* pwm_device;
  353. rt_uint32_t channel_index;
  354. rt_uint16_t ccx_state;
  355. pwm_device = (struct rtdevice_pwm_device*)device;
  356. channel_index = configuration->channel;
  357. if (enable == RT_TRUE)
  358. {
  359. ccx_state = TIM_CCx_Enable;
  360. }
  361. else
  362. {
  363. ccx_state = TIM_CCx_Disable;
  364. }
  365. if (channel_index <= 4 && channel_index > 0)
  366. {
  367. if (pwm_device->channel[channel_index - 1] == 0xFF)
  368. {
  369. return RT_EINVAL;
  370. }
  371. TIM_CCxCmd(pwm_device->periph, pwm_device->channel[channel_index - 1], ccx_state);
  372. }
  373. else
  374. {
  375. return RT_EINVAL;
  376. }
  377. TIM_Cmd(pwm_device->periph, ENABLE);
  378. return RT_EOK;
  379. }
  380. static rt_err_t ch32_pwm_device_get(struct rt_device_pwm* device, struct rt_pwm_configuration* configuration)
  381. {
  382. struct rtdevice_pwm_device* pwm_device;
  383. rt_uint32_t arr_counter, ccr_counter, prescaler, sample_freq;
  384. rt_uint32_t channel_index;
  385. rt_uint32_t tim_clock;
  386. pwm_device = (struct rtdevice_pwm_device*)device;
  387. tim_clock = ch32_tim_clock_get(pwm_device->periph);
  388. channel_index = configuration->channel;
  389. arr_counter = pwm_device->periph->ATRLR + 1;
  390. prescaler = pwm_device->periph->PSC + 1;
  391. sample_freq = (tim_clock / prescaler) / arr_counter;
  392. /* unit:ns */
  393. configuration->period = 1000000000 / sample_freq;
  394. if (channel_index == 1)
  395. {
  396. ccr_counter = pwm_device->periph->CH1CVR + 1;
  397. configuration->pulse = ((ccr_counter * 100) / arr_counter) * configuration->period / 100;
  398. }
  399. else if (channel_index == 2)
  400. {
  401. ccr_counter = pwm_device->periph->CH2CVR + 1;
  402. configuration->pulse = ((ccr_counter * 100) / arr_counter) * configuration->period / 100;
  403. }
  404. else if (channel_index == 3)
  405. {
  406. ccr_counter = pwm_device->periph->CH3CVR + 1;
  407. configuration->pulse = ((ccr_counter * 100) / arr_counter) * configuration->period / 100;
  408. }
  409. else if (channel_index == 4)
  410. {
  411. ccr_counter = pwm_device->periph->CH4CVR + 1;
  412. configuration->pulse = ((ccr_counter * 100) / arr_counter) * configuration->period / 100;
  413. }
  414. else
  415. {
  416. return RT_EINVAL;
  417. }
  418. return RT_EOK;
  419. }
  420. static rt_err_t ch32_pwm_device_set(struct rt_device_pwm* device, struct rt_pwm_configuration* configuration)
  421. {
  422. struct rtdevice_pwm_device* pwm_device;
  423. rt_uint32_t arr_counter, ccr_counter, prescaler, sample_freq;
  424. rt_uint32_t channel_index;
  425. rt_uint32_t tim_clock;
  426. TIM_TimeBaseInitTypeDef TIM_TimeBaseInitType;
  427. TIM_OCInitTypeDef TIM_OCInitType;
  428. pwm_device = (struct rtdevice_pwm_device*)device;
  429. tim_clock = ch32_tim_clock_get(pwm_device->periph);
  430. channel_index = configuration->channel;
  431. /* change to freq, unit:Hz */
  432. sample_freq = 1000000000 / configuration->period;
  433. /* counter = (tim_clk / prescaler) / sample_freq */
  434. /* normally, tim_clk is not need div, if arr_counter over 65536, need div. */
  435. prescaler = 1;
  436. arr_counter = (tim_clock / prescaler) / sample_freq;
  437. if (arr_counter > MAX_COUNTER)
  438. {
  439. /* need div tim_clock
  440. * and round up the prescaler value.
  441. * (tim_clock >> 16) = tim_clock / 65536
  442. */
  443. if ((tim_clock >> 16) % sample_freq == 0)
  444. prescaler = (tim_clock >> 16) / sample_freq;
  445. else
  446. prescaler = (tim_clock >> 16) / sample_freq + 1;
  447. /* counter = (tim_clk / prescaler) / sample_freq */
  448. arr_counter = (tim_clock / prescaler) / sample_freq;
  449. }
  450. /* ccr_counter = duty cycle * arr_counter */
  451. ccr_counter = (configuration->pulse * 100 / configuration->period) * arr_counter / 100;
  452. /* check arr_counter > 1, cxx_counter > 1 */
  453. if (arr_counter < MIN_COUNTER)
  454. {
  455. arr_counter = MIN_COUNTER;
  456. }
  457. if (ccr_counter < MIN_PULSE)
  458. {
  459. ccr_counter = MIN_PULSE;
  460. }
  461. /* TMRe base configuration */
  462. TIM_TimeBaseStructInit(&TIM_TimeBaseInitType);
  463. TIM_TimeBaseInitType.TIM_Period = arr_counter - 1;
  464. TIM_TimeBaseInitType.TIM_Prescaler = prescaler - 1;
  465. TIM_TimeBaseInitType.TIM_ClockDivision = TIM_CKD_DIV1;
  466. TIM_TimeBaseInitType.TIM_CounterMode = TIM_CounterMode_Up;
  467. TIM_TimeBaseInit(pwm_device->periph, &TIM_TimeBaseInitType);
  468. TIM_OCStructInit(&TIM_OCInitType);
  469. TIM_OCInitType.TIM_OCMode = TIM_OCMode_PWM1;
  470. TIM_OCInitType.TIM_OutputState = TIM_OutputState_Enable;
  471. TIM_OCInitType.TIM_Pulse = ccr_counter - 1;
  472. TIM_OCInitType.TIM_OCPolarity = TIM_OCPolarity_High;
  473. if (channel_index == 1)
  474. {
  475. TIM_OC1Init(pwm_device->periph, &TIM_OCInitType);
  476. TIM_OC1PreloadConfig(pwm_device->periph, TIM_OCPreload_Disable);
  477. }
  478. else if (channel_index == 2)
  479. {
  480. TIM_OC2Init(pwm_device->periph, &TIM_OCInitType);
  481. TIM_OC2PreloadConfig(pwm_device->periph, TIM_OCPreload_Disable);
  482. }
  483. else if (channel_index == 3)
  484. {
  485. TIM_OC3Init(pwm_device->periph, &TIM_OCInitType);
  486. TIM_OC3PreloadConfig(pwm_device->periph, TIM_OCPreload_Disable);
  487. }
  488. else if (channel_index == 4)
  489. {
  490. TIM_OC4Init(pwm_device->periph, &TIM_OCInitType);
  491. TIM_OC4PreloadConfig(pwm_device->periph, TIM_OCPreload_Disable);
  492. }
  493. else
  494. {
  495. return RT_EINVAL;
  496. }
  497. TIM_ARRPreloadConfig(pwm_device->periph, ENABLE);
  498. TIM_CtrlPWMOutputs(pwm_device->periph, ENABLE);
  499. return RT_EOK;
  500. }
  501. static rt_err_t drv_pwm_control(struct rt_device_pwm* device, int cmd, void* arg)
  502. {
  503. struct rt_pwm_configuration* configuration;
  504. configuration = (struct rt_pwm_configuration*)arg;
  505. switch (cmd)
  506. {
  507. case PWM_CMD_ENABLE:
  508. return ch32_pwm_device_enable(device, configuration, RT_TRUE);
  509. case PWM_CMD_DISABLE:
  510. return ch32_pwm_device_enable(device, configuration, RT_FALSE);
  511. case PWM_CMD_SET:
  512. return ch32_pwm_device_set(device, configuration);
  513. case PWM_CMD_GET:
  514. return ch32_pwm_device_get(device, configuration);
  515. default:
  516. return RT_EINVAL;
  517. }
  518. }
  519. static struct rt_pwm_ops pwm_ops =
  520. {
  521. .control = drv_pwm_control
  522. };
  523. static int rt_hw_pwm_init(void)
  524. {
  525. int result = RT_EOK;
  526. int index = 0;
  527. int channel_index;
  528. for (index = 0; index < ITEM_NUM(pwm_device_list); index++)
  529. {
  530. ch32_tim_clock_init(pwm_device_list[index].periph);
  531. for (channel_index = 0; channel_index < sizeof(pwm_device_list[index].channel); channel_index++)
  532. {
  533. if (pwm_device_list[index].channel[channel_index] != 0xFF)
  534. {
  535. ch32_pwm_io_init(pwm_device_list[index].periph, pwm_device_list[index].channel[channel_index]);
  536. }
  537. }
  538. if (rt_device_pwm_register(&pwm_device_list[index].parent, pwm_device_list[index].name, &pwm_ops, RT_NULL) == RT_EOK)
  539. {
  540. LOG_D("%s register success", pwm_device_list[index].name);
  541. }
  542. else
  543. {
  544. LOG_D("%s register failed", pwm_device_list[index].name);
  545. result = -RT_ERROR;
  546. }
  547. }
  548. return result;
  549. }
  550. INIT_BOARD_EXPORT(rt_hw_pwm_init);
  551. #endif /* BSP_USING_PWM */