stm32_pwm_0.c 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. /*!
  2. * Copyright (C) 2013-14 Uwe Bonnes (bon@elektron.ikp.physik.tu-darmstadt.de)
  3. *
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions
  8. * are met:
  9. *
  10. * 1. Redistributions of source code must retain the above copyright
  11. * notice, this list of conditions and the following disclaimer.
  12. * 2. Redistributions in binary form must reproduce the above copyright
  13. * notice, this list of conditions and the following disclaimer in the
  14. * documentation and/or other materials provided with the distribution.
  15. * 3. Neither the name of the copyright holders nor the names of
  16. * contributors may be used to endorse or promote products derived
  17. * from this software without specific prior written permission.
  18. *
  19. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  20. * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  21. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  22. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  23. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  24. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  25. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  26. * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
  27. * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  28. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
  29. * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  30. * SUCH DAMAGE.
  31. *
  32. * For additional information see http://www.ethernut.de/
  33. */
  34. /*!
  35. * Provide a n-Bit PWM
  36. * $Id: stm32_pwm_0.c 5681 2014-04-30 08:20:08Z u_bonnes $
  37. */
  38. #include <stdint.h>
  39. #include <cfg/arch.h>
  40. #include <arch/cm3/stm/stm32xxxx.h>
  41. #include <cfg/pwm.h>
  42. #include <dev/gpio.h>
  43. #include <arch/cm3/stm/stm32_gpio.h>
  44. #include <sys/timer.h>
  45. #include <dev/hwtimer_stm32.h>
  46. /* Compile code only when needed definitions are available */
  47. #if defined(STM32_PWM0_TIMER_ID) && defined(STM32_PWM0_PORT) && defined(STM32_PWM0_PIN)\
  48. && defined(STM32_PWM0_TIMER_CHANNEL)
  49. #if defined(STM32_PWM0_TIMER_ID)
  50. #define STM32_PWM_TIMER_ID STM32_PWM0_TIMER_ID
  51. #endif
  52. #if defined(STM32_PWM0_TIMER_CHANNEL)
  53. #define STM32_PWM_TIMER_CHANNEL STM32_PWM0_TIMER_CHANNEL
  54. #endif
  55. #if defined(STM32_PWM0_PORT)
  56. #define STM32_PWM_PORT STM32_PWM0_PORT
  57. #endif
  58. #if defined(STM32_PWM0_PIN)
  59. #define STM32_PWM_PIN STM32_PWM0_PIN
  60. #endif
  61. #if defined(STM32_PWM_TIMER_ID)
  62. #undef STM32TIMER_ID
  63. #define STM32TIMER_ID STM32_PWM_TIMER_ID
  64. #include <arch/cm3/stm/stm32timertran.h>
  65. #define STM32_PWM_BASE STM32TIMER_BASE
  66. #define STM32_PWM_PCLK STM32TIMER_PCLK
  67. #define STM32_PWM_CLK() STM32TIMER_CLK()
  68. #define STM32_PWM_RST() STM32TIMER_RST()
  69. #define STM32_PWM_NCH STM32TIMER_NCH
  70. #define STM32_PWM_BTDR STM32TIMER_BTDR
  71. #define STM32_PWM_AF STM32TIMER_AF(STM32_PWM_PORT, STM32_PWM_PIN)
  72. #endif
  73. /* Use PWM Mode 1 (0x110 on OCxM), Only reload on update event (OCxPE set) */
  74. #if defined(STM32_PWM_TIMER_CHANNEL)
  75. #if STM32_PWM_TIMER_CHANNEL == 1
  76. #define STM32_PWM_OUTPUT_EN() CM3BBSET(STM32_PWM_BASE, TIM_TypeDef, CCER , _BI32(TIM_CCER_CC1E))
  77. #define STM32_PWM_MODE() TIM_CCMode1(STM32_PWM_BASE) = TIM_CCMR1_OC1M_2|TIM_CCMR1_OC1M_1|TIM_CCMR1_OC1PE
  78. #define STM32_PWM_VALUE TIM_Compare1(STM32_PWM_BASE)
  79. #elif STM32_PWM_TIMER_CHANNEL == 2
  80. #define STM32_PWM_OUTPUT_EN() CM3BBSET(STM32_PWM_BASE, TIM_TypeDef, CCER , _BI32(TIM_CCER_CC2E))
  81. #define STM32_PWM_MODE() TIM_CCMode1(STM32_PWM_BASE) = TIM_CCMR1_OC2M_2|TIM_CCMR1_OC2M_1|TIM_CCMR1_OC2PE
  82. #define STM32_PWM_VALUE TIM_Compare2(STM32_PWM_BASE)
  83. #elif STM32_PWM_TIMER_CHANNEL == 3
  84. #define STM32_PWM_OUTPUT_EN() CM3BBSET(STM32_PWM_BASE, TIM_TypeDef, CCER , _BI32(TIM_CCER_CC3E))
  85. #define STM32_PWM_MODE() TIM_CCMode2(STM32_PWM_BASE) = TIM_CCMR2_OC3M_2|TIM_CCMR2_OC3M_1|TIM_CCMR2_OC3PE
  86. #define STM32_PWM_VALUE TIM_Compare3(STM32_PWM_BASE)
  87. #elif STM32_PWM_TIMER_CHANNEL == 4
  88. #define STM32_PWM_OUTPUT_EN() CM3BBSET(STM32_PWM_BASE, TIM_TypeDef, CCER , _BI32(TIM_CCER_CC4E))
  89. #define STM32_PWM_MODE() TIM_CCMode2(STM32_PWM_BASE) = TIM_CCMR2_OC4M_2|TIM_CCMR2_OC4M_1|TIM_CCMR2_OC4PE
  90. #define STM32_PWM_VALUE TIM_Compare4(STM32_PWM_BASE)
  91. #else
  92. #warning Unknown PWM Timer Channel
  93. #endif
  94. #endif
  95. /*!
  96. * \brief Initialize a PWM output
  97. *
  98. * Only few checks is done here!
  99. *
  100. * \param bits Bits of the PWM set value.
  101. *
  102. * \return Achieved frequency or -1
  103. */
  104. uint32_t stm32_pwm0_init(unsigned bits)
  105. {
  106. #if (STM32_PWM_TIMER_CHANNEL == 0) || (STM32_PWM_TIMER_CHANNEL > STM32_PWM_NCH)
  107. /* We requested a channel not available */
  108. return -1;
  109. #else
  110. uint32_t pclk = STM32_PWM_PCLK;
  111. if (bits > STM32TIMER_WIDTH)
  112. return -1;
  113. STM32_PWM_CLK();
  114. STM32_PWM_RST();
  115. /* All registers now reset*/
  116. STM32_PWM_OUTPUT_EN();
  117. STM32_PWM_MODE();
  118. TIM_AutoReloadValue(STM32_PWM_BASE) = (1<<bits) -1;
  119. STM32_PWM_VALUE = 0;
  120. #if defined(STM32_PWM_BTDR)
  121. TIM_Break_Deadtime(STM32_PWM_BASE) = TIM_BDTR_MOE;
  122. #endif
  123. TIM_AutoReload(STM32_PWM_BASE);
  124. TIM_Update(STM32_PWM_BASE);
  125. GpioPinConfigSet(STM32_PWM_PORT, STM32_PWM_PIN, GPIO_CFG_PERIPHAL);
  126. GPIO_PinAFConfig((GPIO_TypeDef*)STM32_PWM_PORT, STM32_PWM_PIN, STM32_PWM_AF);
  127. TIM_StartTimer(STM32_PWM_BASE);
  128. return pclk >> bits;
  129. #endif
  130. }
  131. /*!
  132. * \brief Set PWM value
  133. *
  134. *
  135. * \param value PWM value to set.
  136. *
  137. * \return None.
  138. */
  139. void stm32_pwm0_set(uint32_t value)
  140. {
  141. if (value > TIM_AutoReloadValue(STM32_PWM_BASE))
  142. /* Clip at maximum*/
  143. STM32_PWM_VALUE = TIM_AutoReloadValue(STM32_PWM_BASE);
  144. else
  145. STM32_PWM_VALUE = value;
  146. }
  147. /*!
  148. * \brief Return current set PWM value
  149. *
  150. *
  151. * \return Set PWM value.
  152. */
  153. uint32_t stm32_pwm0_get(void)
  154. {
  155. return STM32_PWM_VALUE;
  156. }
  157. #endif