drv_pwm.c 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. /*
  2. * Copyright (C) 2018 Shanghai Eastsoft Microelectronics Co., Ltd.
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2019-10-23 yuzrain the first version
  9. */
  10. #include <rthw.h>
  11. #include <rtthread.h>
  12. #include <rtdevice.h>
  13. #include <board.h>
  14. #include "md_gpio.h"
  15. /* PWM device control struct */
  16. struct pwm_dev_ctrl {
  17. AD16C4T_TypeDef *timx;
  18. rt_uint8_t chnm; /* Cannel number */
  19. struct rt_pwm_configuration *cfg;
  20. };
  21. #ifdef BSP_USING_PWM_GP16C2T1
  22. /* Remember channel configuration */
  23. static struct rt_pwm_configuration pwm_ch_cfg_gp16c2t1[2] = {
  24. [0] = {
  25. .channel = 1,
  26. .period = 0,
  27. .pulse = 0
  28. },
  29. [1] = {
  30. .channel = 2,
  31. .period = 0,
  32. .pulse = 0
  33. }
  34. };
  35. /* Define static device */
  36. static struct rt_device_pwm pwm_dev_gp16c2t1;
  37. static struct pwm_dev_ctrl pwm_dev_gp16c2t1_ctrl;
  38. #endif
  39. #ifdef BSP_USING_PWM_GP16C2T4
  40. /* Remember channel configuration */
  41. static struct rt_pwm_configuration pwm_ch_cfg_gp16c2t4[2] = {
  42. [0] = {
  43. .channel = 1,
  44. .period = 0,
  45. .pulse = 0
  46. },
  47. [1] = {
  48. .channel = 2,
  49. .period = 0,
  50. .pulse = 0
  51. }
  52. };
  53. /* Define static device */
  54. static struct rt_device_pwm pwm_dev_gp16c2t4;
  55. static struct pwm_dev_ctrl pwm_dev_gp16c2t4_ctrl;
  56. #endif
  57. static void pwm_auto_config_freq(AD16C4T_TypeDef *timerx, uint32_t ns)
  58. {
  59. uint32_t temp_ar;
  60. uint32_t temp_pres = timerx->PRES & 0xFFFF;
  61. uint32_t err_cnt = 0;
  62. /* Automatic setting frequency division ratio */
  63. while (err_cnt++ < 65536)
  64. {
  65. temp_ar = (uint64_t)SystemCoreClock * ns / 1000000000 / (temp_pres + 1);
  66. if (temp_ar <= 0xFFFF)
  67. break;
  68. temp_pres++;
  69. }
  70. /* Write back to PRES */
  71. timerx->PRES = (uint16_t)(temp_pres & 0xFFFF);
  72. timerx->AR = temp_ar;
  73. }
  74. static void pwm_set_duty(AD16C4T_TypeDef *timerx, uint8_t ch, uint32_t ns)
  75. {
  76. uint32_t temp_pres = timerx->PRES & 0xFFFF;
  77. uint64_t tmp = (uint64_t)SystemCoreClock * ns / 1000000000 / (temp_pres + 1);
  78. if (ch == 1)
  79. WRITE_REG(timerx->CCVAL1, (uint32_t)tmp);
  80. else if (ch == 2)
  81. WRITE_REG(timerx->CCVAL2, (uint32_t)tmp);
  82. }
  83. static rt_err_t es32f0_pwm_control(struct rt_device_pwm *device, int cmd, void *arg)
  84. {
  85. rt_err_t ret = RT_EOK;
  86. struct pwm_dev_ctrl *dev_ctrl
  87. = (struct pwm_dev_ctrl *)device->parent.user_data;
  88. struct rt_pwm_configuration *cfg = (struct rt_pwm_configuration *)arg;
  89. AD16C4T_TypeDef *timerx = (AD16C4T_TypeDef *)dev_ctrl->timx;
  90. switch (cmd)
  91. {
  92. case PWM_CMD_ENABLE:
  93. {
  94. if (cfg->channel == 1)
  95. SET_BIT(timerx->CCEP, AD16C4T_CCEP_CC1EN_MSK);
  96. else if (cfg->channel == 2)
  97. SET_BIT(timerx->CCEP, AD16C4T_CCEP_CC2EN_MSK);
  98. break;
  99. }
  100. case PWM_CMD_DISABLE:
  101. {
  102. if (cfg->channel == 1)
  103. CLEAR_BIT(timerx->CCEP, AD16C4T_CCEP_CC1EN_MSK);
  104. else if (cfg->channel == 2)
  105. CLEAR_BIT(timerx->CCEP, AD16C4T_CCEP_CC2EN_MSK);
  106. break;
  107. }
  108. case PWM_CMD_SET:
  109. {
  110. /* count registers max 0xFFFF, auto adjust prescaler */
  111. pwm_auto_config_freq(timerx, cfg->period);
  112. pwm_set_duty(timerx, cfg->channel, cfg->pulse);
  113. /* Remember configuration */
  114. dev_ctrl->cfg[cfg->channel-1].period = cfg->period;
  115. dev_ctrl->cfg[cfg->channel-1].pulse = cfg->pulse;
  116. break;
  117. }
  118. case PWM_CMD_GET:
  119. {
  120. cfg->period = dev_ctrl->cfg[cfg->channel-1].period;
  121. cfg->pulse = dev_ctrl->cfg[cfg->channel-1].pulse;
  122. break;
  123. }
  124. default:
  125. break;
  126. }
  127. return ret;
  128. }
  129. const static struct rt_pwm_ops es32f0_pwm_ops =
  130. {
  131. es32f0_pwm_control
  132. };
  133. int rt_hw_pwm_init(void)
  134. {
  135. rt_err_t ret = RT_EOK;
  136. #ifdef BSP_USING_PWM_GP16C2T1 /* 2 channels */
  137. /* Open clock */
  138. SET_BIT(RCU->APB2EN, RCU_APB2EN_GP16C2T1EN_MSK);
  139. /* GPIO configuration */
  140. md_gpio_set_mode (GPIOB, MD_GPIO_PIN_1, MD_GPIO_MODE_FUNCTION);
  141. md_gpio_set_mode (GPIOB, MD_GPIO_PIN_2, MD_GPIO_MODE_FUNCTION);
  142. md_gpio_set_function0_7 (GPIOB, MD_GPIO_PIN_1, MD_GPIO_AF5);
  143. md_gpio_set_function0_7 (GPIOB, MD_GPIO_PIN_2, MD_GPIO_AF5);
  144. /* Timer configuration */
  145. MODIFY_REG(GP16C2T1->CHMR1, AD16C4T_CHMR1_OUTPUT_CH1MOD_MSK,
  146. (6 << AD16C4T_CHMR1_OUTPUT_CH1MOD_POSS));
  147. MODIFY_REG(GP16C2T1->CHMR1, AD16C4T_CHMR1_OUTPUT_CH2MOD_MSK,
  148. (6 << AD16C4T_CHMR1_OUTPUT_CH2MOD_POSS));
  149. SET_BIT(GP16C2T1->BDCFG, AD16C4T_BDCFG_GOEN_MSK);
  150. SET_BIT(GP16C2T1->CON1, AD16C4T_CON1_CNTEN_MSK);
  151. pwm_dev_gp16c2t1_ctrl.chnm = 2;
  152. pwm_dev_gp16c2t1_ctrl.timx = GP16C2T1;
  153. pwm_dev_gp16c2t1_ctrl.cfg = pwm_ch_cfg_gp16c2t1;
  154. /* Register PWM device */
  155. ret = rt_device_pwm_register(&pwm_dev_gp16c2t1,
  156. "pwm1", &es32f0_pwm_ops, &pwm_dev_gp16c2t1_ctrl);
  157. #endif
  158. #ifdef BSP_USING_PWM_GP16C2T4 /* 2 channels */
  159. /* Open clock */
  160. SET_BIT(RCU->APB2EN, RCU_APB2EN_GP16C2T4EN_MSK);
  161. /* GPIO configuration */
  162. md_gpio_set_mode (GPIOB, MD_GPIO_PIN_12, MD_GPIO_MODE_FUNCTION);
  163. md_gpio_set_mode (GPIOB, MD_GPIO_PIN_14, MD_GPIO_MODE_FUNCTION);
  164. md_gpio_set_function8_15(GPIOB, MD_GPIO_PIN_12, MD_GPIO_AF5);
  165. md_gpio_set_function8_15(GPIOB, MD_GPIO_PIN_14, MD_GPIO_AF5);
  166. /* Timer configuration */
  167. MODIFY_REG(GP16C2T4->CHMR1, AD16C4T_CHMR1_OUTPUT_CH1MOD_MSK,
  168. (6 << AD16C4T_CHMR1_OUTPUT_CH1MOD_POSS));
  169. MODIFY_REG(GP16C2T4->CHMR1, AD16C4T_CHMR1_OUTPUT_CH2MOD_MSK,
  170. (6 << AD16C4T_CHMR1_OUTPUT_CH2MOD_POSS));
  171. SET_BIT(GP16C2T4->BDCFG, AD16C4T_BDCFG_GOEN_MSK);
  172. SET_BIT(GP16C2T4->CON1, AD16C4T_CON1_CNTEN_MSK);
  173. pwm_dev_gp16c2t4_ctrl.chnm = 2;
  174. pwm_dev_gp16c2t4_ctrl.timx = GP16C2T4;
  175. pwm_dev_gp16c2t4_ctrl.cfg = pwm_ch_cfg_gp16c2t4;
  176. /* Register PWM device */
  177. ret = rt_device_pwm_register(&pwm_dev_gp16c2t4,
  178. "pwm2", &es32f0_pwm_ops, &pwm_dev_gp16c2t4_ctrl);
  179. #endif
  180. return ret;
  181. }
  182. INIT_DEVICE_EXPORT(rt_hw_pwm_init);