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