drv_tpwm.c 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. /**************************************************************************//**
  2. *
  3. * @copyright (C) 2020 Nuvoton Technology Corp. All rights reserved.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0
  6. *
  7. * Change Logs:
  8. * Date Author Notes
  9. * 2020-6-17 YCHuang12 First version
  10. *
  11. * Note: 2 channels of a tpwm have the same output.
  12. ******************************************************************************/
  13. #include <rtconfig.h>
  14. #if (defined(BSP_USING_TPWM) && defined(RT_USING_PWM))
  15. #define LOG_TAG "drv.tpwm"
  16. #define DBG_ENABLE
  17. #define DBG_SECTION_NAME LOG_TAG
  18. #define DBG_LEVEL DBG_INFO
  19. #define TPWM_CHANNEL_NUM 2
  20. #include <rtdbg.h>
  21. #include <stdint.h>
  22. #include <rtdevice.h>
  23. #include <rthw.h>
  24. #include "NuMicro.h"
  25. /* Private define ---------------------------------------------------------------*/
  26. #define NU_TPWM_DEVICE(tpwm) (nu_tpwm_t *)(tpwm)
  27. /* Private typedef --------------------------------------------------------------*/
  28. typedef struct nu_tpwm
  29. {
  30. struct rt_device_pwm tpwm_dev;
  31. char *name;
  32. TIMER_T *tpwm_base;
  33. rt_uint32_t channel_mask; //TPWM_CH0 | TPWM_CH1
  34. } nu_tpwm_t;
  35. /* Private functions ------------------------------------------------------------*/
  36. static rt_err_t nu_tpwm_enable(struct rt_device_pwm *tpwm_dev, struct rt_pwm_configuration *tpwm_config, rt_bool_t enable);
  37. static rt_err_t nu_tpwm_set(struct rt_device_pwm *tpwm_dev, struct rt_pwm_configuration *tpwm_config);
  38. static rt_err_t nu_tpwm_get(struct rt_device_pwm *tpwm_dev, struct rt_pwm_configuration *tpwm_config);
  39. static rt_err_t nu_tpwm_control(struct rt_device_pwm *tpwm_dev, int cmd, void *arg);
  40. /* Private variables ------------------------------------------------------------*/
  41. #ifdef BSP_USING_TPWM0
  42. static nu_tpwm_t nu_tpwm0;
  43. #endif
  44. #ifdef BSP_USING_TPWM1
  45. static nu_tpwm_t nu_tpwm1;
  46. #endif
  47. #ifdef BSP_USING_TPWM2
  48. static nu_tpwm_t nu_tpwm2;
  49. #endif
  50. #ifdef BSP_USING_TPWM3
  51. static nu_tpwm_t nu_tpwm3;
  52. #endif
  53. #ifdef BSP_USING_TPWM4
  54. static nu_tpwm_t nu_tpwm4;
  55. #endif
  56. #ifdef BSP_USING_TPWM5
  57. static nu_tpwm_t nu_tpwm5;
  58. #endif
  59. static struct rt_pwm_ops nu_tpwm_ops =
  60. {
  61. nu_tpwm_control
  62. };
  63. /* Functions define ------------------------------------------------------------*/
  64. static rt_err_t nu_tpwm_enable(struct rt_device_pwm *tpwm_dev, struct rt_pwm_configuration *tpwm_config, rt_bool_t enable)
  65. {
  66. rt_err_t result = RT_EOK;
  67. rt_uint32_t tpwm_channel = tpwm_config->channel;
  68. nu_tpwm_t *nu_tpwm = NU_TPWM_DEVICE(tpwm_dev->parent.user_data);
  69. if (enable == RT_TRUE)
  70. {
  71. if (nu_tpwm->channel_mask == 0)
  72. {
  73. TPWM_START_COUNTER(nu_tpwm->tpwm_base);
  74. }
  75. nu_tpwm->channel_mask |= (1 << tpwm_channel);
  76. TPWM_ENABLE_OUTPUT(nu_tpwm->tpwm_base, nu_tpwm->channel_mask);
  77. }
  78. else
  79. {
  80. nu_tpwm->channel_mask &= ~(1 << tpwm_channel);
  81. TPWM_ENABLE_OUTPUT(nu_tpwm->tpwm_base, nu_tpwm->channel_mask);
  82. if (nu_tpwm->channel_mask == 0)
  83. {
  84. TPWM_STOP_COUNTER(nu_tpwm->tpwm_base);
  85. }
  86. }
  87. return result;
  88. }
  89. static rt_err_t nu_tpwm_set(struct rt_device_pwm *tpwm_dev, struct rt_pwm_configuration *tpwm_config)
  90. {
  91. if (tpwm_config->period <= 0)
  92. return -(RT_ERROR);
  93. rt_uint32_t tpwm_freq, tpwm_dutycycle ;
  94. rt_uint32_t tpwm_period = tpwm_config->period;
  95. rt_uint32_t tpwm_pulse = tpwm_config->pulse;
  96. nu_tpwm_t *nu_tpwm = NU_TPWM_DEVICE(tpwm_dev->parent.user_data);
  97. rt_uint32_t pre_tpwm_prescaler = TPWM_GET_PRESCALER(nu_tpwm->tpwm_base);
  98. tpwm_freq = 1000000000 / tpwm_period;
  99. tpwm_dutycycle = (tpwm_pulse * 100) / tpwm_period;
  100. TPWM_ConfigOutputFreqAndDuty(nu_tpwm->tpwm_base, tpwm_freq, tpwm_dutycycle) ;
  101. return RT_EOK;
  102. }
  103. static rt_err_t nu_tpwm_get(struct rt_device_pwm *tpwm_dev, struct rt_pwm_configuration *tpwm_config)
  104. {
  105. rt_uint32_t tpwm_real_period, tpwm_real_duty, time_tick, u32TPWMClockFreq ;
  106. nu_tpwm_t *nu_tpwm = NU_TPWM_DEVICE(tpwm_dev->parent.user_data);
  107. rt_uint32_t tpwm_prescale = TPWM_GET_PRESCALER(nu_tpwm->tpwm_base);
  108. rt_uint32_t tpwm_period = TPWM_GET_PERIOD(nu_tpwm->tpwm_base);
  109. rt_uint32_t tpwm_pulse = TPWM_GET_CMPDAT(nu_tpwm->tpwm_base);
  110. u32TPWMClockFreq = TIMER_GetModuleClock(nu_tpwm->tpwm_base);
  111. time_tick = 1000000000000 / u32TPWMClockFreq;
  112. tpwm_real_period = (((tpwm_prescale + 1) * (tpwm_period + 1)) * time_tick) / 1000;
  113. tpwm_real_duty = (((tpwm_prescale + 1) * tpwm_pulse * time_tick)) / 1000;
  114. tpwm_config->period = tpwm_real_period;
  115. tpwm_config->pulse = tpwm_real_duty;
  116. LOG_I("%s %d %d %d\n", nu_tpwm->name, tpwm_config->channel, tpwm_config->period, tpwm_config->pulse);
  117. return RT_EOK;
  118. }
  119. static rt_err_t nu_tpwm_control(struct rt_device_pwm *tpwm_dev, int cmd, void *arg)
  120. {
  121. struct rt_pwm_configuration *tpwm_config = (struct rt_pwm_configuration *)arg;
  122. RT_ASSERT(tpwm_dev != RT_NULL);
  123. RT_ASSERT(tpwm_config != RT_NULL);
  124. nu_tpwm_t *nu_tpwm = NU_TPWM_DEVICE(tpwm_dev->parent.user_data);
  125. RT_ASSERT(nu_tpwm != RT_NULL);
  126. RT_ASSERT(nu_tpwm->tpwm_base != RT_NULL);
  127. if ((tpwm_config->channel + 1) > TPWM_CHANNEL_NUM)
  128. return -(RT_ERROR);
  129. switch (cmd)
  130. {
  131. case PWM_CMD_ENABLE:
  132. return nu_tpwm_enable(tpwm_dev, tpwm_config, RT_TRUE);
  133. case PWM_CMD_DISABLE:
  134. return nu_tpwm_enable(tpwm_dev, tpwm_config, RT_FALSE);
  135. case PWM_CMD_SET:
  136. return nu_tpwm_set(tpwm_dev, tpwm_config);
  137. case PWM_CMD_GET:
  138. return nu_tpwm_get(tpwm_dev, tpwm_config);
  139. default:
  140. break;
  141. }
  142. return -(RT_EINVAL);
  143. }
  144. int rt_hw_tpwm_init(void)
  145. {
  146. rt_err_t ret = RT_EOK;
  147. #ifdef BSP_USING_TPWM0
  148. nu_tpwm0.tpwm_base = TIMER0;
  149. nu_tpwm0.name = "tpwm0";
  150. nu_tpwm0.channel_mask = 0;
  151. ret = rt_device_pwm_register(&nu_tpwm0.tpwm_dev, nu_tpwm0.name, &nu_tpwm_ops, &nu_tpwm0);
  152. if (ret != RT_EOK)
  153. {
  154. rt_kprintf("tpwm0 register failed\n");
  155. }
  156. SYS_ResetModule(TMR0_RST);
  157. CLK_EnableModuleClock(TMR0_MODULE);
  158. TPWM_ENABLE_PWM_MODE(TIMER0);
  159. #endif
  160. #ifdef BSP_USING_TPWM1
  161. nu_tpwm1.tpwm_base = TIMER1;
  162. nu_tpwm1.name = "tpwm1";
  163. nu_tpwm1.channel_mask = 0;
  164. ret = rt_device_pwm_register(&nu_tpwm1.tpwm_dev, nu_tpwm1.name, &nu_tpwm_ops, &nu_tpwm1);
  165. if (ret != RT_EOK)
  166. {
  167. rt_kprintf("tpwm1 register failed\n");
  168. }
  169. SYS_ResetModule(TMR1_RST);
  170. CLK_EnableModuleClock(TMR1_MODULE);
  171. TPWM_ENABLE_PWM_MODE(TIMER1);
  172. #endif
  173. #ifdef BSP_USING_TPWM2
  174. nu_tpwm2.tpwm_base = TIMER2;
  175. nu_tpwm2.name = "tpwm2";
  176. nu_tpwm2.channel_mask = 0;
  177. ret = rt_device_pwm_register(&nu_tpwm2.tpwm_dev, nu_tpwm2.name, &nu_tpwm_ops, &nu_tpwm2);
  178. if (ret != RT_EOK)
  179. {
  180. rt_kprintf("tpwm2 register failed\n");
  181. }
  182. SYS_ResetModule(TMR2_RST);
  183. CLK_EnableModuleClock(TMR2_MODULE);
  184. TPWM_ENABLE_PWM_MODE(TIMER2);
  185. #endif
  186. #ifdef BSP_USING_TPWM3
  187. nu_tpwm3.tpwm_base = TIMER3;
  188. nu_tpwm3.name = "tpwm3";
  189. nu_tpwm3.channel_mask = 0;
  190. ret = rt_device_pwm_register(&nu_tpwm3.tpwm_dev, nu_tpwm3.name, &nu_tpwm_ops, &nu_tpwm3);
  191. if (ret != RT_EOK)
  192. {
  193. rt_kprintf("tpwm3 register failed\n");
  194. }
  195. SYS_ResetModule(TMR3_RST);
  196. CLK_EnableModuleClock(TMR3_MODULE);
  197. TPWM_ENABLE_PWM_MODE(TIMER3);
  198. #endif
  199. #ifdef BSP_USING_TPWM4
  200. nu_tpwm4.tpwm_base = TIMER4;
  201. nu_tpwm4.name = "tpwm4";
  202. nu_tpwm4.channel_mask = 0;
  203. ret = rt_device_pwm_register(&nu_tpwm4.tpwm_dev, nu_tpwm4.name, &nu_tpwm_ops, &nu_tpwm4);
  204. if (ret != RT_EOK)
  205. {
  206. rt_kprintf("tpwm4 register failed\n");
  207. }
  208. SYS_ResetModule(TMR4_RST);
  209. CLK_EnableModuleClock(TMR4_MODULE);
  210. TPWM_ENABLE_PWM_MODE(TIMER4);
  211. #endif
  212. #ifdef BSP_USING_TPWM5
  213. nu_tpwm5.tpwm_base = TIMER5;
  214. nu_tpwm5.name = "tpwm5";
  215. nu_tpwm5.channel_mask = 0;
  216. ret = rt_device_pwm_register(&nu_tpwm5.tpwm_dev, nu_tpwm5.name, &nu_tpwm_ops, &nu_tpwm5);
  217. if (ret != RT_EOK)
  218. {
  219. rt_kprintf("tpwm5 register failed\n");
  220. }
  221. SYS_ResetModule(TMR5_RST);
  222. CLK_EnableModuleClock(TMR5_MODULE);
  223. TPWM_ENABLE_PWM_MODE(TIMER5);
  224. #endif
  225. return ret;
  226. }
  227. INIT_DEVICE_EXPORT(rt_hw_tpwm_init);
  228. #endif //#if (defined(BSP_USING_TPWM) && defined(RT_USING_PWM))