drv_pwm.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. /*
  2. * Copyright (c) 2006-2018, Synwit Technology Co.,Ltd.
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2018-12-10 Zohar_Lee first version
  9. */
  10. #include <rthw.h>
  11. #include <rtthread.h>
  12. #include <rtdevice.h>
  13. #include <board.h>
  14. #define SWM320_PWM_DEVICE(pwm) (struct swm320_pwm_dev *)(pwm)
  15. #define SWM320_PWM_TIMER_SET(time) ((time) / 1000.0 * 120)
  16. struct swm320_pwm_dev
  17. {
  18. struct rt_device_pwm parent;
  19. PWM_TypeDef *pwm_periph;
  20. };
  21. static rt_err_t swm320_pwm_enable(void *user_data,
  22. struct rt_pwm_configuration *cfg,
  23. rt_bool_t enable)
  24. {
  25. rt_err_t ret = RT_EOK;
  26. if (RT_TRUE == enable)
  27. {
  28. if (2 == cfg->channel)
  29. {
  30. PWM_Start((PWM_TypeDef *)user_data, 1, 1);
  31. }
  32. if (1 == cfg->channel)
  33. {
  34. PWM_Start((PWM_TypeDef *)user_data, 0, 1);
  35. }
  36. if (0 == cfg->channel)
  37. {
  38. PWM_Start((PWM_TypeDef *)user_data, 1, 0);
  39. }
  40. if (3 == cfg->channel)
  41. {
  42. PWM_Start((PWM_TypeDef *)user_data, 0, 0);
  43. }
  44. }
  45. else if (RT_FALSE == enable)
  46. {
  47. if (2 == cfg->channel)
  48. {
  49. PWM_Stop((PWM_TypeDef *)user_data, 1, 1);
  50. }
  51. if (1 == cfg->channel)
  52. {
  53. PWM_Stop((PWM_TypeDef *)user_data, 0, 1);
  54. }
  55. if (0 == cfg->channel)
  56. {
  57. PWM_Stop((PWM_TypeDef *)user_data, 1, 0);
  58. }
  59. if (3 == cfg->channel)
  60. {
  61. PWM_Stop((PWM_TypeDef *)user_data, 0, 0);
  62. }
  63. }
  64. else
  65. {
  66. ret = RT_ERROR;
  67. }
  68. return ret;
  69. }
  70. static rt_err_t swm320_pwm_control(struct rt_device_pwm *device,
  71. int cmd,
  72. void *arg)
  73. {
  74. rt_err_t ret = RT_EOK;
  75. struct swm320_pwm_dev *pwm = SWM320_PWM_DEVICE(device->parent.user_data);
  76. struct rt_pwm_configuration *cfg = (struct rt_pwm_configuration *)arg;
  77. RT_ASSERT(pwm != RT_NULL);
  78. switch (cmd)
  79. {
  80. case PWM_CMD_ENABLE:
  81. ret = swm320_pwm_enable((void *)pwm->pwm_periph, cfg, RT_TRUE);
  82. break;
  83. case PWM_CMD_DISABLE:
  84. ret = swm320_pwm_enable((void *)pwm->pwm_periph, cfg, RT_FALSE);
  85. break;
  86. case PWM_CMD_SET:
  87. PWM_SetHDuty(pwm->pwm_periph,
  88. cfg->channel,
  89. SWM320_PWM_TIMER_SET(cfg->pulse));
  90. PWM_SetCycle(pwm->pwm_periph,
  91. cfg->channel,
  92. SWM320_PWM_TIMER_SET(cfg->period));
  93. break;
  94. case PWM_CMD_GET:
  95. cfg->pulse = PWM_GetHDuty(pwm->pwm_periph, cfg->channel);
  96. break;
  97. default:
  98. break;
  99. }
  100. return ret;
  101. }
  102. const static struct rt_pwm_ops swm320_pwm_ops =
  103. {
  104. swm320_pwm_control
  105. };
  106. int rt_hw_pwm_init(void)
  107. {
  108. rt_err_t ret = RT_EOK;
  109. PWM_InitStructure PWM_initStruct;
  110. PWM_initStruct.clk_div = PWM_CLKDIV_1; /* F_PWM = 120M/1 = 120M */
  111. PWM_initStruct.mode = PWM_MODE_INDEP; /* A路和B路独立输出 */
  112. PWM_initStruct.cycleA = SWM320_PWM_TIMER_SET(1000);
  113. PWM_initStruct.hdutyA = SWM320_PWM_TIMER_SET(500);
  114. PWM_initStruct.initLevelA = 1;
  115. PWM_initStruct.cycleB = SWM320_PWM_TIMER_SET(1000);
  116. PWM_initStruct.hdutyB = SWM320_PWM_TIMER_SET(250);
  117. PWM_initStruct.initLevelB = 1;
  118. PWM_initStruct.HEndAIEn = 0;
  119. PWM_initStruct.NCycleAIEn = 0;
  120. PWM_initStruct.HEndBIEn = 0;
  121. PWM_initStruct.NCycleBIEn = 0;
  122. #ifdef BSP_USING_PWM0
  123. static struct swm320_pwm_dev pwm_dev0;
  124. pwm_dev0.pwm_periph = PWM0;
  125. PWM_Init(pwm_dev0.pwm_periph, &PWM_initStruct);
  126. PORT_Init(PORTA, PIN4, FUNMUX0_PWM0A_OUT, 0);
  127. PORT_Init(PORTA, PIN10, FUNMUX0_PWM0B_OUT, 0);
  128. ret = rt_device_pwm_register(&pwm_dev0.parent,
  129. "pwm0",
  130. &swm320_pwm_ops,
  131. &pwm_dev0);
  132. #endif
  133. #ifdef BSP_USING_PWM1
  134. static struct swm320_pwm_dev pwm_dev1;
  135. pwm_dev1.pwm_periph = PWM1;
  136. PWM_Init(pwm_dev1.pwm_periph, &PWM_initStruct);
  137. PORT_Init(PORTA, PIN5, FUNMUX1_PWM1A_OUT, 0);
  138. PORT_Init(PORTA, PIN9, FUNMUX1_PWM1B_OUT, 0);
  139. ret = rt_device_pwm_register(&pwm_dev1.parent,
  140. "pwm1",
  141. &swm320_pwm_ops,
  142. &pwm_dev1);
  143. #endif
  144. #ifdef BSP_USING_PWM2
  145. static struct swm320_pwm_dev pwm_dev2;
  146. pwm_dev2.pwm_periph = PWM2;
  147. PWM_Init(pwm_dev2.pwm_periph, &PWM_initStruct);
  148. PORT_Init(PORTP, PIN0, FUNMUX0_PWM2A_OUT, 0);
  149. PORT_Init(PORTP, PIN2, FUNMUX0_PWM2B_OUT, 0);
  150. ret = rt_device_pwm_register(&pwm_dev2.parent,
  151. "pwm2",
  152. &swm320_pwm_ops,
  153. &pwm_dev2);
  154. #endif
  155. #ifdef BSP_USING_PWM3
  156. static struct swm320_pwm_dev pwm_dev3;
  157. pwm_dev3.pwm_periph = PWM3;
  158. PWM_Init(pwm_dev3.pwm_periph, &PWM_initStruct);
  159. PORT_Init(PORTP, PIN1, FUNMUX1_PWM3A_OUT, 0);
  160. PORT_Init(PORTP, PIN3, FUNMUX1_PWM3B_OUT, 0);
  161. ret = rt_device_pwm_register(&pwm_dev3.parent,
  162. "pwm3",
  163. &swm320_pwm_ops,
  164. &pwm_dev3);
  165. #endif
  166. return ret;
  167. }
  168. INIT_DEVICE_EXPORT(rt_hw_pwm_init);