fsl_pwm.h 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427
  1. /*
  2. * Copyright (c) 2016, Freescale Semiconductor, Inc.
  3. * Copyright 2016-2017 NXP
  4. *
  5. * Redistribution and use in source and binary forms, with or without modification,
  6. * are permitted provided that the following conditions are met:
  7. *
  8. * o Redistributions of source code must retain the above copyright notice, this list
  9. * of conditions and the following disclaimer.
  10. *
  11. * o Redistributions in binary form must reproduce the above copyright notice, this
  12. * list of conditions and the following disclaimer in the documentation and/or
  13. * other materials provided with the distribution.
  14. *
  15. * o Neither the name of the copyright holder nor the names of its
  16. * contributors may be used to endorse or promote products derived from this
  17. * software without specific prior written permission.
  18. *
  19. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  20. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  21. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  22. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
  23. * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  24. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  25. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  26. * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  27. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  28. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  29. */
  30. #ifndef _FSL_PWM_H_
  31. #define _FSL_PWM_H_
  32. #include "fsl_common.h"
  33. /*!
  34. * @addtogroup pwm_driver
  35. * @{
  36. */
  37. /*******************************************************************************
  38. * Definitions
  39. ******************************************************************************/
  40. /*! @name Driver version */
  41. /*@{*/
  42. #define FSL_PWM_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) /*!< Version 2.0.0 */
  43. /*@}*/
  44. /*! @brief PWM clock source select. */
  45. typedef enum _pwm_clock_source
  46. {
  47. KPWM_PERIPHERAL_CLOCK = 0U, /*!< The Peripheral clock is used as the clock */
  48. KPWM_HIGH_FREQUENCY_CLOCK, /*!< High-frequency reference clock is used as the clock */
  49. KPWM_LOW_FREQUENCY_CLOCK /*!< Low-frequency reference clock(32KHz) is used as the clock */
  50. } pwm_clock_source_t;
  51. /*!
  52. * @brief PWM FIFO water mark select.
  53. * Sets the data level at which the FIFO empty flag will be set
  54. */
  55. typedef enum _pwm_fifo_water_mark
  56. {
  57. KPWM_FIFO_WATERMARK_1 = 0U, /*!< FIFO empty flag is set when there are more than or equal to 1 empty slots */
  58. KPWM_FIFO_WATERMARK_2, /*!< FIFO empty flag is set when there are more than or equal to 2 empty slots */
  59. KPWM_FIFO_WATERMARK_3, /*!< FIFO empty flag is set when there are more than or equal to 3 empty slots */
  60. KPWM_FIFO_WATERMARK_4 /*!< FIFO empty flag is set when there are more than or equal to 4 empty slots */
  61. } pwm_fifo_water_mark_t;
  62. /*!
  63. * @brief PWM byte data swap select.
  64. * It determines the byte ordering of the 16-bit data when it goes into the FIFO from the sample register.
  65. */
  66. typedef enum _pwm_byte_data_swap
  67. {
  68. KPWM_BYTE_NO_SWAP = 0U, /*!< byte ordering remains the same */
  69. KPWM_BYTE_SWAP /*!< byte ordering is reversed */
  70. } pwm_byte_data_swap_t;
  71. /*! @brief PWM half-word data swap select. */
  72. typedef enum _pwm_half_word_data_swap
  73. {
  74. KPWM_HALF_WORD_NO_SWAP = 0U, /*!< Half word swapping does not take place */
  75. KPWM_HALF_WORD_SWAP /*!< Half word from write data bus are swapped */
  76. } pwm_half_word_data_swap_t;
  77. /*! @brief PWM Output Configuration */
  78. typedef enum _pwm_output_configuration
  79. {
  80. KPWM_SET_AT_ROLLOVER_AND_CLEAR_AT_COMPARISON = 0U, /*!< Output pin is set at
  81. rollover and cleared at comparison */
  82. KPWM_CLEAR_AT_ROLLOVER_AND_SET_AT_COMPARISON, /*!< Output pin is
  83. cleared at rollover and set at comparison */
  84. KPWM_NO_CONFIGURE /*!< PWM output is disconnected */
  85. } pwm_output_configuration_t;
  86. /*!
  87. * @brief PWM FIFO sample repeat
  88. * It determines the number of times each sample from the FIFO is to be used.
  89. */
  90. typedef enum _pwm_sample_repeat
  91. {
  92. KPMW_EACH_SAMPLE_ONCE = 0u, /*!< Use each sample once */
  93. KPWM_EACH_SAMPLE_TWICE, /*!< Use each sample twice */
  94. KPWM_EACH_SAMPLE_FOUR_TIMES, /*!< Use each sample four times */
  95. KPWM_EACH_SAMPLE_EIGHT_TIMES /*!< Use each sample eight times */
  96. } pwm_sample_repeat_t;
  97. /*! @brief List of PWM interrupt options */
  98. typedef enum _pwm_interrupt_enable
  99. {
  100. KPWM_FIFO_EMPTY_INTERRUPT_ENABLE = (1U << 0), /*!< This bit controls the generation of the FIFO Empty interrupt. */
  101. KPWM_ROLLOVER_INTERRUPT_ENABLE = (1U << 1), /*!< This bit controls the generation of the Rollover interrupt. */
  102. KPWM_CMPARE_INTERRUPT_ENABLE = (1U << 2) /*!< This bit controls the generation of the Compare interrupt */
  103. } pwm_interrupt_enable_t;
  104. /*! @brief List of PWM status flags */
  105. typedef enum _pwm_status_flags
  106. {
  107. KPWM_FIFO_EMPTY_FLAG = (1U << 3), /*!< This bit indicates the FIFO data level in comparison to the water
  108. level set by FWM field in the control register. */
  109. KPWM_ROLLOVER_FLAG = (1U << 4), /*!< This bit shows that a roll-over event has occurred. */
  110. KPWM_COMPARE_FLAG = (1U << 5), /*!< This bit shows that a compare event has occurred. */
  111. KPWM_FIFO_WRITE_ERROR_FLAG = (1U << 6) /*!< This bit shows that an attempt
  112. has been made to write FIFO when it is full. */
  113. } pwm_status_flags_t;
  114. /*! @brief List of PWM FIFO available */
  115. typedef enum _pwm_fifo_available
  116. {
  117. KPWM_NO_DATA_IN_FIFO_FLAG = 0U, /*!< No data available */
  118. KPWM_ONE_WORD_IN_FIFO_FLAG, /*!< 1 word of data in FIFO */
  119. KPWM_TWO_WWRDS_IN_FIFO_FLAG, /*!< 2 word of data in FIFO */
  120. KPWM_THREE_WORDS_IN_FIFO_FLAG, /*!< 3 word of data in FIFO */
  121. KPWM_FOUR_WORDS_IN_FIFO_FLAG /*!< 4 word of data in FIFO */
  122. } pwm_fifo_available_t;
  123. typedef struct _pwm_config
  124. {
  125. bool enableStopMode; /*!< True: PWM continues to run in stop mode;
  126. False: PWM is paused in stop mode. */
  127. bool enableDozeMode; /*!< True: PWM continues to run in doze mode;
  128. False: PWM is paused in doze mode. */
  129. bool enableWaitMode; /*!< True: PWM continues to run in wait mode;
  130. False: PWM is paused in wait mode. */
  131. bool enableDebugMode; /*!< True: PWM continues to run in debug mode;
  132. False: PWM is paused in debug mode. */
  133. uint16_t prescale; /*!< Pre-scaler to divide down the clock
  134. The prescaler value is not more than 0xFFF. Divide by (value + 1)*/
  135. pwm_clock_source_t clockSource; /*!< Clock source for the counter */
  136. pwm_output_configuration_t outputConfig; /*!< Set the mode of the PWM output on the output pin. */
  137. pwm_fifo_water_mark_t fifoWater; /*!< Set the data level for FIFO. */
  138. pwm_sample_repeat_t sampleRepeat; /*!< The number of times each sample from the FIFO is to be used. */
  139. pwm_byte_data_swap_t byteSwap; /*!< It determines the byte ordering of the 16-bit data when it
  140. goes into the FIFO from the sample register. */
  141. pwm_half_word_data_swap_t halfWordSwap; /*!< It determines which half word data from the 32-bit
  142. IP Bus interface is written into the lower 16 bits of the sample register. */
  143. } pwm_config_t;
  144. /*******************************************************************************
  145. * API
  146. ******************************************************************************/
  147. #if defined(__cplusplus)
  148. extern "C" {
  149. #endif
  150. /*!
  151. * @name Initialization and deinitialization
  152. * @{
  153. */
  154. /*!
  155. * @brief Ungates the PWM clock and configures the peripheral for basic operation.
  156. *
  157. * @note This API should be called at the beginning of the application using the PWM driver.
  158. *
  159. * @param base PWM peripheral base address
  160. * @param config Pointer to user's PWM config structure.
  161. *
  162. * @return kStatus_Success means success; else failed.
  163. */
  164. status_t pwm_init(PWM_Type *base, const pwm_config_t *config);
  165. /*!
  166. * @brief Gate the PWM submodule clock
  167. *
  168. * @param base PWM peripheral base address
  169. */
  170. void pwm_deinit(PWM_Type *base);
  171. /*!
  172. * @brief Fill in the PWM config struct with the default settings
  173. *
  174. * The default values are:
  175. * @code
  176. * config->enableStopMode = false;
  177. * config->enableDozeMode = false;
  178. * config->enableWaitMode = false;
  179. * config->enableDozeMode = false;
  180. * config->clockSource = kPWM_LowFrequencyClock;
  181. * config->prescale = 0U;
  182. * config->outputConfig = kPWM_SetAtRolloverAndClearAtcomparison;
  183. * config->fifoWater = kPWM_FIFOWaterMark_2;
  184. * config->sampleRepeat = kPWM_EachSampleOnce;
  185. * config->byteSwap = kPWM_ByteNoSwap;
  186. * config->halfWordSwap = kPWM_HalfWordNoSwap;
  187. * @endcode
  188. * @param config Pointer to user's PWM config structure.
  189. */
  190. void pwm_get_default_config(pwm_config_t *config);
  191. /*! @}*/
  192. /*!
  193. * @name PWM start and stop.
  194. * @{
  195. */
  196. /*!
  197. * @brief Starts the PWM counter when the PWM is enabled.
  198. *
  199. * When the PWM is enabled, it begins a new period, the output pin is set to start a new period while
  200. * the prescaler and counter are released and counting begins.
  201. *
  202. * @param base PWM peripheral base address
  203. */
  204. static inline void pwm_start_timer(PWM_Type *base)
  205. {
  206. base->PWMCR |= PWM_PWMCR_EN_MASK;
  207. }
  208. /*!
  209. * @brief Stops the PWM counter when the pwm is disabled.
  210. *
  211. * @param base PWM peripheral base address
  212. */
  213. static inline void pwm_stop_timer(PWM_Type *base)
  214. {
  215. base->PWMCR &= ~(PWM_PWMCR_EN_MASK);
  216. }
  217. /*! @}*/
  218. /*!
  219. * @brief Sofrware reset.
  220. *
  221. * PWM is reset when this bit is set to 1. It is a self clearing bit.
  222. * Setting this bit resets all the registers to their reset values except for the STOPEN,
  223. * DOZEN, WAITEN, and DBGEN bits in this control register.
  224. *
  225. * @param base PWM peripheral base address
  226. */
  227. static inline void pwm_software_reset(PWM_Type *base)
  228. {
  229. base->PWMCR |= PWM_PWMCR_SWR_MASK;
  230. }
  231. /*!
  232. * @name Interrupt Interface
  233. * @{
  234. */
  235. /*!
  236. * @brief Enables the selected PWM interrupts.
  237. *
  238. * @param base PWM peripheral base address
  239. * @param mask The interrupts to enable. This is a logical OR of members of the
  240. * enumeration ::pwm_interrupt_enable_t
  241. */
  242. static inline void pwm_enable_interrupts(PWM_Type *base, uint32_t mask)
  243. {
  244. base->PWMIR |= (mask & (PWM_PWMIR_FIE_MASK | PWM_PWMIR_RIE_MASK | PWM_PWMIR_CIE_MASK));
  245. }
  246. /*!
  247. * @brief Disables the selected PWM interrupts.
  248. *
  249. * @param base PWM peripheral base address
  250. * @param mask The interrupts to disable. This is a logical OR of members of the
  251. * enumeration ::pwm_interrupt_enable_t
  252. */
  253. static inline void pwm_disable_interrupts(PWM_Type *base, uint32_t mask)
  254. {
  255. base->PWMIR &= ~(mask & (PWM_PWMIR_FIE_MASK | PWM_PWMIR_RIE_MASK | PWM_PWMIR_CIE_MASK));
  256. }
  257. /*!
  258. * @brief Gets the enabled PWM interrupts.
  259. *
  260. * @param base PWM peripheral base address
  261. *
  262. * @return The enabled interrupts. This is the logical OR of members of the
  263. * enumeration ::pwm_interrupt_enable_t
  264. */
  265. static inline uint32_t pwm_get_enabled_interrupts(PWM_Type *base)
  266. {
  267. return base->PWMIR;
  268. }
  269. /*! @}*/
  270. /*!
  271. * @name Status Interface
  272. * @{
  273. */
  274. /*!
  275. * @brief Gets the PWM status flags.
  276. *
  277. * @param base PWM peripheral base address
  278. *
  279. * @return The status flags. This is the logical OR of members of the
  280. * enumeration ::pwm_status_flags_t
  281. */
  282. static inline uint32_t pwm_get_status_flags(PWM_Type *base)
  283. {
  284. uint32_t statusFlags = base->PWMSR;
  285. statusFlags &= (PWM_PWMSR_FE_MASK | PWM_PWMSR_ROV_MASK | PWM_PWMSR_CMP_MASK | PWM_PWMSR_FWE_MASK);
  286. return statusFlags;
  287. }
  288. /*!
  289. * @brief Clears the PWM status flags.
  290. *
  291. * @param base PWM peripheral base address
  292. * @param mask The status flags to clear. This is a logical OR of members of the
  293. * enumeration ::pwm_status_flags_t
  294. */
  295. static inline void pwm_clear_status_flags(PWM_Type *base, uint32_t mask)
  296. {
  297. base->PWMSR = (mask & (PWM_PWMSR_FE_MASK | PWM_PWMSR_ROV_MASK |
  298. PWM_PWMSR_CMP_MASK | PWM_PWMSR_FWE_MASK));
  299. }
  300. /*!
  301. * @brief Gets the PWM FIFO available.
  302. *
  303. * @param base PWM peripheral base address
  304. *
  305. * @return The status flags. This is the logical OR of members of the
  306. * enumeration ::pwm_fifo_available_t
  307. */
  308. static inline uint32_t pwm_get_fifo_available(PWM_Type *base)
  309. {
  310. return (base->PWMSR & PWM_PWMSR_FIFOAV_MASK);
  311. }
  312. /*! @}*/
  313. /*!
  314. * @name Sample Interface
  315. * @{
  316. */
  317. /*!
  318. * @brief Sets the PWM sample value.
  319. *
  320. * @param base PWM peripheral base address
  321. * @param mask The sample value. This is the input to the 4x16 FIFO. The value in this register denotes
  322. * the value of the sample being currently used.
  323. */
  324. static inline void pwm_set_sample_value(PWM_Type *base, uint32_t value)
  325. {
  326. base->PWMSAR = (value & PWM_PWMSAR_SAMPLE_MASK);
  327. }
  328. /*!
  329. * @brief Gets the PWM sample value.
  330. *
  331. * @param base PWM peripheral base address
  332. *
  333. * @return The sample value. It can be read only when the PWM is enable.
  334. */
  335. static inline uint32_t pwm_get_sample_value(PWM_Type *base)
  336. {
  337. return base->PWMSAR;
  338. }
  339. /*! @}*/
  340. /*!
  341. * @brief Sets the PWM period value.
  342. *
  343. * @param base PWM peripheral base address
  344. * @param mask The period value. The PWM period register (PWM_PWMPR) determines the period of
  345. * the PWM output signal.
  346. * Writing 0xFFFF to this register will achieve the same result as writing 0xFFFE.
  347. * PWMO (Hz) = PCLK(Hz) / (period +2)
  348. */
  349. static inline void pwm_set_period_value(PWM_Type *base, uint32_t value)
  350. {
  351. base->PWMPR = (value & PWM_PWMPR_PERIOD_MASK);
  352. }
  353. /*!
  354. * @brief Gets the PWM period value.
  355. *
  356. * @param base PWM peripheral base address
  357. *
  358. * @return The period value. The PWM period register (PWM_PWMPR) determines the period of
  359. * the PWM output signal.
  360. */
  361. static inline uint32_t pwm_get_period_value(PWM_Type *base)
  362. {
  363. return (base->PWMPR & PWM_PWMPR_PERIOD_MASK);
  364. }
  365. /*!
  366. * @brief Gets the PWM counter value.
  367. *
  368. * @param base PWM peripheral base address
  369. *
  370. * @return The counter value. The current count value.
  371. */
  372. static inline uint32_t pwm_get_counter_value(PWM_Type *base)
  373. {
  374. return (base->PWMCNR & PWM_PWMCNR_COUNT_MASK);
  375. }
  376. #if defined(__cplusplus)
  377. }
  378. #endif
  379. /*! @}*/
  380. #endif /* _FSL_PWM_H_ */