drv_pwm_tmra.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476
  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. * 2022-06-27 lianghongquan first version
  9. */
  10. #include <board.h>
  11. #if (defined RT_USING_PWM) && (defined BSP_USING_PWM_TMRA)
  12. #include "drv_config.h"
  13. #include <drivers/rt_drv_pwm.h>
  14. //#define DRV_DEBUG
  15. #define LOG_TAG "drv.pwm.tmra"
  16. #include <drv_log.h>
  17. #if (!(defined(BSP_USING_PWM_TMRA_1) || defined(BSP_USING_PWM_TMRA_2) || \
  18. defined(BSP_USING_PWM_TMRA_3) || defined(BSP_USING_PWM_TMRA_4) || \
  19. defined(BSP_USING_PWM_TMRA_5) || defined(BSP_USING_PWM_TMRA_6)))
  20. #error "Please define at least one BSP_USING_PWM_TMRA_x"
  21. #endif
  22. enum
  23. {
  24. #ifdef BSP_USING_PWM_TMRA_1
  25. PWM_TMRA_1_INDEX,
  26. #endif
  27. #ifdef BSP_USING_PWM_TMRA_2
  28. PWM_TMRA_2_INDEX,
  29. #endif
  30. #ifdef BSP_USING_PWM_TMRA_3
  31. PWM_TMRA_3_INDEX,
  32. #endif
  33. #ifdef BSP_USING_PWM_TMRA_4
  34. PWM_TMRA_4_INDEX,
  35. #endif
  36. #ifdef BSP_USING_PWM_TMRA_5
  37. PWM_TMRA_5_INDEX,
  38. #endif
  39. #ifdef BSP_USING_PWM_TMRA_6
  40. PWM_TMRA_6_INDEX,
  41. #endif
  42. };
  43. struct hc32_pwm_tmra
  44. {
  45. struct rt_device_pwm pwm_device;
  46. CM_TMRA_TypeDef *instance;
  47. stc_tmra_init_t stcTmraInit;
  48. stc_tmra_pwm_init_t stcPwmInit;
  49. rt_uint8_t channel;
  50. char *name;
  51. };
  52. static struct hc32_pwm_tmra g_pwm_dev_array[] =
  53. {
  54. #ifdef BSP_USING_PWM_TMRA_1
  55. PWM_TMRA_1_CONFIG,
  56. #endif
  57. #ifdef BSP_USING_PWM_TMRA_2
  58. PWM_TMRA_2_CONFIG,
  59. #endif
  60. #ifdef BSP_USING_PWM_TMRA_3
  61. PWM_TMRA_3_CONFIG,
  62. #endif
  63. #ifdef BSP_USING_PWM_TMRA_4
  64. PWM_TMRA_4_CONFIG,
  65. #endif
  66. #ifdef BSP_USING_PWM_TMRA_5
  67. PWM_TMRA_5_CONFIG,
  68. #endif
  69. #ifdef BSP_USING_PWM_TMRA_6
  70. PWM_TMRA_6_CONFIG,
  71. #endif
  72. };
  73. static rt_uint32_t get_tmra_clk_freq_not_div(CM_TMRA_TypeDef *TMRAx)
  74. {
  75. stc_clock_freq_t stcClockFreq;
  76. CLK_GetClockFreq(&stcClockFreq);
  77. return stcClockFreq.u32Pclk1Freq;
  78. }
  79. static rt_uint32_t get_tmra_clk_freq(CM_TMRA_TypeDef *TMRAx)
  80. {
  81. rt_uint32_t u32clkFreq;
  82. uint16_t u16Div;
  83. //
  84. u32clkFreq = get_tmra_clk_freq_not_div(TMRAx);
  85. u16Div = READ_REG16(TMRAx->BCSTR) & TMRA_BCSTR_CKDIV;
  86. switch (u16Div)
  87. {
  88. case (TMRA_CLK_DIV2):
  89. u32clkFreq /= 2;
  90. break;
  91. case (TMRA_CLK_DIV4):
  92. u32clkFreq /= 4;
  93. break;
  94. case (TMRA_CLK_DIV8):
  95. u32clkFreq /= 8;
  96. break;
  97. case (TMRA_CLK_DIV16):
  98. u32clkFreq /= 16;
  99. break;
  100. case (TMRA_CLK_DIV32):
  101. u32clkFreq /= 32;
  102. break;
  103. case (TMRA_CLK_DIV64):
  104. u32clkFreq /= 64;
  105. break;
  106. case (TMRA_CLK_DIV128):
  107. u32clkFreq /= 128;
  108. break;
  109. case (TMRA_CLK_DIV256):
  110. u32clkFreq /= 256;
  111. break;
  112. case (TMRA_CLK_DIV512):
  113. u32clkFreq /= 512;
  114. break;
  115. case (TMRA_CLK_DIV1024):
  116. u32clkFreq /= 1024;
  117. break;
  118. case (TMRA_CLK_DIV1):
  119. default:
  120. break;
  121. }
  122. return u32clkFreq;
  123. }
  124. static rt_err_t drv_pwm_control(struct rt_device_pwm *device, int cmd, void *arg);
  125. static struct rt_pwm_ops drv_ops =
  126. {
  127. drv_pwm_control
  128. };
  129. static rt_err_t drv_pwm_enable(CM_TMRA_TypeDef *TMRAx, struct rt_pwm_configuration *configuration, rt_bool_t enable)
  130. {
  131. if (RT_TRUE == enable) {TMRA_PWM_OutputCmd(TMRAx, configuration->channel, ENABLE);}
  132. else {TMRA_PWM_OutputCmd(TMRAx, configuration->channel, DISABLE);}
  133. return RT_EOK;
  134. }
  135. static rt_err_t drv_pwm_get(CM_TMRA_TypeDef *TMRAx, struct rt_pwm_configuration *configuration)
  136. {
  137. rt_uint32_t u32clkFreq;
  138. rt_uint64_t u64clk_ns;
  139. u32clkFreq = get_tmra_clk_freq(TMRAx);
  140. u64clk_ns = (rt_uint64_t)1000000000ul / u32clkFreq;
  141. configuration->period = u64clk_ns * TMRA_GetPeriodValue(TMRAx);
  142. configuration->pulse = u64clk_ns * TMRA_GetCompareValue(TMRAx, configuration->channel);
  143. return RT_EOK;
  144. }
  145. static rt_err_t drv_pwm_set(CM_TMRA_TypeDef *TMRAx, struct rt_pwm_configuration *configuration)
  146. {
  147. rt_uint32_t u32clkFreq;
  148. rt_uint64_t u64clk_ns;
  149. rt_uint64_t u64val;
  150. u32clkFreq = get_tmra_clk_freq(TMRAx);
  151. u64clk_ns = (rt_uint64_t)1000000000ul / u32clkFreq;
  152. u64val = (rt_uint64_t)configuration->period / u64clk_ns;
  153. if ((configuration->period <= u64clk_ns) || (u64val > 0xFFFF))
  154. {
  155. /* clk not match, need change div */
  156. uint32_t div_bit;
  157. u32clkFreq = get_tmra_clk_freq_not_div(TMRAx);
  158. u64clk_ns = (rt_uint64_t)1000000000ul / u32clkFreq;
  159. u64val = (rt_uint64_t)configuration->period / u64clk_ns;
  160. for (div_bit=0; div_bit<= 10; div_bit++)
  161. {
  162. if (u64val < 0xFFFF) break;
  163. u64val /= 2;
  164. }
  165. if (div_bit > 10) return -RT_ERROR;
  166. TMRA_SetClockDiv(TMRAx, div_bit << TMRA_BCSTR_CKDIV_POS);
  167. u32clkFreq = get_tmra_clk_freq(TMRAx);
  168. u64clk_ns = (rt_uint64_t)1000000000ul / u32clkFreq;
  169. }
  170. TMRA_SetPeriodValue(TMRAx, configuration->period / u64clk_ns);
  171. TMRA_SetCompareValue(TMRAx, configuration->channel, configuration->pulse / u64clk_ns);
  172. return RT_EOK;
  173. }
  174. static rt_err_t drv_pwm_set_period(CM_TMRA_TypeDef *TMRAx, struct rt_pwm_configuration *configuration)
  175. {
  176. rt_uint32_t u32clkFreq;
  177. rt_uint64_t u64clk_ns;
  178. rt_uint64_t u64val;
  179. u32clkFreq = get_tmra_clk_freq(TMRAx);
  180. u64clk_ns = (rt_uint64_t)1000000000ul / u32clkFreq;
  181. u64val = (rt_uint64_t)configuration->period / u64clk_ns;
  182. if ((configuration->period <= u64clk_ns) || (u64val > 0xFFFF))
  183. {
  184. /* clk not match, need change div */
  185. uint32_t div_bit;
  186. u32clkFreq = get_tmra_clk_freq_not_div(TMRAx);
  187. u64clk_ns = (rt_uint64_t)1000000000ul / u32clkFreq;
  188. u64val = (rt_uint64_t)configuration->period / u64clk_ns;
  189. for (div_bit=0; div_bit<= 10; div_bit++)
  190. {
  191. if (u64val < 0xFFFF) break;
  192. u64val /= 2;
  193. }
  194. if (div_bit > 10) return -RT_ERROR;
  195. TMRA_SetClockDiv(TMRAx, div_bit << TMRA_BCSTR_CKDIV_POS);
  196. u32clkFreq = get_tmra_clk_freq(TMRAx);
  197. u64clk_ns = (rt_uint64_t)1000000000ul / u32clkFreq;
  198. }
  199. TMRA_SetPeriodValue(TMRAx, configuration->period / u64clk_ns);
  200. return RT_EOK;
  201. }
  202. static rt_err_t drv_pwm_set_pulse(CM_TMRA_TypeDef *TMRAx, struct rt_pwm_configuration *configuration)
  203. {
  204. rt_uint32_t u32clkFreq;
  205. rt_uint64_t u64clk_ns;
  206. u32clkFreq = get_tmra_clk_freq(TMRAx);
  207. u64clk_ns = (rt_uint64_t)1000000000ul / u32clkFreq;
  208. TMRA_SetCompareValue(TMRAx, configuration->channel, configuration->pulse / u64clk_ns);
  209. return RT_EOK;
  210. }
  211. static rt_err_t drv_pwm_control(struct rt_device_pwm *device, int cmd, void *arg)
  212. {
  213. struct rt_pwm_configuration *configuration = (struct rt_pwm_configuration *)arg;
  214. struct hc32_pwm_tmra *pwm;
  215. pwm = rt_container_of(device, struct hc32_pwm_tmra, pwm_device);
  216. CM_TMRA_TypeDef *TMRAx = pwm->instance;
  217. switch (cmd)
  218. {
  219. case PWMN_CMD_ENABLE:
  220. configuration->complementary = RT_TRUE;
  221. case PWM_CMD_ENABLE:
  222. return drv_pwm_enable(TMRAx, configuration, RT_TRUE);
  223. case PWMN_CMD_DISABLE:
  224. configuration->complementary = RT_FALSE;
  225. case PWM_CMD_DISABLE:
  226. return drv_pwm_enable(TMRAx, configuration, RT_FALSE);
  227. case PWM_CMD_SET:
  228. return drv_pwm_set(TMRAx, configuration);
  229. case PWM_CMD_GET:
  230. return drv_pwm_get(TMRAx, configuration);
  231. case PWM_CMD_SET_PERIOD:
  232. return drv_pwm_set_period(TMRAx, configuration);
  233. case PWM_CMD_SET_PULSE:
  234. return drv_pwm_set_pulse(TMRAx, configuration);
  235. default:
  236. return -RT_EINVAL;
  237. }
  238. }
  239. static rt_err_t _pwm_tmra_init(struct hc32_pwm_tmra *device)
  240. {
  241. CM_TMRA_TypeDef *TMRAx;
  242. uint32_t i;
  243. RT_ASSERT(device != RT_NULL);
  244. TMRAx = device->instance;
  245. TMRA_Init(TMRAx, &device->stcTmraInit);
  246. for (i=0; i<8; i++)
  247. {
  248. if ((device->channel >> i) & 0x01)
  249. {
  250. TMRA_PWM_Init(TMRAx, i, &device->stcPwmInit);
  251. }
  252. }
  253. TMRA_Start(TMRAx);
  254. return RT_EOK;
  255. }
  256. static void pwm_get_channel(void)
  257. {
  258. #ifdef BSP_USING_PWM_TMRA_1
  259. #ifdef BSP_USING_PWM_TMRA_1_CH1
  260. g_pwm_dev_array[PWM_TMRA_1_INDEX].channel |= 1 << 0;
  261. #endif
  262. #ifdef BSP_USING_PWM_TMRA_1_CH2
  263. g_pwm_dev_array[PWM_TMRA_1_INDEX].channel |= 1 << 1;
  264. #endif
  265. #ifdef BSP_USING_PWM_TMRA_1_CH3
  266. g_pwm_dev_array[PWM_TMRA_1_INDEX].channel |= 1 << 2;
  267. #endif
  268. #ifdef BSP_USING_PWM_TMRA_1_CH4
  269. g_pwm_dev_array[PWM_TMRA_1_INDEX].channel |= 1 << 3;
  270. #endif
  271. #ifdef BSP_USING_PWM_TMRA_1_CH5
  272. g_pwm_dev_array[PWM_TMRA_1_INDEX].channel |= 1 << 4;
  273. #endif
  274. #ifdef BSP_USING_PWM_TMRA_1_CH6
  275. g_pwm_dev_array[PWM_TMRA_1_INDEX].channel |= 1 << 5;
  276. #endif
  277. #ifdef BSP_USING_PWM_TMRA_1_CH7
  278. g_pwm_dev_array[PWM_TMRA_1_INDEX].channel |= 1 << 6;
  279. #endif
  280. #ifdef BSP_USING_PWM_TMRA_1_CH8
  281. g_pwm_dev_array[PWM_TMRA_1_INDEX].channel |= 1 << 7;
  282. #endif
  283. #endif
  284. #ifdef BSP_USING_PWM_TMRA_2
  285. #ifdef BSP_USING_PWM_TMRA_2_CH1
  286. g_pwm_dev_array[PWM_TMRA_2_INDEX].channel |= 1 << 0;
  287. #endif
  288. #ifdef BSP_USING_PWM_TMRA_2_CH2
  289. g_pwm_dev_array[PWM_TMRA_2_INDEX].channel |= 1 << 1;
  290. #endif
  291. #ifdef BSP_USING_PWM_TMRA_2_CH3
  292. g_pwm_dev_array[PWM_TMRA_2_INDEX].channel |= 1 << 2;
  293. #endif
  294. #ifdef BSP_USING_PWM_TMRA_2_CH4
  295. g_pwm_dev_array[PWM_TMRA_2_INDEX].channel |= 1 << 3;
  296. #endif
  297. #ifdef BSP_USING_PWM_TMRA_2_CH5
  298. g_pwm_dev_array[PWM_TMRA_2_INDEX].channel |= 1 << 4;
  299. #endif
  300. #ifdef BSP_USING_PWM_TMRA_2_CH6
  301. g_pwm_dev_array[PWM_TMRA_2_INDEX].channel |= 1 << 5;
  302. #endif
  303. #ifdef BSP_USING_PWM_TMRA_2_CH7
  304. g_pwm_dev_array[PWM_TMRA_2_INDEX].channel |= 1 << 6;
  305. #endif
  306. #ifdef BSP_USING_PWM_TMRA_2_CH8
  307. g_pwm_dev_array[PWM_TMRA_2_INDEX].channel |= 1 << 7;
  308. #endif
  309. #endif
  310. #ifdef BSP_USING_PWM_TMRA_3
  311. #ifdef BSP_USING_PWM_TMRA_3_CH1
  312. g_pwm_dev_array[PWM_TMRA_3_INDEX].channel |= 1 << 0;
  313. #endif
  314. #ifdef BSP_USING_PWM_TMRA_3_CH2
  315. g_pwm_dev_array[PWM_TMRA_3_INDEX].channel |= 1 << 1;
  316. #endif
  317. #ifdef BSP_USING_PWM_TMRA_3_CH3
  318. g_pwm_dev_array[PWM_TMRA_3_INDEX].channel |= 1 << 2;
  319. #endif
  320. #ifdef BSP_USING_PWM_TMRA_3_CH4
  321. g_pwm_dev_array[PWM_TMRA_3_INDEX].channel |= 1 << 3;
  322. #endif
  323. #ifdef BSP_USING_PWM_TMRA_3_CH5
  324. g_pwm_dev_array[PWM_TMRA_3_INDEX].channel |= 1 << 4;
  325. #endif
  326. #ifdef BSP_USING_PWM_TMRA_3_CH6
  327. g_pwm_dev_array[PWM_TMRA_3_INDEX].channel |= 1 << 5;
  328. #endif
  329. #ifdef BSP_USING_PWM_TMRA_3_CH7
  330. g_pwm_dev_array[PWM_TMRA_3_INDEX].channel |= 1 << 6;
  331. #endif
  332. #ifdef BSP_USING_PWM_TMRA_3_CH8
  333. g_pwm_dev_array[PWM_TMRA_3_INDEX].channel |= 1 << 7;
  334. #endif
  335. #endif
  336. #ifdef BSP_USING_PWM_TMRA_4
  337. #ifdef BSP_USING_PWM_TMRA_4_CH1
  338. g_pwm_dev_array[PWM_TMRA_4_INDEX].channel |= 1 << 0;
  339. #endif
  340. #ifdef BSP_USING_PWM_TMRA_4_CH2
  341. g_pwm_dev_array[PWM_TMRA_4_INDEX].channel |= 1 << 1;
  342. #endif
  343. #ifdef BSP_USING_PWM_TMRA_4_CH3
  344. g_pwm_dev_array[PWM_TMRA_4_INDEX].channel |= 1 << 2;
  345. #endif
  346. #ifdef BSP_USING_PWM_TMRA_4_CH4
  347. g_pwm_dev_array[PWM_TMRA_4_INDEX].channel |= 1 << 3;
  348. #endif
  349. #ifdef BSP_USING_PWM_TMRA_4_CH5
  350. g_pwm_dev_array[PWM_TMRA_4_INDEX].channel |= 1 << 4;
  351. #endif
  352. #ifdef BSP_USING_PWM_TMRA_4_CH6
  353. g_pwm_dev_array[PWM_TMRA_4_INDEX].channel |= 1 << 5;
  354. #endif
  355. #ifdef BSP_USING_PWM_TMRA_4_CH7
  356. g_pwm_dev_array[PWM_TMRA_4_INDEX].channel |= 1 << 6;
  357. #endif
  358. #ifdef BSP_USING_PWM_TMRA_4_CH8
  359. g_pwm_dev_array[PWM_TMRA_4_INDEX].channel |= 1 << 7;
  360. #endif
  361. #endif
  362. #ifdef BSP_USING_PWM_TMRA_5
  363. #ifdef BSP_USING_PWM_TMRA_5_CH1
  364. g_pwm_dev_array[PWM_TMRA_5_INDEX].channel |= 1 << 0;
  365. #endif
  366. #ifdef BSP_USING_PWM_TMRA_5_CH2
  367. g_pwm_dev_array[PWM_TMRA_5_INDEX].channel |= 1 << 1;
  368. #endif
  369. #ifdef BSP_USING_PWM_TMRA_5_CH3
  370. g_pwm_dev_array[PWM_TMRA_5_INDEX].channel |= 1 << 2;
  371. #endif
  372. #ifdef BSP_USING_PWM_TMRA_5_CH4
  373. g_pwm_dev_array[PWM_TMRA_5_INDEX].channel |= 1 << 3;
  374. #endif
  375. #ifdef BSP_USING_PWM_TMRA_5_CH5
  376. g_pwm_dev_array[PWM_TMRA_5_INDEX].channel |= 1 << 4;
  377. #endif
  378. #ifdef BSP_USING_PWM_TMRA_5_CH6
  379. g_pwm_dev_array[PWM_TMRA_5_INDEX].channel |= 1 << 5;
  380. #endif
  381. #ifdef BSP_USING_PWM_TMRA_5_CH7
  382. g_pwm_dev_array[PWM_TMRA_5_INDEX].channel |= 1 << 6;
  383. #endif
  384. #ifdef BSP_USING_PWM_TMRA_5_CH8
  385. g_pwm_dev_array[PWM_TMRA_5_INDEX].channel |= 1 << 7;
  386. #endif
  387. #endif
  388. #ifdef BSP_USING_PWM_TMRA_6
  389. #ifdef BSP_USING_PWM_TMRA_6_CH1
  390. g_pwm_dev_array[PWM_TMRA_6_INDEX].channel |= 1 << 0;
  391. #endif
  392. #ifdef BSP_USING_PWM_TMRA_6_CH2
  393. g_pwm_dev_array[PWM_TMRA_6_INDEX].channel |= 1 << 1;
  394. #endif
  395. #ifdef BSP_USING_PWM_TMRA_6_CH3
  396. g_pwm_dev_array[PWM_TMRA_6_INDEX].channel |= 1 << 2;
  397. #endif
  398. #ifdef BSP_USING_PWM_TMRA_6_CH4
  399. g_pwm_dev_array[PWM_TMRA_6_INDEX].channel |= 1 << 3;
  400. #endif
  401. #ifdef BSP_USING_PWM_TMRA_6_CH5
  402. g_pwm_dev_array[PWM_TMRA_6_INDEX].channel |= 1 << 4;
  403. #endif
  404. #ifdef BSP_USING_PWM_TMRA_6_CH6
  405. g_pwm_dev_array[PWM_TMRA_6_INDEX].channel |= 1 << 5;
  406. #endif
  407. #ifdef BSP_USING_PWM_TMRA_6_CH7
  408. g_pwm_dev_array[PWM_TMRA_6_INDEX].channel |= 1 << 6;
  409. #endif
  410. #ifdef BSP_USING_PWM_TMRA_6_CH8
  411. g_pwm_dev_array[PWM_TMRA_6_INDEX].channel |= 1 << 7;
  412. #endif
  413. #endif
  414. }
  415. static void _enable_periph_clk(void)
  416. {
  417. #ifdef BSP_USING_PWM_TMRA_1
  418. FCG_Fcg2PeriphClockCmd(FCG2_PERIPH_TMRA_1, ENABLE);
  419. #endif
  420. #ifdef BSP_USING_PWM_TMRA_2
  421. FCG_Fcg2PeriphClockCmd(FCG2_PERIPH_TMRA_2, ENABLE);
  422. #endif
  423. #ifdef BSP_USING_PWM_TMRA_3
  424. FCG_Fcg2PeriphClockCmd(FCG2_PERIPH_TMRA_3, ENABLE);
  425. #endif
  426. #ifdef BSP_USING_PWM_TMRA_4
  427. FCG_Fcg2PeriphClockCmd(FCG2_PERIPH_TMRA_4, ENABLE);
  428. #endif
  429. #ifdef BSP_USING_PWM_TMRA_5
  430. FCG_Fcg2PeriphClockCmd(FCG2_PERIPH_TMRA_5, ENABLE);
  431. #endif
  432. #ifdef BSP_USING_PWM_TMRA_6
  433. FCG_Fcg2PeriphClockCmd(FCG2_PERIPH_TMRA_6, ENABLE);
  434. #endif
  435. }
  436. extern rt_err_t rt_hw_board_pwm_tmra_init(CM_TMRA_TypeDef *TMRAx);
  437. static int rt_hw_pwm_tmra_init(void)
  438. {
  439. int i = 0;
  440. rt_err_t result = RT_EOK;
  441. pwm_get_channel();
  442. _enable_periph_clk();
  443. for (i = 0; i < sizeof(g_pwm_dev_array) / sizeof(g_pwm_dev_array[0]); i++)
  444. {
  445. /* pwm init */
  446. _pwm_tmra_init(&g_pwm_dev_array[i]);
  447. rt_hw_board_pwm_tmra_init(g_pwm_dev_array[i].instance);
  448. /* register UART device */
  449. result = rt_device_pwm_register(&g_pwm_dev_array[i].pwm_device, g_pwm_dev_array[i].name, &drv_ops, &g_pwm_dev_array[i].instance);
  450. RT_ASSERT(result == RT_EOK);
  451. }
  452. return result;
  453. }
  454. INIT_DEVICE_EXPORT(rt_hw_pwm_tmra_init);
  455. #endif /* RT_USING_PWM */