fsl_port.h 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431
  1. /*
  2. * Copyright (c) 2015, 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_PORT_H_
  31. #define _FSL_PORT_H_
  32. #include "fsl_common.h"
  33. /*!
  34. * @addtogroup port
  35. * @{
  36. */
  37. /*******************************************************************************
  38. * Definitions
  39. ******************************************************************************/
  40. /*! @name Driver version */
  41. /*@{*/
  42. /*! Version 2.0.2. */
  43. #define FSL_PORT_DRIVER_VERSION (MAKE_VERSION(2, 0, 2))
  44. /*@}*/
  45. #if defined(FSL_FEATURE_PORT_HAS_PULL_ENABLE) && FSL_FEATURE_PORT_HAS_PULL_ENABLE
  46. /*! @brief Internal resistor pull feature selection */
  47. enum _port_pull
  48. {
  49. kPORT_PullDisable = 0U, /*!< Internal pull-up/down resistor is disabled. */
  50. kPORT_PullDown = 2U, /*!< Internal pull-down resistor is enabled. */
  51. kPORT_PullUp = 3U, /*!< Internal pull-up resistor is enabled. */
  52. };
  53. #endif /* FSL_FEATURE_PORT_HAS_PULL_ENABLE */
  54. #if defined(FSL_FEATURE_PORT_HAS_SLEW_RATE) && FSL_FEATURE_PORT_HAS_SLEW_RATE
  55. /*! @brief Slew rate selection */
  56. enum _port_slew_rate
  57. {
  58. kPORT_FastSlewRate = 0U, /*!< Fast slew rate is configured. */
  59. kPORT_SlowSlewRate = 1U, /*!< Slow slew rate is configured. */
  60. };
  61. #endif /* FSL_FEATURE_PORT_HAS_SLEW_RATE */
  62. #if defined(FSL_FEATURE_PORT_HAS_OPEN_DRAIN) && FSL_FEATURE_PORT_HAS_OPEN_DRAIN
  63. /*! @brief Open Drain feature enable/disable */
  64. enum _port_open_drain_enable
  65. {
  66. kPORT_OpenDrainDisable = 0U, /*!< Open drain output is disabled. */
  67. kPORT_OpenDrainEnable = 1U, /*!< Open drain output is enabled. */
  68. };
  69. #endif /* FSL_FEATURE_PORT_HAS_OPEN_DRAIN */
  70. #if defined(FSL_FEATURE_PORT_HAS_PASSIVE_FILTER) && FSL_FEATURE_PORT_HAS_PASSIVE_FILTER
  71. /*! @brief Passive filter feature enable/disable */
  72. enum _port_passive_filter_enable
  73. {
  74. kPORT_PassiveFilterDisable = 0U, /*!< Passive input filter is disabled. */
  75. kPORT_PassiveFilterEnable = 1U, /*!< Passive input filter is enabled. */
  76. };
  77. #endif
  78. #if defined(FSL_FEATURE_PORT_HAS_DRIVE_STRENGTH) && FSL_FEATURE_PORT_HAS_DRIVE_STRENGTH
  79. /*! @brief Configures the drive strength. */
  80. enum _port_drive_strength
  81. {
  82. kPORT_LowDriveStrength = 0U, /*!< Low-drive strength is configured. */
  83. kPORT_HighDriveStrength = 1U, /*!< High-drive strength is configured. */
  84. };
  85. #endif /* FSL_FEATURE_PORT_HAS_DRIVE_STRENGTH */
  86. #if defined(FSL_FEATURE_PORT_HAS_PIN_CONTROL_LOCK) && FSL_FEATURE_PORT_HAS_PIN_CONTROL_LOCK
  87. /*! @brief Unlock/lock the pin control register field[15:0] */
  88. enum _port_lock_register
  89. {
  90. kPORT_UnlockRegister = 0U, /*!< Pin Control Register fields [15:0] are not locked. */
  91. kPORT_LockRegister = 1U, /*!< Pin Control Register fields [15:0] are locked. */
  92. };
  93. #endif /* FSL_FEATURE_PORT_HAS_PIN_CONTROL_LOCK */
  94. #if defined(FSL_FEATURE_PORT_PCR_MUX_WIDTH) && FSL_FEATURE_PORT_PCR_MUX_WIDTH
  95. /*! @brief Pin mux selection */
  96. typedef enum _port_mux
  97. {
  98. kPORT_PinDisabledOrAnalog = 0U, /*!< Corresponding pin is disabled, but is used as an analog pin. */
  99. kPORT_MuxAsGpio = 1U, /*!< Corresponding pin is configured as GPIO. */
  100. kPORT_MuxAlt2 = 2U, /*!< Chip-specific */
  101. kPORT_MuxAlt3 = 3U, /*!< Chip-specific */
  102. kPORT_MuxAlt4 = 4U, /*!< Chip-specific */
  103. kPORT_MuxAlt5 = 5U, /*!< Chip-specific */
  104. kPORT_MuxAlt6 = 6U, /*!< Chip-specific */
  105. kPORT_MuxAlt7 = 7U, /*!< Chip-specific */
  106. kPORT_MuxAlt8 = 8U, /*!< Chip-specific */
  107. kPORT_MuxAlt9 = 9U, /*!< Chip-specific */
  108. kPORT_MuxAlt10 = 10U, /*!< Chip-specific */
  109. kPORT_MuxAlt11 = 11U, /*!< Chip-specific */
  110. kPORT_MuxAlt12 = 12U, /*!< Chip-specific */
  111. kPORT_MuxAlt13 = 13U, /*!< Chip-specific */
  112. kPORT_MuxAlt14 = 14U, /*!< Chip-specific */
  113. kPORT_MuxAlt15 = 15U, /*!< Chip-specific */
  114. } port_mux_t;
  115. #endif /* FSL_FEATURE_PORT_PCR_MUX_WIDTH */
  116. /*! @brief Configures the interrupt generation condition. */
  117. typedef enum _port_interrupt
  118. {
  119. kPORT_InterruptOrDMADisabled = 0x0U, /*!< Interrupt/DMA request is disabled. */
  120. #if defined(FSL_FEATURE_PORT_HAS_DMA_REQUEST) && FSL_FEATURE_PORT_HAS_DMA_REQUEST
  121. kPORT_DMARisingEdge = 0x1U, /*!< DMA request on rising edge. */
  122. kPORT_DMAFallingEdge = 0x2U, /*!< DMA request on falling edge. */
  123. kPORT_DMAEitherEdge = 0x3U, /*!< DMA request on either edge. */
  124. #endif
  125. #if defined(FSL_FEATURE_PORT_HAS_IRQC_FLAG) && FSL_FEATURE_PORT_HAS_IRQC_FLAG
  126. kPORT_FlagRisingEdge = 0x05U, /*!< Flag sets on rising edge. */
  127. kPORT_FlagFallingEdge = 0x06U, /*!< Flag sets on falling edge. */
  128. kPORT_FlagEitherEdge = 0x07U, /*!< Flag sets on either edge. */
  129. #endif
  130. kPORT_InterruptLogicZero = 0x8U, /*!< Interrupt when logic zero. */
  131. kPORT_InterruptRisingEdge = 0x9U, /*!< Interrupt on rising edge. */
  132. kPORT_InterruptFallingEdge = 0xAU, /*!< Interrupt on falling edge. */
  133. kPORT_InterruptEitherEdge = 0xBU, /*!< Interrupt on either edge. */
  134. kPORT_InterruptLogicOne = 0xCU, /*!< Interrupt when logic one. */
  135. #if defined(FSL_FEATURE_PORT_HAS_IRQC_TRIGGER) && FSL_FEATURE_PORT_HAS_IRQC_TRIGGER
  136. kPORT_ActiveHighTriggerOutputEnable = 0xDU, /*!< Enable active high-trigger output. */
  137. kPORT_ActiveLowTriggerOutputEnable = 0xEU, /*!< Enable active low-trigger output. */
  138. #endif
  139. } port_interrupt_t;
  140. #if defined(FSL_FEATURE_PORT_HAS_DIGITAL_FILTER) && FSL_FEATURE_PORT_HAS_DIGITAL_FILTER
  141. /*! @brief Digital filter clock source selection */
  142. typedef enum _port_digital_filter_clock_source
  143. {
  144. kPORT_BusClock = 0U, /*!< Digital filters are clocked by the bus clock. */
  145. kPORT_LpoClock = 1U, /*!< Digital filters are clocked by the 1 kHz LPO clock. */
  146. } port_digital_filter_clock_source_t;
  147. /*! @brief PORT digital filter feature configuration definition */
  148. typedef struct _port_digital_filter_config
  149. {
  150. uint32_t digitalFilterWidth; /*!< Set digital filter width */
  151. port_digital_filter_clock_source_t clockSource; /*!< Set digital filter clockSource */
  152. } port_digital_filter_config_t;
  153. #endif /* FSL_FEATURE_PORT_HAS_DIGITAL_FILTER */
  154. #if defined(FSL_FEATURE_PORT_PCR_MUX_WIDTH) && FSL_FEATURE_PORT_PCR_MUX_WIDTH
  155. /*! @brief PORT pin configuration structure */
  156. typedef struct _port_pin_config
  157. {
  158. #if defined(FSL_FEATURE_PORT_HAS_PULL_ENABLE) && FSL_FEATURE_PORT_HAS_PULL_ENABLE
  159. uint16_t pullSelect : 2; /*!< No-pull/pull-down/pull-up select */
  160. #else
  161. uint16_t : 2;
  162. #endif /* FSL_FEATURE_PORT_HAS_PULL_ENABLE */
  163. #if defined(FSL_FEATURE_PORT_HAS_SLEW_RATE) && FSL_FEATURE_PORT_HAS_SLEW_RATE
  164. uint16_t slewRate : 1; /*!< Fast/slow slew rate Configure */
  165. #else
  166. uint16_t : 1;
  167. #endif /* FSL_FEATURE_PORT_HAS_SLEW_RATE */
  168. uint16_t : 1;
  169. #if defined(FSL_FEATURE_PORT_HAS_PASSIVE_FILTER) && FSL_FEATURE_PORT_HAS_PASSIVE_FILTER
  170. uint16_t passiveFilterEnable : 1; /*!< Passive filter enable/disable */
  171. #else
  172. uint16_t : 1;
  173. #endif /* FSL_FEATURE_PORT_HAS_PASSIVE_FILTER */
  174. #if defined(FSL_FEATURE_PORT_HAS_OPEN_DRAIN) && FSL_FEATURE_PORT_HAS_OPEN_DRAIN
  175. uint16_t openDrainEnable : 1; /*!< Open drain enable/disable */
  176. #else
  177. uint16_t : 1;
  178. #endif /* FSL_FEATURE_PORT_HAS_OPEN_DRAIN */
  179. #if defined(FSL_FEATURE_PORT_HAS_DRIVE_STRENGTH) && FSL_FEATURE_PORT_HAS_DRIVE_STRENGTH
  180. uint16_t driveStrength : 1; /*!< Fast/slow drive strength configure */
  181. #else
  182. uint16_t : 1;
  183. #endif
  184. uint16_t : 1;
  185. #if defined(FSL_FEATURE_PORT_PCR_MUX_WIDTH) && FSL_FEATURE_PORT_PCR_MUX_WIDTH
  186. uint16_t mux : 3; /*!< Pin mux Configure */
  187. #else
  188. uint16_t : 3;
  189. #endif
  190. uint16_t : 4;
  191. #if defined(FSL_FEATURE_PORT_HAS_PIN_CONTROL_LOCK) && FSL_FEATURE_PORT_HAS_PIN_CONTROL_LOCK
  192. uint16_t lockRegister : 1; /*!< Lock/unlock the PCR field[15:0] */
  193. #else
  194. uint16_t : 1;
  195. #endif /* FSL_FEATURE_PORT_HAS_PIN_CONTROL_LOCK */
  196. } port_pin_config_t;
  197. #endif /* FSL_FEATURE_PORT_PCR_MUX_WIDTH */
  198. /*******************************************************************************
  199. * API
  200. ******************************************************************************/
  201. #if defined(__cplusplus)
  202. extern "C" {
  203. #endif
  204. #if defined(FSL_FEATURE_PORT_PCR_MUX_WIDTH) && FSL_FEATURE_PORT_PCR_MUX_WIDTH
  205. /*! @name Configuration */
  206. /*@{*/
  207. /*!
  208. * @brief Sets the port PCR register.
  209. *
  210. * This is an example to define an input pin or output pin PCR configuration.
  211. * @code
  212. * // Define a digital input pin PCR configuration
  213. * port_pin_config_t config = {
  214. * kPORT_PullUp,
  215. * kPORT_FastSlewRate,
  216. * kPORT_PassiveFilterDisable,
  217. * kPORT_OpenDrainDisable,
  218. * kPORT_LowDriveStrength,
  219. * kPORT_MuxAsGpio,
  220. * kPORT_UnLockRegister,
  221. * };
  222. * @endcode
  223. *
  224. * @param base PORT peripheral base pointer.
  225. * @param pin PORT pin number.
  226. * @param config PORT PCR register configuration structure.
  227. */
  228. static inline void PORT_SetPinConfig(PORT_Type *base, uint32_t pin, const port_pin_config_t *config)
  229. {
  230. assert(config);
  231. uint32_t addr = (uint32_t)&base->PCR[pin];
  232. *(volatile uint16_t *)(addr) = *((const uint16_t *)config);
  233. }
  234. /*!
  235. * @brief Sets the port PCR register for multiple pins.
  236. *
  237. * This is an example to define input pins or output pins PCR configuration.
  238. * @code
  239. * // Define a digital input pin PCR configuration
  240. * port_pin_config_t config = {
  241. * kPORT_PullUp ,
  242. * kPORT_PullEnable,
  243. * kPORT_FastSlewRate,
  244. * kPORT_PassiveFilterDisable,
  245. * kPORT_OpenDrainDisable,
  246. * kPORT_LowDriveStrength,
  247. * kPORT_MuxAsGpio,
  248. * kPORT_UnlockRegister,
  249. * };
  250. * @endcode
  251. *
  252. * @param base PORT peripheral base pointer.
  253. * @param mask PORT pin number macro.
  254. * @param config PORT PCR register configuration structure.
  255. */
  256. static inline void PORT_SetMultiplePinsConfig(PORT_Type *base, uint32_t mask, const port_pin_config_t *config)
  257. {
  258. assert(config);
  259. uint16_t pcrl = *((const uint16_t *)config);
  260. if (mask & 0xffffU)
  261. {
  262. base->GPCLR = ((mask & 0xffffU) << 16) | pcrl;
  263. }
  264. if (mask >> 16)
  265. {
  266. base->GPCHR = (mask & 0xffff0000U) | pcrl;
  267. }
  268. }
  269. /*!
  270. * @brief Configures the pin muxing.
  271. *
  272. * @param base PORT peripheral base pointer.
  273. * @param pin PORT pin number.
  274. * @param mux pin muxing slot selection.
  275. * - #kPORT_PinDisabledOrAnalog: Pin disabled or work in analog function.
  276. * - #kPORT_MuxAsGpio : Set as GPIO.
  277. * - #kPORT_MuxAlt2 : chip-specific.
  278. * - #kPORT_MuxAlt3 : chip-specific.
  279. * - #kPORT_MuxAlt4 : chip-specific.
  280. * - #kPORT_MuxAlt5 : chip-specific.
  281. * - #kPORT_MuxAlt6 : chip-specific.
  282. * - #kPORT_MuxAlt7 : chip-specific.
  283. * @Note : This function is NOT recommended to use together with the PORT_SetPinsConfig, because
  284. * the PORT_SetPinsConfig need to configure the pin mux anyway (Otherwise the pin mux is
  285. * reset to zero : kPORT_PinDisabledOrAnalog).
  286. * This function is recommended to use to reset the pin mux
  287. *
  288. */
  289. static inline void PORT_SetPinMux(PORT_Type *base, uint32_t pin, port_mux_t mux)
  290. {
  291. base->PCR[pin] = (base->PCR[pin] & ~PORT_PCR_MUX_MASK) | PORT_PCR_MUX(mux);
  292. }
  293. #endif /* FSL_FEATURE_PORT_PCR_MUX_WIDTH */
  294. #if defined(FSL_FEATURE_PORT_HAS_DIGITAL_FILTER) && FSL_FEATURE_PORT_HAS_DIGITAL_FILTER
  295. /*!
  296. * @brief Enables the digital filter in one port, each bit of the 32-bit register represents one pin.
  297. *
  298. * @param base PORT peripheral base pointer.
  299. * @param mask PORT pin number macro.
  300. */
  301. static inline void PORT_EnablePinsDigitalFilter(PORT_Type *base, uint32_t mask, bool enable)
  302. {
  303. if (enable == true)
  304. {
  305. base->DFER |= mask;
  306. }
  307. else
  308. {
  309. base->DFER &= ~mask;
  310. }
  311. }
  312. /*!
  313. * @brief Sets the digital filter in one port, each bit of the 32-bit register represents one pin.
  314. *
  315. * @param base PORT peripheral base pointer.
  316. * @param config PORT digital filter configuration structure.
  317. */
  318. static inline void PORT_SetDigitalFilterConfig(PORT_Type *base, const port_digital_filter_config_t *config)
  319. {
  320. assert(config);
  321. base->DFCR = PORT_DFCR_CS(config->clockSource);
  322. base->DFWR = PORT_DFWR_FILT(config->digitalFilterWidth);
  323. }
  324. #endif /* FSL_FEATURE_PORT_HAS_DIGITAL_FILTER */
  325. /*@}*/
  326. /*! @name Interrupt */
  327. /*@{*/
  328. /*!
  329. * @brief Configures the port pin interrupt/DMA request.
  330. *
  331. * @param base PORT peripheral base pointer.
  332. * @param pin PORT pin number.
  333. * @param config PORT pin interrupt configuration.
  334. * - #kPORT_InterruptOrDMADisabled: Interrupt/DMA request disabled.
  335. * - #kPORT_DMARisingEdge : DMA request on rising edge(if the DMA requests exit).
  336. * - #kPORT_DMAFallingEdge: DMA request on falling edge(if the DMA requests exit).
  337. * - #kPORT_DMAEitherEdge : DMA request on either edge(if the DMA requests exit).
  338. * - #kPORT_FlagRisingEdge : Flag sets on rising edge(if the Flag states exit).
  339. * - #kPORT_FlagFallingEdge : Flag sets on falling edge(if the Flag states exit).
  340. * - #kPORT_FlagEitherEdge : Flag sets on either edge(if the Flag states exit).
  341. * - #kPORT_InterruptLogicZero : Interrupt when logic zero.
  342. * - #kPORT_InterruptRisingEdge : Interrupt on rising edge.
  343. * - #kPORT_InterruptFallingEdge: Interrupt on falling edge.
  344. * - #kPORT_InterruptEitherEdge : Interrupt on either edge.
  345. * - #kPORT_InterruptLogicOne : Interrupt when logic one.
  346. * - #kPORT_ActiveHighTriggerOutputEnable : Enable active high-trigger output (if the trigger states exit).
  347. * - #kPORT_ActiveLowTriggerOutputEnable : Enable active low-trigger output (if the trigger states exit).
  348. */
  349. static inline void PORT_SetPinInterruptConfig(PORT_Type *base, uint32_t pin, port_interrupt_t config)
  350. {
  351. base->PCR[pin] = (base->PCR[pin] & ~PORT_PCR_IRQC_MASK) | PORT_PCR_IRQC(config);
  352. }
  353. /*!
  354. * @brief Reads the whole port status flag.
  355. *
  356. * If a pin is configured to generate the DMA request, the corresponding flag
  357. * is cleared automatically at the completion of the requested DMA transfer.
  358. * Otherwise, the flag remains set until a logic one is written to that flag.
  359. * If configured for a level sensitive interrupt that remains asserted, the flag
  360. * is set again immediately.
  361. *
  362. * @param base PORT peripheral base pointer.
  363. * @return Current port interrupt status flags, for example, 0x00010001 means the
  364. * pin 0 and 16 have the interrupt.
  365. */
  366. static inline uint32_t PORT_GetPinsInterruptFlags(PORT_Type *base)
  367. {
  368. return base->ISFR;
  369. }
  370. /*!
  371. * @brief Clears the multiple pin interrupt status flag.
  372. *
  373. * @param base PORT peripheral base pointer.
  374. * @param mask PORT pin number macro.
  375. */
  376. static inline void PORT_ClearPinsInterruptFlags(PORT_Type *base, uint32_t mask)
  377. {
  378. base->ISFR = mask;
  379. }
  380. /*@}*/
  381. #if defined(__cplusplus)
  382. }
  383. #endif
  384. /*! @}*/
  385. #endif /* _FSL_PORT_H_ */